[DXDIAGN]
authorAmine Khaldi <amine.khaldi@reactos.org>
Tue, 1 Oct 2013 17:46:41 +0000 (17:46 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Tue, 1 Oct 2013 17:46:41 +0000 (17:46 +0000)
* Sync with Wine 1.7.1. It was synced just recently (8 years ago) but there's not harm in syncing it again ;)
CORE-7469

svn path=/trunk/; revision=60500

13 files changed:
reactos/dll/directx/wine/dxdiagn/CMakeLists.txt
reactos/dll/directx/wine/dxdiagn/container.c
reactos/dll/directx/wine/dxdiagn/dxdiag_main.c
reactos/dll/directx/wine/dxdiagn/dxdiag_private.h
reactos/dll/directx/wine/dxdiagn/dxdiagn.idl [new file with mode: 0644]
reactos/dll/directx/wine/dxdiagn/dxdiagn.rc [new file with mode: 0644]
reactos/dll/directx/wine/dxdiagn/dxdiagn.rgs [new file with mode: 0644]
reactos/dll/directx/wine/dxdiagn/fil_data.idl [new file with mode: 0644]
reactos/dll/directx/wine/dxdiagn/provider.c
reactos/dll/directx/wine/dxdiagn/regsvr.c [deleted file]
reactos/dll/directx/wine/dxdiagn/resource.h [moved from reactos/dll/directx/wine/dxdiagn/version.rc with 63% similarity]
reactos/include/reactos/wine/dxdiag.h [new file with mode: 0644]
reactos/media/doc/README.WINE

index a3a30b1..182b004 100644 (file)
@@ -1,28 +1,19 @@
 
 
-
+add_definitions(-D__WINESRC__)
 include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
 include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
-
 spec2def(dxdiagn.dll dxdiagn.spec)
 
 spec2def(dxdiagn.dll dxdiagn.spec)
 
-add_library(dxdiagn SHARED
+list(APPEND SOURCE
     container.c
     dxdiag_main.c
     provider.c
     container.c
     dxdiag_main.c
     provider.c
-    regsvr.c
     ${CMAKE_CURRENT_BINARY_DIR}/dxdiagn.def)
 
     ${CMAKE_CURRENT_BINARY_DIR}/dxdiagn.def)
 
-set_module_type(dxdiagn win32dll UNICODE)
-
-target_link_libraries(dxdiagn uuid wine)
-
-add_importlibs(dxdiagn
-    user32
-    advapi32
-    ole32
-    oleaut32
-    msvcrt
-    kernel32
-    ntdll)
-
+add_idl_headers(dxdiagn_idlheader fil_data.idl)
+add_library(dxdiagn SHARED ${SOURCE} dxdiagn.rc)
+set_module_type(dxdiagn win32dll)
+target_link_libraries(dxdiagn strmiids dxguid uuid wine)
+add_dependencies(dxdiagn dxdiagn_idlheader)
+add_importlibs(dxdiagn d3d9 ddraw version ole32 oleaut32 psapi user32 msvcrt kernel32 ntdll)
 add_pch(dxdiagn dxdiag_private.h)
 add_cd_file(TARGET dxdiagn DESTINATION reactos/system32 FOR all)
 add_pch(dxdiagn dxdiag_private.h)
 add_cd_file(TARGET dxdiagn DESTINATION reactos/system32 FOR all)
index 7558171..9b7591a 100644 (file)
@@ -1,6 +1,6 @@
-/*
+/* 
  * IDxDiagContainer Implementation
  * IDxDiagContainer Implementation
- *
+ * 
  * Copyright 2004 Raphael Junqueira
  *
  * This library is free software; you can redistribute it and/or
  * Copyright 2004 Raphael Junqueira
  *
  * This library is free software; you can redistribute it and/or
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  *
  * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
  */
 
 #include <config.h>
  *
  */
 
 #include <config.h>
+
+#define COBJMACROS
 #include "dxdiag_private.h"
 #include <wine/debug.h>
 #include <wine/unicode.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);
 
 #include "dxdiag_private.h"
 #include <wine/debug.h>
 #include <wine/unicode.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);
 
+static inline IDxDiagContainerImpl *impl_from_IDxDiagContainer(IDxDiagContainer *iface)
+{
+    return CONTAINING_RECORD(iface, IDxDiagContainerImpl, IDxDiagContainer_iface);
+}
+
 /* IDxDiagContainer IUnknown parts follow: */
 /* IDxDiagContainer IUnknown parts follow: */
-HRESULT WINAPI IDxDiagContainerImpl_QueryInterface(PDXDIAGCONTAINER iface, REFIID riid, LPVOID *ppobj)
+static HRESULT WINAPI IDxDiagContainerImpl_QueryInterface(IDxDiagContainer *iface, REFIID riid,
+        void **ppobj)
 {
 {
-    IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface;
+    IDxDiagContainerImpl *This = impl_from_IDxDiagContainer(iface);
+
+    if (!ppobj) return E_INVALIDARG;
 
     if (IsEqualGUID(riid, &IID_IUnknown)
         || IsEqualGUID(riid, &IID_IDxDiagContainer)) {
 
     if (IsEqualGUID(riid, &IID_IUnknown)
         || IsEqualGUID(riid, &IID_IDxDiagContainer)) {
-        IDxDiagContainerImpl_AddRef(iface);
+        IUnknown_AddRef(iface);
         *ppobj = This;
         return S_OK;
     }
 
     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
         *ppobj = This;
         return S_OK;
     }
 
     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
+    *ppobj = NULL;
     return E_NOINTERFACE;
 }
 
     return E_NOINTERFACE;
 }
 
-ULONG WINAPI IDxDiagContainerImpl_AddRef(PDXDIAGCONTAINER iface) {
-    IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface;
+static ULONG WINAPI IDxDiagContainerImpl_AddRef(IDxDiagContainer *iface)
+{
+    IDxDiagContainerImpl *This = impl_from_IDxDiagContainer(iface);
     ULONG refCount = InterlockedIncrement(&This->ref);
 
     ULONG refCount = InterlockedIncrement(&This->ref);
 
-    TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1);
+    TRACE("(%p)->(ref before=%u)\n", This, refCount - 1);
 
     DXDIAGN_LockModule();
 
     return refCount;
 }
 
 
     DXDIAGN_LockModule();
 
     return refCount;
 }
 
-ULONG WINAPI IDxDiagContainerImpl_Release(PDXDIAGCONTAINER iface) {
-    IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface;
+static ULONG WINAPI IDxDiagContainerImpl_Release(IDxDiagContainer *iface)
+{
+    IDxDiagContainerImpl *This = impl_from_IDxDiagContainer(iface);
     ULONG refCount = InterlockedDecrement(&This->ref);
 
     ULONG refCount = InterlockedDecrement(&This->ref);
 
-    TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1);
+    TRACE("(%p)->(ref before=%u)\n", This, refCount + 1);
 
     if (!refCount) {
 
     if (!refCount) {
+        IDxDiagProvider_Release(This->pProv);
         HeapFree(GetProcessHeap(), 0, This);
     }
 
     DXDIAGN_UnlockModule();
         HeapFree(GetProcessHeap(), 0, This);
     }
 
     DXDIAGN_UnlockModule();
-
+    
     return refCount;
 }
 
 /* IDxDiagContainer Interface follow: */
     return refCount;
 }
 
 /* IDxDiagContainer Interface follow: */
-HRESULT WINAPI IDxDiagContainerImpl_GetNumberOfChildContainers(PDXDIAGCONTAINER iface, DWORD* pdwCount) {
-  IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface;
+static HRESULT WINAPI IDxDiagContainerImpl_GetNumberOfChildContainers(IDxDiagContainer *iface,
+        DWORD *pdwCount)
+{
+  IDxDiagContainerImpl *This = impl_from_IDxDiagContainer(iface);
+
   TRACE("(%p)\n", iface);
   if (NULL == pdwCount) {
     return E_INVALIDARG;
   }
   TRACE("(%p)\n", iface);
   if (NULL == pdwCount) {
     return E_INVALIDARG;
   }
-  *pdwCount = This->nSubContainers;
+  *pdwCount = This->cont->nSubContainers;
   return S_OK;
 }
 
   return S_OK;
 }
 
-HRESULT WINAPI IDxDiagContainerImpl_EnumChildContainerNames(PDXDIAGCONTAINER iface, DWORD dwIndex, LPWSTR pwszContainer, DWORD cchContainer) {
-  IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface;
-  IDxDiagContainerImpl_SubContainer* p = NULL;
+static HRESULT WINAPI IDxDiagContainerImpl_EnumChildContainerNames(IDxDiagContainer *iface,
+        DWORD dwIndex, LPWSTR pwszContainer, DWORD cchContainer)
+{
+  IDxDiagContainerImpl *This = impl_from_IDxDiagContainer(iface);
+  IDxDiagContainerImpl_Container *p;
   DWORD i = 0;
 
   DWORD i = 0;
 
-  TRACE("(%p, %lu, %s, %lu)\n", iface, dwIndex, debugstr_w(pwszContainer), cchContainer);
+  TRACE("(%p, %u, %p, %u)\n", iface, dwIndex, pwszContainer, cchContainer);
 
 
-  if (NULL == pwszContainer) {
+  if (NULL == pwszContainer || 0 == cchContainer) {
     return E_INVALIDARG;
   }
     return E_INVALIDARG;
   }
-  if (256 > cchContainer) {
-    return DXDIAG_E_INSUFFICIENT_BUFFER;
-  }
 
 
-  p = This->subContainers;
-  while (NULL != p) {
+  LIST_FOR_EACH_ENTRY(p, &This->cont->subContainers, IDxDiagContainerImpl_Container, entry)
+  {
     if (dwIndex == i) {
     if (dwIndex == i) {
-      if (cchContainer <= strlenW(p->contName)) {
-       return DXDIAG_E_INSUFFICIENT_BUFFER;
-      }
+      TRACE("Found container name %s, copying string\n", debugstr_w(p->contName));
       lstrcpynW(pwszContainer, p->contName, cchContainer);
       lstrcpynW(pwszContainer, p->contName, cchContainer);
-      return S_OK;
+      return (cchContainer <= strlenW(p->contName)) ?
+              DXDIAG_E_INSUFFICIENT_BUFFER : S_OK;
     }
     }
-    p = p->next;
     ++i;
   }
     ++i;
   }
+
+  TRACE("Failed to find container name at specified index\n");
+  *pwszContainer = '\0';
   return E_INVALIDARG;
 }
 
   return E_INVALIDARG;
 }
 
-HRESULT WINAPI IDxDiagContainerImpl_GetChildContainerInternal(PDXDIAGCONTAINER iface, LPCWSTR pwszContainer, IDxDiagContainer** ppInstance) {
-  IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface;
-  IDxDiagContainerImpl_SubContainer* p = NULL;
+static HRESULT IDxDiagContainerImpl_GetChildContainerInternal(IDxDiagContainerImpl_Container *cont, LPCWSTR pwszContainer, IDxDiagContainerImpl_Container **subcont) {
+  IDxDiagContainerImpl_Container *p;
 
 
-  p = This->subContainers;
-  while (NULL != p) {
+  LIST_FOR_EACH_ENTRY(p, &cont->subContainers, IDxDiagContainerImpl_Container, entry)
+  {
     if (0 == lstrcmpW(p->contName, pwszContainer)) {
     if (0 == lstrcmpW(p->contName, pwszContainer)) {
-      *ppInstance = (PDXDIAGCONTAINER)p->pCont;
+      *subcont = p;
       return S_OK;
     }
       return S_OK;
     }
-    p = p->next;
   }
   }
+
   return E_INVALIDARG;
 }
 
   return E_INVALIDARG;
 }
 
-HRESULT WINAPI IDxDiagContainerImpl_GetChildContainer(PDXDIAGCONTAINER iface, LPCWSTR pwszContainer, IDxDiagContainer** ppInstance) {
-  IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface;
-  IDxDiagContainer* pContainer = NULL;
+static HRESULT WINAPI IDxDiagContainerImpl_GetChildContainer(IDxDiagContainer *iface,
+        LPCWSTR pwszContainer, IDxDiagContainer **ppInstance)
+{
+  IDxDiagContainerImpl *This = impl_from_IDxDiagContainer(iface);
+  IDxDiagContainerImpl_Container *pContainer = This->cont;
   LPWSTR tmp, orig_tmp;
   INT tmp_len;
   WCHAR* cur;
   HRESULT hr = E_INVALIDARG;
 
   LPWSTR tmp, orig_tmp;
   INT tmp_len;
   WCHAR* cur;
   HRESULT hr = E_INVALIDARG;
 
-  FIXME("(%p, %s, %p)\n", iface, debugstr_w(pwszContainer), ppInstance);
+  TRACE("(%p, %s, %p)\n", iface, debugstr_w(pwszContainer), ppInstance);
 
   if (NULL == ppInstance || NULL == pwszContainer) {
     return E_INVALIDARG;
   }
 
 
   if (NULL == ppInstance || NULL == pwszContainer) {
     return E_INVALIDARG;
   }
 
-  pContainer = (PDXDIAGCONTAINER) This;
+  *ppInstance = NULL;
 
   tmp_len = strlenW(pwszContainer) + 1;
   orig_tmp = tmp = HeapAlloc(GetProcessHeap(), 0, tmp_len * sizeof(WCHAR));
 
   tmp_len = strlenW(pwszContainer) + 1;
   orig_tmp = tmp = HeapAlloc(GetProcessHeap(), 0, tmp_len * sizeof(WCHAR));
@@ -147,17 +165,22 @@ HRESULT WINAPI IDxDiagContainerImpl_GetChildContainer(PDXDIAGCONTAINER iface, LP
   cur = strchrW(tmp, '.');
   while (NULL != cur) {
     *cur = '\0'; /* cut tmp string to '.' */
   cur = strchrW(tmp, '.');
   while (NULL != cur) {
     *cur = '\0'; /* cut tmp string to '.' */
+    if (!*(cur + 1)) break; /* Account for a lone terminating period, as in "cont1.cont2.". */
+    TRACE("Trying to get parent container %s\n", debugstr_w(tmp));
     hr = IDxDiagContainerImpl_GetChildContainerInternal(pContainer, tmp, &pContainer);
     hr = IDxDiagContainerImpl_GetChildContainerInternal(pContainer, tmp, &pContainer);
-    if (!SUCCEEDED(hr) || NULL == pContainer)
+    if (FAILED(hr))
       goto on_error;
     cur++; /* go after '.' (just replaced by \0) */
     tmp = cur;
     cur = strchrW(tmp, '.');
   }
 
       goto on_error;
     cur++; /* go after '.' (just replaced by \0) */
     tmp = cur;
     cur = strchrW(tmp, '.');
   }
 
-  hr = IDxDiagContainerImpl_GetChildContainerInternal(pContainer, tmp, ppInstance);
+  TRACE("Trying to get container %s\n", debugstr_w(tmp));
+  hr = IDxDiagContainerImpl_GetChildContainerInternal(pContainer, tmp, &pContainer);
   if (SUCCEEDED(hr)) {
   if (SUCCEEDED(hr)) {
-    IDxDiagContainerImpl_AddRef((PDXDIAGCONTAINER)*ppInstance);
+    hr = DXDiag_CreateDXDiagContainer(&IID_IDxDiagContainer, pContainer, This->pProv, (void **)ppInstance);
+    if (SUCCEEDED(hr))
+        TRACE("Succeeded in getting the container instance\n");
   }
 
 on_error:
   }
 
 on_error:
@@ -165,130 +188,68 @@ on_error:
   return hr;
 }
 
   return hr;
 }
 
-HRESULT WINAPI IDxDiagContainerImpl_GetNumberOfProps(PDXDIAGCONTAINER iface, DWORD* pdwCount) {
-  IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface;
+static HRESULT WINAPI IDxDiagContainerImpl_GetNumberOfProps(IDxDiagContainer *iface,
+        DWORD *pdwCount)
+{
+  IDxDiagContainerImpl *This = impl_from_IDxDiagContainer(iface);
+
   TRACE("(%p)\n", iface);
   if (NULL == pdwCount) {
     return E_INVALIDARG;
   }
   TRACE("(%p)\n", iface);
   if (NULL == pdwCount) {
     return E_INVALIDARG;
   }
-  *pdwCount = This->nProperties;
+  *pdwCount = This->cont->nProperties;
   return S_OK;
 }
 
   return S_OK;
 }
 
-HRESULT WINAPI IDxDiagContainerImpl_EnumPropNames(PDXDIAGCONTAINER iface, DWORD dwIndex, LPWSTR pwszPropName, DWORD cchPropName) {
-  IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface;
-  IDxDiagContainerImpl_Property* p = NULL;
+static HRESULT WINAPI IDxDiagContainerImpl_EnumPropNames(IDxDiagContainer *iface, DWORD dwIndex,
+        LPWSTR pwszPropName, DWORD cchPropName)
+{
+  IDxDiagContainerImpl *This = impl_from_IDxDiagContainer(iface);
+  IDxDiagContainerImpl_Property *p;
   DWORD i = 0;
 
   DWORD i = 0;
 
-  FIXME("(%p, %lu, %s, %lu)\n", iface, dwIndex, debugstr_w(pwszPropName), cchPropName);
+  TRACE("(%p, %u, %p, %u)\n", iface, dwIndex, pwszPropName, cchPropName);
 
 
-  if (NULL == pwszPropName) {
+  if (NULL == pwszPropName || 0 == cchPropName) {
     return E_INVALIDARG;
   }
     return E_INVALIDARG;
   }
-  if (256 > cchPropName) {
-    return DXDIAG_E_INSUFFICIENT_BUFFER;
-  }
 
 
-  p = This->properties;
-  while (NULL != p) {
+  LIST_FOR_EACH_ENTRY(p, &This->cont->properties, IDxDiagContainerImpl_Property, entry)
+  {
     if (dwIndex == i) {
     if (dwIndex == i) {
-      if (cchPropName <= lstrlenW(p->vName)) {
-       return DXDIAG_E_INSUFFICIENT_BUFFER;
-      }
-      lstrcpynW(pwszPropName, p->vName, cchPropName);
-      return S_OK;
+      TRACE("Found property name %s, copying string\n", debugstr_w(p->propName));
+      lstrcpynW(pwszPropName, p->propName, cchPropName);
+      return (cchPropName <= strlenW(p->propName)) ?
+              DXDIAG_E_INSUFFICIENT_BUFFER : S_OK;
     }
     }
-    p = p->next;
     ++i;
   }
     ++i;
   }
-  return E_INVALIDARG;
-}
-
-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;
+  TRACE("Failed to find property name at specified index\n");
+  return E_INVALIDARG;
 }
 
 }
 
