Source code of Windows XP (NT5)
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.

1095 lines
33 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1998 - 2001
  5. //
  6. // File : bridge.cpp
  7. //
  8. // Contents : bridge context specific code
  9. //
  10. // Notes :
  11. //
  12. // Author : Raghu Gatta (rgatta) 11 May 2001
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. const TCHAR c_stRegKeyBridgeAdapters[] =
  18. _T("SYSTEM\\CurrentControlSet\\Services\\Bridge\\Parameters\\Adapters");
  19. const TCHAR c_stFCMode[] = _T("ForceCompatibilityMode");
  20. CMD_ENTRY g_BridgeSetCmdTable[] = {
  21. CREATE_CMD_ENTRY(BRIDGE_SET_ADAPTER, HandleBridgeSetAdapter),
  22. };
  23. CMD_ENTRY g_BridgeShowCmdTable[] = {
  24. CREATE_CMD_ENTRY(BRIDGE_SHOW_ADAPTER, HandleBridgeShowAdapter),
  25. };
  26. CMD_GROUP_ENTRY g_BridgeCmdGroups[] =
  27. {
  28. CREATE_CMD_GROUP_ENTRY(GROUP_SET, g_BridgeSetCmdTable),
  29. CREATE_CMD_GROUP_ENTRY(GROUP_SHOW, g_BridgeShowCmdTable),
  30. };
  31. ULONG g_ulBridgeNumGroups = sizeof(g_BridgeCmdGroups)/sizeof(CMD_GROUP_ENTRY);
  32. CMD_ENTRY g_BridgeCmds[] =
  33. {
  34. CREATE_CMD_ENTRY(INSTALL, HandleBridgeInstall),
  35. CREATE_CMD_ENTRY(UNINSTALL, HandleBridgeUninstall),
  36. };
  37. ULONG g_ulBridgeNumTopCmds = sizeof(g_BridgeCmds)/sizeof(CMD_ENTRY);
  38. DWORD WINAPI
  39. BridgeDump(
  40. IN LPCWSTR pwszRouter,
  41. IN OUT LPWSTR *ppwcArguments,
  42. IN DWORD dwArgCount,
  43. IN LPCVOID pvData
  44. )
  45. {
  46. //
  47. // Output the string that shows our settings.
  48. // The idea here is to spit out a script that,
  49. // when run from the command line (netsh -f script)
  50. // will cause your component to be configured
  51. // exactly as it is when this dump command was run.
  52. //
  53. PrintMessageFromModule(
  54. g_hModule,
  55. DMP_BRIDGE_HEADER
  56. );
  57. PrintMessageFromModule(
  58. g_hModule,
  59. DMP_BRIDGE_FOOTER
  60. );
  61. return NO_ERROR;
  62. }
  63. HRESULT
  64. HrCycleBridge(
  65. IHNetBridge *pIHNetBridge
  66. )
  67. {
  68. HRESULT hr = S_OK;
  69. //
  70. // Check to see if the bridge is up and running.
  71. // If it is, then disable and reenable
  72. //
  73. do
  74. {
  75. //
  76. // Get the pointer to IID_IHNetConnection interface of this
  77. // bridged connection
  78. //
  79. CComPtr<IHNetConnection> spIHNConn;
  80. hr = pIHNetBridge->QueryInterface(
  81. IID_PPV_ARG(IHNetConnection, &spIHNConn)
  82. );
  83. assert(SUCCEEDED(hr));
  84. if (FAILED(hr))
  85. {
  86. break;
  87. }
  88. INetConnection *pINetConn;
  89. hr = spIHNConn->GetINetConnection(&pINetConn);
  90. if (SUCCEEDED(hr))
  91. {
  92. NETCON_PROPERTIES* pNCProps;
  93. hr = pINetConn->GetProperties(&pNCProps);
  94. if(SUCCEEDED(hr))
  95. {
  96. //
  97. // check status - restart only if already running
  98. //
  99. if (pNCProps->Status == NCS_CONNECTED ||
  100. pNCProps->Status == NCS_CONNECTING)
  101. {
  102. pINetConn->Disconnect();
  103. pINetConn->Connect();
  104. }
  105. NcFreeNetconProperties(pNCProps);
  106. }
  107. ReleaseObj(pINetConn);
  108. }
  109. } while(FALSE);
  110. return hr;
  111. }
  112. DWORD
  113. SetBridgeAdapterInfo(
  114. DWORD adapterId,
  115. BOOL bFlag
  116. )
  117. {
  118. DWORD dwErr = NO_ERROR;
  119. IHNetCfgMgr* pIHNetCfgMgr = NULL;
  120. HRESULT hr = S_OK;
  121. hr = HrInitializeHomenetConfig(
  122. &g_fInitCom,
  123. &pIHNetCfgMgr
  124. );
  125. if (SUCCEEDED(hr))
  126. {
  127. //
  128. // Get the IHNetBridgeSettings
  129. //
  130. CComPtr<IHNetBridgeSettings> spIHNetBridgeSettings;
  131. hr = pIHNetCfgMgr->QueryInterface(
  132. IID_PPV_ARG(IHNetBridgeSettings, &spIHNetBridgeSettings)
  133. );
  134. if (SUCCEEDED(hr))
  135. {
  136. //
  137. // Get the IEnumHNetBridges
  138. //
  139. CComPtr<IEnumHNetBridges> spehBridges;
  140. if ((hr = spIHNetBridgeSettings->EnumBridges(&spehBridges)) == S_OK)
  141. {
  142. //
  143. // Get the first IHNetBridge
  144. //
  145. CComPtr<IHNetBridge> spIHNetBridge;
  146. if ((hr = spehBridges->Next(1, &spIHNetBridge, NULL)) == S_OK)
  147. {
  148. {
  149. //
  150. // We currently should have only one bridge;
  151. // this may change in the future. The
  152. // code here is just to catch future instances
  153. // where this function would have to change in case
  154. // there is more than one bridge.
  155. //
  156. CComPtr<IHNetBridge> spIHNetBridge2;
  157. if ((hr = spehBridges->Next(1, &spIHNetBridge2, NULL)) == S_OK)
  158. {
  159. assert(FALSE);
  160. }
  161. }
  162. //
  163. // Get the IEnumHNetBridgedConnections
  164. //
  165. CComPtr<IEnumHNetBridgedConnections> spehBrdgConns;
  166. if ((hr = spIHNetBridge->EnumMembers(&spehBrdgConns)) == S_OK)
  167. {
  168. //
  169. // enumerate all the IHNetBridgedConnections
  170. //
  171. DWORD id = 0;
  172. IHNetBridgedConnection* pIHNetBConn;
  173. spehBrdgConns->Reset();
  174. while (S_OK == spehBrdgConns->Next(1, &pIHNetBConn, NULL))
  175. {
  176. id++;
  177. if (id != adapterId)
  178. {
  179. //
  180. // release the IHNetBridgedConnection
  181. //
  182. ReleaseObj(pIHNetBConn);
  183. continue;
  184. }
  185. //
  186. // Get the pointer to IID_IHNetConnection interface of this
  187. // bridged connection
  188. //
  189. CComPtr<IHNetConnection> spIHNConn;
  190. hr = pIHNetBConn->QueryInterface(
  191. IID_PPV_ARG(IHNetConnection, &spIHNConn)
  192. );
  193. assert(SUCCEEDED(hr));
  194. if (SUCCEEDED(hr))
  195. {
  196. GUID *pGuid = NULL;
  197. hr = spIHNConn->GetGuid(&pGuid);
  198. if (SUCCEEDED(hr) && (NULL != pGuid))
  199. {
  200. PTCHAR pwszKey = NULL;
  201. int keyLen;
  202. TCHAR wszGuid[128];
  203. HKEY hKey = NULL;
  204. DWORD dwDisp = 0;
  205. BOOL bCycleBridge = TRUE;
  206. DWORD dwOldValue;
  207. DWORD dwNewValue = (bFlag) ? 1 : 0;
  208. do
  209. {
  210. ZeroMemory(wszGuid, sizeof(wszGuid));
  211. StringFromGUID2(
  212. *pGuid,
  213. wszGuid,
  214. ARRAYSIZE(wszGuid)
  215. );
  216. keyLen = _tcslen(c_stRegKeyBridgeAdapters) +
  217. _tcslen(_T("\\")) +
  218. _tcslen(wszGuid) +
  219. 1;
  220. pwszKey = (TCHAR *) HeapAlloc(
  221. GetProcessHeap(),
  222. 0,
  223. keyLen * sizeof(TCHAR)
  224. );
  225. if (!pwszKey)
  226. {
  227. break;
  228. }
  229. ZeroMemory(pwszKey, sizeof(pwszKey));
  230. _tcscpy(pwszKey, c_stRegKeyBridgeAdapters);
  231. _tcscat(pwszKey, _T("\\"));
  232. _tcscat(pwszKey, wszGuid);
  233. dwErr = RegCreateKeyEx(
  234. HKEY_LOCAL_MACHINE,
  235. pwszKey,
  236. 0,
  237. NULL,
  238. REG_OPTION_NON_VOLATILE,
  239. KEY_ALL_ACCESS,
  240. NULL,
  241. &hKey,
  242. &dwDisp
  243. );
  244. if (ERROR_SUCCESS != dwErr)
  245. {
  246. break;
  247. }
  248. //
  249. // if the key was old, get its value
  250. // and compare to see if we need to
  251. // cycle the bridge
  252. //
  253. if (dwDisp &&
  254. dwDisp == REG_OPENED_EXISTING_KEY)
  255. {
  256. DWORD dwSize = sizeof(dwOldValue);
  257. if (ERROR_SUCCESS == RegQueryValueEx(
  258. hKey,
  259. c_stFCMode,
  260. NULL,
  261. NULL,
  262. (LPBYTE)&dwOldValue,
  263. &dwSize))
  264. {
  265. if (dwOldValue == dwNewValue)
  266. {
  267. //
  268. // no need to cycle the bridge
  269. //
  270. bCycleBridge = FALSE;
  271. }
  272. }
  273. }
  274. dwErr = RegSetValueEx(
  275. hKey,
  276. c_stFCMode,
  277. 0,
  278. REG_DWORD,
  279. (LPBYTE) &dwNewValue,
  280. sizeof(dwNewValue)
  281. );
  282. if (ERROR_SUCCESS != dwErr)
  283. {
  284. break;
  285. }
  286. if (bCycleBridge)
  287. {
  288. //
  289. // cycle the (respective) bridge
  290. //
  291. hr = HrCycleBridge(
  292. spIHNetBridge
  293. );
  294. }
  295. } while(FALSE);
  296. //
  297. // cleanup
  298. //
  299. if (hKey)
  300. {
  301. RegCloseKey(hKey);
  302. }
  303. if (pwszKey)
  304. {
  305. HeapFree(GetProcessHeap(), 0, pwszKey);
  306. }
  307. CoTaskMemFree(pGuid);
  308. }
  309. }
  310. //
  311. // release the IHNetBridgedConnection
  312. //
  313. ReleaseObj(pIHNetBConn);
  314. break;
  315. } //while
  316. }
  317. }
  318. }
  319. }
  320. //
  321. // we are done completely
  322. //
  323. hr = HrUninitializeHomenetConfig(
  324. g_fInitCom,
  325. pIHNetCfgMgr
  326. );
  327. }
  328. return (hr==S_OK) ? dwErr : hr;
  329. }
  330. DWORD
  331. WINAPI
  332. HandleBridgeSetAdapter(
  333. IN LPCWSTR pwszMachine,
  334. IN OUT LPWSTR *ppwcArguments,
  335. IN DWORD dwCurrentIndex,
  336. IN DWORD dwArgCount,
  337. IN DWORD dwFlags,
  338. IN LPCVOID pvData,
  339. OUT BOOL *pbDone
  340. )
  341. {
  342. DWORD dwRet = NO_ERROR;
  343. PDWORD pdwTagType = NULL;
  344. DWORD dwNumOpt;
  345. DWORD dwNumArg;
  346. DWORD dwRes;
  347. DWORD dwErrIndex =-1,
  348. i;
  349. //
  350. // default values
  351. //
  352. DWORD id = 0;
  353. DWORD bFCMode = FALSE;
  354. TAG_TYPE pttTags[] =
  355. {
  356. {TOKEN_OPT_ID, NS_REQ_PRESENT, FALSE},
  357. {TOKEN_OPT_FCMODE, NS_REQ_ZERO, FALSE} // not required to allow for
  358. // addition of future flags
  359. };
  360. if (dwCurrentIndex >= dwArgCount)
  361. {
  362. // No arguments specified. At least interface name should be specified.
  363. return ERROR_INVALID_SYNTAX;
  364. }
  365. dwNumArg = dwArgCount - dwCurrentIndex;
  366. pdwTagType = (DWORD *) HeapAlloc(
  367. GetProcessHeap(),
  368. 0,
  369. dwNumArg * sizeof(DWORD)
  370. );
  371. if (NULL == pdwTagType)
  372. {
  373. return ERROR_NOT_ENOUGH_MEMORY;
  374. }
  375. dwRet = PreprocessCommand(
  376. g_hModule,
  377. ppwcArguments,
  378. dwCurrentIndex,
  379. dwArgCount,
  380. pttTags,
  381. ARRAYSIZE(pttTags),
  382. 1, // min args
  383. 2, // max args
  384. pdwTagType
  385. );
  386. if (NO_ERROR != dwRet)
  387. {
  388. HeapFree(GetProcessHeap(), 0, pdwTagType);
  389. if (ERROR_INVALID_OPTION_TAG == dwRet)
  390. {
  391. return ERROR_INVALID_SYNTAX;
  392. }
  393. return dwRet;
  394. }
  395. for ( i = 0; i < dwNumArg; i++)
  396. {
  397. switch (pdwTagType[i])
  398. {
  399. case 0:
  400. {
  401. //
  402. // refers to the 'id' field
  403. //
  404. id = _tcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10);
  405. break;
  406. }
  407. case 1:
  408. {
  409. //
  410. // refers to the 'forcecompatmode' field
  411. // possible values are : enable or disable
  412. //
  413. TOKEN_VALUE rgEnums[] =
  414. {
  415. {TOKEN_OPT_VALUE_ENABLE, TRUE},
  416. {TOKEN_OPT_VALUE_DISABLE, FALSE}
  417. };
  418. dwRet = MatchEnumTag(
  419. g_hModule,
  420. ppwcArguments[i + dwCurrentIndex],
  421. ARRAYSIZE(rgEnums),
  422. rgEnums,
  423. &dwRes
  424. );
  425. if (dwRet != NO_ERROR)
  426. {
  427. dwErrIndex = i;
  428. i = dwNumArg;
  429. dwRet = ERROR_INVALID_PARAMETER;
  430. break;
  431. }
  432. switch (dwRes)
  433. {
  434. case 0:
  435. bFCMode = FALSE;
  436. break;
  437. case 1:
  438. bFCMode = TRUE;
  439. break;
  440. }
  441. break;
  442. }
  443. default:
  444. {
  445. i = dwNumArg;
  446. dwRet = ERROR_INVALID_PARAMETER;
  447. break;
  448. }
  449. } //switch
  450. if (dwRet != NO_ERROR)
  451. {
  452. break ;
  453. }
  454. } //for
  455. //
  456. // adapter id MUST be present
  457. //
  458. if (!pttTags[0].bPresent)
  459. {
  460. dwRet = ERROR_INVALID_SYNTAX;
  461. }
  462. switch(dwRet)
  463. {
  464. case NO_ERROR:
  465. break;
  466. case ERROR_INVALID_PARAMETER:
  467. if (dwErrIndex != -1)
  468. {
  469. PrintError(
  470. g_hModule,
  471. EMSG_BAD_OPTION_VALUE,
  472. ppwcArguments[dwErrIndex + dwCurrentIndex],
  473. pttTags[pdwTagType[dwErrIndex]].pwszTag
  474. );
  475. }
  476. dwRet = ERROR_SUPPRESS_OUTPUT;
  477. break;
  478. default:
  479. //
  480. // error message already printed
  481. //
  482. break;
  483. }
  484. if (pdwTagType)
  485. {
  486. HeapFree(GetProcessHeap(), 0, pdwTagType);
  487. }
  488. if (NO_ERROR != dwRet)
  489. {
  490. return dwRet;
  491. }
  492. //
  493. // we have the requisite info - process them
  494. //
  495. //
  496. // since we may or may not have flag info, check for it
  497. //
  498. if (pttTags[1].bPresent)
  499. {
  500. dwRet = SetBridgeAdapterInfo(
  501. id,
  502. bFCMode
  503. );
  504. }
  505. return dwRet;
  506. }
  507. DWORD
  508. ShowBridgeAdapterInfo(
  509. DWORD id,
  510. IHNetConnection *pIHNConn
  511. )
  512. {
  513. HRESULT hr;
  514. //
  515. // print out the bridged connections details
  516. //
  517. PWSTR pwszName = NULL;
  518. PWSTR pwszState = NULL;
  519. hr = pIHNConn->GetName(&pwszName);
  520. if (SUCCEEDED(hr) && (NULL != pwszName))
  521. {
  522. GUID *pGuid = NULL;
  523. hr = pIHNConn->GetGuid(&pGuid);
  524. if (SUCCEEDED(hr) && (NULL != pGuid))
  525. {
  526. WCHAR wszGuid[128];
  527. ZeroMemory(wszGuid, sizeof(wszGuid));
  528. StringFromGUID2(*pGuid, wszGuid, ARRAYSIZE(wszGuid));
  529. //
  530. // check to see if registry settings present
  531. //
  532. // for forcecompatmode:
  533. // + if key is not present --> disabled
  534. // + if key is present
  535. // 0x1 --> enabled
  536. // 0x0 --> disabled
  537. // + all other errors --> unknown
  538. //
  539. {
  540. HKEY hBAKey;
  541. DWORD msgState = STRING_UNKNOWN;
  542. if (ERROR_SUCCESS == RegOpenKeyEx(
  543. HKEY_LOCAL_MACHINE,
  544. c_stRegKeyBridgeAdapters,
  545. 0,
  546. KEY_READ,
  547. &hBAKey))
  548. {
  549. HKEY hBCKey;
  550. if (ERROR_SUCCESS == RegOpenKeyEx(
  551. hBAKey,
  552. wszGuid,
  553. 0,
  554. KEY_READ,
  555. &hBCKey))
  556. {
  557. DWORD dwFCModeState = 0;
  558. DWORD dwSize = sizeof(dwFCModeState);
  559. if (ERROR_SUCCESS == RegQueryValueEx(
  560. hBCKey,
  561. c_stFCMode,
  562. NULL,
  563. NULL,
  564. (LPBYTE)&dwFCModeState,
  565. &dwSize))
  566. {
  567. switch (dwFCModeState)
  568. {
  569. case 0:
  570. msgState = STRING_DISABLED;
  571. break;
  572. case 1:
  573. msgState = STRING_ENABLED;
  574. break;
  575. default:
  576. msgState = STRING_UNKNOWN;
  577. }
  578. }
  579. else
  580. {
  581. //
  582. // value not present
  583. //
  584. msgState = STRING_DISABLED;
  585. }
  586. RegCloseKey(hBCKey);
  587. }
  588. else
  589. {
  590. //
  591. // bridged connection guid key not present
  592. //
  593. msgState = STRING_DISABLED;
  594. }
  595. RegCloseKey(hBAKey);
  596. }
  597. pwszState = MakeString(g_hModule, msgState);
  598. }
  599. PrintMessage(
  600. L" %1!2d! %2!-27s! %3!s!%n",
  601. id,
  602. pwszName,
  603. pwszState
  604. );
  605. if (pwszState)
  606. {
  607. FreeString(pwszState);
  608. }
  609. CoTaskMemFree(pGuid);
  610. }
  611. CoTaskMemFree(pwszName);
  612. }
  613. return NO_ERROR;
  614. }
  615. DWORD
  616. ShowBridgeAllAdapterInfo(
  617. BOOL bShowAll, // TRUE to show all
  618. DWORD adapterId // valid only if bShowAll is FALSE
  619. )
  620. {
  621. IHNetCfgMgr* pIHNetCfgMgr = NULL;
  622. HRESULT hr = S_OK;
  623. hr = HrInitializeHomenetConfig(
  624. &g_fInitCom,
  625. &pIHNetCfgMgr
  626. );
  627. if (SUCCEEDED(hr))
  628. {
  629. //
  630. // Get the IHNetBridgeSettings
  631. //
  632. CComPtr<IHNetBridgeSettings> spIHNetBridgeSettings;
  633. hr = pIHNetCfgMgr->QueryInterface(
  634. IID_PPV_ARG(IHNetBridgeSettings, &spIHNetBridgeSettings)
  635. );
  636. if (SUCCEEDED(hr))
  637. {
  638. //
  639. // Get the IEnumHNetBridges
  640. //
  641. CComPtr<IEnumHNetBridges> spehBridges;
  642. if ((hr = spIHNetBridgeSettings->EnumBridges(&spehBridges)) == S_OK)
  643. {
  644. //
  645. // Get the first IHNetBridge
  646. //
  647. CComPtr<IHNetBridge> spIHNetBridge;
  648. if ((hr = spehBridges->Next(1, &spIHNetBridge, NULL)) == S_OK)
  649. {
  650. {
  651. //
  652. // We currently should have only one bridge;
  653. // this may change in the future. The
  654. // code here is just to catch future instances
  655. // where this function would have to change in case
  656. // there is more than one bridge.
  657. //
  658. CComPtr<IHNetBridge> spIHNetBridge2;
  659. if ((hr = spehBridges->Next(1, &spIHNetBridge2, NULL)) == S_OK)
  660. {
  661. assert(FALSE);
  662. }
  663. }
  664. //
  665. // Get the IEnumHNetBridgedConnections
  666. //
  667. CComPtr<IEnumHNetBridgedConnections> spehBrdgConns;
  668. if ((hr = spIHNetBridge->EnumMembers(&spehBrdgConns)) == S_OK)
  669. {
  670. //
  671. // spit out header for displaying the list
  672. //
  673. PrintMessageFromModule(
  674. g_hModule,
  675. MSG_BRIDGE_ADAPTER_INFO_HDR
  676. );
  677. //
  678. // enumerate all the IHNetBridgedConnections
  679. //
  680. DWORD id = 0;
  681. IHNetBridgedConnection* pIHNetBConn;
  682. spehBrdgConns->Reset();
  683. while (S_OK == spehBrdgConns->Next(1, &pIHNetBConn, NULL))
  684. {
  685. id++;
  686. //
  687. // check if we are looking for a specific id
  688. //
  689. if (FALSE == bShowAll && id != adapterId)
  690. {
  691. //
  692. // release the IHNetBridgedConnection
  693. //
  694. ReleaseObj(pIHNetBConn);
  695. continue;
  696. }
  697. //
  698. // Get the pointer to IID_IHNetConnection interface of this
  699. // bridged connection
  700. //
  701. CComPtr<IHNetConnection> spIHNConn;
  702. hr = pIHNetBConn->QueryInterface(
  703. IID_PPV_ARG(IHNetConnection, &spIHNConn)
  704. );
  705. assert(SUCCEEDED(hr));
  706. if (SUCCEEDED(hr))
  707. {
  708. ShowBridgeAdapterInfo(
  709. id,
  710. spIHNConn
  711. );
  712. }
  713. //
  714. // release the IHNetBridgedConnection
  715. //
  716. ReleaseObj(pIHNetBConn);
  717. //
  718. // if we reached here and we were looking for a
  719. // specific id, our work is done - break out
  720. //
  721. if (FALSE == bShowAll)
  722. {
  723. break;
  724. }
  725. }
  726. //
  727. // spit out footer for displaying the list
  728. //
  729. PrintMessageFromModule(
  730. g_hModule,
  731. TABLE_SEPARATOR
  732. );
  733. }
  734. }
  735. }
  736. }
  737. //
  738. // we are done completely
  739. //
  740. hr = HrUninitializeHomenetConfig(
  741. g_fInitCom,
  742. pIHNetCfgMgr
  743. );
  744. }
  745. return (hr==S_OK) ? NO_ERROR : hr;
  746. }
  747. DWORD
  748. WINAPI
  749. HandleBridgeShowAdapter(
  750. IN LPCWSTR pwszMachine,
  751. IN OUT LPWSTR *ppwcArguments,
  752. IN DWORD dwCurrentIndex,
  753. IN DWORD dwArgCount,
  754. IN DWORD dwFlags,
  755. IN LPCVOID pvData,
  756. OUT BOOL *pbDone
  757. )
  758. /*++
  759. Routine Description:
  760. Gets options for showing bridge adapter info
  761. Arguements:
  762. ppwcArguments - Argument array
  763. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  764. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  765. Return Value:
  766. NO_ERROR
  767. --*/
  768. {
  769. IHNetCfgMgr* pIHNetCfgMgr = NULL;
  770. HRESULT hr = S_OK;
  771. BOOL bShowAll = FALSE;
  772. DWORD id = 0,
  773. i,
  774. dwRet = NO_ERROR,
  775. dwNumOpt,
  776. dwNumArg,
  777. dwSize,
  778. dwRes;
  779. PDWORD pdwTagType = NULL;
  780. TAG_TYPE pttTags[] =
  781. {
  782. {TOKEN_OPT_ID, NS_REQ_ZERO, FALSE}
  783. };
  784. if (dwCurrentIndex > dwArgCount)
  785. {
  786. //
  787. // No arguments specified
  788. //
  789. return ERROR_INVALID_SYNTAX;
  790. }
  791. if (dwCurrentIndex == dwArgCount)
  792. {
  793. bShowAll = TRUE;
  794. }
  795. dwNumArg = dwArgCount - dwCurrentIndex;
  796. pdwTagType = (DWORD *) HeapAlloc(
  797. GetProcessHeap(),
  798. 0,
  799. dwNumArg * sizeof(DWORD)
  800. );
  801. if (dwNumArg && NULL == pdwTagType)
  802. {
  803. return ERROR_NOT_ENOUGH_MEMORY;
  804. }
  805. dwRet = PreprocessCommand(
  806. g_hModule,
  807. ppwcArguments,
  808. dwCurrentIndex,
  809. dwArgCount,
  810. pttTags,
  811. ARRAYSIZE(pttTags),
  812. 0, // min args
  813. 1, // max args
  814. pdwTagType
  815. );
  816. if (NO_ERROR == dwRet)
  817. {
  818. //
  819. // process each argument...
  820. //
  821. for (i = 0; i < (dwArgCount - dwCurrentIndex); i++)
  822. {
  823. //
  824. // Check its corresponding value in the pdwTagType array.
  825. //
  826. switch (pdwTagType[i])
  827. {
  828. case 0:
  829. //
  830. // refers to the 'id' field
  831. //
  832. id = _tcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10);
  833. break;
  834. default:
  835. //
  836. // Since there is only one valid value, means the arg
  837. // wasn't recognized. Shouldn't reach this point because
  838. // PreprocessCommand wouldn't have returned NO_ERROR if
  839. // this was the case.
  840. //
  841. dwRet = ERROR_INVALID_SYNTAX;
  842. break;
  843. }
  844. }
  845. dwRet = ShowBridgeAllAdapterInfo(
  846. bShowAll,
  847. id
  848. ) ;
  849. }
  850. else
  851. {
  852. dwRet = ERROR_SHOW_USAGE;
  853. }
  854. //
  855. // cleanup
  856. //
  857. if (pdwTagType)
  858. {
  859. HeapFree(GetProcessHeap(), 0, pdwTagType);
  860. }
  861. return dwRet;
  862. }
  863. DWORD
  864. WINAPI
  865. HandleBridgeInstall(
  866. IN LPCWSTR pwszMachine,
  867. IN OUT LPWSTR *ppwcArguments,
  868. IN DWORD dwCurrentIndex,
  869. IN DWORD dwArgCount,
  870. IN DWORD dwFlags,
  871. IN LPCVOID pvData,
  872. OUT BOOL *pbDone
  873. )
  874. {
  875. PrintMessageFromModule(
  876. g_hModule,
  877. HLP_BRIDGE_USE_GUI,
  878. CMD_INSTALL
  879. );
  880. return NO_ERROR;
  881. }
  882. DWORD
  883. WINAPI
  884. HandleBridgeUninstall(
  885. IN LPCWSTR pwszMachine,
  886. IN OUT LPWSTR *ppwcArguments,
  887. IN DWORD dwCurrentIndex,
  888. IN DWORD dwArgCount,
  889. IN DWORD dwFlags,
  890. IN LPCVOID pvData,
  891. OUT BOOL *pbDone
  892. )
  893. {
  894. PrintMessageFromModule(
  895. g_hModule,
  896. HLP_BRIDGE_USE_GUI,
  897. CMD_UNINSTALL
  898. );
  899. return NO_ERROR;
  900. }