| /* |
| * Implements IPropertyBag. (internal) |
| * |
| * hidenori@a2.ctktv.ne.jp |
| */ |
| |
| #include "config.h" |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "wingdi.h" |
| #include "winuser.h" |
| #include "winreg.h" |
| #include "winerror.h" |
| #include "wine/obj_base.h" |
| #include "objidl.h" |
| #include "oleidl.h" |
| #include "ocidl.h" |
| #include "oleauto.h" |
| #include "strmif.h" |
| #include "wine/unicode.h" |
| |
| #include "debugtools.h" |
| DEFAULT_DEBUG_CHANNEL(quartz); |
| |
| #include "quartz_private.h" |
| #include "monprop.h" |
| |
| |
| static HRESULT WINAPI |
| IPropertyBag_fnQueryInterface(IPropertyBag* iface,REFIID riid,void** ppobj) |
| { |
| CRegPropertyBag_THIS(iface,propbag); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); |
| } |
| |
| static ULONG WINAPI |
| IPropertyBag_fnAddRef(IPropertyBag* iface) |
| { |
| CRegPropertyBag_THIS(iface,propbag); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return IUnknown_AddRef(This->unk.punkControl); |
| } |
| |
| static ULONG WINAPI |
| IPropertyBag_fnRelease(IPropertyBag* iface) |
| { |
| CRegPropertyBag_THIS(iface,propbag); |
| |
| TRACE("(%p)->()\n",This); |
| |
| return IUnknown_Release(This->unk.punkControl); |
| } |
| |
| static HRESULT WINAPI |
| IPropertyBag_fnRead(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar,IErrorLog* pLog) |
| { |
| CRegPropertyBag_THIS(iface,propbag); |
| LONG lr; |
| DWORD dwSize; |
| DWORD dwValueType; |
| |
| TRACE("(%p)->(%s,%p,%p)\n",This, |
| debugstr_w(lpszPropName),pVar,pLog); |
| |
| if ( lpszPropName == NULL || pVar == NULL ) |
| return E_POINTER; |
| |
| dwSize = 0; |
| lr = RegQueryValueExW( |
| This->m_hKey, lpszPropName, NULL, |
| &dwValueType, NULL, &dwSize ); |
| if ( lr != ERROR_SUCCESS ) |
| return E_INVALIDARG; |
| |
| switch ( dwValueType ) |
| { |
| case REG_SZ: |
| if ( pVar->n1.n2.vt == VT_EMPTY ) |
| pVar->n1.n2.vt = VT_BSTR; |
| if ( pVar->n1.n2.vt != VT_BSTR ) |
| return E_FAIL; |
| |
| pVar->n1.n2.n3.bstrVal = SysAllocStringByteLen( |
| NULL, dwSize ); |
| if ( pVar->n1.n2.n3.bstrVal == NULL ) |
| return E_OUTOFMEMORY; |
| lr = RegQueryValueExW( |
| This->m_hKey, lpszPropName, NULL, |
| &dwValueType, |
| (BYTE*)pVar->n1.n2.n3.bstrVal, &dwSize ); |
| if ( lr != ERROR_SUCCESS ) |
| { |
| SysFreeString(pVar->n1.n2.n3.bstrVal); |
| return E_FAIL; |
| } |
| break; |
| default: |
| FIXME("(%p)->(%s,%p,%p) - unsupported value type.\n",This, |
| debugstr_w(lpszPropName),pVar,pLog); |
| return E_FAIL; |
| } |
| |
| return NOERROR; |
| } |
| |
| static HRESULT WINAPI |
| IPropertyBag_fnWrite(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar) |
| { |
| CRegPropertyBag_THIS(iface,propbag); |
| |
| FIXME("(%p)->(%s,%p) stub!\n",This, |
| debugstr_w(lpszPropName),pVar); |
| |
| if ( lpszPropName == NULL || pVar == NULL ) |
| return E_POINTER; |
| |
| return E_NOTIMPL; |
| } |
| |
| |
| |
| |
| static ICOM_VTABLE(IPropertyBag) ipropbag = |
| { |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE |
| /* IUnknown fields */ |
| IPropertyBag_fnQueryInterface, |
| IPropertyBag_fnAddRef, |
| IPropertyBag_fnRelease, |
| /* IPropertyBag fields */ |
| IPropertyBag_fnRead, |
| IPropertyBag_fnWrite, |
| }; |
| |
| static HRESULT CRegPropertyBag_InitIPropertyBag( |
| CRegPropertyBag* prpb, HKEY hkRoot, LPCWSTR lpKeyPath ) |
| { |
| ICOM_VTBL(&prpb->propbag) = &ipropbag; |
| |
| if ( RegOpenKeyExW( |
| hkRoot, lpKeyPath, 0, |
| KEY_ALL_ACCESS, &prpb->m_hKey ) != ERROR_SUCCESS ) |
| return E_FAIL; |
| |
| return NOERROR; |
| } |
| |
| static void CRegPropertyBag_UninitIPropertyBag( |
| CRegPropertyBag* prpb ) |
| { |
| RegCloseKey( prpb->m_hKey ); |
| } |
| |
| |
| static void QUARTZ_DestroyRegPropertyBag(IUnknown* punk) |
| { |
| CRegPropertyBag_THIS(punk,unk); |
| |
| CRegPropertyBag_UninitIPropertyBag(This); |
| } |
| |
| |
| /* can I use offsetof safely? - FIXME? */ |
| static QUARTZ_IFEntry IFEntries[] = |
| { |
| { &IID_IPropertyBag, offsetof(CRegPropertyBag,propbag)-offsetof(CRegPropertyBag,unk) }, |
| }; |
| |
| HRESULT QUARTZ_CreateRegPropertyBag( |
| HKEY hkRoot, LPCWSTR lpKeyPath, |
| IPropertyBag** ppPropBag ) |
| { |
| CRegPropertyBag* prpb; |
| HRESULT hr; |
| |
| TRACE("(%08x,%s,%p)\n",hkRoot,debugstr_w(lpKeyPath),ppPropBag ); |
| |
| prpb = (CRegPropertyBag*)QUARTZ_AllocObj( sizeof(CRegPropertyBag) ); |
| if ( prpb == NULL ) |
| return E_OUTOFMEMORY; |
| |
| QUARTZ_IUnkInit( &prpb->unk, NULL ); |
| hr = CRegPropertyBag_InitIPropertyBag( prpb, hkRoot, lpKeyPath ); |
| if ( FAILED(hr) ) |
| { |
| QUARTZ_FreeObj( prpb ); |
| return hr; |
| } |
| |
| prpb->unk.pEntries = IFEntries; |
| prpb->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]); |
| prpb->unk.pOnFinalRelease = &QUARTZ_DestroyRegPropertyBag; |
| |
| *ppPropBag = (IPropertyBag*)(&prpb->propbag); |
| |
| return S_OK; |
| } |
| |
| |