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