-HRESULT WINAPI IDxDiagContainerImpl_AddProp(PDXDIAGCONTAINER iface, LPCWSTR pwszPropName, VARIANT* pVarProp) {
-  IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface;
-  IDxDiagContainerImpl_Property* p = NULL;
-  IDxDiagContainerImpl_Property* pNew = NULL;
+static HRESULT WINAPI IDxDiagContainerImpl_GetProp(IDxDiagContainer *iface, LPCWSTR pwszPropName,
+        VARIANT *pvarProp)
+{
+  IDxDiagContainerImpl *This = impl_from_IDxDiagContainer(iface);
+  IDxDiagContainerImpl_Property *p;
 
 
-  FIXME("(%p, %s, %p)\n", iface, debugstr_w(pwszPropName), pVarProp);
+  TRACE("(%p, %s, %p)\n", iface, debugstr_w(pwszPropName), pvarProp);
 
 
-  if (NULL == pVarProp || NULL == pwszPropName) {
+  if (NULL == pvarProp || NULL == pwszPropName) {
     return E_INVALIDARG;
   }
 
     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;
+  LIST_FOR_EACH_ENTRY(p, &This->cont->properties, IDxDiagContainerImpl_Property, entry)
+  {
+    if (0 == lstrcmpW(p->propName, pwszPropName)) {
+      VariantInit(pvarProp);
+      return VariantCopy(pvarProp, &p->vProp);
     }
     }
-    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;
+  return E_INVALIDARG;
 }
 
 static const IDxDiagContainerVtbl DxDiagContainer_Vtbl =
 }
 
 static const IDxDiagContainerVtbl DxDiagContainer_Vtbl =
@@ -305,17 +266,20 @@ static const IDxDiagContainerVtbl DxDiagContainer_Vtbl =
 };
 
 
 };
 
 
-HRESULT DXDiag_CreateDXDiagContainer(REFIID riid, LPVOID *ppobj) {
+HRESULT DXDiag_CreateDXDiagContainer(REFIID riid, IDxDiagContainerImpl_Container *cont, IDxDiagProvider *pProv, LPVOID *ppobj) {
   IDxDiagContainerImpl* container;
 
   IDxDiagContainerImpl* container;
 
-  TRACE("(%p, %p)\n", debugstr_guid(riid), ppobj);
+  TRACE("(%s, %p)\n", debugstr_guid(riid), ppobj);
 
 
-  container = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDxDiagContainerImpl));
+  container = HeapAlloc(GetProcessHeap(), 0, sizeof(IDxDiagContainerImpl));
   if (NULL == container) {
     *ppobj = NULL;
     return E_OUTOFMEMORY;
   }
   if (NULL == container) {
     *ppobj = NULL;
     return E_OUTOFMEMORY;
   }
-  container->lpVtbl = &DxDiagContainer_Vtbl;
+  container->IDxDiagContainer_iface.lpVtbl = &DxDiagContainer_Vtbl;
   container->ref = 0; /* will be inited with QueryInterface */
   container->ref = 0; /* will be inited with QueryInterface */
-  return IDxDiagContainerImpl_QueryInterface((PDXDIAGCONTAINER)container, riid, ppobj);
+  container->cont = cont;
+  container->pProv = pProv;
+  IDxDiagProvider_AddRef(pProv);
+  return IDxDiagContainerImpl_QueryInterface(&container->IDxDiagContainer_iface, riid, ppobj);
 }
 }
index 94c42e6..58f8917 100644 (file)
@@ -1,6 +1,6 @@
-/*
+/* 
  * DXDiag
  * DXDiag
- *
+ * 
  * Copyright 2004 Raphael Junqueira
  *
  * This library is free software; you can redistribute it and/or
  * Copyright 2004 Raphael Junqueira
  *
  * This library is free software; you can redistribute it and/or
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  *
  * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
  */
 
  *
  */
 
+#define COBJMACROS
+
 #include <config.h>
 #include <config.h>
+#include <stdarg.h>
+
+#include <windef.h>
+#include <winbase.h>
+#include <objbase.h>
+#include <oleauto.h>
+#include <oleidl.h>
+#include <rpcproxy.h>
+#include <initguid.h>
 #include "dxdiag_private.h"
 #include <wine/debug.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);
 
 #include "dxdiag_private.h"
 #include <wine/debug.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);
 
+HINSTANCE dxdiagn_instance = 0;
+
 LONG DXDIAGN_refCount = 0;
 
 /* At process attach */
 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
 {
 LONG DXDIAGN_refCount = 0;
 
 /* At process attach */
 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
 {
-  TRACE("%p,%lx,%p\n", hInstDLL, fdwReason, lpvReserved);
+  TRACE("%p,%x,%p\n", hInstDLL, fdwReason, lpvReserved);
   if (fdwReason == DLL_PROCESS_ATTACH) {
   if (fdwReason == DLL_PROCESS_ATTACH) {
-    DisableThreadLibraryCalls(hInstDLL);
+      dxdiagn_instance = hInstDLL;
+      DisableThreadLibraryCalls(hInstDLL);
   }
   return TRUE;
 }
   }
   return TRUE;
 }
@@ -41,46 +55,60 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
  * DXDiag ClassFactory
  */
 typedef struct {
  * DXDiag ClassFactory
  */
 typedef struct {
-  const IClassFactoryVtbl *lpVtbl;
-  REFCLSID   rclsid;
-  HRESULT   (*pfnCreateInstanceFactory)(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj);
+  IClassFactory IClassFactory_iface;
 } IClassFactoryImpl;
 
 } IClassFactoryImpl;
 
-static HRESULT WINAPI DXDiagCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
-  FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid));
-
-  if (ppobj == NULL) return E_POINTER;
+static HRESULT WINAPI DXDiagCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
+{
+  if (ppv == NULL)
+    return E_POINTER;
+
+  if (IsEqualGUID(&IID_IUnknown, riid))
+    TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
+  else if (IsEqualGUID(&IID_IClassFactory, riid))
+    TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
+  else {
+    FIXME("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
+    *ppv = NULL;
+    return E_NOINTERFACE;
+  }
 
 
-  return E_NOINTERFACE;
+  *ppv = iface;
+  IClassFactory_AddRef(iface);
+  return S_OK;
 }
 
 }
 
-static ULONG WINAPI DXDiagCF_AddRef(LPCLASSFACTORY iface) {
+static ULONG WINAPI DXDiagCF_AddRef(IClassFactory *iface)
+{
   DXDIAGN_LockModule();
 
   return 2; /* non-heap based object */
 }
 
   DXDIAGN_LockModule();
 
   return 2; /* non-heap based object */
 }
 
-static ULONG WINAPI DXDiagCF_Release(LPCLASSFACTORY iface) {
+static ULONG WINAPI DXDiagCF_Release(IClassFactory * iface)
+{
   DXDIAGN_UnlockModule();
 
   return 1; /* non-heap based object */
 }
 
   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);
+static HRESULT WINAPI DXDiagCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, REFIID riid,
+        void **ppv)
+{
+  TRACE("(%p)->(%p,%s,%p)\n", iface, pOuter, debugstr_guid(riid), ppv);
 
 
-  return This->pfnCreateInstanceFactory(iface, pOuter, riid, ppobj);
+  return DXDiag_CreateDXDiagProvider(iface, pOuter, riid, ppv);
 }
 
 }
 
-static HRESULT WINAPI DXDiagCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
+static HRESULT WINAPI DXDiagCF_LockServer(IClassFactory *iface, BOOL dolock)
+{
   TRACE("(%d)\n", dolock);
 
   if (dolock)
     DXDIAGN_LockModule();
   else
     DXDIAGN_UnlockModule();
   TRACE("(%d)\n", dolock);
 
   if (dolock)
     DXDIAGN_LockModule();
   else
     DXDIAGN_UnlockModule();
-
+  
   return S_OK;
 }
 
   return S_OK;
 }
 
@@ -92,10 +120,7 @@ static const IClassFactoryVtbl DXDiagCF_Vtbl = {
   DXDiagCF_LockServer
 };
 
   DXDiagCF_LockServer
 };
 
