sync with trunk r46493
[reactos.git] / dll / win32 / netcfgx / inetcfgcomp_iface.c
1 #include "precomp.h"
2 #include <devguid.h>
3
4 typedef struct
5 {
6 const INetCfgComponent * lpVtbl;
7 LONG ref;
8 NetCfgComponentItem * pItem;
9 INetCfgComponentPropertyUi * pProperty;
10 INetCfg * pNCfg;
11 }INetCfgComponentImpl;
12
13 typedef struct
14 {
15 const IEnumNetCfgComponent * lpVtbl;
16 LONG ref;
17 NetCfgComponentItem * pCurrent;
18 NetCfgComponentItem * pHead;
19 INetCfg * pNCfg;
20 }IEnumNetCfgComponentImpl;
21
22 HRESULT
23 WINAPI
24 INetCfgComponent_fnQueryInterface(
25 INetCfgComponent * iface,
26 REFIID iid,
27 LPVOID * ppvObj)
28 {
29 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
30 *ppvObj = NULL;
31
32 if (IsEqualIID (iid, &IID_IUnknown) ||
33 IsEqualIID (iid, &IID_INetCfgComponent))
34 {
35 *ppvObj = This;
36 INetCfg_AddRef(iface);
37 return S_OK;
38 }
39
40 return E_NOINTERFACE;
41 }
42
43 ULONG
44 WINAPI
45 INetCfgComponent_fnAddRef(
46 INetCfgComponent * iface)
47 {
48 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
49 ULONG refCount = InterlockedIncrement(&This->ref);
50
51 return refCount;
52 }
53
54 ULONG
55 WINAPI
56 INetCfgComponent_fnRelease(
57 INetCfgComponent * iface)
58 {
59 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
60 ULONG refCount = InterlockedDecrement(&This->ref);
61
62 if (!refCount)
63 {
64 CoTaskMemFree(This);
65 }
66 return refCount;
67 }
68
69 HRESULT
70 WINAPI
71 INetCfgComponent_fnGetDisplayName(
72 INetCfgComponent * iface,
73 LPWSTR * ppszwDisplayName)
74 {
75 LPWSTR szName;
76 UINT Length;
77 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
78
79 if (This == NULL || ppszwDisplayName == NULL)
80 return E_POINTER;
81
82 if (This->pItem->szDisplayName)
83 Length = wcslen(This->pItem->szDisplayName)+1;
84 else
85 Length = 1;
86
87 szName = CoTaskMemAlloc(Length * sizeof(WCHAR));
88 if (!szName)
89 return E_OUTOFMEMORY;
90
91 if (Length > 1)
92 wcscpy(szName, This->pItem->szDisplayName);
93 else
94 szName[0] = L'\0';
95
96 *ppszwDisplayName = szName;
97
98 return S_OK;
99 }
100
101 HRESULT
102 WINAPI
103 INetCfgComponent_fnSetDisplayName(
104 INetCfgComponent * iface,
105 LPCWSTR ppszwDisplayName)
106 {
107 LPWSTR szName;
108 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
109
110 if (This == NULL || ppszwDisplayName == NULL)
111 return E_POINTER;
112
113 /* setting name is only supported for network cards */
114 if (!IsEqualGUID(&This->pItem->ClassGUID, &GUID_DEVCLASS_NET))
115 return E_NOTIMPL;
116
117 /// FIXME
118 /// check for invalid characters
119 /// check for write lock
120
121 szName = CoTaskMemAlloc((wcslen(ppszwDisplayName)+1) * sizeof(WCHAR));
122 if (!szName)
123 return E_OUTOFMEMORY;
124
125 wcscpy(szName, ppszwDisplayName);
126 CoTaskMemFree(This->pItem->szDisplayName);
127 This->pItem->szDisplayName = szName;
128 This->pItem->bChanged = TRUE;
129
130 return S_OK;
131 }
132
133 HRESULT
134 WINAPI
135 INetCfgComponent_fnGetHelpText(
136 INetCfgComponent * iface,
137 LPWSTR * ppszwHelpText)
138 {
139 LPWSTR szHelp;
140 UINT Length;
141 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
142
143 if (This == NULL || ppszwHelpText == NULL)
144 return E_POINTER;
145
146 if (This->pItem->szHelpText)
147 Length = wcslen(This->pItem->szHelpText)+1;
148 else
149 Length = 1;
150
151 szHelp = CoTaskMemAlloc(Length * sizeof(WCHAR));
152 if (!szHelp)
153 return E_OUTOFMEMORY;
154
155 if (Length > 1)
156 wcscpy(szHelp, This->pItem->szHelpText);
157 else
158 szHelp[0] = L'\0';
159
160 *ppszwHelpText = szHelp;
161
162 return S_OK;
163 }
164
165 HRESULT
166 WINAPI
167 INetCfgComponent_fnGetId(
168 INetCfgComponent * iface,
169 LPWSTR * ppszwId)
170 {
171 LPWSTR szId;
172 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
173
174 if (This == NULL || ppszwId == NULL)
175 return E_POINTER;
176
177 szId = CoTaskMemAlloc((wcslen(This->pItem->szId)+1) * sizeof(WCHAR));
178 if (!szId)
179 return E_OUTOFMEMORY;
180
181 wcscpy(szId, This->pItem->szId);
182 *ppszwId = szId;
183
184 return S_OK;
185 }
186
187 HRESULT
188 WINAPI
189 INetCfgComponent_fnGetCharacteristics(
190 INetCfgComponent * iface,
191 DWORD * pdwCharacteristics)
192 {
193 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
194
195 if (This == NULL || pdwCharacteristics == NULL)
196 return E_POINTER;
197
198 *pdwCharacteristics = This->pItem->dwCharacteristics;
199
200 return S_OK;
201 }
202
203 HRESULT
204 WINAPI
205 INetCfgComponent_fnGetInstanceGuid(
206 INetCfgComponent * iface,
207 GUID * pGuid)
208 {
209 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
210
211 if (This == NULL || pGuid == NULL)
212 return E_POINTER;
213
214 CopyMemory(pGuid, &This->pItem->InstanceId, sizeof(GUID));
215 return S_OK;
216 }
217
218 HRESULT
219 WINAPI
220 INetCfgComponent_fnGetPnpDevNodeId(
221 INetCfgComponent * iface,
222 LPWSTR * ppszwDevNodeId)
223 {
224 LPWSTR szNode;
225 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
226
227 if (This == NULL || ppszwDevNodeId == NULL)
228 return E_POINTER;
229
230 if (!IsEqualGUID(&GUID_DEVCLASS_NET, &This->pItem->ClassGUID))
231 return E_NOTIMPL;
232
233 szNode = CoTaskMemAlloc((wcslen(This->pItem->szNodeId)+1) * sizeof(WCHAR));
234 if (!szNode)
235 return E_OUTOFMEMORY;
236
237 wcscpy(szNode, This->pItem->szNodeId);
238 *ppszwDevNodeId = szNode;
239 return S_OK;
240 }
241
242 HRESULT
243 WINAPI
244 INetCfgComponent_fnGetClassGuid(
245 INetCfgComponent * iface,
246 GUID * pGuid)
247 {
248 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
249
250 if (This == NULL || pGuid == NULL)
251 return E_POINTER;
252
253 CopyMemory(pGuid, &This->pItem->ClassGUID, sizeof(GUID));
254 return S_OK;
255 }
256
257 HRESULT
258 WINAPI
259 INetCfgComponent_fnGetBindName(
260 INetCfgComponent * iface,
261 LPWSTR * ppszwBindName)
262 {
263 LPWSTR szBind;
264 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
265
266 if (This == NULL || ppszwBindName == NULL)
267 return E_POINTER;
268
269 szBind = CoTaskMemAlloc((wcslen(This->pItem->szBindName)+1) * sizeof(WCHAR));
270 if (!szBind)
271 return E_OUTOFMEMORY;
272
273 wcscpy(szBind, This->pItem->szBindName);
274 *ppszwBindName = szBind;
275
276 return S_OK;
277 }
278
279 HRESULT
280 WINAPI
281 INetCfgComponent_fnGetDeviceStatus(
282 INetCfgComponent * iface,
283 ULONG * pStatus)
284 {
285 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
286
287 if (This == NULL || pStatus == NULL)
288 return E_POINTER;
289
290 if (!IsEqualGUID(&GUID_DEVCLASS_NET, &This->pItem->ClassGUID))
291 return E_UNEXPECTED;
292
293 *pStatus = This->pItem->Status;
294
295 return S_OK;
296 }
297
298 HRESULT
299 WINAPI
300 INetCfgComponent_fnOpenParamKey(
301 INetCfgComponent * iface,
302 HKEY * phkey)
303 {
304 WCHAR szBuffer[200] = L"SYSTEM\\CurrentControlSet\\Services\\";
305 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
306
307 if (This == NULL || phkey == NULL)
308 return E_POINTER;
309
310 wcscat(szBuffer, This->pItem->szBindName);
311 wcscat(szBuffer, L"\\Parameters");
312
313 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ | KEY_WRITE, phkey) == ERROR_SUCCESS)
314 return S_OK;
315 else
316 return E_FAIL;
317 }
318
319
320 HRESULT
321 CreateNotificationObject(
322 INetCfgComponentImpl * This,
323 INetCfgComponent * iface,
324 IUnknown *pUnk)
325 {
326 WCHAR szName[150];
327 HKEY hKey;
328 DWORD dwSize, dwType;
329 GUID CLSID_NotifyObject;
330 LPOLESTR pStr;
331 INetCfgComponentPropertyUi * pNCCPU;
332 INetCfgComponentControl * pNCCC;
333 HRESULT hr;
334 LONG lRet;
335 CLSID ClassGUID;
336 //CLSID InstanceGUID;
337
338 wcscpy(szName,L"SYSTEM\\CurrentControlSet\\Control\\Network\\");
339
340 /* get the Class GUID */
341 hr = INetCfgComponent_GetClassGuid(iface, &ClassGUID);
342 if (FAILED(hr))
343 return hr;
344
345 hr = StringFromCLSID(&ClassGUID, &pStr);
346 if (FAILED(hr))
347 return hr;
348
349 wcscat(szName, pStr);
350 CoTaskMemFree(pStr);
351 wcscat(szName, L"\\");
352
353 /* get the Instance GUID */
354 #if 0
355 hr = INetCfgComponent_GetInstanceGuid(iface, &InstanceGUID);
356 if (FAILED(hr))
357 return hr;
358
359 hr = StringFromCLSID(&InstanceGUID, &pStr);
360 if (FAILED(hr))
361 return hr;
362
363 wcscat(szName, pStr);
364 CoTaskMemFree(pStr);
365 #else
366 // HACK HACK HACK HACK HACK
367 wcscat(szName, L"{RandomProtocolGUID_TCPIP}");
368 #endif
369
370 wcscat(szName, L"\\NDI");
371
372 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
373 return E_FAIL;
374
375 dwSize = sizeof(szName);
376 lRet = RegQueryValueExW(hKey, L"ClsID", NULL, &dwType, (LPBYTE)szName, &dwSize);
377 RegCloseKey(hKey);
378
379 if (lRet != ERROR_SUCCESS && dwType != REG_SZ)
380 return E_FAIL;
381
382 hr = CLSIDFromString(szName, &CLSID_NotifyObject);
383 if (FAILED(hr))
384 return E_FAIL;
385
386 hr = CoCreateInstance(&CLSID_NotifyObject, NULL, CLSCTX_INPROC_SERVER, &IID_INetCfgComponentPropertyUi, (LPVOID*)&pNCCPU);
387 if (FAILED(hr))
388 return E_FAIL;
389
390 hr = INetCfgComponentPropertyUi_QueryInterface(pNCCPU, &IID_INetCfgComponentControl, (LPVOID*)&pNCCC);
391 if (FAILED(hr))
392 {
393 INetCfgComponentPropertyUi_Release(pNCCPU);
394 return hr;
395 }
396
397 hr = INetCfgComponentPropertyUi_QueryPropertyUi(pNCCPU, pUnk);
398 if (FAILED(hr))
399 {
400 INetCfgComponentPropertyUi_Release(pNCCPU);
401 return hr;
402 }
403
404 hr = INetCfgComponentControl_Initialize(pNCCC, iface, This->pNCfg, FALSE);
405 if (FAILED(hr))
406 {
407 INetCfgComponentControl_Release(pNCCC);
408 INetCfgComponentPropertyUi_Release(pNCCPU);
409 return hr;
410 }
411
412 hr = INetCfgComponentPropertyUi_SetContext(pNCCPU, pUnk);
413 if (FAILED(hr))
414 {
415 INetCfgComponentPropertyUi_Release(pNCCPU);
416 return hr;
417 }
418 This->pProperty = pNCCPU;
419 This->pItem->pNCCC = pNCCC;
420
421 return S_OK;
422 }
423
424 HRESULT
425 WINAPI
426 INetCfgComponent_fnRaisePropertyUi(
427 INetCfgComponent * iface,
428 IN HWND hwndParent,
429 IN DWORD dwFlags,
430 IN IUnknown *pUnk)
431 {
432 HRESULT hr;
433 DWORD dwDefPages;
434 UINT Pages;
435 PROPSHEETHEADERW pinfo;
436 HPROPSHEETPAGE * hppages;
437 INT_PTR iResult;
438 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
439
440 if (!This->pProperty)
441 {
442 hr = CreateNotificationObject(This,iface, pUnk);
443 if (FAILED(hr))
444 return hr;
445 }
446
447 if (dwFlags == NCRP_QUERY_PROPERTY_UI)
448 return S_OK;
449
450 dwDefPages = 0;
451 Pages = 0;
452
453 hr = INetCfgComponentPropertyUi_MergePropPages(This->pProperty, &dwDefPages, (BYTE**)&hppages, &Pages, hwndParent, NULL);
454 if (FAILED(hr) || !Pages)
455 {
456 return hr;
457 }
458 ZeroMemory(&pinfo, sizeof(PROPSHEETHEADERW));
459 pinfo.dwSize = sizeof(PROPSHEETHEADERW);
460 pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE | PSH_NOAPPLYNOW;
461 pinfo.u3.phpage = hppages;
462 pinfo.hwndParent = hwndParent;
463 pinfo.nPages = Pages;
464 pinfo.pszCaption = This->pItem->szDisplayName;
465
466 iResult = PropertySheetW(&pinfo);
467 CoTaskMemFree(hppages);
468 if (iResult > 0)
469 {
470 /* indicate that settings should be stored */
471 This->pItem->bChanged = TRUE;
472 return S_OK;
473 }
474 return S_FALSE;
475 }
476 static const INetCfgComponentVtbl vt_NetCfgComponent =
477 {
478 INetCfgComponent_fnQueryInterface,
479 INetCfgComponent_fnAddRef,
480 INetCfgComponent_fnRelease,
481 INetCfgComponent_fnGetDisplayName,
482 INetCfgComponent_fnSetDisplayName,
483 INetCfgComponent_fnGetHelpText,
484 INetCfgComponent_fnGetId,
485 INetCfgComponent_fnGetCharacteristics,
486 INetCfgComponent_fnGetInstanceGuid,
487 INetCfgComponent_fnGetPnpDevNodeId,
488 INetCfgComponent_fnGetClassGuid,
489 INetCfgComponent_fnGetBindName,
490 INetCfgComponent_fnGetDeviceStatus,
491 INetCfgComponent_fnOpenParamKey,
492 INetCfgComponent_fnRaisePropertyUi
493 };
494
495 HRESULT
496 WINAPI
497 INetCfgComponent_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv, NetCfgComponentItem * pItem, INetCfg * pNCfg)
498 {
499 INetCfgComponentImpl *This;
500
501 if (!ppv)
502 return E_POINTER;
503
504 This = (INetCfgComponentImpl *) CoTaskMemAlloc(sizeof (INetCfgComponentImpl));
505 if (!This)
506 return E_OUTOFMEMORY;
507
508 This->ref = 1;
509 This->lpVtbl = (const INetCfgComponent*)&vt_NetCfgComponent;
510 This->pProperty = NULL;
511 This->pItem = pItem;
512 This->pNCfg = pNCfg;
513
514 if (!SUCCEEDED (INetCfgComponent_QueryInterface ((INetCfgComponent*)This, riid, ppv)))
515 {
516 INetCfgComponent_Release((INetCfg*)This);
517 return E_NOINTERFACE;
518 }
519
520 INetCfgComponent_Release((INetCfgComponent*)This);
521 return S_OK;
522 }
523
524
525 /***************************************************************
526 * IEnumNetCfgComponent
527 */
528
529 HRESULT
530 WINAPI
531 IEnumNetCfgComponent_fnQueryInterface(
532 IEnumNetCfgComponent * iface,
533 REFIID iid,
534 LPVOID * ppvObj)
535 {
536 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
537 *ppvObj = NULL;
538
539 if (IsEqualIID (iid, &IID_IUnknown) ||
540 IsEqualIID (iid, &IID_IEnumNetCfgComponent))
541 {
542 *ppvObj = This;
543 INetCfg_AddRef(iface);
544 return S_OK;
545 }
546
547 return E_NOINTERFACE;
548 }
549
550
551 ULONG
552 WINAPI
553 IEnumNetCfgComponent_fnAddRef(
554 IEnumNetCfgComponent * iface)
555 {
556 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
557 ULONG refCount = InterlockedIncrement(&This->ref);
558
559 return refCount;
560 }
561
562 ULONG
563 WINAPI
564 IEnumNetCfgComponent_fnRelease(
565 IEnumNetCfgComponent * iface)
566 {
567 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
568 ULONG refCount = InterlockedDecrement(&This->ref);
569
570 return refCount;
571 }
572
573 HRESULT
574 WINAPI
575 IEnumNetCfgComponent_fnNext(
576 IEnumNetCfgComponent * iface,
577 ULONG celt,
578 INetCfgComponent **rgelt,
579 ULONG *pceltFetched)
580 {
581 HRESULT hr;
582 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
583
584 if (!iface || !rgelt)
585 return E_POINTER;
586
587 if (celt != 1)
588 return E_INVALIDARG;
589
590 if (!This->pCurrent)
591 return S_FALSE;
592
593 hr = INetCfgComponent_Constructor (NULL, &IID_INetCfgComponent, (LPVOID*)rgelt, This->pCurrent, This->pNCfg);
594 if (SUCCEEDED(hr))
595 {
596 This->pCurrent = This->pCurrent->pNext;
597 if (pceltFetched)
598 *pceltFetched = 1;
599 }
600 return hr;
601 }
602
603 HRESULT
604 WINAPI
605 IEnumNetCfgComponent_fnSkip(
606 IEnumNetCfgComponent * iface,
607 ULONG celt)
608 {
609 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
610
611 if (!This->pCurrent)
612 return S_FALSE;
613
614 while(celt-- > 0 && This->pCurrent)
615 This->pCurrent = This->pCurrent->pNext;
616
617 if (!celt)
618 return S_OK;
619 else
620 return S_FALSE;
621 }
622
623 HRESULT
624 WINAPI
625 IEnumNetCfgComponent_fnReset(
626 IEnumNetCfgComponent * iface)
627 {
628 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
629
630 This->pCurrent = This->pHead;
631 return S_OK;
632 }
633
634 HRESULT
635 WINAPI
636 IEnumNetCfgComponent_fnClone(
637 IEnumNetCfgComponent * iface,
638 IEnumNetCfgComponent **ppenum)
639 {
640 return E_NOTIMPL;
641 }
642
643 static const IEnumNetCfgComponentVtbl vt_EnumNetCfgComponent =
644 {
645 IEnumNetCfgComponent_fnQueryInterface,
646 IEnumNetCfgComponent_fnAddRef,
647 IEnumNetCfgComponent_fnRelease,
648 IEnumNetCfgComponent_fnNext,
649 IEnumNetCfgComponent_fnSkip,
650 IEnumNetCfgComponent_fnReset,
651 IEnumNetCfgComponent_fnClone
652 };
653
654 HRESULT
655 WINAPI
656 IEnumNetCfgComponent_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv, NetCfgComponentItem * pItem, INetCfg * pNCfg)
657 {
658 IEnumNetCfgComponentImpl *This;
659
660 if (!ppv)
661 return E_POINTER;
662
663 This = (IEnumNetCfgComponentImpl *) CoTaskMemAlloc(sizeof (IEnumNetCfgComponentImpl));
664 if (!This)
665 return E_OUTOFMEMORY;
666
667 This->ref = 1;
668 This->lpVtbl = (const IEnumNetCfgComponent*)&vt_EnumNetCfgComponent;
669 This->pCurrent = pItem;
670 This->pHead = pItem;
671 This->pNCfg = pNCfg;
672
673 if (!SUCCEEDED (IEnumNetCfgComponent_QueryInterface ((INetCfgComponent*)This, riid, ppv)))
674 {
675 IEnumNetCfgComponent_Release((INetCfg*)This);
676 return E_NOINTERFACE;
677 }
678
679 IEnumNetCfgComponent_Release((IEnumNetCfgComponent*)This);
680 return S_OK;
681 }
682
683