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.

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