-static IClassFactoryImpl DXDiag_CFS[] = {
-  { &DXDiagCF_Vtbl, &CLSID_DxDiagProvider, DXDiag_CreateDXDiagProvider },
-  { NULL, NULL, NULL }
-};
+static IClassFactoryImpl DXDiag_CF = { { &DXDiagCF_Vtbl } };
 
 /***********************************************************************
  *             DllCanUnloadNow (DXDIAGN.@)
 
 /***********************************************************************
  *             DllCanUnloadNow (DXDIAGN.@)
@@ -110,18 +135,30 @@ HRESULT WINAPI DllCanUnloadNow(void)
  */
 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
 {
  */
 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
 {
-    int i = 0;
-
-    TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
-    while (NULL != DXDiag_CFS[i].rclsid) {
-      if (IsEqualGUID(rclsid, DXDiag_CFS[i].rclsid)) {
-             DXDiagCF_AddRef((IClassFactory*) &DXDiag_CFS[i]);
-             *ppv = &DXDiag_CFS[i];
-             return S_OK;
-      }
-      ++i;
+    TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+
+    if (IsEqualGUID(rclsid, &CLSID_DxDiagProvider)) {
+      IClassFactory_AddRef(&DXDiag_CF.IClassFactory_iface);
+      *ppv = &DXDiag_CF.IClassFactory_iface;
+      return S_OK;
     }
 
     }
 
-    FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+    FIXME("(%s,%s,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
     return CLASS_E_CLASSNOTAVAILABLE;
 }
     return CLASS_E_CLASSNOTAVAILABLE;
 }
+
+/***********************************************************************
+ *             DllRegisterServer (DXDIAGN.@)
+ */
+HRESULT WINAPI DllRegisterServer(void)
+{
+    return __wine_register_resources( dxdiagn_instance );
+}
+
+/***********************************************************************
+ *             DllUnregisterServer (DXDIAGN.@)
+ */
+HRESULT WINAPI DllUnregisterServer(void)
+{
+    return __wine_unregister_resources( dxdiagn_instance );
+}
index 5d90a40..ae73a0f 100644 (file)
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  *
  * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
 #ifndef __WINE_DXDIAG_PRIVATE_H
  */
 
 #ifndef __WINE_DXDIAG_PRIVATE_H
 
 #include <windef.h>
 #include <winbase.h>
 
 #include <windef.h>
 #include <winbase.h>
-//#include "wingdi.h"
-//#include "winuser.h"
-//#include "objbase.h"
-//#include "oleauto.h"
+#include <wingdi.h>
 
 
-#include <dxdiag.h>
+#include <wine/list.h>
+#include <wine/dxdiag.h>
+
+#include "resource.h"
 
 /* DXDiag Interfaces: */
 typedef struct IDxDiagProviderImpl  IDxDiagProviderImpl;
 typedef struct IDxDiagContainerImpl IDxDiagContainerImpl;
 
 /* DXDiag Interfaces: */
 typedef struct IDxDiagProviderImpl  IDxDiagProviderImpl;
 typedef struct IDxDiagContainerImpl IDxDiagContainerImpl;
-
-/* ---------------- */
-/* IDxDiagProvider  */
-/* ---------------- */
-
-/*****************************************************************************
- * IDxDiagProvider implementation structure
- */
-struct IDxDiagProviderImpl {
-  /* IUnknown fields */
-  const IDxDiagProviderVtbl *lpVtbl;
-  LONG        ref;
-  /* IDxDiagProvider fields */
-  BOOL        init;
-  DXDIAG_INIT_PARAMS params;
-  IDxDiagContainer* pRootContainer;
-};
-
-/* IUnknown: */
-extern HRESULT WINAPI IDxDiagProviderImpl_QueryInterface(PDXDIAGPROVIDER iface, REFIID riid, LPVOID *ppobj);
-extern ULONG WINAPI IDxDiagProviderImpl_AddRef(PDXDIAGPROVIDER iface);
-extern ULONG WINAPI IDxDiagProviderImpl_Release(PDXDIAGPROVIDER iface);
-
-/* IDxDiagProvider: */
-extern HRESULT WINAPI IDxDiagProviderImpl_Initialize(PDXDIAGPROVIDER iface, DXDIAG_INIT_PARAMS* pParams);
-extern HRESULT WINAPI IDxDiagProviderImpl_GetRootContainer(PDXDIAGPROVIDER iface, IDxDiagContainer** ppInstance);
+typedef struct IDxDiagContainerImpl_Container IDxDiagContainerImpl_Container;
 
 /* ---------------- */
 /* IDxDiagContainer  */
 /* ---------------- */
 
 
 /* ---------------- */
 /* IDxDiagContainer  */
 /* ---------------- */
 
-typedef struct IDxDiagContainerImpl_SubContainer {
-  IDxDiagContainer* pCont;
-  WCHAR* contName;
-  struct IDxDiagContainerImpl_SubContainer* next;
-} IDxDiagContainerImpl_SubContainer;
+struct IDxDiagContainerImpl_Container {
+  struct list entry;
+  WCHAR *contName;
+
+  struct list subContainers;
+  DWORD nSubContainers;
+  struct list properties;
+  DWORD nProperties;
+};
 
 typedef struct IDxDiagContainerImpl_Property {
 
 typedef struct IDxDiagContainerImpl_Property {
-  LPWSTR vName;
-  VARIANT v;
-  struct IDxDiagContainerImpl_Property* next;
+  struct list entry;
+  WCHAR *propName;
+  VARIANT vProp;
 } IDxDiagContainerImpl_Property;
 
 
 } IDxDiagContainerImpl_Property;
 
 
@@ -87,38 +66,27 @@ typedef struct IDxDiagContainerImpl_Property {
  * IDxDiagContainer implementation structure
  */
 struct IDxDiagContainerImpl {
  * IDxDiagContainer implementation structure
  */
 struct IDxDiagContainerImpl {
-  /* IUnknown fields */
-  const IDxDiagContainerVtbl *lpVtbl;
-  LONG        ref;
-  /* IDxDiagContainer fields */
-  IDxDiagContainerImpl_Property* properties;
-  IDxDiagContainerImpl_SubContainer* subContainers;
-  DWORD nProperties;
-  DWORD nSubContainers;
+  IDxDiagContainer IDxDiagContainer_iface;
+  LONG ref;
+  IDxDiagContainerImpl_Container *cont;
+  IDxDiagProvider *pProv;
 };
 
 };
 
-/* IUnknown: */
-extern HRESULT WINAPI IDxDiagContainerImpl_QueryInterface(PDXDIAGCONTAINER iface, REFIID riid, LPVOID *ppobj);
-extern ULONG WINAPI IDxDiagContainerImpl_AddRef(PDXDIAGCONTAINER iface);
-
-/** Internal */
-extern HRESULT WINAPI IDxDiagContainerImpl_AddProp(PDXDIAGCONTAINER iface, LPCWSTR pwszPropName, VARIANT* pVarProp);
-extern HRESULT WINAPI IDxDiagContainerImpl_AddChildContainer(PDXDIAGCONTAINER iface, LPCWSTR pszContName, PDXDIAGCONTAINER pSubCont);
-
 /**
  * factories
  */
 /**
  * factories
  */
-extern HRESULT DXDiag_CreateDXDiagProvider(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj);
+extern HRESULT DXDiag_CreateDXDiagProvider(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj) DECLSPEC_HIDDEN;
 
 /** internal factory */
 
 /** internal factory */
-extern HRESULT DXDiag_CreateDXDiagContainer(REFIID riid, LPVOID *ppobj);
-extern HRESULT DXDiag_InitRootDXDiagContainer(IDxDiagContainer* pRootCont);
+extern HRESULT DXDiag_CreateDXDiagContainer(REFIID riid, IDxDiagContainerImpl_Container *cont, IDxDiagProvider *pProv, LPVOID *ppobj) DECLSPEC_HIDDEN;
 
 /**********************************************************************
  * Dll lifetime tracking declaration for dxdiagn.dll
  */
 
 /**********************************************************************
  * Dll lifetime tracking declaration for dxdiagn.dll
  */
-extern LONG DXDIAGN_refCount;
+extern LONG DXDIAGN_refCount DECLSPEC_HIDDEN;
 static inline void DXDIAGN_LockModule(void) { InterlockedIncrement( &DXDIAGN_refCount ); }
 static inline void DXDIAGN_UnlockModule(void) { InterlockedDecrement( &DXDIAGN_refCount ); }
 
 static inline void DXDIAGN_LockModule(void) { InterlockedIncrement( &DXDIAGN_refCount ); }
 static inline void DXDIAGN_UnlockModule(void) { InterlockedDecrement( &DXDIAGN_refCount ); }
 
+extern HINSTANCE dxdiagn_instance DECLSPEC_HIDDEN;
+
 #endif
 #endif
diff --git a/reactos/dll/directx/wine/dxdiagn/dxdiagn.idl b/reactos/dll/directx/wine/dxdiagn/dxdiagn.idl
new file mode 100644 (file)
index 0000000..3a6b88f
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * COM Classes for dxdiagn
+ *
+ * Copyright 2010 Alexandre Julliard
+ *
+ * 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
+ */
+
+[
+    helpstring("DxDiagProvider Class"),
+    threading(apartment),
+    progid("DxDiag.DxDiagProvider.1"),
+    vi_progid("DxDiag.DxDiagProvider"),
+    uuid(a65b8071-3bfe-4213-9a5b-491da4461ca7)
+]
+coclass DxDiagProvider { interface IDxDiagProvider; }
diff --git a/reactos/dll/directx/wine/dxdiagn/dxdiagn.rc b/reactos/dll/directx/wine/dxdiagn/dxdiagn.rc
new file mode 100644 (file)
index 0000000..2661737
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2004 Raphael Junqueira
+ *
+ * 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 "resource.h"
+
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+STRINGTABLE
+{
+    IDS_REGIONAL_SETTING    "Regional Setting"
+    IDS_PAGE_FILE_FORMAT    "%1!u!MB used, %2!u!MB available"
+}
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+#define WINE_FILEDESCRIPTION_STR "Wine DxDiag 8"
+#define WINE_FILENAME_STR "dxdiagn.dll"
+#define WINE_FILEVERSION 5,3,1,904
+#define WINE_FILEVERSION_STR "5.3.1.904"
+#define WINE_PRODUCTVERSION 5,3,1,904
+#define WINE_PRODUCTVERSION_STR "5.3.1.904"
+
+#include <wine/wine_common_ver.rc>
+
+1 WINE_REGISTRY dxdiagn.rgs
diff --git a/reactos/dll/directx/wine/dxdiagn/dxdiagn.rgs b/reactos/dll/directx/wine/dxdiagn/dxdiagn.rgs
new file mode 100644 (file)
index 0000000..80d609b
--- /dev/null
@@ -0,0 +1,24 @@
+HKCR
+{
+    NoRemove Interface
+    {
+    }
+    NoRemove CLSID
+    {
+        '{A65B8071-3BFE-4213-9A5B-491DA4461CA7}' = s 'DxDiagProvider Class'
+        {
+            InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
+            ProgId = s 'DxDiag.DxDiagProvider.1'
+            VersionIndependentProgId = s 'DxDiag.DxDiagProvider'
+        }
+    }
+    'DxDiag.DxDiagProvider.1' = s 'DxDiagProvider Class'
+    {
+        CLSID = s '{A65B8071-3BFE-4213-9A5B-491DA4461CA7}'
+    }
+    'DxDiag.DxDiagProvider' = s 'DxDiagProvider Class'
+    {
+        CLSID = s '{A65B8071-3BFE-4213-9A5B-491DA4461CA7}'
+        CurVer = s 'DxDiag.DxDiagProvider.1'
+    }
+}
diff --git a/reactos/dll/directx/wine/dxdiagn/fil_data.idl b/reactos/dll/directx/wine/dxdiagn/fil_data.idl
new file mode 100644 (file)
index 0000000..806c053
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Vitaliy Margolen
+ *
+ * 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
+ */
+
+import "objidl.idl";
+import "strmif.idl";
+import "unknwn.idl";
+
+
+/*****************************************************************************
+ * IAMFilterData interface
+ */
+[
+    object,
+    uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
+    pointer_default(unique)
+]
+interface IAMFilterData : IUnknown
+{
+    typedef [unique] IAMFilterData *LPIAMFILTERDATA;
+
+    HRESULT ParseFilterData(
+        [in] BYTE * rgbFilterData,
+        [in] ULONG cb,
+        [out] BYTE ** prgbRegFilter2);
+
+    HRESULT CreateFilterData(
+        [in] REGFILTER2 * prf2,
+        [out] BYTE ** prgbFilterData,
+        [out] ULONG * pcb);
+}
index 9838aff..cb4efff 100644 (file)
@@ -1,7 +1,8 @@
-/*
+/* 
  * IDxDiagProvider Implementation
  * IDxDiagProvider Implementation
- *
- * Copyright 2004 Raphael Junqueira
+ * 
+ * Copyright 2004-2005 Raphael Junqueira
+ * Copyright 2010 Andrew Nguyen
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  *
  * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
  */
 
 #include <config.h>
  *
  */
 
 #include <config.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
 #include "dxdiag_private.h"
 #include "dxdiag_private.h"
+#include <wine/unicode.h>
+#include <winver.h>
+#include <wingdi.h>
+#include <objidl.h>
+#include <uuids.h>
+#include <vfw.h>
+#include <mmddk.h>
+#include <d3d9.h>
+#include <strmif.h>
+#include <initguid.h>
+#include <fil_data.h>
+#include <psapi.h>
+#include <wbemcli.h>
+
 #include <wine/debug.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);
 
 #include <wine/debug.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);
 
+static const WCHAR szEmpty[] = {0};
+
+static HRESULT build_information_tree(IDxDiagContainerImpl_Container **pinfo_root);
+static void free_information_tree(IDxDiagContainerImpl_Container *node);
+
+static const WCHAR szDescription[] = {'s','z','D','e','s','c','r','i','p','t','i','o','n',0};
+static const WCHAR szDeviceName[] = {'s','z','D','e','v','i','c','e','N','a','m','e',0};
+static const WCHAR szKeyDeviceID[] = {'s','z','K','e','y','D','e','v','i','c','e','I','D',0};
+static const WCHAR szKeyDeviceKey[] = {'s','z','K','e','y','D','e','v','i','c','e','K','e','y',0};
+static const WCHAR szVendorId[] = {'s','z','V','e','n','d','o','r','I','d',0};
+static const WCHAR szDeviceId[] = {'s','z','D','e','v','i','c','e','I','d',0};
+static const WCHAR szDeviceIdentifier[] = {'s','z','D','e','v','i','c','e','I','d','e','n','t','i','f','i','e','r',0};
+static const WCHAR dwWidth[] = {'d','w','W','i','d','t','h',0};
+static const WCHAR dwHeight[] = {'d','w','H','e','i','g','h','t',0};
+static const WCHAR dwBpp[] = {'d','w','B','p','p',0};
+static const WCHAR szDisplayMemoryLocalized[] = {'s','z','D','i','s','p','l','a','y','M','e','m','o','r','y','L','o','c','a','l','i','z','e','d',0};
+static const WCHAR szDisplayMemoryEnglish[] = {'s','z','D','i','s','p','l','a','y','M','e','m','o','r','y','E','n','g','l','i','s','h',0};
+static const WCHAR szDriverName[] = {'s','z','D','r','i','v','e','r','N','a','m','e',0};
+static const WCHAR szDriverVersion[] = {'s','z','D','r','i','v','e','r','V','e','r','s','i','o','n',0};
+static const WCHAR szSubSysId[] = {'s','z','S','u','b','S','y','s','I','d',0};
+static const WCHAR szRevisionId[] = {'s','z','R','e','v','i','s','i','o','n','I','d',0};
+static const WCHAR dwRefreshRate[] = {'d','w','R','e','f','r','e','s','h','R','a','t','e',0};
+static const WCHAR szManufacturer[] = {'s','z','M','a','n','u','f','a','c','t','u','r','e','r',0};
+
+struct IDxDiagProviderImpl
+{
+  IDxDiagProvider IDxDiagProvider_iface;
+  LONG ref;
+  BOOL init;
+  DXDIAG_INIT_PARAMS params;
+  IDxDiagContainerImpl_Container *info_root;
+};
+
+static inline IDxDiagProviderImpl *impl_from_IDxDiagProvider(IDxDiagProvider *iface)
+{
+     return CONTAINING_RECORD(iface, IDxDiagProviderImpl, IDxDiagProvider_iface);
+}
+
 /* IDxDiagProvider IUnknown parts follow: */
 /* IDxDiagProvider IUnknown parts follow: */
-HRESULT WINAPI IDxDiagProviderImpl_QueryInterface(PDXDIAGPROVIDER iface, REFIID riid, LPVOID *ppobj)
+static HRESULT WINAPI IDxDiagProviderImpl_QueryInterface(IDxDiagProvider *iface, REFIID riid,
+        void **ppobj)
 {
 {
-    IDxDiagProviderImpl *This = (IDxDiagProviderImpl *)iface;
+    IDxDiagProviderImpl *This = impl_from_IDxDiagProvider(iface);
+
+    if (!ppobj) return E_INVALIDARG;
 
     if (IsEqualGUID(riid, &IID_IUnknown)
         || IsEqualGUID(riid, &IID_IDxDiagProvider)) {
 
     if (IsEqualGUID(riid, &IID_IUnknown)
         || IsEqualGUID(riid, &IID_IDxDiagProvider)) {
-        IDxDiagProviderImpl_AddRef(iface);
+        IUnknown_AddRef(iface);
         *ppobj = This;
         return S_OK;
     }
 
     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
         *ppobj = This;
         return S_OK;
     }
 
     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
+    *ppobj = NULL;
     return E_NOINTERFACE;
 }
 
     return E_NOINTERFACE;
 }
 
-ULONG WINAPI IDxDiagProviderImpl_AddRef(PDXDIAGPROVIDER iface) {
-    IDxDiagProviderImpl *This = (IDxDiagProviderImpl *)iface;
-    TRACE("(%p) : AddRef from %ld\n", This, This->ref);
-    return ++(This->ref);
+static ULONG WINAPI IDxDiagProviderImpl_AddRef(IDxDiagProvider *iface)
+{
+    IDxDiagProviderImpl *This = impl_from_IDxDiagProvider(iface);
+    ULONG refCount = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p)->(ref before=%u)\n", This, refCount - 1);
+
+    DXDIAGN_LockModule();
+
+    return refCount;
 }
 
 }
 
-ULONG WINAPI IDxDiagProviderImpl_Release(PDXDIAGPROVIDER iface) {
-    IDxDiagProviderImpl *This = (IDxDiagProviderImpl *)iface;
-    ULONG ref = --This->ref;
-    TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
-    if (ref == 0) {
+static ULONG WINAPI IDxDiagProviderImpl_Release(IDxDiagProvider *iface)
+{
+    IDxDiagProviderImpl *This = impl_from_IDxDiagProvider(iface);
+    ULONG refCount = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p)->(ref before=%u)\n", This, refCount + 1);
+
+    if (!refCount) {
+        free_information_tree(This->info_root);
         HeapFree(GetProcessHeap(), 0, This);
     }
         HeapFree(GetProcessHeap(), 0, This);
     }
-    return ref;
+
+    DXDIAGN_UnlockModule();
+    
+    return refCount;
 }
 
 /* IDxDiagProvider Interface follow: */
 }
 
 /* IDxDiagProvider Interface follow: */
-HRESULT WINAPI IDxDiagProviderImpl_Initialize(PDXDIAGPROVIDER iface, DXDIAG_INIT_PARAMS* pParams) {
-    IDxDiagProviderImpl *This = (IDxDiagProviderImpl *)iface;
+static HRESULT WINAPI IDxDiagProviderImpl_Initialize(IDxDiagProvider *iface,
+        DXDIAG_INIT_PARAMS *pParams)
+{
+    IDxDiagProviderImpl *This = impl_from_IDxDiagProvider(iface);
+    HRESULT hr;
+
     TRACE("(%p,%p)\n", iface, pParams);
 
     if (NULL == pParams) {
       return E_POINTER;
     }
     TRACE("(%p,%p)\n", iface, pParams);
 
     if (NULL == pParams) {
       return E_POINTER;
     }
-    if (pParams->dwSize != sizeof(DXDIAG_INIT_PARAMS)) {
+    if (pParams->dwSize != sizeof(DXDIAG_INIT_PARAMS) ||
+        pParams->dwDxDiagHeaderVersion != DXDIAG_DX9_SDK_VERSION) {
       return E_INVALIDARG;
     }
 
       return E_INVALIDARG;
     }
 
+    if (!This->info_root)
+    {
+        hr = build_information_tree(&This->info_root);
+        if (FAILED(hr))
+            return hr;
+    }
+
     This->init = TRUE;
     memcpy(&This->params, pParams, pParams->dwSize);
     return S_OK;
 }
 
     This->init = TRUE;
     memcpy(&This->params, pParams, pParams->dwSize);
     return S_OK;
 }
 
-HRESULT WINAPI IDxDiagProviderImpl_GetRootContainer(PDXDIAGPROVIDER iface, IDxDiagContainer** ppInstance) {
-  HRESULT hr = S_OK;
-  IDxDiagProviderImpl *This = (IDxDiagProviderImpl *)iface;
+static HRESULT WINAPI IDxDiagProviderImpl_GetRootContainer(IDxDiagProvider *iface,
+        IDxDiagContainer **ppInstance)
+{
+  IDxDiagProviderImpl *This = impl_from_IDxDiagProvider(iface);
+
   TRACE("(%p,%p)\n", iface, ppInstance);
 
   TRACE("(%p,%p)\n", iface, ppInstance);
 
-  if (NULL == ppInstance) {
-    return E_INVALIDARG;
-  }
   if (FALSE == This->init) {
   if (FALSE == This->init) {
-    return E_INVALIDARG; /* should be E_CO_UNINITIALIZED */
-  }
-  if (NULL == This->pRootContainer) {
-    hr = DXDiag_CreateDXDiagContainer(&IID_IDxDiagContainer, (void**) &This->pRootContainer);
-    if (FAILED(hr)) {
-      return hr;
-    }
+    return CO_E_NOTINITIALIZED;
   }
   }
-  return IDxDiagContainerImpl_QueryInterface((PDXDIAGCONTAINER)This->pRootContainer, &IID_IDxDiagContainer, (void**) ppInstance);
+
+  return DXDiag_CreateDXDiagContainer(&IID_IDxDiagContainer, This->info_root,
+          &This->IDxDiagProvider_iface, (void **)ppInstance);
 }
 
 }
 
-IDxDiagProviderVtbl DxDiagProvider_Vtbl =
+static const IDxDiagProviderVtbl DxDiagProvider_Vtbl =
 {
     IDxDiagProviderImpl_QueryInterface,
     IDxDiagProviderImpl_AddRef,
 {
     IDxDiagProviderImpl_QueryInterface,
     IDxDiagProviderImpl_AddRef,
@@ -108,12 +189,1528 @@ HRESULT DXDiag_CreateDXDiagProvider(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, R
 
   TRACE("(%p, %s, %p)\n", punkOuter, debugstr_guid(riid), ppobj);
 
 
   TRACE("(%p, %s, %p)\n", punkOuter, debugstr_guid(riid), ppobj);
 
+  *ppobj = NULL;
+  if (punkOuter) return CLASS_E_NOAGGREGATION;
+
   provider = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDxDiagProviderImpl));
   provider = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDxDiagProviderImpl));
-  if (NULL == provider) {
-    *ppobj = NULL;
-    return E_OUTOFMEMORY;
-  }
-  provider->lpVtbl = &DxDiagProvider_Vtbl;
+  if (NULL == provider) return E_OUTOFMEMORY;
+  provider->IDxDiagProvider_iface.lpVtbl = &DxDiagProvider_Vtbl;
   provider->ref = 0; /* will be inited with QueryInterface */
   provider->ref = 0; /* will be inited with QueryInterface */
