5 const INetCfg
* lpVtbl
;
6 const INetCfgLock
* lpVtblLock
;
10 NetCfgComponentItem
*pNet
;
11 NetCfgComponentItem
* pService
;
12 NetCfgComponentItem
* pClient
;
13 NetCfgComponentItem
* pProtocol
;
14 } INetCfgImpl
, *LPINetCfgImpl
;
16 static __inline LPINetCfgImpl
impl_from_INetCfgLock(INetCfgLock
*iface
)
18 return (INetCfgImpl
*)((char *)iface
- FIELD_OFFSET(INetCfgImpl
, lpVtblLock
));
25 INetCfgLock_fnQueryInterface(
30 INetCfgImpl
* This
= impl_from_INetCfgLock(iface
);
31 return INetCfg_QueryInterface((INetCfg
*)This
, iid
, ppvObj
);
40 INetCfgImpl
* This
= impl_from_INetCfgLock(iface
);
42 return INetCfg_AddRef((INetCfg
*)This
);
47 INetCfgLock_fnRelease(
50 INetCfgImpl
* This
= impl_from_INetCfgLock(iface
);
51 return INetCfg_Release((INetCfg
*)This
);
56 INetCfgLock_fnAcquireWriteLock(
59 LPCWSTR pszwClientDescription
,
60 LPWSTR
*ppszwClientDescription
)
65 INetCfgImpl
* This
= impl_from_INetCfgLock(iface
);
67 if (This
->bInitialized
)
68 return NETCFG_E_ALREADY_INITIALIZED
;
70 dwResult
= WaitForSingleObject(This
->hMutex
, cmsTimeout
);
71 if (dwResult
== WAIT_TIMEOUT
)
73 if (ppszwClientDescription
)
75 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\NetCfgLockHolder", 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
77 dwResult
= sizeof(szValue
);
78 if (RegQueryValueExW(hKey
, NULL
, NULL
, NULL
, (LPBYTE
)szValue
, &dwResult
) == ERROR_SUCCESS
)
80 szValue
[(sizeof(szValue
)/sizeof(WCHAR
))-1] = L
'\0';
81 *ppszwClientDescription
= CoTaskMemAlloc((wcslen(szValue
)+1) * sizeof(WCHAR
));
82 if (*ppszwClientDescription
)
83 wcscpy(*ppszwClientDescription
, szValue
);
90 else if (dwResult
== WAIT_OBJECT_0
)
92 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\NetCfgLockHolder", 0, NULL
, 0, KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
)
94 RegSetValueExW(hKey
, NULL
, 0, REG_SZ
, (LPBYTE
)pszwClientDescription
, (wcslen(pszwClientDescription
)+1) * sizeof(WCHAR
));
105 INetCfgLock_fnReleaseWriteLock(
108 INetCfgImpl
* This
= impl_from_INetCfgLock(iface
);
110 if (This
->bInitialized
)
111 return NETCFG_E_ALREADY_INITIALIZED
;
114 if (ReleaseMutex(This
->hMutex
))
122 INetCfgLock_fnIsWriteLocked(
124 LPWSTR
*ppszwClientDescription
)
128 DWORD dwSize
, dwType
;
131 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\NetCfgLockHolder", 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
134 dwSize
= sizeof(szValue
);
135 if (RegQueryValueExW(hKey
, NULL
, NULL
, &dwType
, (LPBYTE
)szValue
, &dwSize
) == ERROR_SUCCESS
&& dwType
== REG_SZ
)
138 szValue
[(sizeof(szValue
)/sizeof(WCHAR
))-1] = L
'\0';
139 *ppszwClientDescription
= CoTaskMemAlloc((wcslen(szValue
)+1) * sizeof(WCHAR
));
140 if (*ppszwClientDescription
)
141 wcscpy(*ppszwClientDescription
, szValue
);
153 static const INetCfgLockVtbl vt_NetCfgLock
=
155 INetCfgLock_fnQueryInterface
,
156 INetCfgLock_fnAddRef
,
157 INetCfgLock_fnRelease
,
158 INetCfgLock_fnAcquireWriteLock
,
159 INetCfgLock_fnReleaseWriteLock
,
160 INetCfgLock_fnIsWriteLocked
163 /***************************************************************
168 EnumClientServiceProtocol(HKEY hKey
, const GUID
* pGuid
, NetCfgComponentItem
** pHead
)
175 HKEY hSubKey
, hNDIKey
;
176 NetCfgComponentItem
* pLast
= NULL
, *pCurrent
;
183 dwSize
= sizeof(szName
)/sizeof(WCHAR
);
184 if (RegEnumKeyExW(hKey
, dwIndex
++, szName
, &dwSize
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
186 pCurrent
= CoTaskMemAlloc(sizeof(NetCfgComponentItem
));
188 return E_OUTOFMEMORY
;
190 ZeroMemory(pCurrent
, sizeof(NetCfgComponentItem
));
191 CopyMemory(&pCurrent
->ClassGUID
, pGuid
, sizeof(GUID
));
193 if (FAILED(CLSIDFromString(szName
, &pCurrent
->InstanceId
)))
195 /// ReactOS tcpip guid is not yet generated
196 //CoTaskMemFree(pCurrent);
199 if (RegOpenKeyExW(hKey
, szName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
201 /* retrieve Characteristics */
202 dwSize
= sizeof(DWORD
);
204 RegQueryValueExW(hSubKey
, L
"Characteristics", NULL
, &dwType
, (LPBYTE
)&pCurrent
->dwCharacteristics
, &dwSize
);
205 if (dwType
!= REG_DWORD
)
206 pCurrent
->dwCharacteristics
= 0;
208 /* retrieve ComponentId */
209 dwSize
= sizeof(szText
);
210 if (RegQueryValueExW(hSubKey
, L
"ComponentId", NULL
, &dwType
, (LPBYTE
)szText
, &dwSize
) == ERROR_SUCCESS
)
212 if (dwType
== REG_SZ
)
214 szText
[(sizeof(szText
)/sizeof(WCHAR
))-1] = L
'\0';
215 pCurrent
->szId
= CoTaskMemAlloc((wcslen(szText
)+1)* sizeof(WCHAR
));
217 wcscpy(pCurrent
->szId
, szText
);
221 /* retrieve Description */
222 dwSize
= sizeof(szText
);
223 if (RegQueryValueExW(hSubKey
, L
"Description", NULL
, &dwType
, (LPBYTE
)szText
, &dwSize
) == ERROR_SUCCESS
)
225 if (dwType
== REG_SZ
)
227 szText
[(sizeof(szText
)/sizeof(WCHAR
))-1] = L
'\0';
228 pCurrent
->szDisplayName
= CoTaskMemAlloc((wcslen(szText
)+1)* sizeof(WCHAR
));
229 if (pCurrent
->szDisplayName
)
230 wcscpy(pCurrent
->szDisplayName
, szText
);
234 if (RegOpenKeyExW(hKey
, L
"NDI", 0, KEY_READ
, &hNDIKey
) == ERROR_SUCCESS
)
236 /* retrieve HelpText */
237 dwSize
= sizeof(szText
);
238 if (RegQueryValueExW(hNDIKey
, L
"HelpText", NULL
, &dwType
, (LPBYTE
)szText
, &dwSize
) == ERROR_SUCCESS
)
240 if (dwType
== REG_SZ
)
242 szText
[(sizeof(szText
)/sizeof(WCHAR
))-1] = L
'\0';
243 pCurrent
->szHelpText
= CoTaskMemAlloc((wcslen(szText
)+1)* sizeof(WCHAR
));
244 if (pCurrent
->szHelpText
)
245 wcscpy(pCurrent
->szHelpText
, szText
);
249 /* retrieve Service */
250 dwSize
= sizeof(szText
);
251 if (RegQueryValueExW(hNDIKey
, L
"Service", NULL
, &dwType
, (LPBYTE
)szText
, &dwSize
) == ERROR_SUCCESS
)
253 if (dwType
== REG_SZ
)
255 szText
[(sizeof(szText
)/sizeof(WCHAR
))-1] = L
'\0';
256 pCurrent
->szBindName
= CoTaskMemAlloc((wcslen(szText
)+1)* sizeof(WCHAR
));
257 if (pCurrent
->szBindName
)
258 wcscpy(pCurrent
->szBindName
, szText
);
261 RegCloseKey(hNDIKey
);
263 RegCloseKey(hSubKey
);
268 pLast
->pNext
= pCurrent
;
283 EnumerateNetworkComponent(
284 const GUID
*pGuid
, NetCfgComponentItem
** pHead
)
291 hr
= StringFromCLSID(pGuid
, &pszGuid
);
294 swprintf(szName
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\%s", pszGuid
);
295 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
297 hr
= EnumClientServiceProtocol(hKey
, pGuid
, pHead
);
300 CoTaskMemFree(pszGuid
);
306 EnumerateNetworkAdapter(NetCfgComponentItem
** pHead
)
308 DWORD dwSize
, dwIndex
;
310 SP_DEVINFO_DATA DevInfo
;
313 WCHAR szAdapterNetCfg
[50];
314 WCHAR szDetail
[200] = L
"SYSTEM\\CurrentControlSet\\Control\\Class\\";
315 WCHAR szName
[130] = L
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
316 NetCfgComponentItem
* pLast
= NULL
, *pCurrent
;
318 hInfo
= SetupDiGetClassDevs(&GUID_DEVCLASS_NET
, NULL
, NULL
, DIGCF_PRESENT
);
327 ZeroMemory(&DevInfo
, sizeof(SP_DEVINFO_DATA
));
328 DevInfo
.cbSize
= sizeof(DevInfo
);
330 /* get device info */
331 if (!SetupDiEnumDeviceInfo(hInfo
, dwIndex
++, &DevInfo
))
334 /* get device software registry path */
335 if (!SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DRIVER
, NULL
, (LPBYTE
)&szDetail
[39], sizeof(szDetail
)/sizeof(WCHAR
) - 40, &dwSize
))
338 /* open device registry key */
339 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szDetail
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
342 /* query NetCfgInstanceId for current device */
343 dwSize
= sizeof(szNetCfg
);
344 if (RegQueryValueExW(hKey
, L
"NetCfgInstanceId", NULL
, NULL
, (LPBYTE
)szNetCfg
, &dwSize
) != ERROR_SUCCESS
)
350 /* allocate new INetConnectionItem */
351 pCurrent
= CoTaskMemAlloc(sizeof(NetCfgComponentItem
));
355 ZeroMemory(pCurrent
, sizeof(NetCfgComponentItem
));
356 CopyMemory(&pCurrent
->ClassGUID
, &GUID_DEVCLASS_NET
, sizeof(GUID
));
357 CLSIDFromString(szNetCfg
, &pCurrent
->InstanceId
); //FIXME
360 pCurrent
->szBindName
= CoTaskMemAlloc((wcslen(szNetCfg
)+1) *sizeof(WCHAR
));
361 if (pCurrent
->szBindName
)
362 wcscpy(pCurrent
->szBindName
, szNetCfg
);
364 /* retrieve ComponentId */
365 dwSize
= sizeof(szAdapterNetCfg
);
366 if (RegQueryValueExW(hKey
, L
"ComponentId", NULL
, NULL
, (LPBYTE
)szAdapterNetCfg
, &dwSize
) == ERROR_SUCCESS
)
368 pCurrent
->szId
= CoTaskMemAlloc((wcslen(szAdapterNetCfg
)+1) * sizeof(WCHAR
));
370 wcscpy(pCurrent
->szId
, szAdapterNetCfg
);
372 /* set INetCfgComponent::GetDisplayName */
373 dwSize
= sizeof(szAdapterNetCfg
);
374 if (RegQueryValueExW(hKey
, L
"DriverDesc", NULL
, NULL
, (LPBYTE
)szAdapterNetCfg
, &dwSize
) == ERROR_SUCCESS
)
376 pCurrent
->szDisplayName
= CoTaskMemAlloc((wcslen(szAdapterNetCfg
)+1) * sizeof(WCHAR
));
377 if (pCurrent
->szDisplayName
)
378 wcscpy(pCurrent
->szDisplayName
, szAdapterNetCfg
);
382 /* open network connections details */
383 wcscpy(&szName
[80], szNetCfg
);
384 wcscpy(&szName
[118], L
"\\Connection");
386 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
388 /* retrieve pnp instance id */
389 dwSize
= sizeof(szAdapterNetCfg
);
390 if (RegQueryValueExW(hKey
, L
"PnpInstanceID", NULL
, NULL
, (LPBYTE
)szAdapterNetCfg
, &dwSize
) == ERROR_SUCCESS
)
392 pCurrent
->szNodeId
= CoTaskMemAlloc((wcslen(szAdapterNetCfg
)+1) * sizeof(WCHAR
));
393 if (pCurrent
->szNodeId
)
394 wcscpy(pCurrent
->szNodeId
, szAdapterNetCfg
);
399 if (SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DEVICEDESC
, NULL
, (PBYTE
)szNetCfg
, sizeof(szNetCfg
)/sizeof(WCHAR
), &dwSize
))
401 szNetCfg
[(sizeof(szNetCfg
)/sizeof(WCHAR
))-1] = L
'\0';
402 pCurrent
->szDisplayName
= CoTaskMemAlloc((wcslen(szNetCfg
)+1) * sizeof(WCHAR
));
403 if (pCurrent
->szDisplayName
)
404 wcscpy(pCurrent
->szDisplayName
, szNetCfg
);
408 pLast
->pNext
= pCurrent
;
416 SetupDiDestroyDeviceInfoList(hInfo
);
422 FindNetworkComponent(
423 NetCfgComponentItem
* pHead
,
424 LPCWSTR pszwComponentId
,
425 INetCfgComponent
**pComponent
,
430 if (!_wcsicmp(pHead
->szId
, pszwComponentId
))
432 return INetCfgComponent_Constructor(NULL
, &IID_INetCfgComponent
, (LPVOID
*)pComponent
, pHead
, iface
);
434 pHead
= pHead
->pNext
;
443 INetCfg_fnQueryInterface(
448 INetCfgImpl
* This
= (INetCfgImpl
*)iface
;
451 if (IsEqualIID (iid
, &IID_IUnknown
) ||
452 IsEqualIID (iid
, &IID_INetCfg
))
455 INetCfg_AddRef(iface
);
458 else if (IsEqualIID (iid
, &IID_INetCfgLock
))
460 if (This
->bInitialized
)
461 return NETCFG_E_ALREADY_INITIALIZED
;
463 *ppvObj
= (LPVOID
)&This
->lpVtblLock
;
464 This
->hMutex
= CreateMutexW(NULL
, FALSE
, L
"NetCfgLock");
466 INetCfgLock_AddRef(iface
);
470 return E_NOINTERFACE
;
478 INetCfgImpl
* This
= (INetCfgImpl
*)iface
;
479 ULONG refCount
= InterlockedIncrement(&This
->ref
);
489 INetCfgImpl
* This
= (INetCfgImpl
*)iface
;
490 ULONG refCount
= InterlockedDecrement(&This
->ref
);
494 CoTaskMemFree (This
);
501 INetCfg_fnInitialize(
506 INetCfgImpl
*This
= (INetCfgImpl
*)iface
;
508 if (This
->bInitialized
)
509 return NETCFG_E_ALREADY_INITIALIZED
;
511 hr
= EnumerateNetworkAdapter(&This
->pNet
);
516 hr
= EnumerateNetworkComponent(&GUID_DEVCLASS_NETCLIENT
, &This
->pClient
);
520 hr
= EnumerateNetworkComponent(&GUID_DEVCLASS_NETSERVICE
, &This
->pService
);
525 hr
= EnumerateNetworkComponent(&GUID_DEVCLASS_NETTRANS
, &This
->pProtocol
);
529 This
->bInitialized
= TRUE
;
534 ApplyOrCancelChanges(
535 NetCfgComponentItem
*pHead
,
536 const CLSID
* lpClassGUID
,
547 if (IsEqualGUID(lpClassGUID
, &GUID_DEVCLASS_NET
))
551 if (StringFromCLSID(&pHead
->InstanceId
, &pszGuid
) == NOERROR
)
553 swprintf(szName
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\%s", pszGuid
);
554 CoTaskMemFree(pszGuid
);
556 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
558 RegSetValueExW(hKey
, NULL
, 0, REG_SZ
, (LPBYTE
)pHead
->szDisplayName
, (wcslen(pHead
->szDisplayName
)+1) * sizeof(WCHAR
));
564 else if (pHead
->pNCCC
)
568 INetCfgComponentControl_ApplyRegistryChanges(pHead
->pNCCC
);
570 // implement INetCfgPnpReconfigCallback and pass it to
571 //INetCfgComponentControl_ApplyPnpChanges(pHead->pNCCC, NULL);
575 INetCfgComponentControl_CancelChanges(pHead
->pNCCC
);
579 pHead
= pHead
->pNext
;
585 INetCfg_fnUninitialize(
588 INetCfgImpl
*This
= (INetCfgImpl
*)iface
;
590 if (!This
->bInitialized
)
591 return NETCFG_E_NOT_INITIALIZED
;
602 INetCfgImpl
*This
= (INetCfgImpl
*)iface
;
604 if (!This
->bInitialized
)
605 return NETCFG_E_NOT_INITIALIZED
;
607 ApplyOrCancelChanges(This
->pNet
, &GUID_DEVCLASS_NET
, TRUE
);
608 ApplyOrCancelChanges(This
->pClient
, &GUID_DEVCLASS_NETCLIENT
, TRUE
);
609 ApplyOrCancelChanges(This
->pService
, &GUID_DEVCLASS_NETSERVICE
, TRUE
);
610 ApplyOrCancelChanges(This
->pProtocol
, &GUID_DEVCLASS_NETTRANS
, TRUE
);
620 INetCfgImpl
*This
= (INetCfgImpl
*)iface
;
622 if (!This
->bInitialized
)
623 return NETCFG_E_NOT_INITIALIZED
;
625 ApplyOrCancelChanges(This
->pClient
, &GUID_DEVCLASS_NETCLIENT
, FALSE
);
626 ApplyOrCancelChanges(This
->pService
, &GUID_DEVCLASS_NETSERVICE
, FALSE
);
627 ApplyOrCancelChanges(This
->pProtocol
, &GUID_DEVCLASS_NETTRANS
, FALSE
);
634 INetCfg_fnEnumComponents(
636 const GUID
*pguidClass
,
637 IEnumNetCfgComponent
**ppenumComponent
)
639 INetCfgImpl
*This
= (INetCfgImpl
*)iface
;
641 if (!This
->bInitialized
)
642 return NETCFG_E_NOT_INITIALIZED
;
644 if (IsEqualGUID(&GUID_DEVCLASS_NET
, pguidClass
))
645 return IEnumNetCfgComponent_Constructor (NULL
, &IID_IEnumNetCfgComponent
, (LPVOID
*)ppenumComponent
, This
->pNet
, iface
);
646 else if (IsEqualGUID(&GUID_DEVCLASS_NETCLIENT
, pguidClass
))
647 return IEnumNetCfgComponent_Constructor (NULL
, &IID_IEnumNetCfgComponent
, (LPVOID
*)ppenumComponent
, This
->pClient
, iface
);
648 else if (IsEqualGUID(&GUID_DEVCLASS_NETSERVICE
, pguidClass
))
649 return IEnumNetCfgComponent_Constructor (NULL
, &IID_IEnumNetCfgComponent
, (LPVOID
*)ppenumComponent
, This
->pService
, iface
);
650 else if (IsEqualGUID(&GUID_DEVCLASS_NETTRANS
, pguidClass
))
651 return IEnumNetCfgComponent_Constructor (NULL
, &IID_IEnumNetCfgComponent
, (LPVOID
*)ppenumComponent
, This
->pProtocol
, iface
);
653 return E_NOINTERFACE
;
659 INetCfg_fnFindComponent(
661 LPCWSTR pszwComponentId
,
662 INetCfgComponent
**pComponent
)
665 INetCfgImpl
*This
= (INetCfgImpl
*)iface
;
667 if (!This
->bInitialized
)
668 return NETCFG_E_NOT_INITIALIZED
;
670 hr
= FindNetworkComponent(This
->pClient
, pszwComponentId
, pComponent
, iface
);
674 hr
= FindNetworkComponent(This
->pService
, pszwComponentId
, pComponent
, iface
);
678 hr
= FindNetworkComponent(This
->pProtocol
, pszwComponentId
, pComponent
, iface
);
687 INetCfg_fnQueryNetCfgClass(
689 const GUID
*pguidClass
,
696 static const INetCfgVtbl vt_NetCfg
=
698 INetCfg_fnQueryInterface
,
701 INetCfg_fnInitialize
,
702 INetCfg_fnUninitialize
,
705 INetCfg_fnEnumComponents
,
706 INetCfg_fnFindComponent
,
707 INetCfg_fnQueryNetCfgClass
,
710 HRESULT WINAPI
INetCfg_Constructor (IUnknown
* pUnkOuter
, REFIID riid
, LPVOID
* ppv
)
717 This
= (INetCfgImpl
*) CoTaskMemAlloc(sizeof (INetCfgImpl
));
719 return E_OUTOFMEMORY
;
722 This
->lpVtbl
= (const INetCfg
*)&vt_NetCfg
;
723 This
->lpVtblLock
= (const INetCfgLock
*)&vt_NetCfgLock
;
725 This
->bInitialized
= FALSE
;
727 This
->pClient
= NULL
;
728 This
->pService
= NULL
;
729 This
->pProtocol
= NULL
;
731 if (!SUCCEEDED (INetCfg_QueryInterface ((INetCfg
*)This
, riid
, ppv
)))
733 INetCfg_Release((INetCfg
*)This
);
734 return E_NOINTERFACE
;
737 INetCfg_Release((INetCfg
*)This
);