complete the sync with wine 0.9.2
Modified: trunk/reactos/lib/dxdiagn/container.c
Modified: trunk/reactos/lib/dxdiagn/dxdiag_main.c
Modified: trunk/reactos/lib/dxdiagn/dxdiagn.spec
Modified: trunk/reactos/lib/dxdiagn/dxdiagn.xml

Modified: trunk/reactos/lib/dxdiagn/container.c
--- 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);
 }
-

Modified: trunk/reactos/lib/dxdiagn/dxdiag_main.c
--- 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;
 }
 
 /***********************************************************************

Modified: trunk/reactos/lib/dxdiagn/dxdiagn.spec
--- trunk/reactos/lib/dxdiagn/dxdiagn.spec	2005-12-11 17:51:36 UTC (rev 20069)
+++ trunk/reactos/lib/dxdiagn/dxdiagn.spec	2005-12-11 17:53:49 UTC (rev 20070)
@@ -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()

Modified: trunk/reactos/lib/dxdiagn/dxdiagn.xml
--- trunk/reactos/lib/dxdiagn/dxdiagn.xml	2005-12-11 17:51:36 UTC (rev 20069)
+++ trunk/reactos/lib/dxdiagn/dxdiagn.xml	2005-12-11 17:53:49 UTC (rev 20070)
@@ -17,6 +17,7 @@
 	<library>user32</library>
 	<library>advapi32</library>
 	<library>ole32</library>
+      <library>oleaut32</library>
 	<library>dxguid</library>
 	<library>strmiids</library>
 	<file>container.c</file>