-  return IDxDiagProviderImpl_QueryInterface ((PDXDIAGPROVIDER)provider, riid, ppobj);
+  return IDxDiagProviderImpl_QueryInterface(&provider->IDxDiagProvider_iface, riid, ppobj);
+}
+
+static void free_property_information(IDxDiagContainerImpl_Property *prop)
+{
+    VariantClear(&prop->vProp);
+    HeapFree(GetProcessHeap(), 0, prop->propName);
+    HeapFree(GetProcessHeap(), 0, prop);
+}
+
+static void free_information_tree(IDxDiagContainerImpl_Container *node)
+{
+    IDxDiagContainerImpl_Container *ptr, *cursor2;
+
+    if (!node)
+        return;
+
+    HeapFree(GetProcessHeap(), 0, node->contName);
+
+    LIST_FOR_EACH_ENTRY_SAFE(ptr, cursor2, &node->subContainers, IDxDiagContainerImpl_Container, entry)
+    {
+        IDxDiagContainerImpl_Property *prop, *prop_cursor2;
+
+        LIST_FOR_EACH_ENTRY_SAFE(prop, prop_cursor2, &ptr->properties, IDxDiagContainerImpl_Property, entry)
+        {
+            list_remove(&prop->entry);
+            free_property_information(prop);
+        }
+
+        list_remove(&ptr->entry);
+        free_information_tree(ptr);
+    }
+
+    HeapFree(GetProcessHeap(), 0, node);
+}
+
+static IDxDiagContainerImpl_Container *allocate_information_node(const WCHAR *name)
+{
+    IDxDiagContainerImpl_Container *ret;
+
+    ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
+    if (!ret)
+        return NULL;
+
+    if (name)
+    {
+        ret->contName = HeapAlloc(GetProcessHeap(), 0, (strlenW(name) + 1) * sizeof(*name));
+        if (!ret->contName)
+        {
+            HeapFree(GetProcessHeap(), 0, ret);
+            return NULL;
+        }
+        strcpyW(ret->contName, name);
+    }
+
+    list_init(&ret->subContainers);
+    list_init(&ret->properties);
+
+    return ret;
+}
+
+static IDxDiagContainerImpl_Property *allocate_property_information(const WCHAR *name)
+{
+    IDxDiagContainerImpl_Property *ret;
+
+    ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
+    if (!ret)
+        return NULL;
+
+    ret->propName = HeapAlloc(GetProcessHeap(), 0, (strlenW(name) + 1) * sizeof(*name));
+    if (!ret->propName)
+    {
+        HeapFree(GetProcessHeap(), 0, ret);
+        return NULL;
+    }
+    strcpyW(ret->propName, name);
+
+    return ret;
+}
+
+static inline void add_subcontainer(IDxDiagContainerImpl_Container *node, IDxDiagContainerImpl_Container *subCont)
+{
+    list_add_tail(&node->subContainers, &subCont->entry);
+    ++node->nSubContainers;
+}
+
+static inline HRESULT add_bstr_property(IDxDiagContainerImpl_Container *node, const WCHAR *propName, const WCHAR *str)
+{
+    IDxDiagContainerImpl_Property *prop;
+    BSTR bstr;
+
+    prop = allocate_property_information(propName);
+    if (!prop)
+        return E_OUTOFMEMORY;
+
+    bstr = SysAllocString(str);
+    if (!bstr)
+    {
+        free_property_information(prop);
+        return E_OUTOFMEMORY;
+    }
+
+    V_VT(&prop->vProp) = VT_BSTR;
+    V_BSTR(&prop->vProp) = bstr;
+
+    list_add_tail(&node->properties, &prop->entry);
+    ++node->nProperties;
+
+    return S_OK;
+}
+
+static inline HRESULT add_ui4_property(IDxDiagContainerImpl_Container *node, const WCHAR *propName, DWORD data)
+{
+    IDxDiagContainerImpl_Property *prop;
+
+    prop = allocate_property_information(propName);
+    if (!prop)
+        return E_OUTOFMEMORY;
+
+    V_VT(&prop->vProp) = VT_UI4;
+    V_UI4(&prop->vProp) = data;
+
+    list_add_tail(&node->properties, &prop->entry);
+    ++node->nProperties;
+
+    return S_OK;
+}
+
+static inline HRESULT add_bool_property(IDxDiagContainerImpl_Container *node, const WCHAR *propName, BOOL data)
+{
+    IDxDiagContainerImpl_Property *prop;
+
+    prop = allocate_property_information(propName);
+    if (!prop)
+        return E_OUTOFMEMORY;
+
+    V_VT(&prop->vProp) = VT_BOOL;
+    V_BOOL(&prop->vProp) = data;
+
+    list_add_tail(&node->properties, &prop->entry);
+    ++node->nProperties;
+
+    return S_OK;
+}
+
+static inline HRESULT add_ull_as_bstr_property(IDxDiagContainerImpl_Container *node, const WCHAR *propName, ULONGLONG data )
+{
+    IDxDiagContainerImpl_Property *prop;
+
+    prop = allocate_property_information(propName);
+    if (!prop)
+        return E_OUTOFMEMORY;
+
+    V_VT(&prop->vProp) = VT_UI8;
+    V_UI8(&prop->vProp) = data;
+
+    VariantChangeType(&prop->vProp, &prop->vProp, 0, VT_BSTR);
+
+    list_add_tail(&node->properties, &prop->entry);
+    ++node->nProperties;
+
+    return S_OK;
+}
+
+/* Copied from programs/taskkill/taskkill.c. */
+static DWORD *enumerate_processes(DWORD *list_count)
+{
+    DWORD *pid_list, alloc_bytes = 1024 * sizeof(*pid_list), needed_bytes;
+
+    pid_list = HeapAlloc(GetProcessHeap(), 0, alloc_bytes);
+    if (!pid_list)
+        return NULL;
+
+    for (;;)
+    {
+        DWORD *realloc_list;
+
+        if (!EnumProcesses(pid_list, alloc_bytes, &needed_bytes))
+        {
+            HeapFree(GetProcessHeap(), 0, pid_list);
+            return NULL;
+        }
+
+        /* EnumProcesses can't signal an insufficient buffer condition, so the
+         * only way to possibly determine whether a larger buffer is required
+         * is to see whether the written number of bytes is the same as the
+         * buffer size. If so, the buffer will be reallocated to twice the
+         * size. */
+        if (alloc_bytes != needed_bytes)
+            break;
+
+        alloc_bytes *= 2;
+        realloc_list = HeapReAlloc(GetProcessHeap(), 0, pid_list, alloc_bytes);
+        if (!realloc_list)
+        {
+            HeapFree(GetProcessHeap(), 0, pid_list);
+            return NULL;
+        }
+        pid_list = realloc_list;
+    }
+
+    *list_count = needed_bytes / sizeof(*pid_list);
+    return pid_list;
+}
+
+/* Copied from programs/taskkill/taskkill.c. */
+static BOOL get_process_name_from_pid(DWORD pid, WCHAR *buf, DWORD chars)
+{
+    HANDLE process;
+    HMODULE module;
+    DWORD required_size;
+
+    process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
+    if (!process)
+        return FALSE;
+
+    if (!EnumProcessModules(process, &module, sizeof(module), &required_size))
+    {
+        CloseHandle(process);
+        return FALSE;
+    }
+
+    if (!GetModuleBaseNameW(process, module, buf, chars))
+    {
+        CloseHandle(process);
+        return FALSE;
+    }
+
+    CloseHandle(process);
+    return TRUE;
+}
+
+/* dxdiagn's detection scheme is simply to look for a process called conf.exe. */
+static BOOL is_netmeeting_running(void)
+{
+    static const WCHAR conf_exe[] = {'c','o','n','f','.','e','x','e',0};
+
+    DWORD list_count;
+    DWORD *pid_list = enumerate_processes(&list_count);
+
+    if (pid_list)
+    {
+        DWORD i;
+        WCHAR process_name[MAX_PATH];
+
+        for (i = 0; i < list_count; i++)
+        {
+            if (get_process_name_from_pid(pid_list[i], process_name, sizeof(process_name)/sizeof(WCHAR)) &&
+                !lstrcmpW(conf_exe, process_name))
+            {
+                HeapFree(GetProcessHeap(), 0, pid_list);
+                return TRUE;
+            }
+        }
+        HeapFree(GetProcessHeap(), 0, pid_list);
+    }
+
+    return FALSE;
+}
+
+static HRESULT fill_language_information(IDxDiagContainerImpl_Container *node)
+{
+    static const WCHAR regional_setting_engW[] = {'R','e','g','i','o','n','a','l',' ','S','e','t','t','i','n','g',0};
+    static const WCHAR languages_fmtW[] = {'%','s',' ','(','%','s',':',' ','%','s',')',0};
+    static const WCHAR szLanguagesLocalized[] = {'s','z','L','a','n','g','u','a','g','e','s','L','o','c','a','l','i','z','e','d',0};
+    static const WCHAR szLanguagesEnglish[] = {'s','z','L','a','n','g','u','a','g','e','s','E','n','g','l','i','s','h',0};
+
+    WCHAR system_lang[80], regional_setting[100], user_lang[80], language_str[300];
+    HRESULT hr;
+
+    /* szLanguagesLocalized */
+    GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT, LOCALE_SNATIVELANGNAME, system_lang, sizeof(system_lang)/sizeof(WCHAR));
+    LoadStringW(dxdiagn_instance, IDS_REGIONAL_SETTING, regional_setting, sizeof(regional_setting)/sizeof(WCHAR));
+    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SNATIVELANGNAME, user_lang, sizeof(user_lang)/sizeof(WCHAR));
+
+    snprintfW(language_str, sizeof(language_str)/sizeof(WCHAR), languages_fmtW, system_lang, regional_setting, user_lang);
+
+    hr = add_bstr_property(node, szLanguagesLocalized, language_str);
+    if (FAILED(hr))
+        return hr;
+
+    /* szLanguagesEnglish */
+    GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGLANGUAGE, system_lang, sizeof(system_lang)/sizeof(WCHAR));
+    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SENGLANGUAGE, user_lang, sizeof(user_lang)/sizeof(WCHAR));
+
+    snprintfW(language_str, sizeof(language_str)/sizeof(WCHAR), languages_fmtW, system_lang, regional_setting_engW, user_lang);
+
+    hr = add_bstr_property(node, szLanguagesEnglish, language_str);
+    if (FAILED(hr))
+        return hr;
+
+    return S_OK;
+}
+
+static HRESULT fill_datetime_information(IDxDiagContainerImpl_Container *node)
+{
+    static const WCHAR date_fmtW[] = {'M','\'','/','\'','d','\'','/','\'','y','y','y','y',0};
+    static const WCHAR time_fmtW[] = {'H','H','\'',':','\'','m','m','\'',':','\'','s','s',0};
+    static const WCHAR datetime_fmtW[] = {'%','s',',',' ','%','s',0};
+    static const WCHAR szTimeLocalized[] = {'s','z','T','i','m','e','L','o','c','a','l','i','z','e','d',0};
+    static const WCHAR szTimeEnglish[] = {'s','z','T','i','m','e','E','n','g','l','i','s','h',0};
+
+    SYSTEMTIME curtime;
+    WCHAR date_str[80], time_str[80], datetime_str[200];
+    HRESULT hr;
+
+    GetLocalTime(&curtime);
+
+    GetTimeFormatW(LOCALE_NEUTRAL, 0, &curtime, time_fmtW, time_str, sizeof(time_str)/sizeof(WCHAR));
+
+    /* szTimeLocalized */
+    GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &curtime, NULL, date_str, sizeof(date_str)/sizeof(WCHAR));
+
+    snprintfW(datetime_str, sizeof(datetime_str)/sizeof(WCHAR), datetime_fmtW, date_str, time_str);
+
+    hr = add_bstr_property(node, szTimeLocalized, datetime_str);
+    if (FAILED(hr))
+        return hr;
+
+    /* szTimeEnglish */
+    GetDateFormatW(LOCALE_NEUTRAL, 0, &curtime, date_fmtW, date_str, sizeof(date_str)/sizeof(WCHAR));
+
+    snprintfW(datetime_str, sizeof(datetime_str)/sizeof(WCHAR), datetime_fmtW, date_str, time_str);
+
+    hr = add_bstr_property(node, szTimeEnglish, datetime_str);
+    if (FAILED(hr))
+        return hr;
+
+    return S_OK;
+}
+
+static HRESULT fill_os_string_information(IDxDiagContainerImpl_Container *node, OSVERSIONINFOW *info)
+{
+    static const WCHAR winxpW[] = {'W','i','n','d','o','w','s',' ','X','P',' ','P','r','o','f','e','s','s','i','o','n','a','l',0};
+    static const WCHAR szOSLocalized[] = {'s','z','O','S','L','o','c','a','l','i','z','e','d',0};
+    static const WCHAR szOSExLocalized[] = {'s','z','O','S','E','x','L','o','c','a','l','i','z','e','d',0};
+    static const WCHAR szOSExLongLocalized[] = {'s','z','O','S','E','x','L','o','n','g','L','o','c','a','l','i','z','e','d',0};
+    static const WCHAR szOSEnglish[] = {'s','z','O','S','E','n','g','l','i','s','h',0};
+    static const WCHAR szOSExEnglish[] = {'s','z','O','S','E','x','E','n','g','l','i','s','h',0};
+    static const WCHAR szOSExLongEnglish[] = {'s','z','O','S','E','x','L','o','n','g','E','n','g','l','i','s','h',0};
+
+    static const WCHAR *prop_list[] = {szOSLocalized, szOSExLocalized, szOSExLongLocalized,
+                                       szOSEnglish, szOSExEnglish, szOSExLongEnglish};
+
+    size_t i;
+    HRESULT hr;
+
+    /* FIXME: OS detection should be performed, and localized OS strings
+     * should contain translated versions of the "build" phrase. */
+    for (i = 0; i < sizeof(prop_list)/sizeof(prop_list[0]); i++)
+    {
+        hr = add_bstr_property(node, prop_list[i], winxpW);
+        if (FAILED(hr))
+            return hr;
+    }
+
+    return S_OK;
+}
+
+static HRESULT fill_processor_information(IDxDiagContainerImpl_Container *node)
+{
+    static const WCHAR szProcessorEnglish[] = {'s','z','P','r','o','c','e','s','s','o','r','E','n','g','l','i','s','h',0};
+
+    static const WCHAR cimv2W[] = {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',0};
+    static const WCHAR proc_classW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s','o','r',0};
+    static const WCHAR nameW[] = {'N','a','m','e',0};
+    static const WCHAR max_clock_speedW[] = {'M','a','x','C','l','o','c','k','S','p','e','e','d',0};
+    static const WCHAR cpu_noW[] = {'N','u','m','b','e','r','O','f','L','o','g','i','c','a','l','P','r','o','c','e','s','s','o','r','s',0};
+
+    static const WCHAR processor_fmtW[] = {'%','s','(','%','d',' ','C','P','U','s',')',',',' ','~','%','d','M','H','z',0};
+
+    IWbemLocator *wbem_locator;
+    IWbemServices *wbem_service;
+    IWbemClassObject *wbem_class;
+    IEnumWbemClassObject *wbem_enum;
+    VARIANT cpu_name, cpu_no, clock_speed;
+    WCHAR print_buf[200];
+    BSTR bstr;
+    ULONG no;
+    HRESULT hr;
+
+    hr = CoCreateInstance(&CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, (void**)&wbem_locator);
+    if(FAILED(hr))
+        return hr;
+
+    bstr = SysAllocString(cimv2W);
+    if(!bstr) {
+        IWbemLocator_Release(wbem_locator);
+        return E_OUTOFMEMORY;
+    }
+    hr = IWbemLocator_ConnectServer(wbem_locator, bstr, NULL, NULL, NULL, 0, NULL, NULL, &wbem_service);
+    IWbemLocator_Release(wbem_locator);
+    SysFreeString(bstr);
+    if(FAILED(hr))
+        return hr;
+
+    bstr = SysAllocString(proc_classW);
+    if(!bstr) {
+        IWbemServices_Release(wbem_service);
+        return E_OUTOFMEMORY;
+    }
+    hr = IWbemServices_CreateInstanceEnum(wbem_service, bstr, WBEM_FLAG_SYSTEM_ONLY, NULL, &wbem_enum);
+    IWbemServices_Release(wbem_service);
+    SysFreeString(bstr);
+    if(FAILED(hr))
+        return hr;
+
+    hr = IEnumWbemClassObject_Next(wbem_enum, 1000, 1, &wbem_class, &no);
+    IEnumWbemClassObject_Release(wbem_enum);
+    if(FAILED(hr))
+        return hr;
+
+    hr = IWbemClassObject_Get(wbem_class, cpu_noW, 0, &cpu_no, NULL, NULL);
+    if(FAILED(hr)) {
+        IWbemClassObject_Release(wbem_class);
+        return hr;
+    }
+    hr = IWbemClassObject_Get(wbem_class, max_clock_speedW, 0, &clock_speed, NULL, NULL);
+    if(FAILED(hr)) {
+        IWbemClassObject_Release(wbem_class);
+        return hr;
+    }
+    hr = IWbemClassObject_Get(wbem_class, nameW, 0, &cpu_name, NULL, NULL);
+    IWbemClassObject_Release(wbem_class);
+    if(FAILED(hr))
+        return hr;
+
+    sprintfW(print_buf, processor_fmtW, V_BSTR(&cpu_name), V_I4(&cpu_no), V_I4(&clock_speed));
+    VariantClear(&cpu_name);
+    VariantClear(&cpu_no);
+    VariantClear(&clock_speed);
+
+    return add_bstr_property(node, szProcessorEnglish, print_buf);
+}
+
+static HRESULT build_systeminfo_tree(IDxDiagContainerImpl_Container *node)
+{
+    static const WCHAR dwDirectXVersionMajor[] = {'d','w','D','i','r','e','c','t','X','V','e','r','s','i','o','n','M','a','j','o','r',0};
+    static const WCHAR dwDirectXVersionMinor[] = {'d','w','D','i','r','e','c','t','X','V','e','r','s','i','o','n','M','i','n','o','r',0};
+    static const WCHAR szDirectXVersionLetter[] = {'s','z','D','i','r','e','c','t','X','V','e','r','s','i','o','n','L','e','t','t','e','r',0};
+    static const WCHAR szDirectXVersionLetter_v[] = {'c',0};
+    static const WCHAR bDebug[] = {'b','D','e','b','u','g',0};
+    static const WCHAR bNECPC98[] = {'b','N','E','C','P','C','9','8',0};
+    static const WCHAR szDirectXVersionEnglish[] = {'s','z','D','i','r','e','c','t','X','V','e','r','s','i','o','n','E','n','g','l','i','s','h',0};
+    static const WCHAR szDirectXVersionEnglish_v[] = {'4','.','0','9','.','0','0','0','0','.','0','9','0','4',0};
+    static const WCHAR szDirectXVersionLongEnglish[] = {'s','z','D','i','r','e','c','t','X','V','e','r','s','i','o','n','L','o','n','g','E','n','g','l','i','s','h',0};
+    static const WCHAR szDirectXVersionLongEnglish_v[] = {'=',' ','"','D','i','r','e','c','t','X',' ','9','.','0','c',' ','(','4','.','0','9','.','0','0','0','0','.','0','9','0','4',')',0};
+    static const WCHAR ullPhysicalMemory[] = {'u','l','l','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
+    static const WCHAR ullUsedPageFile[]   = {'u','l','l','U','s','e','d','P','a','g','e','F','i','l','e',0};
+    static const WCHAR ullAvailPageFile[]  = {'u','l','l','A','v','a','i','l','P','a','g','e','F','i','l','e',0};
+    static const WCHAR bNetMeetingRunning[] = {'b','N','e','t','M','e','e','t','i','n','g','R','u','n','n','i','n','g',0};
+    static const WCHAR szWindowsDir[] = {'s','z','W','i','n','d','o','w','s','D','i','r',0};
+    static const WCHAR dwOSMajorVersion[] = {'d','w','O','S','M','a','j','o','r','V','e','r','s','i','o','n',0};
+    static const WCHAR dwOSMinorVersion[] = {'d','w','O','S','M','i','n','o','r','V','e','r','s','i','o','n',0};
+    static const WCHAR dwOSBuildNumber[] = {'d','w','O','S','B','u','i','l','d','N','u','m','b','e','r',0};
+    static const WCHAR dwOSPlatformID[] = {'d','w','O','S','P','l','a','t','f','o','r','m','I','D',0};
+    static const WCHAR szCSDVersion[] = {'s','z','C','S','D','V','e','r','s','i','o','n',0};
+    static const WCHAR szPhysicalMemoryEnglish[] = {'s','z','P','h','y','s','i','c','a','l','M','e','m','o','r','y','E','n','g','l','i','s','h',0};
+    static const WCHAR szPageFileLocalized[] = {'s','z','P','a','g','e','F','i','l','e','L','o','c','a','l','i','z','e','d',0};
+    static const WCHAR szPageFileEnglish[] = {'s','z','P','a','g','e','F','i','l','e','E','n','g','l','i','s','h',0};
+    static const WCHAR szMachineNameLocalized[] = {'s','z','M','a','c','h','i','n','e','N','a','m','e','L','o','c','a','l','i','z','e','d',0};
+    static const WCHAR szMachineNameEnglish[] = {'s','z','M','a','c','h','i','n','e','N','a','m','e','E','n','g','l','i','s','h',0};
+    static const WCHAR szSystemManufacturerEnglish[] = {'s','z','S','y','s','t','e','m','M','a','n','u','f','a','c','t','u','r','e','r','E','n','g','l','i','s','h',0};
+    static const WCHAR szSystemModelEnglish[] = {'s','z','S','y','s','t','e','m','M','o','d','e','l','E','n','g','l','i','s','h',0};
+    static const WCHAR szBIOSEnglish[] = {'s','z','B','I','O','S','E','n','g','l','i','s','h',0};
+    static const WCHAR szSetupParamEnglish[] = {'s','z','S','e','t','u','p','P','a','r','a','m','E','n','g','l','i','s','h',0};
+    static const WCHAR szDxDiagVersion[] = {'s','z','D','x','D','i','a','g','V','e','r','s','i','o','n',0};
+
+    static const WCHAR notpresentW[] = {'N','o','t',' ','p','r','e','s','e','n','t',0};
+
+    static const WCHAR pagefile_fmtW[] = {'%','u','M','B',' ','u','s','e','d',',',' ','%','u','M','B',' ','a','v','a','i','l','a','b','l','e',0};
+    static const WCHAR physmem_fmtW[] = {'%','u','M','B',' ','R','A','M',0};
+
+    HRESULT hr;
+    MEMORYSTATUSEX msex;
+    OSVERSIONINFOW info;
+    DWORD count, usedpage_mb, availpage_mb;
+    WCHAR buffer[MAX_PATH], computer_name[MAX_COMPUTERNAME_LENGTH + 1], print_buf[200], localized_pagefile_fmt[200];
+    DWORD_PTR args[2];
+
+    hr = add_ui4_property(node, dwDirectXVersionMajor, 9);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_ui4_property(node, dwDirectXVersionMinor, 0);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_bstr_property(node, szDirectXVersionLetter, szDirectXVersionLetter_v);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_bstr_property(node, szDirectXVersionEnglish, szDirectXVersionEnglish_v);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_bstr_property(node, szDirectXVersionLongEnglish, szDirectXVersionLongEnglish_v);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_bool_property(node, bDebug, FALSE);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_bool_property(node, bNECPC98, FALSE);
+    if (FAILED(hr))
+        return hr;
+
+    msex.dwLength = sizeof(msex);
+    GlobalMemoryStatusEx(&msex);
+
+    hr = add_ull_as_bstr_property(node, ullPhysicalMemory, msex.ullTotalPhys);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_ull_as_bstr_property(node, ullUsedPageFile, msex.ullTotalPageFile - msex.ullAvailPageFile);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_ull_as_bstr_property(node, ullAvailPageFile, msex.ullAvailPageFile);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_bool_property(node, bNetMeetingRunning, is_netmeeting_running());
+    if (FAILED(hr))
+        return hr;
+
+    info.dwOSVersionInfoSize = sizeof(info);
+    GetVersionExW(&info);
+
+    hr = add_ui4_property(node, dwOSMajorVersion, info.dwMajorVersion);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_ui4_property(node, dwOSMinorVersion, info.dwMinorVersion);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_ui4_property(node, dwOSBuildNumber, info.dwBuildNumber);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_ui4_property(node, dwOSPlatformID, info.dwPlatformId);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_bstr_property(node, szCSDVersion, info.szCSDVersion);
+    if (FAILED(hr))
+        return hr;
+
+    /* FIXME: Roundoff should not be done with truncated division. */
+    snprintfW(print_buf, sizeof(print_buf)/sizeof(WCHAR), physmem_fmtW, (DWORD)(msex.ullTotalPhys / (1024 * 1024)));
+    hr = add_bstr_property(node, szPhysicalMemoryEnglish, print_buf);
+    if (FAILED(hr))
+        return hr;
+
+    usedpage_mb = (DWORD)((msex.ullTotalPageFile - msex.ullAvailPageFile) / (1024 * 1024));
+    availpage_mb = (DWORD)(msex.ullAvailPageFile / (1024 * 1024));
+    LoadStringW(dxdiagn_instance, IDS_PAGE_FILE_FORMAT, localized_pagefile_fmt, sizeof(localized_pagefile_fmt)/sizeof(WCHAR));
+    args[0] = usedpage_mb;
+    args[1] = availpage_mb;
+    FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
+                   localized_pagefile_fmt, 0, 0, print_buf,
+                   sizeof(print_buf)/sizeof(*print_buf), (__ms_va_list*)args);
+
+    hr = add_bstr_property(node, szPageFileLocalized, print_buf);
+    if (FAILED(hr))
+        return hr;
+
+    snprintfW(print_buf, sizeof(print_buf)/sizeof(WCHAR), pagefile_fmtW, usedpage_mb, availpage_mb);
+
+    hr = add_bstr_property(node, szPageFileEnglish, print_buf);
+    if (FAILED(hr))
+        return hr;
+
+    GetWindowsDirectoryW(buffer, MAX_PATH);
+
+    hr = add_bstr_property(node, szWindowsDir, buffer);
+    if (FAILED(hr))
+        return hr;
+
+    count = sizeof(computer_name)/sizeof(WCHAR);
+    if (!GetComputerNameW(computer_name, &count))
+        return E_FAIL;
+
+    hr = add_bstr_property(node, szMachineNameLocalized, computer_name);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_bstr_property(node, szMachineNameEnglish, computer_name);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_bstr_property(node, szSystemManufacturerEnglish, szEmpty);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_bstr_property(node, szSystemModelEnglish, szEmpty);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_bstr_property(node, szBIOSEnglish, szEmpty);
+    if (FAILED(hr))
+        return hr;
+
+    hr = fill_processor_information(node);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_bstr_property(node, szSetupParamEnglish, notpresentW);
+    if (FAILED(hr))
+        return hr;
+
+    hr = add_bstr_property(node, szDxDiagVersion, szEmpty);
+    if (FAILED(hr))
+        return hr;
+
+    hr = fill_language_information(node);
+    if (FAILED(hr))
+        return hr;
+
+    hr = fill_datetime_information(node);
+    if (FAILED(hr))
+        return hr;
+
+    hr = fill_os_string_information(node, &info);
+    if (FAILED(hr))
+        return hr;
+
+    return S_OK;
+}
+
+/* The logic from pixelformat_for_depth() in dlls/wined3d/utils.c is reversed. */
+static DWORD depth_for_pixelformat(D3DFORMAT format)
+{
+    switch (format)
+    {
+    case D3DFMT_P8: return 8;
+    case D3DFMT_X1R5G5B5: return 15;
+    case D3DFMT_R5G6B5: return 16;
+    /* This case will fail to distinguish an original bpp of 24. */
+    case D3DFMT_X8R8G8B8: return 32;
+    default:
+        FIXME("Unknown D3DFORMAT %d, returning 32 bpp\n", format);
+        return 32;
+    }
+}
+
+static BOOL get_texture_memory(GUID *adapter, DWORD *available_mem)
+{
+    IDirectDraw7 *pDirectDraw;
+    HRESULT hr;
+    DDSCAPS2 dd_caps;
+
+    hr = DirectDrawCreateEx(adapter, (void **)&pDirectDraw, &IID_IDirectDraw7, NULL);
+    if (SUCCEEDED(hr))
+    {
+        dd_caps.dwCaps = DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
+        dd_caps.dwCaps2 = dd_caps.dwCaps3 = dd_caps.u1.dwCaps4 = 0;
+        hr = IDirectDraw7_GetAvailableVidMem(pDirectDraw, &dd_caps, available_mem, NULL);
+        IDirectDraw7_Release(pDirectDraw);
+        if (SUCCEEDED(hr))
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+static const WCHAR *vendor_id_to_manufacturer_string(DWORD vendor_id)
+{
+    static const WCHAR atiW[] = {'A','T','I',' ','T','e','c','h','n','o','l','o','g','i','e','s',' ','I','n','c','.',0};
+    static const WCHAR nvidiaW[] = {'N','V','I','D','I','A',0};
+    static const WCHAR intelW[] = {'I','n','t','e','l',' ','C','o','r','p','o','r','a','t','i','o','n',0};
+    static const WCHAR unknownW[] = {'U','n','k','n','o','w','n',0};
+
+    /* Enumeration copied from dlls/wined3d/wined3d_private.h and slightly modified. */
+    enum pci_vendor
+    {
+        HW_VENDOR_AMD = 0x1002,
+        HW_VENDOR_NVIDIA = 0x10de,
+        HW_VENDOR_INTEL = 0x8086,
+    };
+
+    switch (vendor_id)
+    {
+    case HW_VENDOR_AMD:
+        return atiW;
+    case HW_VENDOR_NVIDIA:
+        return nvidiaW;
+    case HW_VENDOR_INTEL:
+        return intelW;
+    default:
+        FIXME("Unknown PCI vendor ID 0x%04x\n", vendor_id);
+        return unknownW;
+    }
+}
+
+static HRESULT fill_display_information_d3d(IDxDiagContainerImpl_Container *node)
+{
+    IDxDiagContainerImpl_Container *display_adapter;
+    HRESULT hr;
+    IDirect3D9 *pDirect3D9;
+    WCHAR buffer[256];
+    UINT index, count;
+
+    pDirect3D9 = Direct3DCreate9(D3D_SDK_VERSION);
+    if (!pDirect3D9)
+        return E_FAIL;
+
+    count = IDirect3D9_GetAdapterCount(pDirect3D9);
+    for (index = 0; index < count; index++)
+    {
+        static const WCHAR adapterid_fmtW[] = {'%','u',0};
+        static const WCHAR driverversion_fmtW[] = {'%','u','.','%','u','.','%','0','4','u','.','%','0','4','u',0};
+        static const WCHAR id_fmtW[] = {'0','x','%','0','4','x',0};
+        static const WCHAR subsysid_fmtW[] = {'0','x','%','0','8','x',0};
+        static const WCHAR mem_fmt[] = {'%','.','1','f',' ','M','B',0};
+
+        D3DADAPTER_IDENTIFIER9 adapter_info;
+        D3DDISPLAYMODE adapter_mode;
+        DWORD available_mem = 0;
+
+        snprintfW(buffer, sizeof(buffer)/sizeof(WCHAR), adapterid_fmtW, index);
+        display_adapter = allocate_information_node(buffer);
+        if (!display_adapter)
+        {
+            hr = E_OUTOFMEMORY;
+            goto cleanup;
+        }
+
+        add_subcontainer(node, display_adapter);
+
+        hr = IDirect3D9_GetAdapterIdentifier(pDirect3D9, index, 0, &adapter_info);
+        if (SUCCEEDED(hr))
+        {
+            WCHAR driverW[sizeof(adapter_info.Driver)];
+            WCHAR descriptionW[sizeof(adapter_info.Description)];
+            WCHAR devicenameW[sizeof(adapter_info.DeviceName)];
+
+            MultiByteToWideChar(CP_ACP, 0, adapter_info.Driver, -1, driverW, sizeof(driverW)/sizeof(WCHAR));
+            MultiByteToWideChar(CP_ACP, 0, adapter_info.Description, -1, descriptionW, sizeof(descriptionW)/sizeof(WCHAR));
+            MultiByteToWideChar(CP_ACP, 0, adapter_info.DeviceName, -1, devicenameW, sizeof(devicenameW)/sizeof(WCHAR));
+
+            hr = add_bstr_property(display_adapter, szDriverName, driverW);
+            if (FAILED(hr))
+                goto cleanup;
+
+            hr = add_bstr_property(display_adapter, szDescription, descriptionW);
+            if (FAILED(hr))
+                goto cleanup;
+
+            hr = add_bstr_property(display_adapter, szDeviceName, devicenameW);
+            if (FAILED(hr))
+                goto cleanup;
+
+            snprintfW(buffer, sizeof(buffer)/sizeof(WCHAR), driverversion_fmtW,
+                      HIWORD(adapter_info.DriverVersion.u.HighPart), LOWORD(adapter_info.DriverVersion.u.HighPart),
+                      HIWORD(adapter_info.DriverVersion.u.LowPart), LOWORD(adapter_info.DriverVersion.u.LowPart));
+
+            hr = add_bstr_property(display_adapter, szDriverVersion, buffer);
+            if (FAILED(hr))
+                goto cleanup;
+
+            snprintfW(buffer, sizeof(buffer)/sizeof(WCHAR), id_fmtW, adapter_info.VendorId);
+            hr = add_bstr_property(display_adapter, szVendorId, buffer);
+            if (FAILED(hr))
+                goto cleanup;
+
+            snprintfW(buffer, sizeof(buffer)/sizeof(WCHAR), id_fmtW, adapter_info.DeviceId);
+            hr = add_bstr_property(display_adapter, szDeviceId, buffer);
+            if (FAILED(hr))
+                goto cleanup;
+
+            snprintfW(buffer, sizeof(buffer)/sizeof(WCHAR), subsysid_fmtW, adapter_info.SubSysId);
+            hr = add_bstr_property(display_adapter, szSubSysId, buffer);
+            if (FAILED(hr))
+                goto cleanup;
+
+            snprintfW(buffer, sizeof(buffer)/sizeof(WCHAR), id_fmtW, adapter_info.Revision);
+            hr = add_bstr_property(display_adapter, szRevisionId, buffer);
+            if (FAILED(hr))
+                goto cleanup;
+
+            StringFromGUID2(&adapter_info.DeviceIdentifier, buffer, 39);
+            hr = add_bstr_property(display_adapter, szDeviceIdentifier, buffer);
+            if (FAILED(hr))
+                goto cleanup;
+
+            hr = add_bstr_property(display_adapter, szManufacturer, vendor_id_to_manufacturer_string(adapter_info.VendorId));
+            if (FAILED(hr))
+                goto cleanup;
+        }
+
+        hr = IDirect3D9_GetAdapterDisplayMode(pDirect3D9, index, &adapter_mode);
+        if (SUCCEEDED(hr))
+        {
+            hr = add_ui4_property(display_adapter, dwWidth, adapter_mode.Width);
+            if (FAILED(hr))
+                goto cleanup;
+
+            hr = add_ui4_property(display_adapter, dwHeight, adapter_mode.Height);
+            if (FAILED(hr))
+                goto cleanup;
+
+            hr = add_ui4_property(display_adapter, dwRefreshRate, adapter_mode.RefreshRate);
+            if (FAILED(hr))
+                goto cleanup;
+
+            hr = add_ui4_property(display_adapter, dwBpp, depth_for_pixelformat(adapter_mode.Format));
+            if (FAILED(hr))
+                goto cleanup;
+        }
+
+        hr = add_bstr_property(display_adapter, szKeyDeviceKey, szEmpty);
+        if (FAILED(hr))
+            goto cleanup;
+
+        hr = add_bstr_property(display_adapter, szKeyDeviceID, szEmpty);
+        if (FAILED(hr))
+            goto cleanup;
+
+        if (!get_texture_memory(&adapter_info.DeviceIdentifier, &available_mem))
+            WARN("get_texture_memory helper failed\n");
+
+        snprintfW(buffer, sizeof(buffer)/sizeof(buffer[0]), mem_fmt, available_mem / 1000000.0f);
+
+        hr = add_bstr_property(display_adapter, szDisplayMemoryLocalized, buffer);
+        if (FAILED(hr))
+            goto cleanup;
+
+        hr = add_bstr_property(display_adapter, szDisplayMemoryEnglish, buffer);
+        if (FAILED(hr))
+            goto cleanup;
+    }
+
+    hr = S_OK;
+cleanup:
+    IDirect3D9_Release(pDirect3D9);
+    return hr;
+}
+
+static HRESULT fill_display_information_fallback(IDxDiagContainerImpl_Container *node)
+{
+    static const WCHAR szAdapterID[] = {'0',0};
+    static const WCHAR *empty_properties[] = {szDeviceIdentifier, szVendorId, szDeviceId,
+                                              szKeyDeviceKey, szKeyDeviceID, szDriverName,
+                                              szDriverVersion, szSubSysId, szRevisionId,
+                                              szManufacturer};
+
+    IDxDiagContainerImpl_Container *display_adapter;
+    HRESULT hr;
+    IDirectDraw7 *pDirectDraw;
+    DDSCAPS2 dd_caps;
+    DISPLAY_DEVICEW disp_dev;
+    DDSURFACEDESC2 surface_descr;
+    DWORD tmp;
+    WCHAR buffer[256];
+
+    display_adapter = allocate_information_node(szAdapterID);
+    if (!display_adapter)
+        return E_OUTOFMEMORY;
+
+    add_subcontainer(node, display_adapter);
+
+    disp_dev.cb = sizeof(disp_dev);
+    if (EnumDisplayDevicesW( NULL, 0, &disp_dev, 0 ))
+    {
+        hr = add_bstr_property(display_adapter, szDeviceName, disp_dev.DeviceName);
+        if (FAILED(hr))
+            return hr;
+
+        hr = add_bstr_property(display_adapter, szDescription, disp_dev.DeviceString);
+        if (FAILED(hr))
+            return hr;
+    }
+
+    /* Silently ignore a failure from DirectDrawCreateEx. */
+    hr = DirectDrawCreateEx(NULL, (void **)&pDirectDraw, &IID_IDirectDraw7, NULL);
+    if (FAILED(hr))
+        return S_OK;
+
+    dd_caps.dwCaps = DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
+    dd_caps.dwCaps2 = dd_caps.dwCaps3 = dd_caps.u1.dwCaps4 = 0;
+    hr = IDirectDraw7_GetAvailableVidMem(pDirectDraw, &dd_caps, &tmp, NULL);
+    if (SUCCEEDED(hr))
+    {
+        static const WCHAR mem_fmt[] = {'%','.','1','f',' ','M','B',0};
+
+        snprintfW(buffer, sizeof(buffer)/sizeof(buffer[0]), mem_fmt, tmp / 1000000.0f);
+
+        hr = add_bstr_property(display_adapter, szDisplayMemoryLocalized, buffer);
+        if (FAILED(hr))
+            goto cleanup;
+
+        hr = add_bstr_property(display_adapter, szDisplayMemoryEnglish, buffer);
+        if (FAILED(hr))
+            goto cleanup;
+    }
+
+    surface_descr.dwSize = sizeof(surface_descr);
+    hr = IDirectDraw7_GetDisplayMode(pDirectDraw, &surface_descr);
+    if (SUCCEEDED(hr))
+    {
+        if (surface_descr.dwFlags & DDSD_WIDTH)
+        {
+            hr = add_ui4_property(display_adapter, dwWidth, surface_descr.dwWidth);
+            if (FAILED(hr))
+                goto cleanup;
+        }
+
+        if (surface_descr.dwFlags & DDSD_HEIGHT)
+        {
+            hr = add_ui4_property(display_adapter, dwHeight, surface_descr.dwHeight);
+            if (FAILED(hr))
+                goto cleanup;
+        }
+
+        if (surface_descr.dwFlags & DDSD_PIXELFORMAT)
+        {
+            hr = add_ui4_property(display_adapter, dwBpp, surface_descr.u4.ddpfPixelFormat.u1.dwRGBBitCount);
+            if (FAILED(hr))
+                goto cleanup;
+        }
+    }
+
+    hr = add_ui4_property(display_adapter, dwRefreshRate, 60);
+    if (FAILED(hr))
+        goto cleanup;
+
+    for (tmp = 0; tmp < sizeof(empty_properties)/sizeof(empty_properties[0]); tmp++)
+    {
+        hr = add_bstr_property(display_adapter, empty_properties[tmp], szEmpty);
+        if (FAILED(hr))
+            goto cleanup;
+    }
+
+    hr = S_OK;
+cleanup:
+    IDirectDraw7_Release(pDirectDraw);
+    return hr;
+}
+
+static HRESULT build_displaydevices_tree(IDxDiagContainerImpl_Container *node)
+{
+    HRESULT hr;
+
+    /* Try to use Direct3D to obtain the required information first. */
+    hr = fill_display_information_d3d(node);
+    if (hr != E_FAIL)
+        return hr;
+
+    return fill_display_information_fallback(node);
+}
+
+static HRESULT build_directsound_tree(IDxDiagContainerImpl_Container *node)
+{
+    static const WCHAR DxDiag_SoundDevices[] = {'D','x','D','i','a','g','_','S','o','u','n','d','D','e','v','i','c','e','s',0};
+    static const WCHAR DxDiag_SoundCaptureDevices[] = {'D','x','D','i','a','g','_','S','o','u','n','d','C','a','p','t','u','r','e','D','e','v','i','c','e','s',0};
+
+    IDxDiagContainerImpl_Container *cont;
+
+    cont = allocate_information_node(DxDiag_SoundDevices);
+    if (!cont)
+        return E_OUTOFMEMORY;
+
+    add_subcontainer(node, cont);
+
+    cont = allocate_information_node(DxDiag_SoundCaptureDevices);
+    if (!cont)
+        return E_OUTOFMEMORY;
+
+    add_subcontainer(node, cont);
+
+    return S_OK;
+}
+
+static HRESULT build_directmusic_tree(IDxDiagContainerImpl_Container *node)
+{
+    return S_OK;
+}
+
+static HRESULT build_directinput_tree(IDxDiagContainerImpl_Container *node)
+{
+    return S_OK;
+}
+
+static HRESULT build_directplay_tree(IDxDiagContainerImpl_Container *node)
+{
+    return S_OK;
+}
+
+static HRESULT build_systemdevices_tree(IDxDiagContainerImpl_Container *node)
+{
+    return S_OK;
+}
+
+static HRESULT fill_file_description(IDxDiagContainerImpl_Container *node, const WCHAR *szFilePath, const WCHAR *szFileName)
+{
+    static const WCHAR szSlashSep[] = {'\\',0};
+    static const WCHAR szPath[] = {'s','z','P','a','t','h',0};
+    static const WCHAR szName[] = {'s','z','N','a','m','e',0};
+    static const WCHAR szVersion[] = {'s','z','V','e','r','s','i','o','n',0};
+    static const WCHAR szAttributes[] = {'s','z','A','t','t','r','i','b','u','t','e','s',0};
+    static const WCHAR szLanguageEnglish[] = {'s','z','L','a','n','g','u','a','g','e','E','n','g','l','i','s','h',0};
+    static const WCHAR dwFileTimeHigh[] = {'d','w','F','i','l','e','T','i','m','e','H','i','g','h',0};
+    static const WCHAR dwFileTimeLow[] = {'d','w','F','i','l','e','T','i','m','e','L','o','w',0};
+    static const WCHAR bBeta[] = {'b','B','e','t','a',0};
+    static const WCHAR bDebug[] = {'b','D','e','b','u','g',0};
+    static const WCHAR bExists[] = {'b','E','x','i','s','t','s',0};
+
+    /* Values */
+    static const WCHAR szFinal_Retail_v[] = {'F','i','n','a','l',' ','R','e','t','a','i','l',0};
+    static const WCHAR szEnglish_v[] = {'E','n','g','l','i','s','h',0};
+    static const WCHAR szVersionFormat[] = {'%','u','.','%','0','2','u','.','%','0','4','u','.','%','0','4','u',0};
+
+    HRESULT hr;
+    WCHAR *szFile;
+    WCHAR szVersion_v[1024];
+    DWORD retval, hdl;
+    void *pVersionInfo = NULL;
+    BOOL boolret = FALSE;
+    UINT uiLength;
+    VS_FIXEDFILEINFO *pFileInfo;
+
+    TRACE("Filling container %p for %s in %s\n", node,
+          debugstr_w(szFileName), debugstr_w(szFilePath));
+
+    szFile = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * (lstrlenW(szFilePath) +
+                                            lstrlenW(szFileName) + 2 /* slash + terminator */));
+    if (!szFile)
+        return E_OUTOFMEMORY;
+
+    lstrcpyW(szFile, szFilePath);
+    lstrcatW(szFile, szSlashSep);
+    lstrcatW(szFile, szFileName);
+
+    retval = GetFileVersionInfoSizeW(szFile, &hdl);
+    if (retval)
+    {
+        pVersionInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, retval);
+        if (!pVersionInfo)
+        {
+            hr = E_OUTOFMEMORY;
+            goto cleanup;
+        }
+
+        if (GetFileVersionInfoW(szFile, 0, retval, pVersionInfo) &&
+            VerQueryValueW(pVersionInfo, szSlashSep, (void **)&pFileInfo, &uiLength))
+            boolret = TRUE;
+    }
+
+    hr = add_bstr_property(node, szPath, szFile);
+    if (FAILED(hr))
+        goto cleanup;
+
+    hr = add_bstr_property(node, szName, szFileName);
+    if (FAILED(hr))
+        goto cleanup;
+
+    hr = add_bool_property(node, bExists, boolret);
+    if (FAILED(hr))
+        goto cleanup;
+
+    if (boolret)
+    {
+        snprintfW(szVersion_v, sizeof(szVersion_v)/sizeof(szVersion_v[0]),
+                  szVersionFormat,
+                  HIWORD(pFileInfo->dwFileVersionMS),
+                  LOWORD(pFileInfo->dwFileVersionMS),
+                  HIWORD(pFileInfo->dwFileVersionLS),
+                  LOWORD(pFileInfo->dwFileVersionLS));
+
+        TRACE("Found version as (%s)\n", debugstr_w(szVersion_v));
+
+        hr = add_bstr_property(node, szVersion, szVersion_v);
+        if (FAILED(hr))
+            goto cleanup;
+
+        hr = add_bstr_property(node, szAttributes, szFinal_Retail_v);
+        if (FAILED(hr))
+            goto cleanup;
+
+        hr = add_bstr_property(node, szLanguageEnglish, szEnglish_v);
+        if (FAILED(hr))
+            goto cleanup;
+
+        hr = add_ui4_property(node, dwFileTimeHigh, pFileInfo->dwFileDateMS);
+        if (FAILED(hr))
+            goto cleanup;
+
+        hr = add_ui4_property(node, dwFileTimeLow, pFileInfo->dwFileDateLS);
+        if (FAILED(hr))
+            goto cleanup;
+
+        hr = add_bool_property(node, bBeta, ((pFileInfo->dwFileFlags & pFileInfo->dwFileFlagsMask) & VS_FF_PRERELEASE) != 0);
+        if (FAILED(hr))
+            goto cleanup;
+
+        hr = add_bool_property(node, bDebug, ((pFileInfo->dwFileFlags & pFileInfo->dwFileFlagsMask) & VS_FF_DEBUG) != 0);
+        if (FAILED(hr))
+            goto cleanup;
+    }
+
+    hr = S_OK;
+cleanup:
+    HeapFree(GetProcessHeap(), 0, pVersionInfo);
+    HeapFree(GetProcessHeap(), 0, szFile);
+
+    return hr;
+}
+static HRESULT build_directxfiles_tree(IDxDiagContainerImpl_Container *node)
+{
+    static const WCHAR dlls[][15] =
+    {
+        {'d','3','d','8','.','d','l','l',0},
+        {'d','3','d','9','.','d','l','l',0},
+        {'d','d','r','a','w','.','d','l','l',0},
+        {'d','e','v','e','n','u','m','.','d','l','l',0},
+        {'d','i','n','p','u','t','8','.','d','l','l',0},
+        {'d','i','n','p','u','t','.','d','l','l',0},
+        {'d','m','b','a','n','d','.','d','l','l',0},
+        {'d','m','c','o','m','p','o','s','.','d','l','l',0},
+        {'d','m','i','m','e','.','d','l','l',0},
+        {'d','m','l','o','a','d','e','r','.','d','l','l',0},
+        {'d','m','s','c','r','i','p','t','.','d','l','l',0},
+        {'d','m','s','t','y','l','e','.','d','l','l',0},
+        {'d','m','s','y','n','t','h','.','d','l','l',0},
+        {'d','m','u','s','i','c','.','d','l','l',0},
+        {'d','p','l','a','y','x','.','d','l','l',0},
+        {'d','p','n','e','t','.','d','l','l',0},
+        {'d','s','o','u','n','d','.','d','l','l',0},
+        {'d','s','w','a','v','e','.','d','l','l',0},
+        {'d','x','d','i','a','g','n','.','d','l','l',0},
+        {'q','u','a','r','t','z','.','d','l','l',0}
+    };
+
+    HRESULT hr;
+    WCHAR szFilePath[MAX_PATH];
+    INT i;
+
+    GetSystemDirectoryW(szFilePath, MAX_PATH);
+
+    for (i = 0; i < sizeof(dlls) / sizeof(dlls[0]); i++)
+    {
+        static const WCHAR szFormat[] = {'%','d',0};
+
+        WCHAR szFileID[5];
+        IDxDiagContainerImpl_Container *file_container;
+
+        snprintfW(szFileID, sizeof(szFileID)/sizeof(szFileID[0]), szFormat, i);
+
+        file_container = allocate_information_node(szFileID);
+        if (!file_container)
+            return E_OUTOFMEMORY;
+
+        hr = fill_file_description(file_container, szFilePath, dlls[i]);
+        if (FAILED(hr))
+        {
+            free_information_tree(file_container);
+            continue;
+        }
+
+        add_subcontainer(node, file_container);
+    }
+
+    return S_OK;
+}
+
+static HRESULT read_property_names(IPropertyBag *pPropBag, VARIANT *friendly_name, VARIANT *clsid_name)
+{
+    static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
+    static const WCHAR wszClsidName[] = {'C','L','S','I','D',0};
+
+    HRESULT hr;
+
+    VariantInit(friendly_name);
+    VariantInit(clsid_name);
+
+    hr = IPropertyBag_Read(pPropBag, wszFriendlyName, friendly_name, 0);
+    if (FAILED(hr))
+        return hr;
+
+    hr = IPropertyBag_Read(pPropBag, wszClsidName, clsid_name, 0);
+    if (FAILED(hr))
+    {
+        VariantClear(friendly_name);
+        return hr;
+    }
+
+    return S_OK;
+}
+
+static HRESULT fill_filter_data_information(IDxDiagContainerImpl_Container *subcont, BYTE *pData, ULONG cb)
+{
+    static const WCHAR szVersionW[] = {'s','z','V','e','r','s','i','o','n',0};
+    static const WCHAR dwInputs[] = {'d','w','I','n','p','u','t','s',0};
+    static const WCHAR dwOutputs[] = {'d','w','O','u','t','p','u','t','s',0};
+    static const WCHAR dwMeritW[] = {'d','w','M','e','r','i','t',0};
+    static const WCHAR szVersionFormat[] = {'v','%','d',0};
+
+    HRESULT hr;
+    IFilterMapper2 *pFileMapper = NULL;
+    IAMFilterData *pFilterData = NULL;
+    BYTE *ppRF = NULL;
+    REGFILTER2 *pRF = NULL;
+    WCHAR bufferW[10];
+    ULONG j;
+    DWORD dwNOutputs = 0;
+    DWORD dwNInputs = 0;
+
+    hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IFilterMapper2,
+                          (void **)&pFileMapper);
+    if (FAILED(hr))
+        return hr;
+
+    hr = IFilterMapper2_QueryInterface(pFileMapper, &IID_IAMFilterData, (void **)&pFilterData);
+    if (FAILED(hr))
+        goto cleanup;
+
+    hr = IAMFilterData_ParseFilterData(pFilterData, pData, cb, (BYTE **)&ppRF);
+    if (FAILED(hr))
+        goto cleanup;
+    pRF = ((REGFILTER2**)ppRF)[0];
+
+    snprintfW(bufferW, sizeof(bufferW)/sizeof(bufferW[0]), szVersionFormat, pRF->dwVersion);
+    hr = add_bstr_property(subcont, szVersionW, bufferW);
+    if (FAILED(hr))
+        goto cleanup;
+
+    if (pRF->dwVersion == 1)
+    {
+        for (j = 0; j < pRF->u.s1.cPins; j++)
+            if (pRF->u.s1.rgPins[j].bOutput)
+                dwNOutputs++;
+            else
+                dwNInputs++;
+    }
+    else if (pRF->dwVersion == 2)
+    {
+        for (j = 0; j < pRF->u.s2.cPins2; j++)
+            if (pRF->u.s2.rgPins2[j].dwFlags & REG_PINFLAG_B_OUTPUT)
+                dwNOutputs++;
+            else
+                dwNInputs++;
+    }
+
+    hr = add_ui4_property(subcont, dwInputs, dwNInputs);
+    if (FAILED(hr))
+        goto cleanup;
+
+    hr = add_ui4_property(subcont, dwOutputs, dwNOutputs);
+    if (FAILED(hr))
+        goto cleanup;
+
+    hr = add_ui4_property(subcont, dwMeritW, pRF->dwMerit);
+    if (FAILED(hr))
+        goto cleanup;
+
+    hr = S_OK;
+cleanup:
+    CoTaskMemFree(pRF);
+    if (pFilterData) IAMFilterData_Release(pFilterData);
+    if (pFileMapper) IFilterMapper2_Release(pFileMapper);
+
+    return hr;
+}
+
+static HRESULT fill_filter_container(IDxDiagContainerImpl_Container *subcont, IMoniker *pMoniker)
+{
+    static const WCHAR szName[] = {'s','z','N','a','m','e',0};
+    static const WCHAR ClsidFilterW[] = {'C','l','s','i','d','F','i','l','t','e','r',0};
+    static const WCHAR wszFilterDataName[] = {'F','i','l','t','e','r','D','a','t','a',0};
+
+    HRESULT hr;
+    IPropertyBag *pPropFilterBag = NULL;
+    BYTE *pData;
+    VARIANT friendly_name;
+    VARIANT clsid_name;
+    VARIANT v;
+
+    VariantInit(&friendly_name);
+    VariantInit(&clsid_name);
+    VariantInit(&v);
+
+    hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (void **)&pPropFilterBag);
+    if (FAILED(hr))
+        return hr;
+
+    hr = read_property_names(pPropFilterBag, &friendly_name, &clsid_name);
+    if (FAILED(hr))
+        goto cleanup;
+
+    TRACE("Name = %s\n", debugstr_w(V_BSTR(&friendly_name)));
+    TRACE("CLSID = %s\n", debugstr_w(V_BSTR(&clsid_name)));
+
+    hr = add_bstr_property(subcont, szName, V_BSTR(&friendly_name));
+    if (FAILED(hr))
+        goto cleanup;
+
+    hr = add_bstr_property(subcont, ClsidFilterW, V_BSTR(&clsid_name));
+    if (FAILED(hr))
+        goto cleanup;
+
+    hr = IPropertyBag_Read(pPropFilterBag, wszFilterDataName, &v, NULL);
+    if (FAILED(hr))
+        goto cleanup;
+
+    hr = SafeArrayAccessData(V_ARRAY(&v), (void **)&pData);
+    if (FAILED(hr))
+        goto cleanup;
+
+    hr = fill_filter_data_information(subcont, pData, V_ARRAY(&v)->rgsabound->cElements);
+    SafeArrayUnaccessData(V_ARRAY(&v));
+    if (FAILED(hr))
+        goto cleanup;
+
+    hr = S_OK;
+cleanup:
+    VariantClear(&v);
+    VariantClear(&clsid_name);
+    VariantClear(&friendly_name);
+    if (pPropFilterBag) IPropertyBag_Release(pPropFilterBag);
+
+    return hr;
+}
+
+static HRESULT build_directshowfilters_tree(IDxDiagContainerImpl_Container *node)
+{
+    static const WCHAR szCatName[] = {'s','z','C','a','t','N','a','m','e',0};
+    static const WCHAR ClsidCatW[] = {'C','l','s','i','d','C','a','t',0};
+    static const WCHAR szIdFormat[] = {'%','d',0};
+
+    HRESULT hr;
+    int i = 0;
+    ICreateDevEnum *pCreateDevEnum;
+    IEnumMoniker *pEmCat = NULL;
+    IMoniker *pMCat = NULL;
+       IEnumMoniker *pEnum = NULL;
+
+    hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
+                          &IID_ICreateDevEnum, (void **)&pCreateDevEnum);
+    if (FAILED(hr))
+        return hr;
+
+    hr = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum, &CLSID_ActiveMovieCategories, &pEmCat, 0);
+    if (FAILED(hr))
+        goto cleanup;
+
+    while (IEnumMoniker_Next(pEmCat, 1, &pMCat, NULL) == S_OK)
+    {
+        VARIANT vCatName;
+        VARIANT vCatClsid;
+        IPropertyBag *pPropBag;
+        CLSID clsidCat;
+        IMoniker *pMoniker = NULL;
+
+        hr = IMoniker_BindToStorage(pMCat, NULL, NULL, &IID_IPropertyBag, (void **)&pPropBag);
+        if (FAILED(hr))
+        {
+            IMoniker_Release(pMCat);
+            break;
+        }
+
+        hr = read_property_names(pPropBag, &vCatName, &vCatClsid);
+        IPropertyBag_Release(pPropBag);
+        if (FAILED(hr))
+        {
+            IMoniker_Release(pMCat);
+            break;
+        }
+
+        hr = CLSIDFromString(V_BSTR(&vCatClsid), &clsidCat);
+        if (FAILED(hr))
+        {
+            IMoniker_Release(pMCat);
+            VariantClear(&vCatClsid);
+            VariantClear(&vCatName);
+            break;
+        }
+
+        hr = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum, &clsidCat, &pEnum, 0);
+        if (hr != S_OK)
+        {
+            IMoniker_Release(pMCat);
+            VariantClear(&vCatClsid);
+            VariantClear(&vCatName);
+            continue;
+        }
+
+        TRACE("Enumerating class %s\n", debugstr_guid(&clsidCat));
+
+        while (IEnumMoniker_Next(pEnum, 1, &pMoniker, NULL) == S_OK)
+        {
+            WCHAR bufferW[10];
+            IDxDiagContainerImpl_Container *subcont;
+
+            snprintfW(bufferW, sizeof(bufferW)/sizeof(bufferW[0]), szIdFormat, i);
+            subcont = allocate_information_node(bufferW);
+            if (!subcont)
+            {
+                hr = E_OUTOFMEMORY;
+                IMoniker_Release(pMoniker);
+                break;
+            }
+
+            hr = add_bstr_property(subcont, szCatName, V_BSTR(&vCatName));
+            if (FAILED(hr))
+            {
+                free_information_tree(subcont);
+                IMoniker_Release(pMoniker);
+                break;
+            }
+
+            hr = add_bstr_property(subcont, ClsidCatW, V_BSTR(&vCatClsid));
+            if (FAILED(hr))
+            {
+                free_information_tree(subcont);
+                IMoniker_Release(pMoniker);
+                break;
+            }
+
+            hr = fill_filter_container(subcont, pMoniker);
+            if (FAILED(hr))
+            {
+                free_information_tree(subcont);
+                IMoniker_Release(pMoniker);
+                break;
+            }
+
+            add_subcontainer(node, subcont);
+            i++;
+            IMoniker_Release(pMoniker);
+        }
+
+        IEnumMoniker_Release(pEnum);
+        IMoniker_Release(pMCat);
+        VariantClear(&vCatClsid);
+        VariantClear(&vCatName);
+
+        if (FAILED(hr))
+            break;
+    }
+
+cleanup:
+    if (pEmCat) IEnumMoniker_Release(pEmCat);
+    ICreateDevEnum_Release(pCreateDevEnum);
+    return hr;
+}
+
+static HRESULT build_logicaldisks_tree(IDxDiagContainerImpl_Container *node)
+{
+    return S_OK;
+}
+
+static HRESULT build_information_tree(IDxDiagContainerImpl_Container **pinfo_root)
+{
+    static const WCHAR DxDiag_SystemInfo[] = {'D','x','D','i','a','g','_','S','y','s','t','e','m','I','n','f','o',0};
+    static const WCHAR DxDiag_DisplayDevices[] = {'D','x','D','i','a','g','_','D','i','s','p','l','a','y','D','e','v','i','c','e','s',0};
+    static const WCHAR DxDiag_DirectSound[] = {'D','x','D','i','a','g','_','D','i','r','e','c','t','S','o','u','n','d',0};
+    static const WCHAR DxDiag_DirectMusic[] = {'D','x','D','i','a','g','_','D','i','r','e','c','t','M','u','s','i','c',0};
+    static const WCHAR DxDiag_DirectInput[] = {'D','x','D','i','a','g','_','D','i','r','e','c','t','I','n','p','u','t',0};
+    static const WCHAR DxDiag_DirectPlay[] = {'D','x','D','i','a','g','_','D','i','r','e','c','t','P','l','a','y',0};
+    static const WCHAR DxDiag_SystemDevices[] = {'D','x','D','i','a','g','_','S','y','s','t','e','m','D','e','v','i','c','e','s',0};
+    static const WCHAR DxDiag_DirectXFiles[] = {'D','x','D','i','a','g','_','D','i','r','e','c','t','X','F','i','l','e','s',0};
+    static const WCHAR DxDiag_DirectShowFilters[] = {'D','x','D','i','a','g','_','D','i','r','e','c','t','S','h','o','w','F','i','l','t','e','r','s',0};
+    static const WCHAR DxDiag_LogicalDisks[] = {'D','x','D','i','a','g','_','L','o','g','i','c','a','l','D','i','s','k','s',0};
+
+    static const struct
+    {
+        const WCHAR *name;
+        HRESULT (*initfunc)(IDxDiagContainerImpl_Container *);
+    } root_children[] =
+    {
+        {DxDiag_SystemInfo, build_systeminfo_tree},
+        {DxDiag_DisplayDevices, build_displaydevices_tree},
+        {DxDiag_DirectSound, build_directsound_tree},
+        {DxDiag_DirectMusic, build_directmusic_tree},
+        {DxDiag_DirectInput, build_directinput_tree},
+        {DxDiag_DirectPlay, build_directplay_tree},
+        {DxDiag_SystemDevices, build_systemdevices_tree},
+        {DxDiag_DirectXFiles, build_directxfiles_tree},
+        {DxDiag_DirectShowFilters, build_directshowfilters_tree},
+        {DxDiag_LogicalDisks, build_logicaldisks_tree},
+    };
+
+    IDxDiagContainerImpl_Container *info_root;
+    size_t index;
+
+    info_root = allocate_information_node(NULL);
+    if (!info_root)
+        return E_OUTOFMEMORY;
+
+    for (index = 0; index < sizeof(root_children)/sizeof(root_children[0]); index++)
+    {
+        IDxDiagContainerImpl_Container *node;
+        HRESULT hr;
+
+        node = allocate_information_node(root_children[index].name);
+        if (!node)
+        {
+            free_information_tree(info_root);
+            return E_OUTOFMEMORY;
+        }
+
+        hr = root_children[index].initfunc(node);
+        if (FAILED(hr))
+        {
+            free_information_tree(node);
+            free_information_tree(info_root);
+            return hr;
+        }
+
+        add_subcontainer(info_root, node);
+    }
+
+    *pinfo_root = info_root;
+    return S_OK;
 }
 }
