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.

1251 lines
32 KiB

  1. //=============================================================================
  2. // Copyright (c) 2000 Microsoft Corporation
  3. // Abstract:
  4. // This module implements 6to4 configuration commands.
  5. //=============================================================================
  6. #include "precomp.h"
  7. #pragma hdrstop
  8. #define KEY_ENABLE_RESOLUTION L"EnableResolution"
  9. #define KEY_ENABLE_ROUTING L"EnableRouting"
  10. #define KEY_ENABLE_SITELOCALS L"EnableSiteLocals"
  11. #define KEY_RESOLUTION_INTERVAL L"ResolutionInterval"
  12. #define KEY_UNDO_ON_STOP L"UndoOnStop"
  13. #define KEY_RELAY_NAME L"RelayName"
  14. PWCHAR
  15. pwszStateString[] = {
  16. TOKEN_VALUE_DEFAULT,
  17. TOKEN_VALUE_AUTOMATIC,
  18. TOKEN_VALUE_ENABLED,
  19. TOKEN_VALUE_DISABLED,
  20. };
  21. // The guid for this context
  22. //
  23. GUID g_Ip6to4Guid = IP6TO4_GUID;
  24. // The commands supported in this context
  25. //
  26. CMD_ENTRY g_Ip6to4SetCmdTable[] =
  27. {
  28. CREATE_CMD_ENTRY(IP6TO4_SET_INTERFACE,Ip6to4HandleSetInterface),
  29. CREATE_CMD_ENTRY(IP6TO4_SET_RELAY, Ip6to4HandleSetRelay),
  30. CREATE_CMD_ENTRY(IP6TO4_SET_ROUTING, Ip6to4HandleSetRouting),
  31. CREATE_CMD_ENTRY(IP6TO4_SET_STATE, Ip6to4HandleSetState),
  32. };
  33. CMD_ENTRY g_Ip6to4ShowCmdTable[] =
  34. {
  35. CREATE_CMD_ENTRY(IP6TO4_SHOW_INTERFACE,Ip6to4HandleShowInterface),
  36. CREATE_CMD_ENTRY(IP6TO4_SHOW_RELAY, Ip6to4HandleShowRelay),
  37. CREATE_CMD_ENTRY(IP6TO4_SHOW_ROUTING, Ip6to4HandleShowRouting),
  38. CREATE_CMD_ENTRY(IP6TO4_SHOW_STATE, Ip6to4HandleShowState),
  39. };
  40. CMD_GROUP_ENTRY g_Ip6to4CmdGroups[] =
  41. {
  42. CREATE_CMD_GROUP_ENTRY(GROUP_SET, g_Ip6to4SetCmdTable),
  43. CREATE_CMD_GROUP_ENTRY(GROUP_SHOW, g_Ip6to4ShowCmdTable),
  44. };
  45. ULONG g_ulIp6to4NumGroups = sizeof(g_Ip6to4CmdGroups)/sizeof(CMD_GROUP_ENTRY);
  46. CMD_ENTRY g_Ip6to4TopCmds[] =
  47. {
  48. CREATE_CMD_ENTRY(IP6TO4_RESET, Ip6to4HandleReset),
  49. };
  50. ULONG g_ulNumIp6to4TopCmds = sizeof(g_Ip6to4TopCmds)/sizeof(CMD_ENTRY);
  51. #if 0
  52. TOKEN_VALUE AdminStates[] = {
  53. { VAL_AUTOMATIC, TOKEN_AUTOMATIC },
  54. { VAL_ENABLED, TOKEN_ENABLED },
  55. { VAL_DISABLED, TOKEN_DISABLED },
  56. { VAL_DEFAULT, TOKEN_DEFAULT },
  57. };
  58. #endif
  59. BOOL
  60. GetString(
  61. IN HKEY hKey,
  62. IN LPCTSTR lpName,
  63. IN PWCHAR pwszBuff,
  64. IN ULONG ulLength)
  65. {
  66. DWORD dwErr, dwType;
  67. ULONG ulSize, ulValue;
  68. WCHAR buff[NI_MAXHOST];
  69. ulSize = sizeof(ulValue);
  70. dwErr = RegQueryValueEx(hKey, lpName, NULL, &dwType, (PBYTE)pwszBuff,
  71. &ulLength);
  72. if (dwErr != ERROR_SUCCESS) {
  73. return FALSE;
  74. }
  75. if (dwType != REG_SZ) {
  76. return FALSE;
  77. }
  78. return TRUE;
  79. }
  80. ULONG
  81. GetInteger(
  82. IN HKEY hKey,
  83. IN LPCTSTR lpName,
  84. IN ULONG ulDefault)
  85. {
  86. DWORD dwErr, dwType;
  87. ULONG ulSize, ulValue;
  88. char buff[20];
  89. ulSize = sizeof(ulValue);
  90. dwErr = RegQueryValueEx(hKey, lpName, NULL, &dwType, (PBYTE)&ulValue,
  91. &ulSize);
  92. if (dwErr != ERROR_SUCCESS) {
  93. return ulDefault;
  94. }
  95. if (dwType != REG_DWORD) {
  96. return ulDefault;
  97. }
  98. return ulValue;
  99. }
  100. DWORD
  101. SetInteger(
  102. IN HKEY hKey,
  103. IN LPCTSTR lpName,
  104. IN ULONG ulValue)
  105. {
  106. DWORD dwErr;
  107. ULONG ulOldValue;
  108. ulOldValue = GetInteger(hKey, lpName, VAL_DEFAULT);
  109. if (ulValue == ulOldValue) {
  110. return NO_ERROR;
  111. }
  112. if (ulValue == VAL_DEFAULT) {
  113. dwErr = RegDeleteValue(hKey, lpName);
  114. if (dwErr == ERROR_FILE_NOT_FOUND) {
  115. dwErr = NO_ERROR;
  116. }
  117. } else {
  118. dwErr = RegSetValueEx(hKey, lpName, 0, REG_DWORD, (PBYTE)&ulValue,
  119. sizeof(ulValue));
  120. }
  121. return dwErr;
  122. }
  123. DWORD
  124. SetString(
  125. IN HKEY hKey,
  126. IN LPCTSTR lpName,
  127. IN PWCHAR pwcValue)
  128. {
  129. DWORD dwErr;
  130. if (!pwcValue[0] || !_wcsicmp(pwcValue, TOKEN_VALUE_DEFAULT)) {
  131. dwErr = RegDeleteValue(hKey, lpName);
  132. if (dwErr == ERROR_FILE_NOT_FOUND) {
  133. dwErr = NO_ERROR;
  134. }
  135. } else {
  136. dwErr = RegSetValueEx(hKey, lpName, 0, REG_SZ, (PBYTE)pwcValue,
  137. (wcslen(pwcValue)+1) * sizeof(WCHAR));
  138. }
  139. return dwErr;
  140. }
  141. DWORD
  142. WINAPI
  143. Ip6to4StartHelper(
  144. IN CONST GUID *pguidParent,
  145. IN DWORD dwVersion)
  146. /*++
  147. Routine Description
  148. Used to initialize the helper.
  149. Arguments
  150. pguidParent Ifmon's guid
  151. pfnRegisterContext
  152. Return Value
  153. NO_ERROR
  154. other error code
  155. --*/
  156. {
  157. DWORD dwErr = NO_ERROR;
  158. NS_CONTEXT_ATTRIBUTES attMyAttributes;
  159. // Initialize
  160. //
  161. ZeroMemory(&attMyAttributes, sizeof(attMyAttributes));
  162. attMyAttributes.pwszContext = L"6to4";
  163. attMyAttributes.guidHelper = g_Ip6to4Guid;
  164. attMyAttributes.dwVersion = IP6TO4_VERSION;
  165. attMyAttributes.dwFlags = 0;
  166. attMyAttributes.pfnDumpFn = Ip6to4Dump;
  167. attMyAttributes.ulNumTopCmds= g_ulNumIp6to4TopCmds;
  168. attMyAttributes.pTopCmds = (CMD_ENTRY (*)[])&g_Ip6to4TopCmds;
  169. attMyAttributes.ulNumGroups = g_ulIp6to4NumGroups;
  170. attMyAttributes.pCmdGroups = (CMD_GROUP_ENTRY (*)[])&g_Ip6to4CmdGroups;
  171. dwErr = RegisterContext( &attMyAttributes );
  172. if (dwErr != NO_ERROR) {
  173. return dwErr;
  174. }
  175. //
  176. // Register ISATAP context.
  177. //
  178. return IsatapStartHelper(pguidParent, dwVersion);
  179. }
  180. DWORD
  181. Ip6to4PokeService()
  182. {
  183. SC_HANDLE hService, hSCManager;
  184. BOOL bResult;
  185. SERVICE_STATUS ServiceStatus;
  186. DWORD dwErr = NO_ERROR;
  187. hSCManager = OpenSCManager(NULL, NULL, GENERIC_READ);
  188. if (hSCManager == NULL) {
  189. return GetLastError();
  190. }
  191. do {
  192. hService = OpenService(hSCManager, L"6to4", SERVICE_ALL_ACCESS);
  193. if (hService == NULL) {
  194. dwErr = GetLastError();
  195. break;
  196. }
  197. // Tell the 6to4 service to re-read its config info
  198. if (!ControlService(hService,
  199. SERVICE_CONTROL_PARAMCHANGE,
  200. &ServiceStatus)) {
  201. dwErr = GetLastError();
  202. }
  203. CloseServiceHandle(hService);
  204. } while (FALSE);
  205. CloseServiceHandle(hSCManager);
  206. return dwErr;
  207. }
  208. DWORD
  209. Ip6to4StopService()
  210. {
  211. SC_HANDLE hService, hSCManager;
  212. BOOL bResult;
  213. SERVICE_STATUS ServiceStatus;
  214. DWORD dwErr = NO_ERROR;
  215. hSCManager = OpenSCManager(NULL, NULL, GENERIC_READ);
  216. if (hSCManager == NULL) {
  217. return GetLastError();
  218. }
  219. do {
  220. hService = OpenService(hSCManager, L"6to4", SERVICE_ALL_ACCESS);
  221. if (hService == NULL) {
  222. dwErr = GetLastError();
  223. break;
  224. }
  225. // Tell the 6to4 service to stop
  226. if (!ControlService(hService,
  227. SERVICE_CONTROL_STOP,
  228. &ServiceStatus)) {
  229. dwErr = GetLastError();
  230. }
  231. CloseServiceHandle(hService);
  232. } while (FALSE);
  233. CloseServiceHandle(hSCManager);
  234. return dwErr;
  235. }
  236. DWORD
  237. Ip6to4QueryServiceStatus(
  238. IN LPSERVICE_STATUS pStatus)
  239. {
  240. SC_HANDLE hService, hSCManager;
  241. BOOL bResult;
  242. SERVICE_STATUS ServiceStatus;
  243. DWORD dwErr = NO_ERROR;
  244. hSCManager = OpenSCManager(NULL, NULL, GENERIC_READ);
  245. if (hSCManager == NULL) {
  246. return GetLastError();
  247. }
  248. do {
  249. hService = OpenService(hSCManager, L"6to4", GENERIC_READ);
  250. if (hService == NULL) {
  251. dwErr = GetLastError();
  252. break;
  253. }
  254. if (!QueryServiceStatus(hService, pStatus)) {
  255. dwErr = GetLastError();
  256. }
  257. CloseServiceHandle(hService);
  258. } while (FALSE);
  259. CloseServiceHandle(hSCManager);
  260. return dwErr;
  261. }
  262. DWORD
  263. Ip6to4StartService()
  264. {
  265. SC_HANDLE hService, hSCManager;
  266. BOOL bResult;
  267. SERVICE_STATUS ServiceStatus;
  268. DWORD dwErr = NO_ERROR;
  269. hSCManager = OpenSCManager(NULL, NULL, GENERIC_READ);
  270. if (hSCManager == NULL) {
  271. return GetLastError();
  272. }
  273. do {
  274. hService = OpenService(hSCManager, L"6to4", SERVICE_ALL_ACCESS);
  275. if (hService == NULL) {
  276. dwErr = GetLastError();
  277. break;
  278. }
  279. // Tell the 6to4 service to start
  280. if (!StartService(hService, 0, NULL)) {
  281. dwErr = GetLastError();
  282. }
  283. CloseServiceHandle(hService);
  284. } while (FALSE);
  285. CloseServiceHandle(hSCManager);
  286. return dwErr;
  287. }
  288. TOKEN_VALUE rgtvEnums[] = {
  289. { TOKEN_VALUE_AUTOMATIC, VAL_AUTOMATIC },
  290. { TOKEN_VALUE_ENABLED, VAL_ENABLED },
  291. { TOKEN_VALUE_DISABLED, VAL_DISABLED },
  292. { TOKEN_VALUE_DEFAULT, VAL_DEFAULT },
  293. };
  294. #define BM_ENABLE_ROUTING 0x01
  295. #define BM_ENABLE_SITELOCALS 0x02
  296. DWORD
  297. Ip6to4HandleSetInterface(
  298. IN LPCWSTR pwszMachine,
  299. IN OUT LPWSTR *ppwcArguments,
  300. IN DWORD dwCurrentIndex,
  301. IN DWORD dwArgCount,
  302. IN DWORD dwFlags,
  303. IN LPCVOID pvData,
  304. OUT BOOL *pbDone
  305. )
  306. {
  307. DWORD dwErr = NO_ERROR;
  308. HKEY hInterfaces, hIf;
  309. STATE stEnableRouting;
  310. DWORD dwBitVector = 0;
  311. TAG_TYPE pttTags[] = {{TOKEN_NAME, TRUE, FALSE},
  312. {TOKEN_ROUTING, TRUE, FALSE}};
  313. DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
  314. DWORD dwNumArg;
  315. DWORD i;
  316. WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  317. DWORD dwBufferSize = sizeof(wszInterfaceName);
  318. PWCHAR wszIfFriendlyName = NULL;
  319. // Parse arguments
  320. dwErr = PreprocessCommand(g_hModule,
  321. ppwcArguments,
  322. dwCurrentIndex,
  323. dwArgCount,
  324. pttTags,
  325. sizeof(pttTags)/sizeof(TAG_TYPE),
  326. 2,
  327. sizeof(pttTags)/sizeof(TAG_TYPE),
  328. rgdwTagType );
  329. if (dwErr isnot NO_ERROR) {
  330. return dwErr;
  331. }
  332. for (i=0; i<dwArgCount-dwCurrentIndex; i++) {
  333. switch(rgdwTagType[i]) {
  334. case 0: // NAME
  335. dwErr = Connect();
  336. if (dwErr isnot NO_ERROR) {
  337. break;
  338. }
  339. dwErr = GetIfNameFromFriendlyName(ppwcArguments[i + dwCurrentIndex],
  340. wszInterfaceName, &dwBufferSize);
  341. Disconnect();
  342. if (dwErr isnot NO_ERROR)
  343. {
  344. DisplayMessage(g_hModule, EMSG_INVALID_INTERFACE,
  345. ppwcArguments[i + dwCurrentIndex]);
  346. dwErr = ERROR_SUPPRESS_OUTPUT;
  347. break;
  348. }
  349. wszIfFriendlyName = ppwcArguments[i + dwCurrentIndex];
  350. break;
  351. case 1: // STATE
  352. dwErr = MatchEnumTag(NULL,
  353. ppwcArguments[dwCurrentIndex + i],
  354. NUM_TOKENS_IN_TABLE(rgtvEnums),
  355. rgtvEnums,
  356. (PDWORD)&stEnableRouting);
  357. if (dwErr isnot NO_ERROR) {
  358. dwErr = ERROR_INVALID_PARAMETER;
  359. break;
  360. }
  361. dwBitVector |= BM_ENABLE_ROUTING;
  362. break;
  363. default:
  364. dwErr = ERROR_INVALID_SYNTAX;
  365. break;
  366. }
  367. if (dwErr isnot NO_ERROR) {
  368. return dwErr;
  369. }
  370. }
  371. // Now do the sets
  372. dwErr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, KEY_INTERFACES, 0,
  373. NULL, 0, KEY_ALL_ACCESS, NULL, &hInterfaces, NULL);
  374. if (dwErr != NO_ERROR) {
  375. return dwErr;
  376. }
  377. dwErr = RegCreateKeyEx(hInterfaces, wszInterfaceName, 0,
  378. NULL, 0, KEY_ALL_ACCESS, NULL, &hIf, NULL);
  379. if (dwErr != NO_ERROR) {
  380. RegCloseKey(hInterfaces);
  381. return dwErr;
  382. }
  383. if (dwBitVector & BM_ENABLE_ROUTING) {
  384. dwErr = SetInteger(hIf, KEY_ENABLE_ROUTING, stEnableRouting);
  385. if (dwErr != NO_ERROR)
  386. return dwErr;
  387. }
  388. RegCloseKey(hIf);
  389. RegCloseKey(hInterfaces);
  390. Ip6to4PokeService();
  391. return ERROR_OKAY;
  392. }
  393. DWORD
  394. Ip6to4HandleSetRouting(
  395. IN LPCWSTR pwszMachine,
  396. IN OUT LPWSTR *ppwcArguments,
  397. IN DWORD dwCurrentIndex,
  398. IN DWORD dwArgCount,
  399. IN DWORD dwFlags,
  400. IN LPCVOID pvData,
  401. OUT BOOL *pbDone
  402. )
  403. {
  404. DWORD dwErr = NO_ERROR;
  405. HKEY hGlobal;
  406. STATE stEnableRouting;
  407. STATE stEnableSiteLocals;
  408. DWORD dwBitVector = 0;
  409. TAG_TYPE pttTags[] = {{TOKEN_ROUTING, FALSE, FALSE},
  410. {TOKEN_SITELOCALS, FALSE, FALSE}};
  411. DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
  412. DWORD dwNumArg;
  413. DWORD i;
  414. // Parse arguments
  415. dwErr = PreprocessCommand(g_hModule,
  416. ppwcArguments,
  417. dwCurrentIndex,
  418. dwArgCount,
  419. pttTags,
  420. sizeof(pttTags)/sizeof(TAG_TYPE),
  421. 1,
  422. sizeof(pttTags)/sizeof(TAG_TYPE),
  423. rgdwTagType );
  424. if (dwErr isnot NO_ERROR) {
  425. return dwErr;
  426. }
  427. for (i=0; i<dwArgCount-dwCurrentIndex; i++) {
  428. switch(rgdwTagType[i]) {
  429. case 0: // STATE
  430. dwErr = MatchEnumTag(NULL,
  431. ppwcArguments[dwCurrentIndex + i],
  432. NUM_TOKENS_IN_TABLE(rgtvEnums),
  433. rgtvEnums,
  434. (PDWORD)&stEnableRouting);
  435. if (dwErr isnot NO_ERROR) {
  436. dwErr = ERROR_INVALID_PARAMETER;
  437. break;
  438. }
  439. dwBitVector |= BM_ENABLE_ROUTING;
  440. break;
  441. case 1: // SITELOCALS
  442. dwErr = MatchEnumTag(NULL,
  443. ppwcArguments[dwCurrentIndex + i],
  444. NUM_TOKENS_IN_TABLE(rgtvEnums),
  445. rgtvEnums,
  446. (PDWORD)&stEnableSiteLocals);
  447. if (dwErr isnot NO_ERROR) {
  448. dwErr = ERROR_INVALID_PARAMETER;
  449. break;
  450. }
  451. dwBitVector |= BM_ENABLE_SITELOCALS;
  452. break;
  453. default:
  454. dwErr = ERROR_INVALID_SYNTAX;
  455. break;
  456. }
  457. if (dwErr isnot NO_ERROR) {
  458. return dwErr;
  459. }
  460. }
  461. // Now do the sets
  462. dwErr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, KEY_GLOBAL, 0,
  463. NULL, 0, KEY_ALL_ACCESS, NULL, &hGlobal, NULL);
  464. if (dwErr != NO_ERROR) {
  465. return dwErr;
  466. }
  467. if (dwBitVector & BM_ENABLE_ROUTING) {
  468. dwErr = SetInteger(hGlobal, KEY_ENABLE_ROUTING, stEnableRouting);
  469. if (dwErr != NO_ERROR)
  470. return dwErr;
  471. }
  472. if (dwBitVector & BM_ENABLE_SITELOCALS) {
  473. dwErr = SetInteger(hGlobal, KEY_ENABLE_SITELOCALS, stEnableSiteLocals);
  474. if (dwErr != NO_ERROR)
  475. return dwErr;
  476. }
  477. RegCloseKey(hGlobal);
  478. Ip6to4PokeService();
  479. return ERROR_OKAY;
  480. }
  481. #define BM_ENABLE_RESOLUTION 0x01
  482. #define BM_RELAY_NAME 0x02
  483. #define BM_RESOLUTION_INTERVAL 0x04
  484. DWORD
  485. Ip6to4HandleSetRelay(
  486. IN LPCWSTR pwszMachine,
  487. IN OUT LPWSTR *ppwcArguments,
  488. IN DWORD dwCurrentIndex,
  489. IN DWORD dwArgCount,
  490. IN DWORD dwFlags,
  491. IN LPCVOID pvData,
  492. OUT BOOL *pbDone
  493. )
  494. {
  495. DWORD dwErr = NO_ERROR;
  496. HKEY hGlobal;
  497. STATE stEnableResolution;
  498. ULONG ulResolutionInterval;
  499. PWCHAR pwszRelayName;
  500. DWORD dwBitVector = 0;
  501. TAG_TYPE pttTags[] = {{TOKEN_RELAY_NAME, FALSE, FALSE},
  502. {TOKEN_STATE, FALSE, FALSE},
  503. {TOKEN_INTERVAL, FALSE, FALSE}};
  504. DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
  505. DWORD dwNumArg;
  506. DWORD i;
  507. // Parse arguments
  508. dwErr = PreprocessCommand(g_hModule,
  509. ppwcArguments,
  510. dwCurrentIndex,
  511. dwArgCount,
  512. pttTags,
  513. sizeof(pttTags)/sizeof(TAG_TYPE),
  514. 1,
  515. sizeof(pttTags)/sizeof(TAG_TYPE),
  516. rgdwTagType );
  517. if (dwErr isnot NO_ERROR) {
  518. return dwErr;
  519. }
  520. for (i=0; i<dwArgCount-dwCurrentIndex; i++) {
  521. switch(rgdwTagType[i]) {
  522. case 0: // RELAYNAME
  523. pwszRelayName = ppwcArguments[dwCurrentIndex + i];
  524. dwBitVector |= BM_RELAY_NAME;
  525. break;
  526. case 1: // STATE
  527. dwErr = MatchEnumTag(NULL,
  528. ppwcArguments[dwCurrentIndex + i],
  529. NUM_TOKENS_IN_TABLE(rgtvEnums),
  530. rgtvEnums,
  531. (PDWORD)&stEnableResolution);
  532. if (dwErr isnot NO_ERROR) {
  533. dwErr = ERROR_INVALID_PARAMETER;
  534. break;
  535. }
  536. dwBitVector |= BM_ENABLE_RESOLUTION;
  537. break;
  538. case 2: // INTERVAL
  539. ulResolutionInterval = wcstoul(ppwcArguments[dwCurrentIndex + i],
  540. NULL, 10);
  541. dwBitVector |= BM_RESOLUTION_INTERVAL;
  542. break;
  543. default:
  544. dwErr = ERROR_INVALID_SYNTAX;
  545. break;
  546. }
  547. if (dwErr isnot NO_ERROR) {
  548. return dwErr;
  549. }
  550. }
  551. // Now do the sets
  552. dwErr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, KEY_GLOBAL, 0,
  553. NULL, 0, KEY_ALL_ACCESS, NULL, &hGlobal, NULL);
  554. if (dwErr != NO_ERROR) {
  555. return dwErr;
  556. }
  557. if (dwBitVector & BM_ENABLE_RESOLUTION) {
  558. dwErr = SetInteger(hGlobal, KEY_ENABLE_RESOLUTION, stEnableResolution);
  559. if (dwErr != NO_ERROR)
  560. return dwErr;
  561. }
  562. if (dwBitVector & BM_RELAY_NAME) {
  563. dwErr = SetString(hGlobal, KEY_RELAY_NAME, pwszRelayName);
  564. if (dwErr != NO_ERROR)
  565. return dwErr;
  566. }
  567. if (dwBitVector & BM_RESOLUTION_INTERVAL) {
  568. dwErr = SetInteger(hGlobal, KEY_RESOLUTION_INTERVAL, ulResolutionInterval);
  569. if (dwErr != NO_ERROR)
  570. return dwErr;
  571. }
  572. RegCloseKey(hGlobal);
  573. Ip6to4PokeService();
  574. return ERROR_OKAY;
  575. }
  576. #define BM_ENABLE_6TO4 0x01
  577. #define BM_UNDO_ON_STOP 0x02
  578. DWORD
  579. Ip6to4HandleSetState(
  580. IN LPCWSTR pwszMachine,
  581. IN OUT LPWSTR *ppwcArguments,
  582. IN DWORD dwCurrentIndex,
  583. IN DWORD dwArgCount,
  584. IN DWORD dwFlags,
  585. IN LPCVOID pvData,
  586. OUT BOOL *pbDone
  587. )
  588. {
  589. DWORD dwErr = NO_ERROR;
  590. HKEY hGlobal;
  591. STATE stEnable6to4;
  592. STATE stUndoOnStop;
  593. DWORD dwBitVector = 0;
  594. TAG_TYPE pttTags[] = {{TOKEN_STATE, FALSE, FALSE},
  595. {TOKEN_UNDO_ON_STOP, FALSE, FALSE}};
  596. DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
  597. DWORD dwNumArg;
  598. DWORD i;
  599. // Parse arguments
  600. dwErr = PreprocessCommand(g_hModule,
  601. ppwcArguments,
  602. dwCurrentIndex,
  603. dwArgCount,
  604. pttTags,
  605. sizeof(pttTags)/sizeof(TAG_TYPE),
  606. 1,
  607. sizeof(pttTags)/sizeof(TAG_TYPE),
  608. rgdwTagType );
  609. if (dwErr isnot NO_ERROR) {
  610. return dwErr;
  611. }
  612. for (i=0; i<dwArgCount-dwCurrentIndex; i++) {
  613. switch(rgdwTagType[i]) {
  614. case 0: // STATE
  615. dwErr = MatchEnumTag(NULL,
  616. ppwcArguments[dwCurrentIndex + i],
  617. NUM_TOKENS_IN_TABLE(rgtvEnums),
  618. rgtvEnums,
  619. (PDWORD)&stEnable6to4);
  620. if (dwErr isnot NO_ERROR) {
  621. dwErr = ERROR_INVALID_PARAMETER;
  622. break;
  623. }
  624. dwBitVector |= BM_ENABLE_6TO4;
  625. break;
  626. case 1: // UNDOONSTOP
  627. dwErr = MatchEnumTag(NULL,
  628. ppwcArguments[dwCurrentIndex + i],
  629. NUM_TOKENS_IN_TABLE(rgtvEnums),
  630. rgtvEnums,
  631. (PDWORD)&stUndoOnStop);
  632. if (dwErr isnot NO_ERROR) {
  633. dwErr = ERROR_INVALID_PARAMETER;
  634. break;
  635. }
  636. dwBitVector |= BM_UNDO_ON_STOP;
  637. break;
  638. default:
  639. dwErr = ERROR_INVALID_SYNTAX;
  640. break;
  641. }
  642. if (dwErr isnot NO_ERROR) {
  643. return dwErr;
  644. }
  645. }
  646. // Now do the sets
  647. dwErr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, KEY_GLOBAL, 0,
  648. NULL, 0, KEY_ALL_ACCESS, NULL, &hGlobal, NULL);
  649. if (dwErr != NO_ERROR) {
  650. return dwErr;
  651. }
  652. if (dwBitVector & BM_ENABLE_6TO4) {
  653. if (stEnable6to4 == VAL_ENABLED) {
  654. dwErr = Ip6to4StartService();
  655. } else if (stEnable6to4 == VAL_DISABLED) {
  656. dwErr = Ip6to4StopService();
  657. }
  658. }
  659. if (dwBitVector & BM_UNDO_ON_STOP) {
  660. dwErr = SetInteger(hGlobal, KEY_UNDO_ON_STOP, stUndoOnStop);
  661. if (dwErr != NO_ERROR)
  662. return dwErr;
  663. }
  664. RegCloseKey(hGlobal);
  665. Ip6to4PokeService();
  666. return ERROR_OKAY;
  667. }
  668. DWORD
  669. ShowInterfaceConfig(
  670. IN BOOL bDump)
  671. {
  672. DWORD dwErr = NO_ERROR;
  673. HKEY hInterfaces, hIf;
  674. STATE stEnableRouting;
  675. int i;
  676. WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  677. DWORD dwBufferSize;
  678. WCHAR wszIfFriendlyName[MAX_INTERFACE_NAME_LEN + 1];
  679. dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_INTERFACES, 0, GENERIC_READ,
  680. &hInterfaces);
  681. if (dwErr != NO_ERROR) {
  682. if (!bDump) {
  683. DisplayMessage(g_hModule, MSG_IP_NO_ENTRIES);
  684. }
  685. return ERROR_SUPPRESS_OUTPUT;
  686. }
  687. dwErr = Connect();
  688. if (dwErr isnot NO_ERROR) {
  689. return dwErr;
  690. }
  691. for (i=0; ; i++) {
  692. dwBufferSize = MAX_INTERFACE_NAME_LEN + 1;
  693. dwErr = RegEnumKeyEx(hInterfaces, i, wszInterfaceName, &dwBufferSize,
  694. 0, NULL, NULL, NULL);
  695. if (dwErr != NO_ERROR) {
  696. if (dwErr == ERROR_NO_MORE_ITEMS) {
  697. dwErr = NO_ERROR;
  698. }
  699. break;
  700. }
  701. dwBufferSize = sizeof(wszIfFriendlyName);
  702. dwErr = GetFriendlyNameFromIfName(wszInterfaceName,
  703. wszIfFriendlyName,
  704. &dwBufferSize);
  705. if (dwErr != NO_ERROR) {
  706. wcscpy(wszIfFriendlyName, wszInterfaceName);
  707. }
  708. dwErr = RegOpenKeyEx(hInterfaces, wszInterfaceName, 0, GENERIC_READ,
  709. &hIf);
  710. if (dwErr != NO_ERROR) {
  711. break;
  712. }
  713. stEnableRouting = GetInteger(hIf,
  714. KEY_ENABLE_ROUTING,
  715. VAL_DEFAULT);
  716. if (bDump) {
  717. if (stEnableRouting != VAL_DEFAULT) {
  718. DisplayMessageT(DMP_IP6TO4_SET_INTERFACE);
  719. DisplayMessageT(DMP_QUOTED_STRING_ARG,
  720. TOKEN_NAME,
  721. wszIfFriendlyName);
  722. DisplayMessageT(DMP_STRING_ARG,
  723. TOKEN_ROUTING,
  724. pwszStateString[stEnableRouting]);
  725. DisplayMessage(g_hModule, MSG_NEWLINE);
  726. }
  727. } else {
  728. if (i==0) {
  729. DisplayMessage(g_hModule, MSG_INTERFACE_HEADER);
  730. }
  731. DisplayMessage(g_hModule, MSG_INTERFACE_ROUTING_STATE,
  732. pwszStateString[stEnableRouting],
  733. wszIfFriendlyName);
  734. }
  735. }
  736. RegCloseKey(hInterfaces);
  737. Disconnect();
  738. return dwErr;
  739. }
  740. DWORD
  741. Ip6to4HandleShowInterface(
  742. IN LPCWSTR pwszMachine,
  743. IN OUT LPWSTR *ppwcArguments,
  744. IN DWORD dwCurrentIndex,
  745. IN DWORD dwArgCount,
  746. IN DWORD dwFlags,
  747. IN LPCVOID pvData,
  748. OUT BOOL *pbDone
  749. )
  750. {
  751. return ShowInterfaceConfig(FALSE);
  752. }
  753. DWORD
  754. ShowRoutingConfig(
  755. IN BOOL bDump)
  756. {
  757. DWORD dwErr = NO_ERROR;
  758. HKEY hGlobal;
  759. STATE stEnableRouting;
  760. STATE stEnableSiteLocals;
  761. dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_GLOBAL, 0, KEY_QUERY_VALUE,
  762. &hGlobal);
  763. if (dwErr != NO_ERROR) {
  764. hGlobal = INVALID_HANDLE_VALUE;
  765. dwErr = NO_ERROR;
  766. }
  767. stEnableRouting = GetInteger(hGlobal,
  768. KEY_ENABLE_ROUTING,
  769. VAL_DEFAULT);
  770. stEnableSiteLocals = GetInteger(hGlobal,
  771. KEY_ENABLE_SITELOCALS,
  772. VAL_DEFAULT);
  773. RegCloseKey(hGlobal);
  774. if (bDump) {
  775. if ((stEnableRouting != VAL_DEFAULT)
  776. || (stEnableSiteLocals != VAL_DEFAULT)) {
  777. DisplayMessageT(DMP_IP6TO4_SET_ROUTING);
  778. if (stEnableRouting != VAL_DEFAULT) {
  779. DisplayMessageT(DMP_STRING_ARG,
  780. TOKEN_ROUTING,
  781. pwszStateString[stEnableRouting]);
  782. }
  783. if (stEnableSiteLocals != VAL_DEFAULT) {
  784. DisplayMessageT(DMP_STRING_ARG,
  785. TOKEN_SITELOCALS,
  786. pwszStateString[stEnableSiteLocals]);
  787. }
  788. DisplayMessage(g_hModule, MSG_NEWLINE);
  789. }
  790. } else {
  791. DisplayMessage(g_hModule, MSG_ROUTING_STATE,
  792. pwszStateString[stEnableRouting]);
  793. DisplayMessage(g_hModule, MSG_SITELOCALS_STATE,
  794. pwszStateString[stEnableSiteLocals]);
  795. }
  796. return dwErr;
  797. }
  798. DWORD
  799. Ip6to4HandleShowRouting(
  800. IN LPCWSTR pwszMachine,
  801. IN OUT LPWSTR *ppwcArguments,
  802. IN DWORD dwCurrentIndex,
  803. IN DWORD dwArgCount,
  804. IN DWORD dwFlags,
  805. IN LPCVOID pvData,
  806. OUT BOOL *pbDone
  807. )
  808. {
  809. return ShowRoutingConfig(FALSE);
  810. }
  811. DWORD
  812. ShowRelayConfig(
  813. IN BOOL bDump)
  814. {
  815. DWORD dwErr = NO_ERROR;
  816. HKEY hGlobal;
  817. STATE stEnableResolution;
  818. ULONG ulResolutionInterval;
  819. WCHAR pwszRelayName[NI_MAXHOST];
  820. BOOL bHaveRelayName;
  821. dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_GLOBAL, 0, KEY_QUERY_VALUE,
  822. &hGlobal);
  823. if (dwErr != NO_ERROR) {
  824. hGlobal = INVALID_HANDLE_VALUE;
  825. dwErr = NO_ERROR;
  826. }
  827. stEnableResolution = GetInteger(hGlobal,
  828. KEY_ENABLE_RESOLUTION,
  829. VAL_DEFAULT);
  830. bHaveRelayName = GetString(hGlobal, KEY_RELAY_NAME, pwszRelayName,
  831. NI_MAXHOST);
  832. ulResolutionInterval = GetInteger(hGlobal,
  833. KEY_RESOLUTION_INTERVAL,
  834. 0);
  835. RegCloseKey(hGlobal);
  836. if (bDump) {
  837. if (bHaveRelayName || (stEnableResolution != VAL_DEFAULT)
  838. || (ulResolutionInterval > 0)) {
  839. DisplayMessageT(DMP_IP6TO4_SET_RELAY);
  840. if (bHaveRelayName) {
  841. DisplayMessageT(DMP_STRING_ARG, TOKEN_NAME,
  842. pwszRelayName);
  843. }
  844. if (stEnableResolution != VAL_DEFAULT) {
  845. DisplayMessageT(DMP_STRING_ARG,
  846. TOKEN_STATE,
  847. pwszStateString[stEnableResolution]);
  848. }
  849. if (ulResolutionInterval > 0) {
  850. DisplayMessageT(DMP_INTEGER_ARG, TOKEN_INTERVAL,
  851. ulResolutionInterval);
  852. }
  853. DisplayMessage(g_hModule, MSG_NEWLINE);
  854. }
  855. } else {
  856. DisplayMessage(g_hModule, MSG_RELAY_NAME);
  857. if (bHaveRelayName) {
  858. DisplayMessage(g_hModule, MSG_STRING, pwszRelayName);
  859. } else {
  860. DisplayMessage(g_hModule, MSG_STRING, TOKEN_VALUE_DEFAULT);
  861. }
  862. DisplayMessage(g_hModule, MSG_RESOLUTION_STATE,
  863. pwszStateString[stEnableResolution]);
  864. DisplayMessage(g_hModule, MSG_RESOLUTION_INTERVAL);
  865. if (ulResolutionInterval) {
  866. DisplayMessage(g_hModule, MSG_MINUTES, ulResolutionInterval);
  867. } else {
  868. DisplayMessage(g_hModule, MSG_STRING, TOKEN_VALUE_DEFAULT);
  869. }
  870. }
  871. return dwErr;
  872. }
  873. DWORD
  874. Ip6to4HandleShowRelay(
  875. IN LPCWSTR pwszMachine,
  876. IN OUT LPWSTR *ppwcArguments,
  877. IN DWORD dwCurrentIndex,
  878. IN DWORD dwArgCount,
  879. IN DWORD dwFlags,
  880. IN LPCVOID pvData,
  881. OUT BOOL *pbDone
  882. )
  883. {
  884. return ShowRelayConfig(FALSE);
  885. }
  886. DWORD
  887. Ip6to4HandleReset(
  888. IN LPCWSTR pwszMachine,
  889. IN OUT LPWSTR *ppwcArguments,
  890. IN DWORD dwCurrentIndex,
  891. IN DWORD dwArgCount,
  892. IN DWORD dwFlags,
  893. IN LPCVOID pvData,
  894. OUT BOOL *pbDone
  895. )
  896. {
  897. HKEY hGlobal;
  898. DWORD dwErr;
  899. // Nuke global params
  900. dwErr = RegDeleteKey(HKEY_LOCAL_MACHINE, KEY_GLOBAL);
  901. if ((dwErr != NO_ERROR) && (dwErr != ERROR_FILE_NOT_FOUND)) {
  902. return dwErr;
  903. }
  904. // Nuke all interface config
  905. dwErr = SHDeleteKey(HKEY_LOCAL_MACHINE, KEY_INTERFACES);
  906. if ((dwErr != NO_ERROR) && (dwErr != ERROR_FILE_NOT_FOUND)) {
  907. return dwErr;
  908. }
  909. // Start/poke the service
  910. Ip6to4PokeService();
  911. return ERROR_OKAY;
  912. }
  913. DWORD
  914. ShowStateConfig(
  915. IN BOOL bDump)
  916. {
  917. DWORD dwErr = NO_ERROR;
  918. HKEY hGlobal;
  919. STATE stEnable6to4;
  920. STATE stUndoOnStop;
  921. SERVICE_STATUS ServiceStatus;
  922. DWORD dwCurrentState;
  923. dwErr = Ip6to4QueryServiceStatus(&ServiceStatus);
  924. if (dwErr != NO_ERROR) {
  925. return dwErr;
  926. }
  927. if (ServiceStatus.dwCurrentState == SERVICE_STOPPED) {
  928. stEnable6to4 = VAL_DISABLED;
  929. } else {
  930. stEnable6to4 = VAL_ENABLED;
  931. }
  932. dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_GLOBAL, 0, KEY_QUERY_VALUE,
  933. &hGlobal);
  934. if (dwErr != NO_ERROR) {
  935. hGlobal = INVALID_HANDLE_VALUE;
  936. dwErr = NO_ERROR;
  937. }
  938. stUndoOnStop = GetInteger(hGlobal,
  939. KEY_UNDO_ON_STOP,
  940. VAL_DEFAULT);
  941. RegCloseKey(hGlobal);
  942. if (bDump) {
  943. if ((stEnable6to4 != VAL_DEFAULT) || (stUndoOnStop != VAL_DEFAULT)) {
  944. DisplayMessageT(DMP_IP6TO4_SET_STATE);
  945. if (stEnable6to4 != VAL_DEFAULT) {
  946. DisplayMessageT(DMP_STRING_ARG, TOKEN_STATE,
  947. pwszStateString[stEnable6to4]);
  948. }
  949. if (stUndoOnStop != VAL_DEFAULT) {
  950. DisplayMessageT(DMP_STRING_ARG, TOKEN_UNDO_ON_STOP,
  951. pwszStateString[stUndoOnStop]);
  952. }
  953. DisplayMessage(g_hModule, MSG_NEWLINE);
  954. }
  955. } else {
  956. DisplayMessage(g_hModule, MSG_IP6TO4_STATE,
  957. pwszStateString[stEnable6to4]);
  958. DisplayMessage(g_hModule, MSG_UNDO_ON_STOP_STATE,
  959. pwszStateString[stUndoOnStop]);
  960. }
  961. return dwErr;
  962. }
  963. DWORD
  964. Ip6to4HandleShowState(
  965. IN LPCWSTR pwszMachine,
  966. IN OUT LPWSTR *ppwcArguments,
  967. IN DWORD dwCurrentIndex,
  968. IN DWORD dwArgCount,
  969. IN DWORD dwFlags,
  970. IN LPCVOID pvData,
  971. OUT BOOL *pbDone
  972. )
  973. {
  974. return ShowStateConfig(FALSE);
  975. }
  976. DWORD
  977. WINAPI
  978. Ip6to4Dump(
  979. IN LPCWSTR pwszRouter,
  980. IN OUT LPWSTR *ppwcArguments,
  981. IN DWORD dwArgCount,
  982. IN LPCVOID pvData
  983. )
  984. /*++
  985. Routine Description
  986. Used when dumping all contexts
  987. Arguments
  988. Return Value
  989. NO_ERROR
  990. --*/
  991. {
  992. DWORD dwErr;
  993. HANDLE hFile = (HANDLE)-1;
  994. DisplayMessage( g_hModule, DMP_IP6TO4_HEADER );
  995. DisplayMessageT(DMP_IP6TO4_PUSHD);
  996. ShowStateConfig(TRUE);
  997. ShowRelayConfig(TRUE);
  998. ShowRoutingConfig(TRUE);
  999. ShowInterfaceConfig(TRUE);
  1000. DisplayMessageT(DMP_IP6TO4_POPD);
  1001. DisplayMessage( g_hModule, DMP_IP6TO4_FOOTER );
  1002. return NO_ERROR;
  1003. }