Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

815 lines
18 KiB

  1. #include <windows.h>
  2. #include "netconn.h"
  3. #include "globals.h"
  4. #include "localstr.h"
  5. #include <netcfgx.h>
  6. #include <devguid.h>
  7. #include <shlwapi.h>
  8. #define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0]))
  9. #pragma warning(disable:4100) // unreferenced formal parameter
  10. enum NetApplyChanges
  11. {
  12. Apply,
  13. Cancel,
  14. Nothing
  15. };
  16. HRESULT UninitNetCfg(INetCfg* pnetcfg, INetCfgLock* pnetcfglock, NetApplyChanges applychanges)
  17. {
  18. HRESULT hr = S_OK;
  19. if (Apply == applychanges)
  20. {
  21. hr = pnetcfg->Apply();
  22. }
  23. else if (Cancel == applychanges)
  24. {
  25. hr = pnetcfg->Cancel();
  26. }
  27. // Note: Don't set hr to anything after this point. We want to preserve the value from Apply
  28. // or Cancel - especially Apply which may signal a reboot is necessary.
  29. // Release even if this stuff above fails. Caller probably won't check return.
  30. pnetcfg->Uninitialize();
  31. if (pnetcfglock)
  32. {
  33. pnetcfglock->ReleaseWriteLock();
  34. pnetcfglock->Release();
  35. }
  36. pnetcfg->Release();
  37. CoUninitialize();
  38. return hr;
  39. }
  40. HRESULT InitNetCfg(INetCfg** ppnetcfg, INetCfgLock** ppnetcfglock)
  41. {
  42. BOOL fLockAquired = FALSE;
  43. *ppnetcfg = NULL;
  44. if (ppnetcfglock)
  45. {
  46. *ppnetcfglock = NULL;
  47. }
  48. HRESULT hr = CoInitialize(NULL);
  49. if (SUCCEEDED(hr))
  50. {
  51. hr = CoCreateInstance( CLSID_CNetCfg, NULL, CLSCTX_SERVER,
  52. IID_INetCfg, (void**) ppnetcfg);
  53. if (SUCCEEDED(hr))
  54. {
  55. if (ppnetcfglock)
  56. {
  57. hr = (*ppnetcfg)->QueryInterface(IID_INetCfgLock, (void**) ppnetcfglock);
  58. if (SUCCEEDED(hr))
  59. {
  60. LPWSTR pszCurrentLockHolder;
  61. hr = (*ppnetcfglock)->AcquireWriteLock(5, WIZARDNAME, &pszCurrentLockHolder);
  62. if (S_OK == hr)
  63. {
  64. fLockAquired = TRUE;
  65. }
  66. else
  67. {
  68. hr = NETCFG_E_NO_WRITE_LOCK;
  69. }
  70. }
  71. }
  72. if (SUCCEEDED(hr))
  73. {
  74. hr = (*ppnetcfg)->Initialize(NULL);
  75. }
  76. }
  77. // Clean up our mess if we failed
  78. if (FAILED(hr))
  79. {
  80. if (ppnetcfglock)
  81. {
  82. if (*ppnetcfglock)
  83. {
  84. if (fLockAquired)
  85. {
  86. (*ppnetcfglock)->ReleaseWriteLock();
  87. }
  88. (*ppnetcfglock)->Release();
  89. *ppnetcfglock = NULL;
  90. }
  91. }
  92. if (*ppnetcfg)
  93. {
  94. (*ppnetcfg)->Release();
  95. *ppnetcfg = NULL;
  96. }
  97. }
  98. }
  99. return hr;
  100. }
  101. LPWSTR NineXIdToComponentId(LPCWSTR psz9xid)
  102. {
  103. LPWSTR pszComponentId = NULL;
  104. if (0 == StrCmpI(psz9xid, SZ_PROTOCOL_TCPIP))
  105. {
  106. pszComponentId = &NETCFG_TRANS_CID_MS_TCPIP;
  107. } else if (0 == StrCmpI(psz9xid, SZ_CLIENT_MICROSOFT))
  108. {
  109. pszComponentId = &NETCFG_CLIENT_CID_MS_MSClient;
  110. }
  111. return pszComponentId;
  112. }
  113. // EnumComponents and TestRunDll are test-only stuff and should be removed - TODO
  114. void EnumComponents(INetCfg* pnetcfg, const GUID* pguid)
  115. {
  116. IEnumNetCfgComponent* penum;
  117. HRESULT hr = pnetcfg->EnumComponents(pguid, &penum);
  118. if (SUCCEEDED(hr))
  119. {
  120. INetCfgComponent* pcomponent;
  121. while (S_OK == (hr = penum->Next(1, &pcomponent, NULL)))
  122. {
  123. LPWSTR pszId;
  124. LPWSTR pszName;
  125. hr = pcomponent->GetId(&pszId);
  126. if (SUCCEEDED(hr))
  127. {
  128. OutputDebugString(pszId);
  129. CoTaskMemFree(pszId);
  130. }
  131. hr = pcomponent->GetDisplayName(&pszName);
  132. if (SUCCEEDED(hr))
  133. {
  134. OutputDebugString(L" - ");
  135. OutputDebugString(pszName);
  136. CoTaskMemFree(pszName);
  137. }
  138. OutputDebugString(L"\n");
  139. pcomponent->Release();
  140. }
  141. penum->Release();
  142. }
  143. }
  144. void APIENTRY TestRunDll(HWND hwndStub, HINSTANCE hAppInstance, LPSTR pszCmdLine, int nCmdShow)
  145. {
  146. HRESULT hr = S_OK;
  147. CoInitialize(NULL);
  148. INetCfg *pnetcfg = NULL;
  149. hr = CoCreateInstance( CLSID_CNetCfg, NULL, CLSCTX_SERVER,
  150. IID_INetCfg, (LPVOID*)&pnetcfg);
  151. if (SUCCEEDED(hr))
  152. {
  153. hr = pnetcfg->Initialize(NULL);
  154. if (SUCCEEDED(hr))
  155. {
  156. OutputDebugString(L"GUID_DEVCLASS_NET\n");
  157. EnumComponents(pnetcfg, &GUID_DEVCLASS_NET);
  158. OutputDebugString(L"\nGUID_DEVCLASS_NETTRANS\n");
  159. EnumComponents(pnetcfg, &GUID_DEVCLASS_NETTRANS);
  160. OutputDebugString(L"\nGUID_DEVCLASS_NETCLIENT\n");
  161. EnumComponents(pnetcfg, &GUID_DEVCLASS_NETCLIENT);
  162. OutputDebugString(L"\nGUID_DEVCLASS_NETSERVICE\n");
  163. EnumComponents(pnetcfg, &GUID_DEVCLASS_NETSERVICE);
  164. pnetcfg->Uninitialize();
  165. }
  166. pnetcfg->Release();
  167. }
  168. CoUninitialize();
  169. }
  170. BOOL IsComponentInstalled(LPCWSTR pszId)
  171. {
  172. BOOL fInstalled = FALSE;
  173. INetCfg* pnetcfg;
  174. HRESULT hr = InitNetCfg(&pnetcfg, NULL);
  175. if (SUCCEEDED(hr))
  176. {
  177. INetCfgComponent* pcomponent;
  178. HRESULT hr = pnetcfg->FindComponent(pszId, &pcomponent);
  179. if (S_OK == hr)
  180. {
  181. // Component found
  182. pcomponent->Release();
  183. fInstalled = TRUE;
  184. }
  185. hr = UninitNetCfg(pnetcfg, NULL, Nothing);
  186. }
  187. return fInstalled;
  188. }
  189. HRESULT InstallComponent(const GUID* pguidType, LPCWSTR pszId)
  190. {
  191. INetCfg* pnetcfg;
  192. INetCfgLock* pnetcfglock;
  193. // Init & aquire a write lock
  194. HRESULT hr = InitNetCfg(&pnetcfg, &pnetcfglock);
  195. if (SUCCEEDED(hr))
  196. {
  197. INetCfgClassSetup* pnetcfgclasssetup;
  198. hr = pnetcfg->QueryNetCfgClass(pguidType, IID_INetCfgClassSetup, (void**) &pnetcfgclasssetup);
  199. if (SUCCEEDED(hr))
  200. {
  201. INetCfgComponent* pNewComp;
  202. OBO_TOKEN obotoken;
  203. ZeroMemory(&obotoken, sizeof(OBO_TOKEN));
  204. obotoken.Type = OBO_USER;
  205. hr = pnetcfgclasssetup->Install(
  206. pszId,
  207. &obotoken,
  208. 0, /* NSF_POSTSYSINSTALL ? */
  209. 0,
  210. NULL,
  211. NULL,
  212. &pNewComp);
  213. if (SUCCEEDED(hr))
  214. {
  215. pNewComp->Release();
  216. }
  217. pnetcfgclasssetup->Release();
  218. }
  219. // Free our mess and apply changes if we succeeded in installing our component
  220. hr = UninitNetCfg(pnetcfg, pnetcfglock, (SUCCEEDED(hr)) ? Apply : Cancel);
  221. }
  222. return hr;
  223. }
  224. // NOT USED. But keep around since NetConnFree is used.
  225. //
  226. LPVOID WINAPI NetConnAlloc(DWORD cbAlloc)
  227. {
  228. return LocalAlloc(LMEM_FIXED, cbAlloc);
  229. }
  230. // USED.
  231. //
  232. VOID WINAPI NetConnFree(LPVOID pMem)
  233. {
  234. if (pMem)
  235. LocalFree(pMem);
  236. }
  237. // USED. Only one call with (SZ_PROTOCOL_TCPIP, TRUE).
  238. //
  239. BOOL WINAPI IsProtocolInstalled(LPCWSTR pszProtocolDeviceID, BOOL bExhaustive)
  240. {
  241. BOOL fSuccess = FALSE;
  242. LPCWSTR pszTransportId = NineXIdToComponentId(pszProtocolDeviceID);
  243. if (pszTransportId)
  244. {
  245. fSuccess = IsComponentInstalled(pszTransportId);
  246. }
  247. return fSuccess;
  248. }
  249. // USED. Called once with (FALSE)
  250. //
  251. BOOL WINAPI IsMSClientInstalled(BOOL bExhaustive)
  252. {
  253. return IsComponentInstalled(NETCFG_CLIENT_CID_MS_MSClient);
  254. }
  255. // USED. Only one call with (hwnd, NULL, NULL)
  256. //
  257. HRESULT WINAPI InstallTCPIP(HWND hwndParent, PROGRESS_CALLBACK pfnProgress, LPVOID pvProgressParam)
  258. {
  259. HRESULT hr = InstallComponent(&GUID_DEVCLASS_NETTRANS, NETCFG_TRANS_CID_MS_TCPIP);
  260. // Map the reboot result code
  261. if (NETCFG_S_REBOOT == hr)
  262. {
  263. hr = NETCONN_NEED_RESTART;
  264. }
  265. return hr;
  266. }
  267. // USED. Called once with (hwnd, NULL, NULL)
  268. //
  269. HRESULT WINAPI InstallMSClient(HWND hwndParent, PROGRESS_CALLBACK pfnProgress, LPVOID pvProgressParam)
  270. {
  271. HRESULT hr = InstallComponent(&GUID_DEVCLASS_NETCLIENT, NETCFG_CLIENT_CID_MS_MSClient);
  272. // Map the reboot result code
  273. if (NETCFG_S_REBOOT == hr)
  274. {
  275. hr = NETCONN_NEED_RESTART;
  276. }
  277. return hr;
  278. }
  279. // USED. Called once with (hwnd, NULL, NULL).
  280. //
  281. HRESULT WINAPI InstallSharing(HWND hwndParent, PROGRESS_CALLBACK pfnProgress, LPVOID pvProgressParam)
  282. {
  283. HRESULT hr = InstallComponent(&GUID_DEVCLASS_NETSERVICE, NETCFG_SERVICE_CID_MS_SERVER);
  284. // Map the reboot result code
  285. if (NETCFG_S_REBOOT == hr)
  286. {
  287. hr = NETCONN_NEED_RESTART;
  288. }
  289. return hr;
  290. }
  291. // USED. Called once with (TRUE)
  292. //
  293. BOOL WINAPI IsSharingInstalled(BOOL bExhaustive)
  294. {
  295. return IsComponentInstalled(NETCFG_SERVICE_CID_MS_SERVER);
  296. }
  297. // USED. Called once with (SZ_CLIENT_MICROSOFT, TRUE).
  298. //
  299. BOOL WINAPI IsClientInstalled(LPCWSTR pszClient, BOOL bExhaustive)
  300. {
  301. BOOL fSuccess = FALSE;
  302. LPCWSTR pszClientId = NineXIdToComponentId(pszClient);
  303. if (pszClientId)
  304. {
  305. fSuccess = IsComponentInstalled(pszClientId);
  306. }
  307. return fSuccess;
  308. }
  309. // USED. Called four times.
  310. // This is always TRUE on NT?
  311. BOOL WINAPI IsAccessControlUserLevel()
  312. {
  313. return TRUE;
  314. }
  315. // USED. Called once.
  316. // This can't be disabled on NT
  317. HRESULT WINAPI DisableUserLevelAccessControl()
  318. {
  319. return E_NOTIMPL;
  320. }
  321. #define CopyStrMacro(Dest) if (SUCCEEDED(hr)) {StrCpyNW((Dest), pszTemp, ARRAYSIZE((Dest))); CoTaskMemFree(pszTemp);}
  322. HRESULT FillAdapterInfo(INetCfgComponent* pcomponent, NETADAPTER* pNetAdapter)
  323. {
  324. HRESULT hr = S_OK;
  325. LPWSTR pszTemp;
  326. DWORD dwCharacteristics;
  327. // szDisplayName
  328. hr = pcomponent->GetDisplayName(&pszTemp);
  329. if (SUCCEEDED(hr))
  330. {
  331. OutputDebugString(L"\n\nDisplayName:");
  332. OutputDebugString(pszTemp);
  333. StrCpyNW(pNetAdapter->szDisplayName, pszTemp, ARRAYSIZE(pNetAdapter->szDisplayName));
  334. CoTaskMemFree(pszTemp);
  335. }
  336. // szDeviceID
  337. hr = pcomponent->GetId(&pszTemp);
  338. if (SUCCEEDED(hr))
  339. {
  340. OutputDebugString(L"\nId:");
  341. OutputDebugString(pszTemp);
  342. StrCpyNW(pNetAdapter->szDeviceID, pszTemp, ARRAYSIZE(pNetAdapter->szDeviceID));
  343. CoTaskMemFree(pszTemp);
  344. }
  345. // review - unused as of now - maybe remove
  346. hr = pcomponent->GetPnpDevNodeId(&pszTemp);
  347. if (SUCCEEDED(hr))
  348. {
  349. OutputDebugString(L"\nPnpDevNodeId:");
  350. OutputDebugString(pszTemp);
  351. }
  352. // review - assuming szEnumKey is actually the BindName since it is used in EnumMatchingNetBindings.
  353. hr = pcomponent->GetBindName(&pszTemp);
  354. if (SUCCEEDED(hr))
  355. {
  356. OutputDebugString(L"\nBindName:");
  357. OutputDebugString(pszTemp);
  358. StrCpyNW(pNetAdapter->szEnumKey, pszTemp, ARRAYSIZE(pNetAdapter->szEnumKey));
  359. CoTaskMemFree(pszTemp);
  360. }
  361. // Also usused
  362. DWORD dwStatus;
  363. hr = pcomponent->GetDeviceStatus(&dwStatus);
  364. if (SUCCEEDED(hr))
  365. {
  366. WCHAR szTemp[20];
  367. wnsprintf(szTemp, ARRAYSIZE(szTemp), L"%x", dwStatus);
  368. OutputDebugString(L"\nDeviceStatus:");
  369. OutputDebugString(szTemp);
  370. }
  371. hr = pcomponent->GetCharacteristics(&dwCharacteristics);
  372. if (SUCCEEDED(hr))
  373. {
  374. WCHAR szTemp[20];
  375. wnsprintf(szTemp, ARRAYSIZE(szTemp), L"%x", dwCharacteristics);
  376. OutputDebugString(L"\nCharacteristics:");
  377. OutputDebugString(szTemp);
  378. }
  379. // szClassKey ??
  380. // szManufacturer - don't care
  381. pNetAdapter->szManufacturer[0] = 0;
  382. // szInfFileName - don't care
  383. pNetAdapter->szInfFileName[0] = 0;
  384. // bNicType - review
  385. pNetAdapter->bNicType = (BYTE)((dwCharacteristics & NCF_VIRTUAL) ? NIC_VIRTUAL : NIC_UNKNOWN);
  386. // bNetType - review
  387. pNetAdapter->bNetType = (BYTE)((dwCharacteristics & NCF_PHYSICAL) ? NETTYPE_LAN : NETTYPE_PPTP);
  388. // bNetSubType - review
  389. pNetAdapter->bNetSubType = SUBTYPE_NONE;
  390. // bIcsStatus (internet connection sharing??)- review
  391. pNetAdapter->bIcsStatus = ICS_NONE;
  392. // bError - review
  393. pNetAdapter->bError = NICERR_NONE;
  394. // bWarning - review
  395. pNetAdapter->bWarning = NICWARN_NONE;
  396. return S_OK;
  397. }
  398. #define ALLOCGROWBY 10
  399. int AllocAndGetAdapterInfo(IEnumNetCfgComponent* penum, NETADAPTER** pprgNetAdapters)
  400. {
  401. *pprgNetAdapters = NULL;
  402. UINT iMaxItems = 0;
  403. UINT iCurrentItem = 0;
  404. HRESULT hr = S_OK;
  405. while (S_OK == hr)
  406. {
  407. INetCfgComponent* pnetadapter;
  408. hr = penum->Next(1, &pnetadapter, NULL);
  409. if (S_OK == hr)
  410. {
  411. if (iCurrentItem == iMaxItems)
  412. {
  413. // Time to allocate some memory
  414. iMaxItems += ALLOCGROWBY;
  415. if (*pprgNetAdapters)
  416. {
  417. NETADAPTER* pTemp = (NETADAPTER*) LocalReAlloc(*pprgNetAdapters, sizeof(NETADAPTER) * iMaxItems, LMEM_ZEROINIT);
  418. if (!pTemp)
  419. {
  420. hr = E_OUTOFMEMORY;
  421. LocalFree(*pprgNetAdapters);
  422. *pprgNetAdapters = NULL;
  423. }
  424. else
  425. {
  426. *pprgNetAdapters = pTemp;
  427. }
  428. }
  429. else
  430. {
  431. *pprgNetAdapters = (NETADAPTER*) LocalAlloc(LMEM_ZEROINIT, sizeof(NETADAPTER) * iMaxItems);
  432. if (!*pprgNetAdapters)
  433. {
  434. hr = E_OUTOFMEMORY;
  435. }
  436. }
  437. }
  438. if (SUCCEEDED(hr))
  439. {
  440. hr = FillAdapterInfo(pnetadapter, (*pprgNetAdapters) + iCurrentItem);
  441. }
  442. pnetadapter->Release();
  443. iCurrentItem ++;
  444. }
  445. else
  446. {
  447. // We've got as many as we can; we're done
  448. }
  449. }
  450. return iCurrentItem;
  451. }
  452. // USED. Called four times - out parameter is never NULL.
  453. //
  454. int WINAPI EnumNetAdapters(NETADAPTER FAR** pprgNetAdapters)
  455. {
  456. *pprgNetAdapters = NULL;
  457. int iAdapters = 0;
  458. INetCfg* pnetcfg;
  459. HRESULT hr = InitNetCfg(&pnetcfg, NULL);
  460. if (SUCCEEDED(hr))
  461. {
  462. IEnumNetCfgComponent* penum;
  463. hr = pnetcfg->EnumComponents(&GUID_DEVCLASS_NET, &penum);
  464. if (SUCCEEDED(hr))
  465. {
  466. iAdapters = AllocAndGetAdapterInfo(penum, pprgNetAdapters);
  467. }
  468. hr = UninitNetCfg(pnetcfg, NULL, Nothing);
  469. }
  470. return iAdapters;
  471. }
  472. // USED. Called once with bAutodial TRUE or FALSE and szConnection not used.
  473. //
  474. void WINAPI EnableAutodial(BOOL bAutodial, LPCWSTR szConnection = NULL)
  475. {
  476. }
  477. // USED. Called twice.
  478. //
  479. BOOL WINAPI IsAutodialEnabled()
  480. {
  481. return FALSE;
  482. }
  483. // USED. Called once.
  484. //
  485. void WINAPI SetDefaultDialupConnection(LPCWSTR pszConnectionName)
  486. {
  487. }
  488. // Used. Called once.
  489. //
  490. void WINAPI GetDefaultDialupConnection(LPWSTR pszConnectionName, int cchMax)
  491. {
  492. }
  493. // Used. Called four times. Second parameter is always SZ_PROTOCOL_TCPIP.
  494. // Update: Actually only called once from SetHomeConnection. The other three are #if 0'd.
  495. // Update2: SetHomeConnection needs to have a different implementation for NT, so this is never really called.
  496. //
  497. int WINAPI EnumMatchingNetBindings(LPCWSTR pszParentBinding, LPCWSTR pszDeviceID, LPWSTR** pprgBindings)
  498. {
  499. return 0;
  500. }
  501. HRESULT WINAPI RestartNetAdapter(DWORD devnode)
  502. {
  503. return E_NOTIMPL;
  504. }
  505. // NOT USED.
  506. //
  507. /*
  508. HRESULT WINAPI InstallProtocol(LPCWSTR pszProtocol, HWND hwndParent, PROGRESS_CALLBACK pfnCallback, LPVOID pvCallbackParam)
  509. {
  510. return E_NOTIMPL;
  511. }
  512. */
  513. // NOT USED.
  514. //
  515. /*
  516. HRESULT WINAPI RemoveProtocol(LPCWSTR pszProtocol)
  517. {
  518. return E_NOTIMPL;
  519. }
  520. */
  521. // NOT USED.
  522. //
  523. /*
  524. HRESULT WINAPI EnableBrowseMaster()
  525. {
  526. return E_NOTIMPL;
  527. }
  528. */
  529. // NOT USED.
  530. //
  531. /*
  532. BOOL WINAPI IsFileSharingEnabled()
  533. {
  534. return FALSE;
  535. }
  536. */
  537. // NOT USED.
  538. //
  539. /*
  540. BOOL WINAPI IsPrinterSharingEnabled()
  541. {
  542. return FALSE;
  543. }
  544. */
  545. // NOT USED.
  546. //
  547. /*
  548. BOOL WINAPI FindConflictingService(LPCWSTR pszWantService, NETSERVICE* pConflict)
  549. {
  550. return FALSE;
  551. }
  552. */
  553. // NOT USED.
  554. //
  555. /*
  556. HRESULT WINAPI EnableSharingAppropriately()
  557. {
  558. return E_NOTIMPL;
  559. }
  560. */
  561. // NOT USED.
  562. //
  563. /*
  564. HRESULT WINAPI InstallNetAdapter(LPCWSTR pszDeviceID, LPCWSTR pszInfPath, HWND hwndParent, PROGRESS_CALLBACK pfnProgress, LPVOID pvCallbackParam)
  565. {
  566. return E_NOTIMPL;
  567. }
  568. */
  569. // NOT USED.
  570. //
  571. /*
  572. HRESULT WINAPI EnableQuickLogon()
  573. {
  574. return E_NOTIMPL;
  575. }
  576. */
  577. // NOT USED.
  578. //
  579. /*
  580. HRESULT WINAPI DetectHardware(LPCWSTR pszDeviceID)
  581. {
  582. return E_NOTIMPL;
  583. }
  584. */
  585. // NOT USED.
  586. //
  587. /*
  588. BOOL WINAPI IsProtocolBoundToAdapter(LPCWSTR pszProtocolID, const NETADAPTER* pAdapter)
  589. {
  590. return FALSE;
  591. }
  592. */
  593. // NOT USED.
  594. //
  595. /*
  596. HRESULT WINAPI EnableNetAdapter(const NETADAPTER* pAdapter)
  597. {
  598. return E_NOTIMPL;
  599. }
  600. */
  601. // NOT USED.
  602. //
  603. /*
  604. HRESULT WINAPI RemoveClient(LPCWSTR pszClient)
  605. {
  606. return E_NOTIMPL;
  607. }
  608. */
  609. // NOT USED.
  610. //
  611. /*
  612. HRESULT WINAPI RemoveGhostedAdapters(LPCWSTR pszDeviceID)
  613. {
  614. return E_NOTIMPL;
  615. }
  616. */
  617. // NOT USED.
  618. //
  619. /*
  620. HRESULT WINAPI RemoveUnknownAdapters(LPCWSTR pszDeviceID)
  621. {
  622. return E_NOTIMPL;
  623. }
  624. */
  625. // NOT USED.
  626. //
  627. /*
  628. BOOL WINAPI DoesAdapterMatchDeviceID(const NETADAPTER* pAdapter, LPCWSTR pszDeviceID)
  629. {
  630. return FALSE;
  631. }
  632. */
  633. // NOT USED.
  634. //
  635. /*
  636. BOOL WINAPI IsAdapterBroadband(const NETADAPTER* pAdapter)
  637. {
  638. return FALSE;
  639. }
  640. */
  641. // NOT USED.
  642. //
  643. /*
  644. void WINAPI SaveBroadbandSettings(LPCWSTR pszBroadbandAdapterNumber)
  645. {
  646. }
  647. */
  648. // NOT USED.
  649. //
  650. /*
  651. BOOL WINAPI UpdateBroadbandSettings(LPWSTR pszEnumKeyBuf, int cchEnumKeyBuf)
  652. {
  653. return FALSE;
  654. }
  655. */