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.

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