6 const INetCfg
* lpVtbl
;
7 const INetCfgLock
* lpVtblLock
;
11 NetCfgComponentItem
*pNet
;
12 NetCfgComponentItem
* pService
;
13 NetCfgComponentItem
* pClient
;
14 NetCfgComponentItem
* pProtocol
;
15 } INetCfgImpl
, *LPINetCfgImpl
;
17 static LPINetCfgImpl __inline
impl_from_INetCfgLock(INetCfgLock
*iface
)
19 return (INetCfgImpl
*)((char *)iface
- FIELD_OFFSET(INetCfgImpl
, lpVtblLock
));
26 INetCfgLock_fnQueryInterface(
31 INetCfgImpl
* This
= impl_from_INetCfgLock(iface
);
32 return INetCfg_QueryInterface((INetCfg
*)This
, iid
, ppvObj
);
41 INetCfgImpl
* This
= impl_from_INetCfgLock(iface
);
43 return INetCfg_AddRef((INetCfg
*)This
);
48 INetCfgLock_fnRelease(
51 INetCfgImpl
* This
= impl_from_INetCfgLock(iface
);
52 return INetCfg_Release((INetCfg
*)This
);
57 INetCfgLock_fnAcquireWriteLock(
60 LPCWSTR pszwClientDescription
,
61 LPWSTR
*ppszwClientDescription
)
66 INetCfgImpl
* This
= impl_from_INetCfgLock(iface
);
68 if (This
->bInitialized
)
69 return NETCFG_E_ALREADY_INITIALIZED
;
71 dwResult
= WaitForSingleObject(This
->hMutex
, cmsTimeout
);
72 if (dwResult
== WAIT_TIMEOUT
)
74 if (ppszwClientDescription
)
76 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\NetCfgLockHolder", 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
78 dwResult
= sizeof(szValue
);
79 if (RegQueryValueExW(hKey
, NULL
, NULL
, NULL
, (LPBYTE
)szValue
, &dwResult
) == ERROR_SUCCESS
)
81 szValue
[(sizeof(szValue
)/sizeof(WCHAR
))-1] = L
'\0';
82 *ppszwClientDescription
= CoTaskMemAlloc((wcslen(szValue
)+1) * sizeof(WCHAR
));
83 if (*ppszwClientDescription
)
84 wcscpy(*ppszwClientDescription
, szValue
);
91 else if (dwResult
== WAIT_OBJECT_0
)
93 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\NetCfgLockHolder", 0, NULL
, 0, KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
)
95 RegSetValueExW(hKey
, NULL
, 0, REG_SZ
, (LPBYTE
)pszwClientDescription
, (wcslen(pszwClientDescription
)+1) * sizeof(WCHAR
));
106 INetCfgLock_fnReleaseWriteLock(
109 INetCfgImpl
* This
= impl_from_INetCfgLock(iface
);
111 if (This
->bInitialized
)
112 return NETCFG_E_ALREADY_INITIALIZED
;
115 if (ReleaseMutex(This
->hMutex
))
123 INetCfgLock_fnIsWriteLocked(
125 LPWSTR
*ppszwClientDescription
)
129 DWORD dwSize
, dwType
;
132 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\NetCfgLockHolder", 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
135 dwSize
= sizeof(szValue
);
136 if (RegQueryValueExW(hKey
, NULL
, NULL
, &dwType
, (LPBYTE
)szValue
, &dwSize
) == ERROR_SUCCESS
&& dwType
== REG_SZ
)
139 szValue
[(sizeof(szValue
)/sizeof(WCHAR
))-1] = L
'\0';
140 *ppszwClientDescription
= CoTaskMemAlloc((wcslen(szValue
)+1) * sizeof(WCHAR
));
141 if (*ppszwClientDescription
)
142 wcscpy(*ppszwClientDescription
, szValue
);
154 static const INetCfgLockVtbl vt_NetCfgLock
=
156 INetCfgLock_fnQueryInterface
,
157 INetCfgLock_fnAddRef
,
158 INetCfgLock_fnRelease
,
159 INetCfgLock_fnAcquireWriteLock
,
160 INetCfgLock_fnReleaseWriteLock
,
161 INetCfgLock_fnIsWriteLocked
164 /***************************************************************
169 EnumClientServiceProtocol(HKEY hKey
, const GUID
* pGuid
, NetCfgComponentItem
** pHead
)
174 DWORD dwCharacteristics
;
177 HKEY hSubKey
, hNDIKey
;
178 NetCfgComponentItem
* pLast
= NULL
, *pCurrent
;
183 dwCharacteristics
= 0;
186 dwSize
= sizeof(szName
)/sizeof(WCHAR
);
187 if (RegEnumKeyExW(hKey
, dwIndex
++, szName
, &dwSize
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
189 pCurrent
= CoTaskMemAlloc(sizeof(NetCfgComponentItem
));
191 return E_OUTOFMEMORY
;
193 ZeroMemory(pCurrent
, sizeof(NetCfgComponentItem
));
194 CopyMemory(&pCurrent
->ClassGUID
, pGuid
, sizeof(GUID
));
196 if (FAILED(CLSIDFromString(szName
, &pCurrent
->InstanceId
)))
198 /// ReactOS tcpip guid is not yet generated
199 //CoTaskMemFree(pCurrent);
202 if (RegOpenKeyExW(hKey
, szName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
204 /* retrieve Characteristics */
205 dwSize
= sizeof(DWORD
);
207 RegQueryValueExW(hSubKey
, L
"Characteristics", NULL
, &dwType
, (LPBYTE
)&pCurrent
->dwCharacteristics
, &dwSize
);
208 if (dwType
!= REG_DWORD
)
209 pCurrent
->dwCharacteristics
= 0;
211 /* retrieve ComponentId */
212 dwSize
= sizeof(szText
);
213 if (RegQueryValueExW(hSubKey
, L
"ComponentId", NULL
, &dwType
, (LPBYTE
)szText
, &dwSize
) == ERROR_SUCCESS
)
215 if (dwType
== REG_SZ
)
217 szText
[(sizeof(szText
)/sizeof(WCHAR
))-1] = L
'\0';
218 pCurrent
->szId
= CoTaskMemAlloc((wcslen(szText
)+1)* sizeof(WCHAR
));
220 wcscpy(pCurrent
->szId
, szText
);
224 /* retrieve Description */
225 dwSize
= sizeof(szText
);
226 if (RegQueryValueExW(hSubKey
, L
"Description", NULL
, &dwType
, (LPBYTE
)szText
, &dwSize
) == ERROR_SUCCESS
)
228 if (dwType
== REG_SZ
)
230 szText
[(sizeof(szText
)/sizeof(WCHAR
))-1] = L
'\0';
231 pCurrent
->szDisplayName
= CoTaskMemAlloc((wcslen(szText
)+1)* sizeof(WCHAR
));
232 if (pCurrent
->szDisplayName
)
233 wcscpy(pCurrent
->szDisplayName
, szText
);
237 if (RegOpenKeyExW(hKey
, L
"NDI", 0, KEY_READ
, &hNDIKey
) == ERROR_SUCCESS
)
239 /* retrieve HelpText */
240 dwSize
= sizeof(szText
);
241 if (RegQueryValueExW(hNDIKey
, L
"HelpText", NULL
, &dwType
, (LPBYTE
)szText
, &dwSize
) == ERROR_SUCCESS
)
243 if (dwType
== REG_SZ
)
245 szText
[(sizeof(szText
)/sizeof(WCHAR
))-1] = L
'\0';
246 pCurrent
->szHelpText
= CoTaskMemAlloc((wcslen(szText
)+1)* sizeof(WCHAR
));
247 if (pCurrent
->szHelpText
)
248 wcscpy(pCurrent
->szHelpText
, szText
);
252 /* retrieve Service */
253 dwSize
= sizeof(szText
);
254 if (RegQueryValueExW(hNDIKey
, L
"Service", NULL
, &dwType
, (LPBYTE
)szText
, &dwSize
) == ERROR_SUCCESS
)
256 if (dwType
== REG_SZ
)
258 szText
[(sizeof(szText
)/sizeof(WCHAR
))-1] = L
'\0';
259 pCurrent
->szBindName
= CoTaskMemAlloc((wcslen(szText
)+1)* sizeof(WCHAR
));
260 if (pCurrent
->szBindName
)
261 wcscpy(pCurrent
->szBindName
, szText
);
264 RegCloseKey(hNDIKey
);
266 RegCloseKey(hSubKey
);
271 pLast
->pNext
= pCurrent
;
286 EnumerateNetworkComponent(
287 const GUID
*pGuid
, NetCfgComponentItem
** pHead
)
294 hr
= StringFromCLSID(pGuid
, &pszGuid
);
297 swprintf(szName
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\%s", pszGuid
);
298 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
300 hr
= EnumClientServiceProtocol(hKey
, pGuid
, pHead
);
303 CoTaskMemFree(pszGuid
);
309 EnumerateNetworkAdapter(NetCfgComponentItem
** pHead
)
311 DWORD dwSize
, dwIndex
;
313 SP_DEVINFO_DATA DevInfo
;
316 WCHAR szAdapterNetCfg
[50];
317 WCHAR szDetail
[200] = L
"SYSTEM\\CurrentControlSet\\Control\\Class\\";
318 WCHAR szName
[130] = L
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
319 NetCfgComponentItem
* pLast
= NULL
, *pCurrent
;
321 hInfo
= SetupDiGetClassDevs(&GUID_DEVCLASS_NET
, NULL
, NULL
, DIGCF_PRESENT
);
330 ZeroMemory(&DevInfo
, sizeof(SP_DEVINFO_DATA
));
331 DevInfo
.cbSize
= sizeof(DevInfo
);
333 /* get device info */
334 if (!SetupDiEnumDeviceInfo(hInfo
, dwIndex
++, &DevInfo
))
337 /* get device software registry path */
338 if (!SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DRIVER
, NULL
, (LPBYTE
)&szDetail
[39], sizeof(szDetail
)/sizeof(WCHAR
) - 40, &dwSize
))
341 /* open device registry key */
342 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szDetail
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
345 /* query NetCfgInstanceId for current device */
346 dwSize
= sizeof(szNetCfg
);
347 if (RegQueryValueExW(hKey
, L
"NetCfgInstanceId", NULL
, NULL
, (LPBYTE
)szNetCfg
, &dwSize
) != ERROR_SUCCESS
)
353 /* allocate new INetConnectionItem */
354 pCurrent
= CoTaskMemAlloc(sizeof(NetCfgComponentItem
));
358 ZeroMemory(pCurrent
, sizeof(NetCfgComponentItem
));
359 CopyMemory(&pCurrent
->ClassGUID
, &GUID_DEVCLASS_NET
, sizeof(GUID
));
360 CLSIDFromString(szNetCfg
, &pCurrent
->InstanceId
); //FIXME
363 pCurrent
->szBindName
= CoTaskMemAlloc((wcslen(szNetCfg
)+1) *sizeof(WCHAR
));
364 if (pCurrent
->szBindName
)
365 wcscpy(pCurrent
->szBindName
, szNetCfg
);
367 /* retrieve ComponentId */
368 dwSize
= sizeof(szAdapterNetCfg
);
369 if (RegQueryValueExW(hKey
, L
"ComponentId", NULL
, NULL
, (LPBYTE
)szAdapterNetCfg
, &dwSize
) == ERROR_SUCCESS
)
371 pCurrent
->szId
= CoTaskMemAlloc((wcslen(szAdapterNetCfg
)+1) * sizeof(WCHAR
));
373 wcscpy(pCurrent
->szId
, szAdapterNetCfg
);
375 /* set INetCfgComponent::GetDisplayName */
376 dwSize
= sizeof(szAdapterNetCfg
);
377 if (RegQueryValueExW(hKey
, L
"DriverDesc", NULL
, NULL
, (LPBYTE
)szAdapterNetCfg
, &dwSize
) == ERROR_SUCCESS
)
379 pCurrent
->szDisplayName
= CoTaskMemAlloc((wcslen(szAdapterNetCfg
)+1) * sizeof(WCHAR
));
380 if (pCurrent
->szDisplayName
)
381 wcscpy(pCurrent
->szDisplayName
, szAdapterNetCfg
);
385 /* open network connections details */
386 wcscpy(&szName
[80], szNetCfg
);
387 wcscpy(&szName
[118], L
"\\Connection");
389 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, szName
, 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
391 /* retrieve pnp instance id */
392 dwSize
= sizeof(szAdapterNetCfg
);
393 if (RegQueryValueExW(hKey
, L
"PnpInstanceID", NULL
, NULL
, (LPBYTE
)szAdapterNetCfg
, &dwSize
) == ERROR_SUCCESS
)
395 pCurrent
->szNodeId
= CoTaskMemAlloc((wcslen(szAdapterNetCfg
)+1) * sizeof(WCHAR
));
396 if (pCurrent
->szNodeId
)
397 wcscpy(pCurrent
->szNodeId
, szAdapterNetCfg
);
402 if (SetupDiGetDeviceRegistryPropertyW(hInfo
, &DevInfo
, SPDRP_DEVICEDESC
, NULL
, (PBYTE
)szNetCfg
, sizeof(szNetCfg
)/sizeof(WCHAR
), &dwSize
))
404 szNetCfg
[(sizeof(szNetCfg
)/sizeof(WCHAR
))-1] = L
'\0';
405 pCurrent
->szDisplayName
= CoTaskMemAlloc((wcslen(szNetCfg
)+1) * sizeof(WCHAR
));
406 if (pCurrent
->szDisplayName
)
407 wcscpy(pCurrent
->szDisplayName
, szNetCfg
);
411 pLast
->pNext
= pCurrent
;
419 SetupDiDestroyDeviceInfoList(hInfo
);
425 FindNetworkComponent(
426 NetCfgComponentItem
* pHead
,
427 LPCWSTR pszwComponentId
,
428 INetCfgComponent
**pComponent
,
433 if (!wcsicmp(pHead
->szId
, pszwComponentId
))
435 return INetCfgComponent_Constructor(NULL
, &IID_INetCfgComponent
, (LPVOID
*)pComponent
, pHead
, iface
);
437 pHead
= pHead
->pNext
;
446 INetCfg_fnQueryInterface(
451 INetCfgImpl
* This
= (INetCfgImpl
*)iface
;
454 if (IsEqualIID (iid
, &IID_IUnknown
) ||
455 IsEqualIID (iid
, &IID_INetCfg
))
458 INetCfg_AddRef(iface
);
461 else if (IsEqualIID (iid
, &IID_INetCfgLock
))
463 if (This
->bInitialized
)
464 return NETCFG_E_ALREADY_INITIALIZED
;
466 *ppvObj
= (LPVOID
)&This
->lpVtblLock
;
467 This
->hMutex
= CreateMutexW(NULL
, FALSE
, L
"NetCfgLock");
469 INetCfgLock_AddRef(iface
);
473 return E_NOINTERFACE
;
481 INetCfgImpl
* This
= (INetCfgImpl
*)iface
;
482 ULONG refCount
= InterlockedIncrement(&This
->ref
);
492 INetCfgImpl
* This
= (INetCfgImpl
*)iface
;
493 ULONG refCount
= InterlockedDecrement(&This
->ref
);
497 CoTaskMemFree (This
);
504 INetCfg_fnInitialize(
509 INetCfgImpl
*This
= (INetCfgImpl
*)iface
;
511 if (This
->bInitialized
)
512 return NETCFG_E_ALREADY_INITIALIZED
;
514 hr
= EnumerateNetworkAdapter(&This
->pNet
);
519 hr
= EnumerateNetworkComponent(&GUID_DEVCLASS_NETCLIENT
, &This
->pClient
);
523 hr
= EnumerateNetworkComponent(&GUID_DEVCLASS_NETSERVICE
, &This
->pService
);
528 hr
= EnumerateNetworkComponent(&GUID_DEVCLASS_NETTRANS
, &This
->pProtocol
);
532 This
->bInitialized
= TRUE
;
538 INetCfg_fnUninitialize(
541 INetCfgImpl
*This
= (INetCfgImpl
*)iface
;
543 if (!This
->bInitialized
)
544 return NETCFG_E_NOT_INITIALIZED
;
555 INetCfgImpl
*This
= (INetCfgImpl
*)iface
;
557 if (!This
->bInitialized
)
558 return NETCFG_E_NOT_INITIALIZED
;
569 INetCfgImpl
*This
= (INetCfgImpl
*)iface
;
571 if (!This
->bInitialized
)
572 return NETCFG_E_NOT_INITIALIZED
;
579 INetCfg_fnEnumComponents(
581 const GUID
*pguidClass
,
582 IEnumNetCfgComponent
**ppenumComponent
)
584 INetCfgImpl
*This
= (INetCfgImpl
*)iface
;
586 if (!This
->bInitialized
)
587 return NETCFG_E_NOT_INITIALIZED
;
589 if (IsEqualGUID(&GUID_DEVCLASS_NET
, pguidClass
))
590 return IEnumNetCfgComponent_Constructor (NULL
, &IID_IEnumNetCfgComponent
, (LPVOID
*)ppenumComponent
, This
->pNet
, iface
);
591 else if (IsEqualGUID(&GUID_DEVCLASS_NETCLIENT
, pguidClass
))
592 return IEnumNetCfgComponent_Constructor (NULL
, &IID_IEnumNetCfgComponent
, (LPVOID
*)ppenumComponent
, This
->pClient
, iface
);
593 else if (IsEqualGUID(&GUID_DEVCLASS_NETSERVICE
, pguidClass
))
594 return IEnumNetCfgComponent_Constructor (NULL
, &IID_IEnumNetCfgComponent
, (LPVOID
*)ppenumComponent
, This
->pService
, iface
);
595 else if (IsEqualGUID(&GUID_DEVCLASS_NETTRANS
, pguidClass
))
596 return IEnumNetCfgComponent_Constructor (NULL
, &IID_IEnumNetCfgComponent
, (LPVOID
*)ppenumComponent
, This
->pProtocol
, iface
);
598 return E_NOINTERFACE
;
604 INetCfg_fnFindComponent(
606 LPCWSTR pszwComponentId
,
607 INetCfgComponent
**pComponent
)
610 INetCfgImpl
*This
= (INetCfgImpl
*)iface
;
612 if (!This
->bInitialized
)
613 return NETCFG_E_NOT_INITIALIZED
;
615 hr
= FindNetworkComponent(This
->pClient
, pszwComponentId
, pComponent
, iface
);
619 hr
= FindNetworkComponent(This
->pService
, pszwComponentId
, pComponent
, iface
);
623 hr
= FindNetworkComponent(This
->pProtocol
, pszwComponentId
, pComponent
, iface
);
632 INetCfg_fnQueryNetCfgClass(
634 const GUID
*pguidClass
,
641 static const INetCfgVtbl vt_NetCfg
=
643 INetCfg_fnQueryInterface
,
646 INetCfg_fnInitialize
,
647 INetCfg_fnUninitialize
,
650 INetCfg_fnEnumComponents
,
651 INetCfg_fnFindComponent
,
652 INetCfg_fnQueryNetCfgClass
,
655 HRESULT WINAPI
INetCfg_Constructor (IUnknown
* pUnkOuter
, REFIID riid
, LPVOID
* ppv
)
662 This
= (INetCfgImpl
*) CoTaskMemAlloc(sizeof (INetCfgImpl
));
664 return E_OUTOFMEMORY
;
667 This
->lpVtbl
= (const INetCfg
*)&vt_NetCfg
;
668 This
->lpVtblLock
= (const INetCfgLock
*)&vt_NetCfgLock
;
670 This
->bInitialized
= FALSE
;
672 This
->pClient
= NULL
;
673 This
->pService
= NULL
;
674 This
->pProtocol
= NULL
;
676 if (!SUCCEEDED (INetCfg_QueryInterface ((INetCfg
*)This
, riid
, ppv
)))
678 INetCfg_Release((INetCfg
*)This
);
679 return E_NOINTERFACE
;
682 INetCfg_Release((INetCfg
*)This
);