2 * IDxDiagContainer Implementation
4 * Copyright 2004 Raphael Junqueira
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "dxdiag_private.h"
24 #include "wine/debug.h"
25 #include "wine/unicode.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(dxdiag
);
29 /* IDxDiagContainer IUnknown parts follow: */
30 HRESULT WINAPI
IDxDiagContainerImpl_QueryInterface(PDXDIAGCONTAINER iface
, REFIID riid
, LPVOID
*ppobj
)
32 IDxDiagContainerImpl
*This
= (IDxDiagContainerImpl
*)iface
;
34 if (IsEqualGUID(riid
, &IID_IUnknown
)
35 || IsEqualGUID(riid
, &IID_IDxDiagContainer
)) {
36 IDxDiagContainerImpl_AddRef(iface
);
41 WARN("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppobj
);
45 ULONG WINAPI
IDxDiagContainerImpl_AddRef(PDXDIAGCONTAINER iface
) {
46 IDxDiagContainerImpl
*This
= (IDxDiagContainerImpl
*)iface
;
47 ULONG refCount
= InterlockedIncrement(&This
->ref
);
49 TRACE("(%p)->(ref before=%lu)\n", This
, refCount
- 1);
56 ULONG WINAPI
IDxDiagContainerImpl_Release(PDXDIAGCONTAINER iface
) {
57 IDxDiagContainerImpl
*This
= (IDxDiagContainerImpl
*)iface
;
58 ULONG refCount
= InterlockedDecrement(&This
->ref
);
60 TRACE("(%p)->(ref before=%lu)\n", This
, refCount
+ 1);
63 HeapFree(GetProcessHeap(), 0, This
);
66 DXDIAGN_UnlockModule();
71 /* IDxDiagContainer Interface follow: */
72 HRESULT WINAPI
IDxDiagContainerImpl_GetNumberOfChildContainers(PDXDIAGCONTAINER iface
, DWORD
* pdwCount
) {
73 IDxDiagContainerImpl
*This
= (IDxDiagContainerImpl
*)iface
;
74 TRACE("(%p)\n", iface
);
75 if (NULL
== pdwCount
) {
78 *pdwCount
= This
->nSubContainers
;
82 HRESULT WINAPI
IDxDiagContainerImpl_EnumChildContainerNames(PDXDIAGCONTAINER iface
, DWORD dwIndex
, LPWSTR pwszContainer
, DWORD cchContainer
) {
83 IDxDiagContainerImpl
*This
= (IDxDiagContainerImpl
*)iface
;
84 IDxDiagContainerImpl_SubContainer
* p
= NULL
;
87 TRACE("(%p, %lu, %s, %lu)\n", iface
, dwIndex
, debugstr_w(pwszContainer
), cchContainer
);
89 if (NULL
== pwszContainer
) {
92 if (256 > cchContainer
) {
93 return DXDIAG_E_INSUFFICIENT_BUFFER
;
96 p
= This
->subContainers
;
99 if (cchContainer
<= strlenW(p
->contName
)) {
100 return DXDIAG_E_INSUFFICIENT_BUFFER
;
102 lstrcpynW(pwszContainer
, p
->contName
, cchContainer
);
111 HRESULT WINAPI
IDxDiagContainerImpl_GetChildContainerInternal(PDXDIAGCONTAINER iface
, LPCWSTR pwszContainer
, IDxDiagContainer
** ppInstance
) {
112 IDxDiagContainerImpl
*This
= (IDxDiagContainerImpl
*)iface
;
113 IDxDiagContainerImpl_SubContainer
* p
= NULL
;
115 p
= This
->subContainers
;
117 if (0 == lstrcmpW(p
->contName
, pwszContainer
)) {
118 *ppInstance
= (PDXDIAGCONTAINER
)p
->pCont
;
126 HRESULT WINAPI
IDxDiagContainerImpl_GetChildContainer(PDXDIAGCONTAINER iface
, LPCWSTR pwszContainer
, IDxDiagContainer
** ppInstance
) {
127 IDxDiagContainerImpl
*This
= (IDxDiagContainerImpl
*)iface
;
128 IDxDiagContainer
* pContainer
= NULL
;
129 LPWSTR tmp
, orig_tmp
;
132 HRESULT hr
= E_INVALIDARG
;
134 FIXME("(%p, %s, %p)\n", iface
, debugstr_w(pwszContainer
), ppInstance
);
136 if (NULL
== ppInstance
|| NULL
== pwszContainer
) {
140 pContainer
= (PDXDIAGCONTAINER
) This
;
142 tmp_len
= strlenW(pwszContainer
) + 1;
143 orig_tmp
= tmp
= HeapAlloc(GetProcessHeap(), 0, tmp_len
* sizeof(WCHAR
));
144 if (NULL
== tmp
) return E_FAIL
;
145 lstrcpynW(tmp
, pwszContainer
, tmp_len
);
147 cur
= strchrW(tmp
, '.');
148 while (NULL
!= cur
) {
149 *cur
= '\0'; /* cut tmp string to '.' */
150 hr
= IDxDiagContainerImpl_GetChildContainerInternal(pContainer
, tmp
, &pContainer
);
151 if (!SUCCEEDED(hr
) || NULL
== pContainer
)
153 cur
++; /* go after '.' (just replaced by \0) */
155 cur
= strchrW(tmp
, '.');
158 hr
= IDxDiagContainerImpl_GetChildContainerInternal(pContainer
, tmp
, ppInstance
);
160 IDxDiagContainerImpl_AddRef((PDXDIAGCONTAINER
)*ppInstance
);
164 HeapFree(GetProcessHeap(), 0, orig_tmp
);
168 HRESULT WINAPI
IDxDiagContainerImpl_GetNumberOfProps(PDXDIAGCONTAINER iface
, DWORD
* pdwCount
) {
169 IDxDiagContainerImpl
*This
= (IDxDiagContainerImpl
*)iface
;
170 TRACE("(%p)\n", iface
);
171 if (NULL
== pdwCount
) {
174 *pdwCount
= This
->nProperties
;
178 HRESULT WINAPI
IDxDiagContainerImpl_EnumPropNames(PDXDIAGCONTAINER iface
, DWORD dwIndex
, LPWSTR pwszPropName
, DWORD cchPropName
) {
179 IDxDiagContainerImpl
*This
= (IDxDiagContainerImpl
*)iface
;
180 IDxDiagContainerImpl_Property
* p
= NULL
;
183 FIXME("(%p, %lu, %s, %lu)\n", iface
, dwIndex
, debugstr_w(pwszPropName
), cchPropName
);
185 if (NULL
== pwszPropName
) {
188 if (256 > cchPropName
) {
189 return DXDIAG_E_INSUFFICIENT_BUFFER
;
192 p
= This
->properties
;
195 if (cchPropName
<= lstrlenW(p
->vName
)) {
196 return DXDIAG_E_INSUFFICIENT_BUFFER
;
198 lstrcpynW(pwszPropName
, p
->vName
, cchPropName
);
207 HRESULT WINAPI
IDxDiagContainerImpl_GetProp(PDXDIAGCONTAINER iface
, LPCWSTR pwszPropName
, VARIANT
* pvarProp
) {
208 IDxDiagContainerImpl
*This
= (IDxDiagContainerImpl
*)iface
;
209 IDxDiagContainerImpl_Property
* p
= NULL
;
210 FIXME("(%p, %s, %p)\n", iface
, debugstr_w(pwszPropName
), pvarProp
);
212 if (NULL
== pvarProp
|| NULL
== pwszPropName
) {
216 p
= This
->properties
;
218 if (0 == lstrcmpW(p
->vName
, pwszPropName
)) {
219 VariantCopy(pvarProp
, &p
->v
);
227 HRESULT WINAPI
IDxDiagContainerImpl_AddProp(PDXDIAGCONTAINER iface
, LPCWSTR pwszPropName
, VARIANT
* pVarProp
) {
228 IDxDiagContainerImpl
*This
= (IDxDiagContainerImpl
*)iface
;
229 IDxDiagContainerImpl_Property
* p
= NULL
;
230 IDxDiagContainerImpl_Property
* pNew
= NULL
;
232 FIXME("(%p, %s, %p)\n", iface
, debugstr_w(pwszPropName
), pVarProp
);
234 if (NULL
== pVarProp
|| NULL
== pwszPropName
) {
238 pNew
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDxDiagContainerImpl_Property
));
240 return E_OUTOFMEMORY
;
242 VariantInit(&pNew
->v
);
243 VariantCopy(&pNew
->v
, pVarProp
);
244 pNew
->vName
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, (lstrlenW(pwszPropName
) + 1) * sizeof(WCHAR
));
245 lstrcpyW(pNew
->vName
, pwszPropName
);
248 p
= This
->properties
;
250 This
->properties
= pNew
;
252 while (NULL
!= p
->next
) {
261 HRESULT WINAPI
IDxDiagContainerImpl_AddChildContainer(PDXDIAGCONTAINER iface
, LPCWSTR pszContName
, PDXDIAGCONTAINER pSubCont
) {
262 IDxDiagContainerImpl
*This
= (IDxDiagContainerImpl
*)iface
;
263 IDxDiagContainerImpl_SubContainer
* p
= NULL
;
264 IDxDiagContainerImpl_SubContainer
* pNew
= NULL
;
266 FIXME("(%p, %s, %p)\n", iface
, debugstr_w(pszContName
), pSubCont
);
268 if (NULL
== pSubCont
|| NULL
== pszContName
) {
272 pNew
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDxDiagContainerImpl_SubContainer
));
274 return E_OUTOFMEMORY
;
276 pNew
->pCont
= pSubCont
;
277 pNew
->contName
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, (lstrlenW(pszContName
) + 1) * sizeof(WCHAR
));
278 lstrcpyW(pNew
->contName
, pszContName
);
281 p
= This
->subContainers
;
283 This
->subContainers
= pNew
;
285 while (NULL
!= p
->next
) {
290 ++This
->nSubContainers
;
294 static const IDxDiagContainerVtbl DxDiagContainer_Vtbl
=
296 IDxDiagContainerImpl_QueryInterface
,
297 IDxDiagContainerImpl_AddRef
,
298 IDxDiagContainerImpl_Release
,
299 IDxDiagContainerImpl_GetNumberOfChildContainers
,
300 IDxDiagContainerImpl_EnumChildContainerNames
,
301 IDxDiagContainerImpl_GetChildContainer
,
302 IDxDiagContainerImpl_GetNumberOfProps
,
303 IDxDiagContainerImpl_EnumPropNames
,
304 IDxDiagContainerImpl_GetProp
308 HRESULT
DXDiag_CreateDXDiagContainer(REFIID riid
, LPVOID
*ppobj
) {
309 IDxDiagContainerImpl
* container
;
311 TRACE("(%p, %p)\n", debugstr_guid(riid
), ppobj
);
313 container
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDxDiagContainerImpl
));
314 if (NULL
== container
) {
316 return E_OUTOFMEMORY
;
318 container
->lpVtbl
= &DxDiagContainer_Vtbl
;
319 container
->ref
= 0; /* will be inited with QueryInterface */
320 return IDxDiagContainerImpl_QueryInterface((PDXDIAGCONTAINER
)container
, riid
, ppobj
);