--- trunk/reactos/lib/dxdiagn/container.c 2005-12-11 17:51:36 UTC (rev 20069)
+++ trunk/reactos/lib/dxdiagn/container.c 2005-12-11 17:53:49 UTC (rev 20070)
@@ -44,18 +44,28 @@
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_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 @@
return E_INVALIDARG;
}
+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_SubContainer* p = NULL;
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 @@
return E_INVALIDARG;
}
- p = This->subContainers;
+ 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, '.');
+ }
+
+ 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;
+ 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;
+ 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 (0 == lstrcmpW(p->contName, pwszContainer)) {
- IDxDiagContainerImpl_QueryInterface((PDXDIAGCONTAINER)p, &IID_IDxDiagContainer, (void**) ppInstance);
+ 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_GetNumberOfProps(PDXDIAGCONTAINER iface, DWORD* pdwCount) {
- /* IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; */
- FIXME("(%p, %p): stub\n", iface, pdwCount);
+HRESULT WINAPI IDxDiagContainerImpl_GetProp(PDXDIAGCONTAINER iface, LPCWSTR pwszPropName, VARIANT* 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_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);
+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;
+ }
+
+ 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_GetProp(PDXDIAGCONTAINER iface, LPCWSTR pwszPropName, VARIANT* pvarProp) {
- /* IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; */
- FIXME("(%p, %s, %p): stub\n", iface, debugstr_w(pwszPropName), pvarProp);
+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;
}
-
-IDxDiagContainerVtbl DxDiagContainer_Vtbl =
+static const IDxDiagContainerVtbl DxDiagContainer_Vtbl =
{
IDxDiagContainerImpl_QueryInterface,
IDxDiagContainerImpl_AddRef,
@@ -167,4 +319,3 @@
container->ref = 0; /* will be inited with QueryInterface */
return IDxDiagContainerImpl_QueryInterface((PDXDIAGCONTAINER)container, riid, ppobj);
}
-
--- trunk/reactos/lib/dxdiagn/dxdiag_main.c 2005-12-11 17:51:36 UTC (rev 20069)
+++ trunk/reactos/lib/dxdiagn/dxdiag_main.c 2005-12-11 17:53:49 UTC (rev 20070)
@@ -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 @@
* 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);
- 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 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 @@
*/
HRESULT WINAPI DllCanUnloadNow(void)
{
- return S_FALSE;
+ return DXDIAGN_refCount != 0 ? S_FALSE : S_OK;
}
/***********************************************************************