diff --git a/dlls/sapi/Makefile.in b/dlls/sapi/Makefile.in index 5303299d5d3..b8b4bebe0a4 100644 --- a/dlls/sapi/Makefile.in +++ b/dlls/sapi/Makefile.in @@ -2,7 +2,8 @@ MODULE = sapi.dll IMPORTS = uuid ole32 user32 advapi32 C_SRCS = \ - main.c + main.c \ + token.c IDL_SRCS = \ sapi_classes.idl \ diff --git a/dlls/sapi/main.c b/dlls/sapi/main.c index 53c3bef0ab9..edbb5d9bd5a 100644 --- a/dlls/sapi/main.c +++ b/dlls/sapi/main.c @@ -27,13 +27,104 @@ #include "winbase.h" #include "objbase.h" #include "rpcproxy.h" +#include "oaidl.h" +#include "ocidl.h" + +#include "initguid.h" +#include "sapiddk.h" #include "wine/debug.h" +#include "sapi_private.h" + WINE_DEFAULT_DEBUG_CHANNEL(sapi); static HINSTANCE hinstance; +struct class_factory +{ + IClassFactory IClassFactory_iface; + HRESULT (*create_instance)(IUnknown *, REFIID, void **); +}; + +static inline struct class_factory *impl_from_IClassFactory( IClassFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct class_factory, IClassFactory_iface ); +} + +static HRESULT WINAPI class_factory_QueryInterface( IClassFactory *iface, + REFIID iid, void **obj ) +{ + if (IsEqualIID( iid, &IID_IUnknown ) || + IsEqualIID( iid, &IID_IClassFactory )) + { + IClassFactory_AddRef( iface ); + *obj = iface; + return S_OK; + } + + FIXME( "interface %s not implemented\n", debugstr_guid( iid ) ); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI class_factory_AddRef( IClassFactory *iface ) +{ + return 2; +} + +static ULONG WINAPI class_factory_Release( IClassFactory *iface ) +{ + return 1; +} + +static HRESULT WINAPI class_factory_CreateInstance( IClassFactory *iface, + IUnknown *outer, REFIID iid, + void **obj ) +{ + struct class_factory *This = impl_from_IClassFactory( iface ); + + TRACE( "%p %s %p\n", outer, debugstr_guid( iid ), obj ); + + *obj = NULL; + return This->create_instance( outer, iid, obj ); +} + +static HRESULT WINAPI class_factory_LockServer( IClassFactory *iface, + BOOL lock ) +{ + FIXME( "%d: stub!\n", lock ); + return S_OK; +} + +static const struct IClassFactoryVtbl class_factory_vtbl = +{ + class_factory_QueryInterface, + class_factory_AddRef, + class_factory_Release, + class_factory_CreateInstance, + class_factory_LockServer +}; + +static struct class_factory data_key_cf = { { &class_factory_vtbl }, data_key_create }; + +/****************************************************************** + * DllGetClassObject + */ +HRESULT WINAPI DllGetClassObject( REFCLSID clsid, REFIID iid, void **obj ) +{ + IClassFactory *cf = NULL; + + TRACE( "(%s %s %p)\n", debugstr_guid( clsid ), debugstr_guid( iid ), obj ); + + if (IsEqualCLSID( clsid, &CLSID_SpDataKey )) + cf = &data_key_cf.IClassFactory_iface; + + if (!cf) return CLASS_E_CLASSNOTAVAILABLE; + + return IClassFactory_QueryInterface( cf, iid, obj ); +} + BOOL WINAPI DllMain( HINSTANCE dll, DWORD reason, LPVOID reserved ) { switch (reason) diff --git a/dlls/sapi/sapi.spec b/dlls/sapi/sapi.spec index 6f279a1d16e..b16365d0c9f 100644 --- a/dlls/sapi/sapi.spec +++ b/dlls/sapi/sapi.spec @@ -1,4 +1,4 @@ @ stdcall -private DllCanUnloadNow() -#@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() diff --git a/dlls/sapi/sapi_private.h b/dlls/sapi/sapi_private.h new file mode 100644 index 00000000000..7809f5025d3 --- /dev/null +++ b/dlls/sapi/sapi_private.h @@ -0,0 +1,31 @@ +/* + * Speech API (SAPI) private header file. + * + * Copyright (C) 2017 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +HRESULT data_key_create( IUnknown *outer, REFIID iid, void **obj ) DECLSPEC_HIDDEN; + +static inline void * __WINE_ALLOC_SIZE(1) heap_alloc(size_t len) +{ + return HeapAlloc(GetProcessHeap(), 0, len); +} + +static inline BOOL heap_free(void *mem) +{ + return HeapFree(GetProcessHeap(), 0, mem); +} diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c new file mode 100644 index 00000000000..bcacba82216 --- /dev/null +++ b/dlls/sapi/token.c @@ -0,0 +1,215 @@ +/* + * Speech API (SAPI) token implementation. + * + * Copyright (C) 2017 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "sapiddk.h" +#include "sperror.h" + +#include "wine/debug.h" + +#include "sapi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(sapi); + +struct data_key +{ + ISpRegDataKey ISpRegDataKey_iface; + LONG ref; +}; + +struct data_key *impl_from_ISpRegDataKey( ISpRegDataKey *iface ) +{ + return CONTAINING_RECORD( iface, struct data_key, ISpRegDataKey_iface ); +} + +static HRESULT WINAPI data_key_QueryInterface( ISpRegDataKey *iface, REFIID iid, void **obj ) +{ + struct data_key *This = impl_from_ISpRegDataKey( iface ); + + TRACE( "(%p)->(%s %p)\n", This, debugstr_guid( iid ), obj ); + + if (IsEqualIID( iid, &IID_IUnknown ) || + IsEqualIID( iid, &IID_ISpDataKey ) || + IsEqualIID( iid, &IID_ISpRegDataKey )) + { + ISpRegDataKey_AddRef( iface ); + *obj = iface; + return S_OK; + } + + FIXME( "interface %s not implemented\n", debugstr_guid( iid ) ); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI data_key_AddRef( ISpRegDataKey *iface ) +{ + struct data_key *This = impl_from_ISpRegDataKey( iface ); + ULONG ref = InterlockedIncrement( &This->ref ); + + TRACE( "(%p) ref = %u\n", This, ref ); + return ref; +} + +static ULONG WINAPI data_key_Release( ISpRegDataKey *iface ) +{ + struct data_key *This = impl_from_ISpRegDataKey( iface ); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE( "(%p) ref = %u\n", This, ref ); + + if (!ref) + { + heap_free( This ); + } + + return ref; +} + +static HRESULT WINAPI data_key_SetData( ISpRegDataKey *iface, LPCWSTR name, + ULONG size, const BYTE *data ) +{ + FIXME( "stub\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI data_key_GetData( ISpRegDataKey *iface, LPCWSTR name, + ULONG *size, BYTE *data ) +{ + FIXME( "stub\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI data_key_SetStringValue( ISpRegDataKey *iface, + LPCWSTR name, LPCWSTR value ) +{ + FIXME( "stub\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI data_key_GetStringValue( ISpRegDataKey *iface, + LPCWSTR name, LPWSTR *value ) +{ + FIXME( "stub\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI data_key_SetDWORD( ISpRegDataKey *iface, + LPCWSTR name, DWORD value ) +{ + FIXME( "stub\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI data_key_GetDWORD( ISpRegDataKey *iface, + LPCWSTR name, DWORD *pdwValue ) +{ + FIXME( "stub\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI data_key_OpenKey( ISpRegDataKey *iface, + LPCWSTR name, ISpDataKey **sub_key ) +{ + FIXME( "stub\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI data_key_CreateKey( ISpRegDataKey *iface, + LPCWSTR name, ISpDataKey **sub_key ) +{ + FIXME( "stub\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI data_key_DeleteKey( ISpRegDataKey *iface, LPCWSTR name ) +{ + FIXME( "stub\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI data_key_DeleteValue( ISpRegDataKey *iface, LPCWSTR name ) +{ + FIXME( "stub\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI data_key_EnumKeys( ISpRegDataKey *iface, + ULONG index, LPWSTR *sub_key ) +{ + FIXME( "stub\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI data_key_EnumValues( ISpRegDataKey *iface, + ULONG index, LPWSTR *value ) +{ + FIXME( "stub\n" ); + return E_NOTIMPL; +} + +static HRESULT WINAPI data_key_SetKey( ISpRegDataKey *iface, + HKEY key, BOOL read_only ) +{ + FIXME( "stub\n" ); + return E_NOTIMPL; +} + +const struct ISpRegDataKeyVtbl data_key_vtbl = +{ + data_key_QueryInterface, + data_key_AddRef, + data_key_Release, + data_key_SetData, + data_key_GetData, + data_key_SetStringValue, + data_key_GetStringValue, + data_key_SetDWORD, + data_key_GetDWORD, + data_key_OpenKey, + data_key_CreateKey, + data_key_DeleteKey, + data_key_DeleteValue, + data_key_EnumKeys, + data_key_EnumValues, + data_key_SetKey +}; + +HRESULT data_key_create( IUnknown *outer, REFIID iid, void **obj ) +{ + struct data_key *This = heap_alloc( sizeof(*This) ); + HRESULT hr; + + if (!This) return E_OUTOFMEMORY; + This->ISpRegDataKey_iface.lpVtbl = &data_key_vtbl; + This->ref = 1; + + hr = ISpRegDataKey_QueryInterface( &This->ISpRegDataKey_iface, iid, obj ); + + ISpRegDataKey_Release( &This->ISpRegDataKey_iface ); + return hr; +}