/* * 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; HKEY key; BOOL read_only; }; 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) { if (This->key) RegCloseKey( This->key ); 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 ) { struct data_key *This = impl_from_ISpRegDataKey( iface ); TRACE( "(%p)->(%p %d)\n", This, key, read_only ); if (This->key) return SPERR_ALREADY_INITIALIZED; This->key = key; This->read_only = read_only; return S_OK; } 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; This->key = NULL; This->read_only = FALSE; hr = ISpRegDataKey_QueryInterface( &This->ISpRegDataKey_iface, iid, obj ); ISpRegDataKey_Release( &This->ISpRegDataKey_iface ); return hr; } struct token_enum { ISpObjectTokenEnumBuilder ISpObjectTokenEnumBuilder_iface; LONG ref; BOOL init; WCHAR *req, *opt; ULONG count; }; struct token_enum *impl_from_ISpObjectTokenEnumBuilder( ISpObjectTokenEnumBuilder *iface ) { return CONTAINING_RECORD( iface, struct token_enum, ISpObjectTokenEnumBuilder_iface ); } static HRESULT WINAPI token_enum_QueryInterface( ISpObjectTokenEnumBuilder *iface, REFIID iid, void **obj ) { struct token_enum *This = impl_from_ISpObjectTokenEnumBuilder( iface ); TRACE( "(%p)->(%s %p)\n", This, debugstr_guid( iid ), obj ); if (IsEqualIID( iid, &IID_IUnknown ) || IsEqualIID( iid, &IID_IEnumSpObjectTokens ) || IsEqualIID( iid, &IID_ISpObjectTokenEnumBuilder )) { ISpObjectTokenEnumBuilder_AddRef( iface ); *obj = iface; return S_OK; } FIXME( "interface %s not implemented\n", debugstr_guid( iid ) ); *obj = NULL; return E_NOINTERFACE; } static ULONG WINAPI token_enum_AddRef( ISpObjectTokenEnumBuilder *iface ) { struct token_enum *This = impl_from_ISpObjectTokenEnumBuilder( iface ); ULONG ref = InterlockedIncrement( &This->ref ); TRACE( "(%p) ref = %u\n", This, ref ); return ref; } static ULONG WINAPI token_enum_Release( ISpObjectTokenEnumBuilder *iface ) { struct token_enum *This = impl_from_ISpObjectTokenEnumBuilder( iface ); ULONG ref = InterlockedDecrement(&This->ref); TRACE( "(%p) ref = %u\n", This, ref ); if (!ref) { heap_free( This->req ); heap_free( This->opt ); heap_free( This ); } return ref; } static HRESULT WINAPI token_enum_Next( ISpObjectTokenEnumBuilder *iface, ULONG num, ISpObjectToken **tokens, ULONG *fetched ) { FIXME( "stub\n" ); return E_NOTIMPL; } static HRESULT WINAPI token_enum_Skip( ISpObjectTokenEnumBuilder *iface, ULONG num ) { FIXME( "stub\n" ); return E_NOTIMPL; } static HRESULT WINAPI token_enum_Reset( ISpObjectTokenEnumBuilder *iface) { FIXME( "stub\n" ); return E_NOTIMPL; } static HRESULT WINAPI token_enum_Clone( ISpObjectTokenEnumBuilder *iface, IEnumSpObjectTokens **clone ) { FIXME( "stub\n" ); return E_NOTIMPL; } static HRESULT WINAPI token_enum_Item( ISpObjectTokenEnumBuilder *iface, ULONG index, ISpObjectToken **token ) { FIXME( "stub\n" ); return E_NOTIMPL; } static HRESULT WINAPI token_enum_GetCount( ISpObjectTokenEnumBuilder *iface, ULONG *count ) { struct token_enum *This = impl_from_ISpObjectTokenEnumBuilder( iface ); TRACE( "(%p)->(%p)\n", This, count ); if (!This->init) return SPERR_UNINITIALIZED; *count = This->count; return S_OK; } static HRESULT WINAPI token_enum_SetAttribs( ISpObjectTokenEnumBuilder *iface, LPCWSTR req, LPCWSTR opt) { struct token_enum *This = impl_from_ISpObjectTokenEnumBuilder( iface ); TRACE( "(%p)->(%s %s)\n", This, debugstr_w( req ), debugstr_w( opt ) ); if (This->init) return SPERR_ALREADY_INITIALIZED; if (req) { This->req = heap_strdupW( req ); if (!This->req) goto out_of_mem; } if (opt) { This->opt = heap_strdupW( opt ); if (!This->opt) goto out_of_mem; } This->init = TRUE; return S_OK; out_of_mem: heap_free( This->req ); return E_OUTOFMEMORY; } static HRESULT WINAPI token_enum_AddTokens( ISpObjectTokenEnumBuilder *iface, ULONG num, ISpObjectToken **tokens ) { FIXME( "stub\n" ); return E_NOTIMPL; } static HRESULT WINAPI token_enum_AddTokensFromDataKey( ISpObjectTokenEnumBuilder *iface, ISpDataKey *data_key, LPCWSTR sub_key, LPCWSTR cat_id ) { FIXME( "stub\n" ); return E_NOTIMPL; } static HRESULT WINAPI token_enum_AddTokensFromTokenEnum( ISpObjectTokenEnumBuilder *iface, IEnumSpObjectTokens *token_enum ) { FIXME( "stub\n" ); return E_NOTIMPL; } static HRESULT WINAPI token_enum_Sort( ISpObjectTokenEnumBuilder *iface, LPCWSTR first ) { FIXME( "stub\n" ); return E_NOTIMPL; } const struct ISpObjectTokenEnumBuilderVtbl token_enum_vtbl = { token_enum_QueryInterface, token_enum_AddRef, token_enum_Release, token_enum_Next, token_enum_Skip, token_enum_Reset, token_enum_Clone, token_enum_Item, token_enum_GetCount, token_enum_SetAttribs, token_enum_AddTokens, token_enum_AddTokensFromDataKey, token_enum_AddTokensFromTokenEnum, token_enum_Sort }; HRESULT token_enum_create( IUnknown *outer, REFIID iid, void **obj ) { struct token_enum *This = heap_alloc( sizeof(*This) ); HRESULT hr; if (!This) return E_OUTOFMEMORY; This->ISpObjectTokenEnumBuilder_iface.lpVtbl = &token_enum_vtbl; This->ref = 1; This->req = NULL; This->opt = NULL; This->init = FALSE; This->count = 0; hr = ISpObjectTokenEnumBuilder_QueryInterface( &This->ISpObjectTokenEnumBuilder_iface, iid, obj ); ISpObjectTokenEnumBuilder_Release( &This->ISpObjectTokenEnumBuilder_iface ); return hr; }