- fix dxdiag.h (again)
- IDxDiagContainerImpl implementation
- IDxDiagProvider::GetRootContainer (that creates the root container)

diff --git a/dlls/dxdiagn/Makefile.in b/dlls/dxdiagn/Makefile.in
index bb71f9b..4198f4c 100644
--- a/dlls/dxdiagn/Makefile.in
+++ b/dlls/dxdiagn/Makefile.in
@@ -7,6 +7,7 @@
 EXTRALIBS = -ldxguid -luuid
 
 C_SRCS = \
+	container.c \
 	dxdiag_main.c \
 	provider.c \
 	regsvr.c
diff --git a/dlls/dxdiagn/container.c b/dlls/dxdiagn/container.c
new file mode 100644
index 0000000..0703323
--- /dev/null
+++ b/dlls/dxdiagn/container.c
@@ -0,0 +1,170 @@
+/* 
+ * IDxDiagContainer Implementation
+ * 
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "config.h"
+#include "dxdiag_private.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);
+
+/* IDxDiagContainer IUnknown parts follow: */
+HRESULT WINAPI IDxDiagContainerImpl_QueryInterface(PDXDIAGCONTAINER iface, REFIID riid, LPVOID *ppobj)
+{
+    ICOM_THIS(IDxDiagContainerImpl,iface);
+
+    if (IsEqualGUID(riid, &IID_IUnknown)
+        || IsEqualGUID(riid, &IID_IDxDiagContainer)) {
+        IDxDiagContainerImpl_AddRef(iface);
+        *ppobj = This;
+        return S_OK;
+    }
+
+    WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
+    return E_NOINTERFACE;
+}
+
+ULONG WINAPI IDxDiagContainerImpl_AddRef(PDXDIAGCONTAINER iface) {
+    ICOM_THIS(IDxDiagContainerImpl,iface);
+    TRACE("(%p) : AddRef from %ld\n", This, This->ref);
+    return ++(This->ref);
+}
+
+ULONG WINAPI IDxDiagContainerImpl_Release(PDXDIAGCONTAINER iface) {
+    ICOM_THIS(IDxDiagContainerImpl,iface);
+    ULONG ref = --This->ref;
+    TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
+    if (ref == 0) {
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+    return ref;
+}
+
+/* IDxDiagContainer Interface follow: */
+HRESULT WINAPI IDxDiagContainerImpl_GetNumberOfChildContainers(PDXDIAGCONTAINER iface, DWORD* pdwCount) {
+  ICOM_THIS(IDxDiagContainerImpl,iface);
+  TRACE("(%p)\n", iface);
+  if (NULL == pdwCount) {
+    return E_INVALIDARG;
+  }
+  *pdwCount = This->nSubContainers;
+  return S_OK;
+}
+
+HRESULT WINAPI IDxDiagContainerImpl_EnumChildContainerNames(PDXDIAGCONTAINER iface, DWORD dwIndex, LPWSTR pwszContainer, DWORD cchContainer) {
+  IDxDiagContainerImpl_SubContainer* p = NULL;
+  DWORD i = 0;
+  ICOM_THIS(IDxDiagContainerImpl,iface);
+  
+  TRACE("(%p, %lu, %s, %lu)\n", iface, dwIndex, debugstr_w(pwszContainer), cchContainer);
+
+  if (NULL == pwszContainer) {
+    return E_INVALIDARG;
+  }
+  if (256 > cchContainer) {
+    return DXDIAG_E_INSUFFICIENT_BUFFER;
+  }
+  
+  p = This->subContainers;
+  while (NULL != p) {
+    if (dwIndex == i) {  
+      if (cchContainer <= strlenW(p->contName)) {
+	return DXDIAG_E_INSUFFICIENT_BUFFER;
+      }
+      lstrcpynW(pwszContainer, p->contName, cchContainer);
+      return S_OK;
+    }
+    p = p->next;
+    ++i;
+  }  
+  return E_INVALIDARG;
+}
+
+HRESULT WINAPI IDxDiagContainerImpl_GetChildContainer(PDXDIAGCONTAINER iface, LPCWSTR pwszContainer, IDxDiagContainer** ppInstance) {
+  IDxDiagContainerImpl_SubContainer* p = NULL;
+  ICOM_THIS(IDxDiagContainerImpl,iface);
+
+  FIXME("(%p, %s, %p)\n", iface, debugstr_w(pwszContainer), ppInstance);
+
+  if (NULL == ppInstance || NULL == pwszContainer) {
+    return E_INVALIDARG;
+  }
+
+  p = This->subContainers;
+  while (NULL != p) {
+    if (0 == lstrcmpW(p->contName, pwszContainer)) {      
+      IDxDiagContainerImpl_QueryInterface((PDXDIAGCONTAINER)p, &IID_IDxDiagContainer, (void**) ppInstance);
+      return S_OK;
+    }
+    p = p->next;
+  }
+
+  return E_INVALIDARG;
+}
+
+HRESULT WINAPI IDxDiagContainerImpl_GetNumberOfProps(PDXDIAGCONTAINER iface, DWORD* pdwCount) {
+  /* ICOM_THIS(IDxDiagContainerImpl,iface); */
+  FIXME("(%p, %p): stub\n", iface, pdwCount);
+  return S_OK;
+}
+
+HRESULT WINAPI IDxDiagContainerImpl_EnumPropNames(PDXDIAGCONTAINER iface, DWORD dwIndex, LPWSTR pwszPropName, DWORD cchPropName) {
+  /* ICOM_THIS(IDxDiagContainerImpl,iface); */
+  FIXME("(%p, %lu, %s, %lu): stub\n", iface, dwIndex, debugstr_w(pwszPropName), cchPropName);
+  return S_OK;
+}
+
+HRESULT WINAPI IDxDiagContainerImpl_GetProp(PDXDIAGCONTAINER iface, LPCWSTR pwszPropName, VARIANT* pvarProp) {
+  /* ICOM_THIS(IDxDiagContainerImpl,iface); */
+  FIXME("(%p, %s, %p): stub\n", iface, debugstr_w(pwszPropName), pvarProp);
+  return S_OK;
+}
+
+
+ICOM_VTABLE(IDxDiagContainer) DxDiagContainer_Vtbl =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    IDxDiagContainerImpl_QueryInterface,
+    IDxDiagContainerImpl_AddRef,
+    IDxDiagContainerImpl_Release,
+    IDxDiagContainerImpl_GetNumberOfChildContainers,
+    IDxDiagContainerImpl_EnumChildContainerNames,
+    IDxDiagContainerImpl_GetChildContainer,
+    IDxDiagContainerImpl_GetNumberOfProps,
+    IDxDiagContainerImpl_EnumPropNames,
+    IDxDiagContainerImpl_GetProp
+};
+
+
+HRESULT DXDiag_CreateDXDiagContainer(REFIID riid, LPVOID *ppobj) {
+  IDxDiagContainerImpl* container;
+
+  TRACE("(%p, %p)\n", debugstr_guid(riid), ppobj);
+  
+  container = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDxDiagContainerImpl));
+  if (NULL == container) {
+    *ppobj = NULL;
+    return E_OUTOFMEMORY;
+  }
+  container->lpVtbl = &DxDiagContainer_Vtbl;
+  container->ref = 0; /* will be inited with QueryInterface */
+  return IDxDiagContainerImpl_QueryInterface((PDXDIAGCONTAINER)container, riid, ppobj);
+}
diff --git a/dlls/dxdiagn/dxdiag_private.h b/dlls/dxdiagn/dxdiag_private.h
index b2b8d7c..a8531c3 100644
--- a/dlls/dxdiagn/dxdiag_private.h
+++ b/dlls/dxdiagn/dxdiag_private.h
@@ -42,17 +42,19 @@
 /*****************************************************************************
  * Predeclare the interface implementation structures
  */
