diff --git a/reactos/dll/directx/wine/dxdiagn/CMakeLists.txt b/reactos/dll/directx/wine/dxdiagn/CMakeLists.txt index a3a30b1f861..182b0045b33 100644 --- a/reactos/dll/directx/wine/dxdiagn/CMakeLists.txt +++ b/reactos/dll/directx/wine/dxdiagn/CMakeLists.txt @@ -1,28 +1,19 @@ - +add_definitions(-D__WINESRC__) include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) - spec2def(dxdiagn.dll dxdiagn.spec) -add_library(dxdiagn SHARED +list(APPEND SOURCE container.c dxdiag_main.c provider.c - regsvr.c ${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) diff --git a/reactos/dll/directx/wine/dxdiagn/container.c b/reactos/dll/directx/wine/dxdiagn/container.c index 75581714da4..9b7591a00a0 100644 --- a/reactos/dll/directx/wine/dxdiagn/container.c +++ b/reactos/dll/directx/wine/dxdiagn/container.c @@ -1,6 +1,6 @@ -/* +/* * IDxDiagContainer Implementation - * + * * Copyright 2004 Raphael Junqueira * * This library is free software; you can redistribute it and/or @@ -15,129 +15,147 @@ * * 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 + +#define COBJMACROS #include "dxdiag_private.h" #include #include WINE_DEFAULT_DEBUG_CHANNEL(dxdiag); -/* IDxDiagContainer IUnknown parts follow: */ -HRESULT WINAPI IDxDiagContainerImpl_QueryInterface(PDXDIAGCONTAINER iface, REFIID riid, LPVOID *ppobj) +static inline IDxDiagContainerImpl *impl_from_IDxDiagContainer(IDxDiagContainer *iface) { - IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; + return CONTAINING_RECORD(iface, IDxDiagContainerImpl, IDxDiagContainer_iface); +} + +/* IDxDiagContainer IUnknown parts follow: */ +static HRESULT WINAPI IDxDiagContainerImpl_QueryInterface(IDxDiagContainer *iface, REFIID riid, + void **ppobj) +{ + IDxDiagContainerImpl *This = impl_from_IDxDiagContainer(iface); + + if (!ppobj) return E_INVALIDARG; 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 = NULL; 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); - TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1); + TRACE("(%p)->(ref before=%u)\n", This, refCount - 1); 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); - TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1); + TRACE("(%p)->(ref before=%u)\n", This, refCount + 1); if (!refCount) { + IDxDiagProvider_Release(This->pProv); HeapFree(GetProcessHeap(), 0, This); } DXDIAGN_UnlockModule(); - + 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; } - *pdwCount = This->nSubContainers; + *pdwCount = This->cont->nSubContainers; 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; - 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; } - 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 (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); - return S_OK; + return (cchContainer <= strlenW(p->contName)) ? + DXDIAG_E_INSUFFICIENT_BUFFER : S_OK; } - p = p->next; ++i; } + + TRACE("Failed to find container name at specified index\n"); + *pwszContainer = '\0'; 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)) { - *ppInstance = (PDXDIAGCONTAINER)p->pCont; + *subcont = p; return S_OK; } - p = p->next; } + return E_INVALIDARG; } -HRESULT WINAPI IDxDiagContainerImpl_GetChildContainer(PDXDIAGCONTAINER iface, LPCWSTR pwszContainer, IDxDiagContainer** ppInstance) { - IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; - IDxDiagContainer* pContainer = NULL; +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; - 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; } - pContainer = (PDXDIAGCONTAINER) This; + *ppInstance = NULL; 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 '.' */ + 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); - if (!SUCCEEDED(hr) || NULL == pContainer) + if (FAILED(hr)) 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)) { - 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: @@ -165,130 +188,68 @@ on_error: 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; } - *pdwCount = This->nProperties; + *pdwCount = This->cont->nProperties; 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; - 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; } - 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 (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; } + + TRACE("Failed to find property name at specified index\n"); 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); +static HRESULT WINAPI IDxDiagContainerImpl_GetProp(IDxDiagContainer *iface, LPCWSTR pwszPropName, + VARIANT *pvarProp) +{ + IDxDiagContainerImpl *This = impl_from_IDxDiagContainer(iface); + IDxDiagContainerImpl_Property *p; + + TRACE("(%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; + 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 = p->next; - } - return S_OK; -} - -HRESULT WINAPI IDxDiagContainerImpl_AddProp(PDXDIAGCONTAINER iface, LPCWSTR pwszPropName, VARIANT* pVarProp) { - IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; - IDxDiagContainerImpl_Property* p = NULL; - IDxDiagContainerImpl_Property* pNew = NULL; - - FIXME("(%p, %s, %p)\n", iface, debugstr_w(pwszPropName), pVarProp); - - if (NULL == pVarProp || NULL == pwszPropName) { - return E_INVALIDARG; } - pNew = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDxDiagContainerImpl_Property)); - if (NULL == pNew) { - return E_OUTOFMEMORY; - } - VariantInit(&pNew->v); - VariantCopy(&pNew->v, pVarProp); - pNew->vName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (lstrlenW(pwszPropName) + 1) * sizeof(WCHAR)); - lstrcpyW(pNew->vName, pwszPropName); - pNew->next = NULL; - - p = This->properties; - if (NULL == p) { - This->properties = pNew; - } else { - while (NULL != p->next) { - p = p->next; - } - p->next = pNew; - } - ++This->nProperties; - return S_OK; -} - -HRESULT WINAPI IDxDiagContainerImpl_AddChildContainer(PDXDIAGCONTAINER iface, LPCWSTR pszContName, PDXDIAGCONTAINER pSubCont) { - IDxDiagContainerImpl *This = (IDxDiagContainerImpl *)iface; - IDxDiagContainerImpl_SubContainer* p = NULL; - IDxDiagContainerImpl_SubContainer* pNew = NULL; - - FIXME("(%p, %s, %p)\n", iface, debugstr_w(pszContName), pSubCont); - - if (NULL == pSubCont || NULL == pszContName) { - return E_INVALIDARG; - } - - pNew = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDxDiagContainerImpl_SubContainer)); - if (NULL == pNew) { - return E_OUTOFMEMORY; - } - pNew->pCont = pSubCont; - pNew->contName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (lstrlenW(pszContName) + 1) * sizeof(WCHAR)); - lstrcpyW(pNew->contName, pszContName); - pNew->next = NULL; - - p = This->subContainers; - if (NULL == p) { - This->subContainers = pNew; - } else { - while (NULL != p->next) { - p = p->next; - } - p->next = pNew; - } - ++This->nSubContainers; - return S_OK; + return E_INVALIDARG; } 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; - 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; } - container->lpVtbl = &DxDiagContainer_Vtbl; + container->IDxDiagContainer_iface.lpVtbl = &DxDiagContainer_Vtbl; 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); } diff --git a/reactos/dll/directx/wine/dxdiagn/dxdiag_main.c b/reactos/dll/directx/wine/dxdiagn/dxdiag_main.c index 94c42e606dc..58f89179737 100644 --- a/reactos/dll/directx/wine/dxdiagn/dxdiag_main.c +++ b/reactos/dll/directx/wine/dxdiagn/dxdiag_main.c @@ -1,6 +1,6 @@ -/* +/* * DXDiag - * + * * Copyright 2004 Raphael Junqueira * * This library is free software; you can redistribute it and/or @@ -15,24 +15,38 @@ * * 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 +#include + +#include +#include +#include +#include +#include +#include +#include #include "dxdiag_private.h" #include 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) { - TRACE("%p,%lx,%p\n", hInstDLL, fdwReason, lpvReserved); + TRACE("%p,%x,%p\n", hInstDLL, fdwReason, lpvReserved); if (fdwReason == DLL_PROCESS_ATTACH) { - DisableThreadLibraryCalls(hInstDLL); + dxdiagn_instance = hInstDLL; + DisableThreadLibraryCalls(hInstDLL); } return TRUE; } @@ -41,46 +55,60 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) * DXDiag ClassFactory */ typedef struct { - const IClassFactoryVtbl *lpVtbl; - REFCLSID rclsid; - HRESULT (*pfnCreateInstanceFactory)(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj); + IClassFactory IClassFactory_iface; } IClassFactoryImpl; -static HRESULT WINAPI DXDiagCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) { - FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid)); +static HRESULT WINAPI DXDiagCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) +{ + if (ppv == NULL) + return E_POINTER; - if (ppobj == 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 */ } -static ULONG WINAPI DXDiagCF_Release(LPCLASSFACTORY iface) { +static ULONG WINAPI DXDiagCF_Release(IClassFactory * iface) +{ 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(); - + return S_OK; } @@ -92,10 +120,7 @@ static const IClassFactoryVtbl DXDiagCF_Vtbl = { DXDiagCF_LockServer }; -static IClassFactoryImpl DXDiag_CFS[] = { - { &DXDiagCF_Vtbl, &CLSID_DxDiagProvider, DXDiag_CreateDXDiagProvider }, - { NULL, NULL, NULL } -}; +static IClassFactoryImpl DXDiag_CF = { { &DXDiagCF_Vtbl } }; /*********************************************************************** * DllCanUnloadNow (DXDIAGN.@) @@ -110,18 +135,30 @@ HRESULT WINAPI DllCanUnloadNow(void) */ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { - int i = 0; + TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); - 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; + 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; } + +/*********************************************************************** + * DllRegisterServer (DXDIAGN.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + return __wine_register_resources( dxdiagn_instance ); +} + +/*********************************************************************** + * DllUnregisterServer (DXDIAGN.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + return __wine_unregister_resources( dxdiagn_instance ); +} diff --git a/reactos/dll/directx/wine/dxdiagn/dxdiag_private.h b/reactos/dll/directx/wine/dxdiagn/dxdiag_private.h index 5d90a400a03..ae73a0f6372 100644 --- a/reactos/dll/directx/wine/dxdiagn/dxdiag_private.h +++ b/reactos/dll/directx/wine/dxdiagn/dxdiag_private.h @@ -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 - * 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 @@ -29,57 +29,36 @@ #include #include -//#include "wingdi.h" -//#include "winuser.h" -//#include "objbase.h" -//#include "oleauto.h" +#include -#include +#include +#include + +#include "resource.h" /* 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 */ /* ---------------- */ -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 { - LPWSTR vName; - VARIANT v; - struct IDxDiagContainerImpl_Property* next; + struct list entry; + WCHAR *propName; + VARIANT vProp; } IDxDiagContainerImpl_Property; @@ -87,38 +66,27 @@ typedef struct IDxDiagContainerImpl_Property { * 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 */ -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 */ -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 */ -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 ); } +extern HINSTANCE dxdiagn_instance DECLSPEC_HIDDEN; + #endif diff --git a/reactos/dll/directx/wine/dxdiagn/dxdiagn.idl b/reactos/dll/directx/wine/dxdiagn/dxdiagn.idl new file mode 100644 index 00000000000..3a6b88fe04b --- /dev/null +++ b/reactos/dll/directx/wine/dxdiagn/dxdiagn.idl @@ -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 index 00000000000..2661737f25c --- /dev/null +++ b/reactos/dll/directx/wine/dxdiagn/dxdiagn.rc @@ -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 + +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 index 00000000000..80d609b058f --- /dev/null +++ b/reactos/dll/directx/wine/dxdiagn/dxdiagn.rgs @@ -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 index 00000000000..806c053429f --- /dev/null +++ b/reactos/dll/directx/wine/dxdiagn/fil_data.idl @@ -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); +} diff --git a/reactos/dll/directx/wine/dxdiagn/provider.c b/reactos/dll/directx/wine/dxdiagn/provider.c index 9838aff58de..cb4efff6e71 100644 --- a/reactos/dll/directx/wine/dxdiagn/provider.c +++ b/reactos/dll/directx/wine/dxdiagn/provider.c @@ -1,7 +1,8 @@ -/* +/* * 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 @@ -15,86 +16,166 @@ * * 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 + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT #include "dxdiag_private.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include WINE_DEFAULT_DEBUG_CHANNEL(dxdiag); -/* IDxDiagProvider IUnknown parts follow: */ -HRESULT WINAPI IDxDiagProviderImpl_QueryInterface(PDXDIAGPROVIDER iface, REFIID riid, LPVOID *ppobj) +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 { - IDxDiagProviderImpl *This = (IDxDiagProviderImpl *)iface; + 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: */ +static HRESULT WINAPI IDxDiagProviderImpl_QueryInterface(IDxDiagProvider *iface, REFIID riid, + void **ppobj) +{ + IDxDiagProviderImpl *This = impl_from_IDxDiagProvider(iface); + + if (!ppobj) return E_INVALIDARG; 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 = NULL; 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); } - return ref; + + DXDIAGN_UnlockModule(); + + return refCount; } /* 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; } - if (pParams->dwSize != sizeof(DXDIAG_INIT_PARAMS)) { + if (pParams->dwSize != sizeof(DXDIAG_INIT_PARAMS) || + pParams->dwDxDiagHeaderVersion != DXDIAG_DX9_SDK_VERSION) { 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; } -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); - if (NULL == ppInstance) { - return E_INVALIDARG; - } if (FALSE == This->init) { - return E_INVALIDARG; /* should be E_CO_UNINITIALIZED */ + return CO_E_NOTINITIALIZED; } - 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); + + 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, @@ -108,12 +189,1528 @@ HRESULT DXDiag_CreateDXDiagProvider(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, R 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)); - 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 */ - 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 index 748cc22e01f..00000000000 --- a/reactos/dll/directx/wine/dxdiagn/regsvr.c +++ /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 -//#include - -#include -#include -//#include "wingdi.h" -//#include "winuser.h" -#include -//#include "winerror.h" - -#include -#include "dxdiag_private.h" -#include - -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; -} diff --git a/reactos/dll/directx/wine/dxdiagn/version.rc b/reactos/dll/directx/wine/dxdiagn/resource.h similarity index 63% rename from reactos/dll/directx/wine/dxdiagn/version.rc rename to reactos/dll/directx/wine/dxdiagn/resource.h index e4e973d3a93..dd6c1a3bd03 100644 --- a/reactos/dll/directx/wine/dxdiagn/version.rc +++ b/reactos/dll/directx/wine/dxdiagn/resource.h @@ -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 @@ -13,14 +15,10 @@ * * 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 -#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 index 00000000000..47cd36ee76f --- /dev/null +++ b/reactos/include/reactos/wine/dxdiag.h @@ -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 + +#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 diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 607a1b7dd80..27caedb5957 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -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/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