diff --git a/reactos/dll/directx/wine/dxdiagn/regsvr.c b/reactos/dll/directx/wine/dxdiagn/regsvr.c
deleted file mode 100644 (file)
index 748cc22..0000000
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- *     self-registerable dll functions for dxdiag.dll
- *
- * Copyright (C) 2004 Raphael Junqueira
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#define WIN32_NO_STATUS
-#define _INC_WINDOWS
-#define COM_NO_WINDOWS_H
-
-#include <stdarg.h>
-//#include <string.h>
-
-#include <windef.h>
-#include <winbase.h>
-//#include "wingdi.h"
-//#include "winuser.h"
-#include <winreg.h>
-//#include "winerror.h"
-
-#include <initguid.h>
-#include "dxdiag_private.h"
-#include <wine/debug.h>
-
-WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);
-
-/*
- * Near the bottom of this file are the exported DllRegisterServer and
- * DllUnregisterServer, which make all this worthwhile.
- */
-
-/***********************************************************************
- *             interface for self-registering
- */
-struct regsvr_interface
-{
-    IID const *iid;            /* NULL for end of list */
-    LPCSTR name;               /* can be NULL to omit */
-    IID const *base_iid;       /* can be NULL to omit */
-    int num_methods;           /* can be <0 to omit */
-    CLSID const *ps_clsid;     /* can be NULL to omit */
-    CLSID const *ps_clsid32;   /* can be NULL to omit */
-};
-
-static HRESULT register_interfaces(struct regsvr_interface const *list);
-static HRESULT unregister_interfaces(struct regsvr_interface const *list);
-
-struct regsvr_coclass
-{
-    CLSID const *clsid;                /* NULL for end of list */
-    LPCSTR name;               /* can be NULL to omit */
-    LPCSTR ips;                        /* can be NULL to omit */
-    LPCSTR ips32;              /* can be NULL to omit */
-    LPCSTR ips32_tmodel;       /* can be NULL to omit */
-    LPCSTR progid;             /* can be NULL to omit */
-    LPCSTR viprogid;           /* can be NULL to omit */
-    LPCSTR progid_extra;       /* can be NULL to omit */
-};
-
-static HRESULT register_coclasses(struct regsvr_coclass const *list);
-static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
-
-/***********************************************************************
- *             static string constants
- */
-static WCHAR const interface_keyname[10] = {
-    'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
-static WCHAR const base_ifa_keyname[14] = {
-    'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
-    'e', 0 };
-static WCHAR const num_methods_keyname[11] = {
-    'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
-static WCHAR const ps_clsid_keyname[15] = {
-    'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
-    'i', 'd', 0 };
-static WCHAR const ps_clsid32_keyname[17] = {
-    'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
-    'i', 'd', '3', '2', 0 };
-static WCHAR const clsid_keyname[6] = {
-    'C', 'L', 'S', 'I', 'D', 0 };
-static WCHAR const curver_keyname[7] = {
-    'C', 'u', 'r', 'V', 'e', 'r', 0 };
-static WCHAR const ips_keyname[13] = {
-    'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
-    0 };
-static WCHAR const ips32_keyname[15] = {
-    'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
-    '3', '2', 0 };
-static WCHAR const progid_keyname[7] = {
-    'P', 'r', 'o', 'g', 'I', 'D', 0 };
-static WCHAR const viprogid_keyname[25] = {
-    'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
-    'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
-    0 };
-static char const tmodel_valuename[] = "ThreadingModel";
-
-/***********************************************************************
- *             static helper functions
- */
-static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
-static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
-                                  WCHAR const *value);
-static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
-                                  char const *value);
-static LONG register_progid(WCHAR const *clsid,
-                           char const *progid, char const *curver_progid,
-                           char const *name, char const *extra);
-static LONG recursive_delete_key(HKEY key);
-static LONG recursive_delete_keyA(HKEY base, char const *name);
-static LONG recursive_delete_keyW(HKEY base, WCHAR const *name);
-
-/***********************************************************************
- *             register_interfaces
- */
-static HRESULT register_interfaces(struct regsvr_interface const *list)
-{
-    LONG res = ERROR_SUCCESS;
-    HKEY interface_key;
-
-    res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
-                         KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
-    if (res != ERROR_SUCCESS) goto error_return;
-
-    for (; res == ERROR_SUCCESS && list->iid; ++list) {
-       WCHAR buf[39];
-       HKEY iid_key;
-
-       StringFromGUID2(list->iid, buf, 39);
-       res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
-                             KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
-       if (res != ERROR_SUCCESS) goto error_close_interface_key;
-
-       if (list->name) {
-           res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
-                                (CONST BYTE*)(list->name),
-                                strlen(list->name) + 1);
-           if (res != ERROR_SUCCESS) goto error_close_iid_key;
-       }
-
-       if (list->base_iid) {
-           register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
-           if (res != ERROR_SUCCESS) goto error_close_iid_key;
-       }
-
-       if (0 <= list->num_methods) {
-           static WCHAR const fmt[3] = { '%', 'd', 0 };
-           HKEY key;
-
-           res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
-                                 KEY_READ | KEY_WRITE, NULL, &key, NULL);
-           if (res != ERROR_SUCCESS) goto error_close_iid_key;
-
-           wsprintfW(buf, fmt, list->num_methods);
-           res = RegSetValueExW(key, NULL, 0, REG_SZ,
-                                (CONST BYTE*)buf,
-                                (lstrlenW(buf) + 1) * sizeof(WCHAR));
-           RegCloseKey(key);
-
-           if (res != ERROR_SUCCESS) goto error_close_iid_key;
-       }
-
-       if (list->ps_clsid) {
-           register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
-           if (res != ERROR_SUCCESS) goto error_close_iid_key;
-       }
-
-       if (list->ps_clsid32) {
-           register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
-           if (res != ERROR_SUCCESS) goto error_close_iid_key;
-       }
-
-    error_close_iid_key:
-       RegCloseKey(iid_key);
-    }
-
-error_close_interface_key:
-    RegCloseKey(interface_key);
-error_return:
-    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- *             unregister_interfaces
- */
-static HRESULT unregister_interfaces(struct regsvr_interface const *list)
-{
-    LONG res = ERROR_SUCCESS;
-    HKEY interface_key;
-
-    res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
-                       KEY_READ | KEY_WRITE, &interface_key);
-    if (res == ERROR_FILE_NOT_FOUND) return S_OK;
-    if (res != ERROR_SUCCESS) goto error_return;
-
-    for (; res == ERROR_SUCCESS && list->iid; ++list) {
-       WCHAR buf[39];
-
-       StringFromGUID2(list->iid, buf, 39);
-       res = recursive_delete_keyW(interface_key, buf);
-    }
-
-    RegCloseKey(interface_key);
-error_return:
-    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- *             register_coclasses
- */
-static HRESULT register_coclasses(struct regsvr_coclass const *list)
-{
-    LONG res = ERROR_SUCCESS;
-    HKEY coclass_key;
-
-    res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
-                         KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
-    if (res != ERROR_SUCCESS) goto error_return;
-
-    for (; res == ERROR_SUCCESS && list->clsid; ++list) {
-       WCHAR buf[39];
-       HKEY clsid_key;
-
-       StringFromGUID2(list->clsid, buf, 39);
-       res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
-                             KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
-       if (res != ERROR_SUCCESS) goto error_close_coclass_key;
-
-       if (list->name) {
-           res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
-                                (CONST BYTE*)(list->name),
-                                strlen(list->name) + 1);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-       }
-
-       if (list->ips) {
-           res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-       }
-
-       if (list->ips32) {
-           HKEY ips32_key;
-
-           res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
-                                 KEY_READ | KEY_WRITE, NULL,
-                                 &ips32_key, NULL);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-
-           res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
-                                (CONST BYTE*)list->ips32,
-                                lstrlenA(list->ips32) + 1);
-           if (res == ERROR_SUCCESS && list->ips32_tmodel)
-               res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
-                                    (CONST BYTE*)list->ips32_tmodel,
-                                    strlen(list->ips32_tmodel) + 1);
-           RegCloseKey(ips32_key);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-       }
-
-       if (list->progid) {
-           res = register_key_defvalueA(clsid_key, progid_keyname,
-                                        list->progid);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-
-           res = register_progid(buf, list->progid, NULL,
-                                 list->name, list->progid_extra);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-       }
-
-       if (list->viprogid) {
-           res = register_key_defvalueA(clsid_key, viprogid_keyname,
-                                        list->viprogid);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-
-           res = register_progid(buf, list->viprogid, list->progid,
-                                 list->name, list->progid_extra);
-           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-       }
-
-    error_close_clsid_key:
-       RegCloseKey(clsid_key);
-    }
-
-error_close_coclass_key:
-    RegCloseKey(coclass_key);
-error_return:
-    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- *             unregister_coclasses
- */
-static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
-{
-    LONG res = ERROR_SUCCESS;
-    HKEY coclass_key;
-
-    res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
-                       KEY_READ | KEY_WRITE, &coclass_key);
-    if (res == ERROR_FILE_NOT_FOUND) return S_OK;
-    if (res != ERROR_SUCCESS) goto error_return;
-
-    for (; res == ERROR_SUCCESS && list->clsid; ++list) {
-       WCHAR buf[39];
-
-       StringFromGUID2(list->clsid, buf, 39);
-       res = recursive_delete_keyW(coclass_key, buf);
-       if (res != ERROR_SUCCESS) goto error_close_coclass_key;
-
-       if (list->progid) {
-           res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->progid);
-           if (res != ERROR_SUCCESS) goto error_close_coclass_key;
-       }
-
-       if (list->viprogid) {
-           res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->viprogid);
-           if (res != ERROR_SUCCESS) goto error_close_coclass_key;
-       }
-    }
-
-error_close_coclass_key:
-    RegCloseKey(coclass_key);
-error_return:
-    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- *             regsvr_key_guid
- */
-static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
-{
-    WCHAR buf[39];
-
-    StringFromGUID2(guid, buf, 39);
-    return register_key_defvalueW(base, name, buf);
-}
-
-/***********************************************************************
- *             regsvr_key_defvalueW
- */
-static LONG register_key_defvalueW(
-    HKEY base,
-    WCHAR const *name,
-    WCHAR const *value)
-{
-    LONG res;
-    HKEY key;
-
-    res = RegCreateKeyExW(base, name, 0, NULL, 0,
-                         KEY_READ | KEY_WRITE, NULL, &key, NULL);
-    if (res != ERROR_SUCCESS) return res;
-    res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
-                        (lstrlenW(value) + 1) * sizeof(WCHAR));
-    RegCloseKey(key);
-    return res;
-}
-
-/***********************************************************************
- *             regsvr_key_defvalueA
- */
-static LONG register_key_defvalueA(
-    HKEY base,
-    WCHAR const *name,
-    char const *value)
-{
-    LONG res;
-    HKEY key;
-
-    res = RegCreateKeyExW(base, name, 0, NULL, 0,
-                         KEY_READ | KEY_WRITE, NULL, &key, NULL);
-    if (res != ERROR_SUCCESS) return res;
-    res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
-                        lstrlenA(value) + 1);
-    RegCloseKey(key);
-    return res;
-}
-
-/***********************************************************************
- *             regsvr_progid
- */
-static LONG register_progid(
-    WCHAR const *clsid,
-    char const *progid,
-    char const *curver_progid,
-    char const *name,
-    char const *extra)
-{
-    LONG res;
-    HKEY progid_key;
-
-    res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
-                         NULL, 0, KEY_READ | KEY_WRITE, NULL,
-                         &progid_key, NULL);
-    if (res != ERROR_SUCCESS) return res;
-
-    if (name) {
-       res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
-                            (CONST BYTE*)name, strlen(name) + 1);
-       if (res != ERROR_SUCCESS) goto error_close_progid_key;
-    }
-
-    if (clsid) {
-       res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
-       if (res != ERROR_SUCCESS) goto error_close_progid_key;
-    }
-
-    if (curver_progid) {
-       res = register_key_defvalueA(progid_key, curver_keyname,
-                                    curver_progid);
-       if (res != ERROR_SUCCESS) goto error_close_progid_key;
-    }
-
-    if (extra) {
-       HKEY extra_key;
-
-       res = RegCreateKeyExA(progid_key, extra, 0,
-                             NULL, 0, KEY_READ | KEY_WRITE, NULL,
-                             &extra_key, NULL);
-       if (res == ERROR_SUCCESS)
-           RegCloseKey(extra_key);
-    }
-
-error_close_progid_key:
-    RegCloseKey(progid_key);
-    return res;
-}
-
-/***********************************************************************
- *             recursive_delete_key
- */
-static LONG recursive_delete_key(HKEY key)
-{
-    LONG res;
-    WCHAR subkey_name[MAX_PATH];
-    DWORD cName;
-    HKEY subkey;
-
-    for (;;) {
-       cName = sizeof(subkey_name) / sizeof(WCHAR);
-       res = RegEnumKeyExW(key, 0, subkey_name, &cName,
-                           NULL, NULL, NULL, NULL);
-       if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) {
-           res = ERROR_SUCCESS; /* presumably we're done enumerating */
-           break;
-       }
-       res = RegOpenKeyExW(key, subkey_name, 0,
-                           KEY_READ | KEY_WRITE, &subkey);
-       if (res == ERROR_FILE_NOT_FOUND) continue;
-       if (res != ERROR_SUCCESS) break;
-
-       res = recursive_delete_key(subkey);
-       RegCloseKey(subkey);
-       if (res != ERROR_SUCCESS) break;
-    }
-
-    if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0);
-    return res;
-}
-
-/***********************************************************************
- *             recursive_delete_keyA
- */
-static LONG recursive_delete_keyA(HKEY base, char const *name)
-{
-    LONG res;
-    HKEY key;
-
-    res = RegOpenKeyExA(base, name, 0, KEY_READ | KEY_WRITE, &key);
-    if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
-    if (res != ERROR_SUCCESS) return res;
-    res = recursive_delete_key(key);
-    RegCloseKey(key);
-    return res;
-}
-
-/***********************************************************************
- *             recursive_delete_keyW
- */
-static LONG recursive_delete_keyW(HKEY base, WCHAR const *name)
-{
-    LONG res;
-    HKEY key;
-
-    res = RegOpenKeyExW(base, name, 0, KEY_READ | KEY_WRITE, &key);
-    if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
-    if (res != ERROR_SUCCESS) return res;
-    res = recursive_delete_key(key);
-    RegCloseKey(key);
-    return res;
-}
-
-/***********************************************************************
- *             coclass list
- */
-static struct regsvr_coclass const coclass_list[] = {
-    {
-           &CLSID_DxDiagProvider,
-           "DxDiagProvider Class",
-           NULL,
-           "dxdiagn.dll",
-           "Apartment",
-           NULL,
-           "DxDiag.DxDiagProvider.1",
-           "DxDiag.DxDiagProvider"
-    },
-    { NULL }                   /* list terminator */
-};
-
-/***********************************************************************
- *             interface list
- */
-
-static struct regsvr_interface const interface_list[] = {
-    { NULL }                   /* list terminator */
-};
-
-/***********************************************************************
- *             DllRegisterServer (DXDIAGN.@)
- */
-HRESULT WINAPI DllRegisterServer(void)
-{
-    HRESULT hr;
-
-    TRACE("\n");
-
-    hr = register_coclasses(coclass_list);
-    if (SUCCEEDED(hr))
-       hr = register_interfaces(interface_list);
-    return hr;
-}
-
-/***********************************************************************
- *             DllUnregisterServer (DXDIAGN.@)
- */
-HRESULT WINAPI DllUnregisterServer(void)
-{
-    HRESULT hr;
-
-    TRACE("\n");
-
-    hr = unregister_coclasses(coclass_list);
-    if (SUCCEEDED(hr))
-       hr = unregister_interfaces(interface_list);
-    return hr;
-}
similarity index 63%
rename from reactos/dll/directx/wine/dxdiagn/version.rc
rename to reactos/dll/directx/wine/dxdiagn/resource.h
index e4e973d..dd6c1a3 100644 (file)
@@ -1,5 +1,7 @@
 /*
 /*
- * Copyright 2004 Raphael Junqueira
+ * Resource identifiers for dxdiagn
+ *
+ * Copyright 2011 Andrew Nguyen
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  *
  * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  */
 
