From 3785710133cccff597f159291cc8f8ecd4b087e4 Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Sun, 11 Dec 2005 17:53:49 +0000 Subject: [PATCH] complete the sync with wine 0.9.2 svn path=/trunk/; revision=20070 --- reactos/lib/dxdiagn/container.c | 201 ++++++++++++++++++++++++++---- reactos/lib/dxdiagn/dxdiag_main.c | 41 +++--- reactos/lib/dxdiagn/dxdiagn.spec | 8 +- reactos/lib/dxdiagn/dxdiagn.xml | 1 + 4 files changed, 205 insertions(+), 46 deletions(-) diff --git a/reactos/lib/dxdiagn/container.c b/reactos/lib/dxdiagn/container.c index 7f6e4831bf8..aa15d1082e0 100644 --- a/reactos/lib/dxdiagn/container.c +++ b/reactos/lib/dxdiagn/container.c @@ -44,18 +44,28 @@ HRESULT WINAPI IDxDiagContainerImpl_QueryInterface(PDXDIAGCONTAINER iface, REFII ULONG WINAPI IDxDiagContainerImpl_AddRef(PDXDIAGCONTAINER iface) { IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; - TRACE("(%p) : AddRef from %ld\n", This, This->ref); - return ++(This->ref); + ULONG refCount = InterlockedIncrement(&This->ref); + + TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1); + + DXDIAGN_LockModule(); + + return refCount; } ULONG WINAPI IDxDiagContainerImpl_Release(PDXDIAGCONTAINER iface) { IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; - ULONG ref = --This->ref; - TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref); - if (ref == 0) { + ULONG refCount = InterlockedDecrement(&This->ref); + + TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1); + + if (!refCount) { HeapFree(GetProcessHeap(), 0, This); } - return ref; + + DXDIAGN_UnlockModule(); + + return refCount; } /* IDxDiagContainer Interface follow: */ @@ -70,9 +80,9 @@ HRESULT WINAPI IDxDiagContainerImpl_GetNumberOfChildContainers(PDXDIAGCONTAINER } HRESULT WINAPI IDxDiagContainerImpl_EnumChildContainerNames(PDXDIAGCONTAINER iface, DWORD dwIndex, LPWSTR pwszContainer, DWORD cchContainer) { + IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; IDxDiagContainerImpl_SubContainer* p = NULL; DWORD i = 0; - IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; TRACE("(%p, %lu, %s, %lu)\n", iface, dwIndex, debugstr_w(pwszContainer), cchContainer); @@ -98,9 +108,28 @@ HRESULT WINAPI IDxDiagContainerImpl_EnumChildContainerNames(PDXDIAGCONTAINER ifa return E_INVALIDARG; } -HRESULT WINAPI IDxDiagContainerImpl_GetChildContainer(PDXDIAGCONTAINER iface, LPCWSTR pwszContainer, IDxDiagContainer** ppInstance) { +HRESULT WINAPI IDxDiagContainerImpl_GetChildContainerInternal(PDXDIAGCONTAINER iface, LPCWSTR pwszContainer, IDxDiagContainer** ppInstance) { + IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; IDxDiagContainerImpl_SubContainer* p = NULL; + + p = This->subContainers; + while (NULL != p) { + if (0 == lstrcmpW(p->contName, pwszContainer)) { + *ppInstance = (PDXDIAGCONTAINER)p->pCont; + return S_OK; + } + p = p->next; + } + return E_INVALIDARG; +} + +HRESULT WINAPI IDxDiagContainerImpl_GetChildContainer(PDXDIAGCONTAINER iface, LPCWSTR pwszContainer, IDxDiagContainer** ppInstance) { IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; + IDxDiagContainer* pContainer = NULL; + LPWSTR tmp, orig_tmp; + INT tmp_len; + WCHAR* cur; + HRESULT hr = E_INVALIDARG; FIXME("(%p, %s, %p)\n", iface, debugstr_w(pwszContainer), ppInstance); @@ -108,38 +137,161 @@ HRESULT WINAPI IDxDiagContainerImpl_GetChildContainer(PDXDIAGCONTAINER iface, LP return E_INVALIDARG; } - p = This->subContainers; - while (NULL != p) { - if (0 == lstrcmpW(p->contName, pwszContainer)) { - IDxDiagContainerImpl_QueryInterface((PDXDIAGCONTAINER)p, &IID_IDxDiagContainer, (void**) ppInstance); - return S_OK; - } - p = p->next; + pContainer = (PDXDIAGCONTAINER) This; + + tmp_len = strlenW(pwszContainer) + 1; + orig_tmp = tmp = HeapAlloc(GetProcessHeap(), 0, tmp_len * sizeof(WCHAR)); + if (NULL == tmp) return E_FAIL; + lstrcpynW(tmp, pwszContainer, tmp_len); + + cur = strchrW(tmp, '.'); + while (NULL != cur) { + *cur = '\0'; /* cut tmp string to '.' */ + hr = IDxDiagContainerImpl_GetChildContainerInternal(pContainer, tmp, &pContainer); + if (!SUCCEEDED(hr) || NULL == pContainer) + goto on_error; + *cur++; /* go after '.' (just replaced by \0) */ + tmp = cur; + cur = strchrW(tmp, '.'); } - return E_INVALIDARG; + hr = IDxDiagContainerImpl_GetChildContainerInternal(pContainer, tmp, ppInstance); + if (SUCCEEDED(hr)) { + IDxDiagContainerImpl_AddRef((PDXDIAGCONTAINER)*ppInstance); + } + +on_error: + HeapFree(GetProcessHeap(), 0, orig_tmp); + return hr; } HRESULT WINAPI IDxDiagContainerImpl_GetNumberOfProps(PDXDIAGCONTAINER iface, DWORD* pdwCount) { - /* IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; */ - FIXME("(%p, %p): stub\n", iface, pdwCount); + IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; + TRACE("(%p)\n", iface); + if (NULL == pdwCount) { + return E_INVALIDARG; + } + *pdwCount = This->nProperties; return S_OK; } HRESULT WINAPI IDxDiagContainerImpl_EnumPropNames(PDXDIAGCONTAINER iface, DWORD dwIndex, LPWSTR pwszPropName, DWORD cchPropName) { - /* IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; */ - FIXME("(%p, %lu, %s, %lu): stub\n", iface, dwIndex, debugstr_w(pwszPropName), cchPropName); - return S_OK; + IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; + IDxDiagContainerImpl_Property* p = NULL; + DWORD i = 0; + + FIXME("(%p, %lu, %s, %lu)\n", iface, dwIndex, debugstr_w(pwszPropName), cchPropName); + + if (NULL == pwszPropName) { + return E_INVALIDARG; + } + if (256 > cchPropName) { + return DXDIAG_E_INSUFFICIENT_BUFFER; + } + + p = This->properties; + while (NULL != p) { + if (dwIndex == i) { + if (cchPropName <= lstrlenW(p->vName)) { + return DXDIAG_E_INSUFFICIENT_BUFFER; + } + lstrcpynW(pwszPropName, p->vName, cchPropName); + return S_OK; + } + p = p->next; + ++i; + } + return E_INVALIDARG; } HRESULT WINAPI IDxDiagContainerImpl_GetProp(PDXDIAGCONTAINER iface, LPCWSTR pwszPropName, VARIANT* pvarProp) { - /* IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; */ - FIXME("(%p, %s, %p): stub\n", iface, debugstr_w(pwszPropName), pvarProp); + IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; + IDxDiagContainerImpl_Property* p = NULL; + FIXME("(%p, %s, %p)\n", iface, debugstr_w(pwszPropName), pvarProp); + + if (NULL == pvarProp || NULL == pwszPropName) { + return E_INVALIDARG; + } + + p = This->properties; + while (NULL != p) { + if (0 == lstrcmpW(p->vName, pwszPropName)) { + VariantCopy(pvarProp, &p->v); + return S_OK; + } + p = p->next; + } return S_OK; } +HRESULT WINAPI IDxDiagContainerImpl_AddProp(PDXDIAGCONTAINER iface, LPCWSTR pwszPropName, VARIANT* pVarProp) { + IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; + IDxDiagContainerImpl_Property* p = NULL; + IDxDiagContainerImpl_Property* pNew = NULL; + + FIXME("(%p, %s, %p)\n", iface, debugstr_w(pwszPropName), pVarProp); + + if (NULL == pVarProp || NULL == pwszPropName) { + return E_INVALIDARG; + } -IDxDiagContainerVtbl DxDiagContainer_Vtbl = + pNew = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDxDiagContainerImpl_Property)); + if (NULL == pNew) { + return E_OUTOFMEMORY; + } + VariantInit(&pNew->v); + VariantCopy(&pNew->v, pVarProp); + pNew->vName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (lstrlenW(pwszPropName) + 1) * sizeof(WCHAR)); + lstrcpyW(pNew->vName, pwszPropName); + pNew->next = NULL; + + p = This->properties; + if (NULL == p) { + This->properties = pNew; + } else { + while (NULL != p->next) { + p = p->next; + } + p->next = pNew; + } + ++This->nProperties; + return S_OK; +} + +HRESULT WINAPI IDxDiagContainerImpl_AddChildContainer(PDXDIAGCONTAINER iface, LPCWSTR pszContName, PDXDIAGCONTAINER pSubCont) { + IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; + IDxDiagContainerImpl_SubContainer* p = NULL; + IDxDiagContainerImpl_SubContainer* pNew = NULL; + + FIXME("(%p, %s, %p)\n", iface, debugstr_w(pszContName), pSubCont); + + if (NULL == pSubCont || NULL == pszContName) { + return E_INVALIDARG; + } + + pNew = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDxDiagContainerImpl_SubContainer)); + if (NULL == pNew) { + return E_OUTOFMEMORY; + } + pNew->pCont = pSubCont; + pNew->contName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (lstrlenW(pszContName) + 1) * sizeof(WCHAR)); + lstrcpyW(pNew->contName, pszContName); + pNew->next = NULL; + + p = This->subContainers; + if (NULL == p) { + This->subContainers = pNew; + } else { + while (NULL != p->next) { + p = p->next; + } + p->next = pNew; + } + ++This->nSubContainers; + return S_OK; +} + +static const IDxDiagContainerVtbl DxDiagContainer_Vtbl = { IDxDiagContainerImpl_QueryInterface, IDxDiagContainerImpl_AddRef, @@ -167,4 +319,3 @@ HRESULT DXDiag_CreateDXDiagContainer(REFIID riid, LPVOID *ppobj) { container->ref = 0; /* will be inited with QueryInterface */ return IDxDiagContainerImpl_QueryInterface((PDXDIAGCONTAINER)container, riid, ppobj); } - diff --git a/reactos/lib/dxdiagn/dxdiag_main.c b/reactos/lib/dxdiagn/dxdiag_main.c index 71dadc70b51..b72f9cd464c 100644 --- a/reactos/lib/dxdiagn/dxdiag_main.c +++ b/reactos/lib/dxdiagn/dxdiag_main.c @@ -25,6 +25,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dxdiag); +LONG DXDIAGN_refCount = 0; + /* At process attach */ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) { @@ -39,45 +41,50 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) * DXDiag ClassFactory */ typedef struct { - /* IUnknown fields */ - IClassFactoryVtbl *lpVtbl; - DWORD ref; + const IClassFactoryVtbl *lpVtbl; REFCLSID rclsid; HRESULT (*pfnCreateInstanceFactory)(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj); } IClassFactoryImpl; static HRESULT WINAPI DXDiagCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid)); + + if (ppobj == NULL) return E_POINTER; - FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj); return E_NOINTERFACE; } static ULONG WINAPI DXDiagCF_AddRef(LPCLASSFACTORY iface) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; - return InterlockedIncrement(&This->ref); + DXDIAGN_LockModule(); + + return 2; /* non-heap based object */ } static ULONG WINAPI DXDiagCF_Release(LPCLASSFACTORY iface) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; - /* static class, won't be freed */ - return InterlockedDecrement(&This->ref); + DXDIAGN_UnlockModule(); + + return 1; /* non-heap based object */ } static HRESULT WINAPI DXDiagCF_CreateInstance(LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj) { IClassFactoryImpl *This = (IClassFactoryImpl *)iface; - TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj); + return This->pfnCreateInstanceFactory(iface, pOuter, riid, ppobj); } static HRESULT WINAPI DXDiagCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; - FIXME("(%p)->(%d),stub!\n",This,dolock); + TRACE("(%d)\n", dolock); + + if (dolock) + DXDIAGN_LockModule(); + else + DXDIAGN_UnlockModule(); + return S_OK; } -static IClassFactoryVtbl DXDiagCF_Vtbl = { +static const IClassFactoryVtbl DXDiagCF_Vtbl = { DXDiagCF_QueryInterface, DXDiagCF_AddRef, DXDiagCF_Release, @@ -86,8 +93,8 @@ static IClassFactoryVtbl DXDiagCF_Vtbl = { }; static IClassFactoryImpl DXDiag_CFS[] = { - { &DXDiagCF_Vtbl, 1, &CLSID_DxDiagProvider, DXDiag_CreateDXDiagProvider }, - { NULL, 0, NULL, NULL } + { &DXDiagCF_Vtbl, &CLSID_DxDiagProvider, DXDiag_CreateDXDiagProvider }, + { NULL, NULL, NULL } }; /*********************************************************************** @@ -95,7 +102,7 @@ static IClassFactoryImpl DXDiag_CFS[] = { */ HRESULT WINAPI DllCanUnloadNow(void) { - return S_FALSE; + return DXDIAGN_refCount != 0 ? S_FALSE : S_OK; } /*********************************************************************** diff --git a/reactos/lib/dxdiagn/dxdiagn.spec b/reactos/lib/dxdiagn/dxdiagn.spec index 9da6bf3e2e9..b16365d0c9f 100644 --- a/reactos/lib/dxdiagn/dxdiagn.spec +++ b/reactos/lib/dxdiagn/dxdiagn.spec @@ -1,4 +1,4 @@ -@ stdcall -private DllCanUnloadNow() DllCanUnloadNow -@ stdcall -private DllGetClassObject(ptr ptr ptr) DllGetClassObject -@ stdcall -private DllRegisterServer() DllRegisterServer -@ stdcall -private DllUnregisterServer() DllUnregisterServer +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/reactos/lib/dxdiagn/dxdiagn.xml b/reactos/lib/dxdiagn/dxdiagn.xml index c9f98e3419b..9de8c81d6e2 100644 --- a/reactos/lib/dxdiagn/dxdiagn.xml +++ b/reactos/lib/dxdiagn/dxdiagn.xml @@ -17,6 +17,7 @@ user32 advapi32 ole32 + oleaut32 dxguid strmiids container.c -- 2.17.1