-extern ICOM_VTABLE(IDxDiagProvider) DirectPlay8Client_Vtbl;
+extern ICOM_VTABLE(IDxDiagProvider) DxDiagProvider_Vtbl;
 
 /*****************************************************************************
  * IDxDiagProvider implementation structure
  */
-struct IDxDiagProviderImpl
-{
+struct IDxDiagProviderImpl {
   /* IUnknown fields */
   ICOM_VFIELD(IDxDiagProvider);
   DWORD       ref;
   /* IDxDiagProvider fields */
+  BOOL        init;
+  DXDIAG_INIT_PARAMS params;
+  IDxDiagContainer* pRootContainer;
 };
 
 /* IUnknown: */
@@ -64,11 +66,54 @@
 extern HRESULT WINAPI IDxDiagProviderImpl_Initialize(PDXDIAGPROVIDER iface, DXDIAG_INIT_PARAMS* pParams);
 extern HRESULT WINAPI IDxDiagProviderImpl_GetRootContainer(PDXDIAGPROVIDER iface, IDxDiagContainer** ppInstance);
 
+/* ---------------- */
+/* IDxDiagContainer  */
+/* ---------------- */
+
+typedef struct IDxDiagContainerImpl_SubContainer {
+  IDxDiagContainer* pCont;
+  WCHAR* contName;
+  struct IDxDiagContainerImpl_SubContainer* next;
+} IDxDiagContainerImpl_SubContainer;
+
+/*****************************************************************************
+ * Predeclare the interface implementation structures
+ */
+extern ICOM_VTABLE(IDxDiagContainer) DxDiagContainer_Vtbl;
+
+/*****************************************************************************
+ * IDxDiagContainer implementation structure
+ */
+struct IDxDiagContainerImpl {
+  /* IUnknown fields */
+  ICOM_VFIELD(IDxDiagContainer);
+  DWORD       ref;
+  /* IDxDiagContainer fields */
+  IDxDiagContainerImpl_SubContainer* subContainers;
+  DWORD nSubContainers;
+};
+
+/* IUnknown: */
+extern HRESULT WINAPI IDxDiagContainerImpl_QueryInterface(PDXDIAGCONTAINER iface, REFIID riid, LPVOID *ppobj);
+extern ULONG WINAPI IDxDiagContainerImpl_AddRef(PDXDIAGCONTAINER iface);
+extern ULONG WINAPI IDxDiagContainerImpl_Release(PDXDIAGCONTAINER iface);
+
+/* IDxDiagContainer: */
+extern HRESULT WINAPI IDxDiagContainerImpl_GetNumberOfChildContainers(PDXDIAGCONTAINER iface,  DWORD* pdwCount);
+extern HRESULT WINAPI IDxDiagContainerImpl_EnumChildContainerNames(PDXDIAGCONTAINER iface, DWORD dwIndex, LPWSTR pwszContainer, DWORD cchContainer);
+extern HRESULT WINAPI IDxDiagContainerImpl_GetChildContainer(PDXDIAGCONTAINER iface, LPCWSTR pwszContainer, IDxDiagContainer** ppInstance);
+extern HRESULT WINAPI IDxDiagContainerImpl_GetNumberOfProps(PDXDIAGCONTAINER iface, DWORD* pdwCount);
+extern HRESULT WINAPI IDxDiagContainerImpl_EnumPropNames(PDXDIAGCONTAINER iface, DWORD dwIndex, LPWSTR pwszPropName, DWORD cchPropName);
+extern HRESULT WINAPI IDxDiagContainerImpl_GetProp(PDXDIAGCONTAINER iface, LPCWSTR pwszPropName, VARIANT* pvarProp);
+
 /**
  * factories
  */
 extern HRESULT DXDiag_CreateDXDiagProvider(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj);
 
+/** internal factory */
+extern HRESULT DXDiag_CreateDXDiagContainer(REFIID riid, LPVOID *ppobj);
+
 
 
 #endif
diff --git a/dlls/dxdiagn/provider.c b/dlls/dxdiagn/provider.c
index afc8554..93418d5 100644
--- a/dlls/dxdiagn/provider.c
+++ b/dlls/dxdiagn/provider.c
@@ -59,11 +59,39 @@
 
 /* IDxDiagProvider Interface follow: */
 HRESULT WINAPI IDxDiagProviderImpl_Initialize(PDXDIAGPROVIDER iface, DXDIAG_INIT_PARAMS* pParams) {
-  return S_OK;
+    ICOM_THIS(IDxDiagProviderImpl, iface);
+    TRACE("(%p,%p)\n", iface, pParams);
+
+    if (NULL == pParams) {
+      return E_POINTER;
+    }
+    if (pParams->dwSize != sizeof(DXDIAG_INIT_PARAMS)) {
+      return E_INVALIDARG;
+    }
+
+    This->init = TRUE;
+    memcpy(&This->params, pParams, pParams->dwSize);
+    return S_OK;
 }
 
 HRESULT WINAPI IDxDiagProviderImpl_GetRootContainer(PDXDIAGPROVIDER iface, IDxDiagContainer** ppInstance) {
-  return S_OK;
+  HRESULT hr = S_OK;
+  ICOM_THIS(IDxDiagProviderImpl, iface);
+  TRACE("(%p,%p)\n", iface, ppInstance);
+
+  if (NULL == ppInstance) {
+    return E_INVALIDARG;
+  }
+  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 IDxDiagContainerImpl_QueryInterface((PDXDIAGCONTAINER)This->pRootContainer, &IID_IDxDiagContainer, (void**) ppInstance);
 }
 
 ICOM_VTABLE(IDxDiagProvider) DxDiagProvider_Vtbl =
diff --git a/include/dxdiag.h b/include/dxdiag.h
index caa21f2..8563a47 100644
--- a/include/dxdiag.h
+++ b/include/dxdiag.h
@@ -31,12 +31,12 @@
 #define DXDIAG_DX9_SDK_VERSION 111
 
 #define _FACDXDIAG  0x007
-#define MAKE_DXDIAGHRESULT( code )  MAKE_HRESULT( 1, _FACDDXDIAG, code )
+#define MAKE_DXDIAGHRESULT( code )  MAKE_HRESULT( 1, _FACDXDIAG, code )
 
 /*
  * DXDiag Errors
  */
-#define DXDIAG_E_INSUFFICIENT_BUFFER       MAKE_DXDIAGHRESULT(007A)
+#define DXDIAG_E_INSUFFICIENT_BUFFER       MAKE_DXDIAGHRESULT(0x007A)
 
 
 /*****************************************************************************