-#define WINE_FILEDESCRIPTION_STR "Wine DxDiag 8"
-#define WINE_FILENAME_STR "dxdiagn.dll"
-#define WINE_FILEVERSION 5,3,1,902
-#define WINE_FILEVERSION_STR "5.3.1.902"
-#define WINE_PRODUCTVERSION 5,3,1,902
-#define WINE_PRODUCTVERSION_STR "5.3"
+#include <windef.h>
 
 
-#include "wine/wine_common_ver.rc"
+#define IDS_REGIONAL_SETTING 1
+#define IDS_PAGE_FILE_FORMAT 2
diff --git a/reactos/include/reactos/wine/dxdiag.h b/reactos/include/reactos/wine/dxdiag.h
new file mode 100644 (file)
index 0000000..47cd36e
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2004 Raphael Junqueira
+ *
+ * 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
+ */
+
+#ifndef __WINE_DXDIAG_H
+#define __WINE_DXDIAG_H
+
+#include <ole2.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+/*****************************************************************************
+ * #defines and error codes
+ */
+#define DXDIAG_DX9_SDK_VERSION 111
+
+#define _FACDXDIAG  0x007
+#define MAKE_DXDIAGHRESULT( code )  MAKE_HRESULT( 1, _FACDXDIAG, code )
+
+/*
+ * DXDiag Errors
+ */
+#define DXDIAG_E_INSUFFICIENT_BUFFER       MAKE_DXDIAGHRESULT(0x007A)
+
+
+/*****************************************************************************
+ * DXDiag structures Typedefs
+ */
+typedef struct _DXDIAG_INIT_PARAMS {
+  DWORD  dwSize;
+  DWORD  dwDxDiagHeaderVersion;
+  BOOL   bAllowWHQLChecks;
+  VOID*  pReserved;
+} DXDIAG_INIT_PARAMS;
+
+
+/*****************************************************************************
+ * Predeclare the interfaces
+ */
+/* CLSIDs */
+DEFINE_GUID(CLSID_DxDiagProvider,   0xA65B8071, 0x3BFE, 0x4213, 0x9A, 0x5B, 0x49, 0x1D, 0xA4, 0x46, 0x1C, 0xA7);
+
+/* IIDs */
+DEFINE_GUID(IID_IDxDiagProvider,    0x9C6B4CB0, 0x23F8, 0x49CC, 0xA3, 0xED, 0x45, 0xA5, 0x50, 0x00, 0xA6, 0xD2);
+DEFINE_GUID(IID_IDxDiagContainer,   0x7D0F462F, 0x4064, 0x4862, 0xBC, 0x7F, 0x93, 0x3E, 0x50, 0x58, 0xC1, 0x0F);
+
+/* typedef definitions */
+typedef struct IDxDiagProvider *LPDXDIAGPROVIDER,   *PDXDIAGPROVIDER;
+typedef struct IDxDiagContainer *LPDXDIAGCONTAINER,  *PDXDIAGCONTAINER;
+
+/*****************************************************************************
+ * IDxDiagContainer interface
+ */
+#ifdef WINE_NO_UNICODE_MACROS
+#undef GetProp
+#endif
+
+#define INTERFACE IDxDiagContainer
+DECLARE_INTERFACE_(IDxDiagContainer,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDxDiagContainer methods ***/
+    STDMETHOD(GetNumberOfChildContainers)(THIS_  DWORD* pdwCount) PURE;
+    STDMETHOD(EnumChildContainerNames)(THIS_ DWORD dwIndex, LPWSTR pwszContainer, DWORD cchContainer) PURE;
+    STDMETHOD(GetChildContainer)(THIS_ LPCWSTR pwszContainer, IDxDiagContainer** ppInstance) PURE;
+    STDMETHOD(GetNumberOfProps)(THIS_ DWORD* pdwCount) PURE;
+    STDMETHOD(EnumPropNames)(THIS_ DWORD dwIndex, LPWSTR pwszPropName, DWORD cchPropName) PURE;
+    STDMETHOD(GetProp)(THIS_ LPCWSTR pwszPropName, VARIANT* pvarProp) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define        IDxDiagContainer_QueryInterface(p,a,b)               (p)->lpVtbl->QueryInterface(p,a,b)
+#define        IDxDiagContainer_AddRef(p)                           (p)->lpVtbl->AddRef(p)
+#define        IDxDiagContainer_Release(p)                          (p)->lpVtbl->Release(p)
+/*** IDxDiagContainer methods ***/
+#define IDxDiagContainer_GetNumberOfChildContainers(p,a)     (p)->lpVtbl->GetNumberOfChildContainers(p,a)
+#define IDxDiagContainer_EnumChildContainerNames(p,a,b,c)    (p)->lpVtbl->EnumChildContainerNames(p,a,b,c)
+#define IDxDiagContainer_GetChildContainer(p,a,b)            (p)->lpVtbl->GetChildContainer(p,a,b)
+#define IDxDiagContainer_GetNumberOfProps(p,a)               (p)->lpVtbl->GetNumberOfProps(p,a)
+#define IDxDiagContainer_EnumPropNames(p,a,b,c)              (p)->lpVtbl->EnumPropNames(p,a,b,c)
+#define IDxDiagContainer_GetProp(p,a,b)                      (p)->lpVtbl->GetProp(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define        IDxDiagContainer_QueryInterface(p,a,b)               (p)->QueryInterface(a,b)
+#define        IDxDiagContainer_AddRef(p)                           (p)->AddRef()
+#define        IDxDiagContainer_Release(p)                          (p)->Release()
+/*** IDxDiagContainer methods ***/
+#define IDxDiagContainer_GetNumberOfChildContainers(p,a)     (p)->GetNumberOfChildContainers(a)
+#define IDxDiagContainer_EnumChildContainerNames(p,a,b,c)    (p)->EnumChildContainerNames(a,b,c)
+#define IDxDiagContainer_GetChildContainer(p,a,b)            (p)->GetChildContainer(a,b)
+#define IDxDiagContainer_GetNumberOfProps(p,a)               (p)->GetNumberOfProps(a)
+#define IDxDiagContainer_EnumPropNames(p,a,b,c)              (p)->EnumPropNames(a,b,c)
+#define IDxDiagContainer_GetProp(p,a,b)                      (p)->GetProp(a,b)
+#endif
+
+/*****************************************************************************
+ * IDxDiagProvider interface
+ */
+#define INTERFACE IDxDiagProvider
+DECLARE_INTERFACE_(IDxDiagProvider,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDxDiagProvider methods ***/
+    STDMETHOD(Initialize)(THIS_ DXDIAG_INIT_PARAMS* pParams) PURE;
+    STDMETHOD(GetRootContainer)(THIS_ IDxDiagContainer** ppInstance) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define        IDxDiagProvider_QueryInterface(p,a,b)                (p)->lpVtbl->QueryInterface(p,a,b)
+#define        IDxDiagProvider_AddRef(p)                            (p)->lpVtbl->AddRef(p)
+#define        IDxDiagProvider_Release(p)                           (p)->lpVtbl->Release(p)
+/*** IDxDiagProvider methods ***/
+#define IDxDiagProvider_Initialize(p,a)                      (p)->lpVtbl->Initialize(p,a)
+#define IDxDiagProvider_GetRootContainer(p,a)                (p)->lpVtbl->GetRootContainer(p,a)
+#else
+/*** IUnknown methods ***/
+#define        IDxDiagProvider_QueryInterface(p,a,b)                (p)->QueryInterface(a,b)
+#define        IDxDiagProvider_AddRef(p)                            (p)->AddRef()
+#define        IDxDiagProvider_Release(p)                           (p)->Release()
+/*** IDxDiagProvider methods ***/
+#define IDxDiagProvider_Initialize(p,a)                      (p)->Initialize(a)
+#define IDxDiagProvider_GetRootContainer(p,a)                (p)->GetRootContainer(a)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 607a1b7..27caedb 100644 (file)
@@ -40,7 +40,7 @@ reactos/dll/directx/wine/dmusic         # Synced to Wine-1.5.26
 reactos/dll/directx/wine/dplay          # Synced to Wine-1.7.1
 reactos/dll/directx/wine/dplayx         # Synced to Wine-1.7.1
 reactos/dll/directx/wine/dsound         # Synced to Wine-1.7.1
 reactos/dll/directx/wine/dplay          # Synced to Wine-1.7.1
 reactos/dll/directx/wine/dplayx         # Synced to Wine-1.7.1
 reactos/dll/directx/wine/dsound         # Synced to Wine-1.7.1
-reactos/dll/directx/wine/dxdiagn        # Synced to Wine-0_9_5
+reactos/dll/directx/wine/dxdiagn        # Synced to Wine-1.7.1
 reactos/dll/directx/wine/dxgi           # Synced to Wine-1.7.1
 reactos/dll/directx/wine/msdmo          # Autosync
 reactos/dll/directx/wine/qedit          # Autosync
 reactos/dll/directx/wine/dxgi           # Synced to Wine-1.7.1
 reactos/dll/directx/wine/msdmo          # Autosync
 reactos/dll/directx/wine/qedit          # Autosync