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.

1258 lines
32 KiB

  1. /*
  2. File Steelhead.c
  3. Implementation of functions to update the registry when an
  4. NT 4.0 Steelhead to NT 5.0 upgrade takes place.
  5. Paul Mayfield, 8/11/97
  6. Copyright 1997 Microsoft.
  7. */
  8. #include "upgrade.h"
  9. #include <wchar.h>
  10. #include <rtcfg.h>
  11. //
  12. // Macro for convenience
  13. //
  14. #define BREAK_ON_ERROR(_err) if ((_err)) break
  15. //
  16. // Defines a function to get nt4.0 interface name from a
  17. // guid.
  18. //
  19. typedef HRESULT (*GetGuidFromInterfaceNameProc)(PWCHAR,LPGUID);
  20. //
  21. // The following define what is needed to infer guids from 4.0
  22. // interface names.
  23. //
  24. WCHAR NetCfgLibName[] = L"netshell.dll";
  25. CHAR GuidProcName[] = "HrGetInstanceGuidOfPreNT5NetCardInstance";
  26. static const WCHAR c_szwInternalAdapter [] = L"Internal";
  27. static const WCHAR c_szwLoopbackAdapter [] = L"Loopback";
  28. GetGuidFromInterfaceNameProc GetGuid = NULL;
  29. // Function uses the application defined parameter to initialize the
  30. // system of mapping old interface names to new ones.
  31. //
  32. DWORD SeedInterfaceNameMapper(
  33. OUT PHANDLE phParam)
  34. {
  35. HINSTANCE hLibModule;
  36. // Load the library
  37. hLibModule = LoadLibraryW(NetCfgLibName);
  38. if (hLibModule == NULL) {
  39. PrintMessage(L"Unable to load NetCfgLibName\n");
  40. return GetLastError();
  41. }
  42. // Get the appropriate function pointers
  43. GetGuid = (GetGuidFromInterfaceNameProc)
  44. GetProcAddress(hLibModule, GuidProcName);
  45. if (GetGuid == NULL) {
  46. PrintMessage(L"Unable to get GuidProcName\n");
  47. return ERROR_CAN_NOT_COMPLETE;
  48. }
  49. // Assign the return value
  50. *phParam = (HANDLE)hLibModule;
  51. return NO_ERROR;
  52. }
  53. //
  54. // Cleans up the interface name mapper.
  55. //
  56. DWORD CleanupInterfaceNameMapper(HANDLE hParam) {
  57. HINSTANCE hLibModule = (HINSTANCE)hParam;
  58. if (hLibModule) {
  59. if (! FreeLibrary(hLibModule))
  60. PrintMessage(L"Unable to free library\n");
  61. }
  62. return NO_ERROR;
  63. }
  64. //
  65. // Determines whether the type of interface being examined
  66. // should have its name changed.
  67. //
  68. BOOL IfNeedsNameUpdate(
  69. IN MPR_INTERFACE_0 * If)
  70. {
  71. // Validate parameters
  72. if (!If) {
  73. PrintMessage(L"Null interface passed to IfNeedsNameUpdate.\n");
  74. return FALSE;
  75. }
  76. // Only lan interfaces can have their names updated
  77. if (If->dwIfType == ROUTER_IF_TYPE_DEDICATED)
  78. return TRUE;
  79. return FALSE;
  80. }
  81. //
  82. // Returns a pointer to the packet name portion of the
  83. // interface name if it exists.
  84. //
  85. PWCHAR FindPacketName(
  86. IN PWCHAR IfName)
  87. {
  88. PWCHAR res;
  89. if ((res = wcsstr(IfName,L"/Ethernet_SNAP")) != NULL)
  90. return res;
  91. if ((res = wcsstr(IfName,L"/Ethernet_II")) != NULL)
  92. return res;
  93. if ((res = wcsstr(IfName,L"/Ethernet_802.2")) != NULL)
  94. return res;
  95. if ((res = wcsstr(IfName,L"/Ethernet_802.3")) != NULL)
  96. return res;
  97. return NULL;
  98. }
  99. //
  100. // Upgrades a packet name from the 4.0 convention to
  101. // the nt5 convention.
  102. //
  103. PWCHAR UpgradePktName(
  104. IN PWCHAR PacketName)
  105. {
  106. PWCHAR res;
  107. if ((res = wcsstr(PacketName,L"/Ethernet_SNAP")) != NULL)
  108. return L"/SNAP";
  109. if ((res = wcsstr(PacketName,L"/Ethernet_II")) != NULL)
  110. return L"/EthII";
  111. if ((res = wcsstr(PacketName,L"/Ethernet_802.2")) != NULL)
  112. return L"/802.2";
  113. if ((res = wcsstr(PacketName,L"/Ethernet_802.3")) != NULL)
  114. return L"/802.3";
  115. return L"";
  116. }
  117. //
  118. // Provides the mapping between old interface names and new guid
  119. // interface names.
  120. //
  121. DWORD UpdateInterfaceName(
  122. IN PWCHAR IName)
  123. {
  124. HRESULT hResult;
  125. GUID Guid;
  126. PWCHAR GuidName=NULL;
  127. PWCHAR PacketName=NULL;
  128. WCHAR SavedPacketName[MAX_INTEFACE_NAME_LEN];
  129. WCHAR SavedIName[MAX_INTEFACE_NAME_LEN];
  130. PWCHAR ptr;
  131. // Validate parameters
  132. if (! IName) {
  133. PrintMessage(L"Invalid parameter to UpdateInterfaceName.\n");
  134. return ERROR_INVALID_PARAMETER;
  135. }
  136. // Save off the packet name if it exists and remove if from the
  137. // interface name
  138. wcscpy(SavedIName, IName);
  139. PacketName = FindPacketName(SavedIName);
  140. if (PacketName) {
  141. wcscpy(SavedPacketName, PacketName);
  142. *PacketName = 0;
  143. }
  144. // Get the guid of the interface name
  145. hResult = (*GetGuid)(SavedIName,&Guid);
  146. if (hResult != S_OK) {
  147. PrintMessage(L"Unable to get guid function.\n");
  148. return ERROR_CAN_NOT_COMPLETE;
  149. }
  150. // Format the guid as a string
  151. if (UuidToStringW(&Guid, &GuidName) != RPC_S_OK) {
  152. PrintMessage(L"Not enough memory to create guid string.\n");
  153. return ERROR_NOT_ENOUGH_MEMORY;
  154. }
  155. // Capitalize the guid string (all letters are hexidecimal
  156. // string characters)
  157. ptr = GuidName;
  158. while (ptr && *ptr) {
  159. if ((*ptr <= L'z') && (*ptr >= L'a'))
  160. *ptr = towupper(*ptr);
  161. ptr++;
  162. }
  163. // Change the interface name according to the new mapping
  164. if (PacketName) {
  165. wsprintf(IName, L"{%s}%s", GuidName, UpgradePktName(SavedPacketName));
  166. }
  167. else
  168. wsprintfW(IName,L"{%s}", GuidName);
  169. // Cleanup
  170. if (GuidName)
  171. RpcStringFreeW(&GuidName);
  172. return NO_ERROR;
  173. }
  174. //
  175. // Provides the mapping between old interface names and new guid
  176. // interface names.
  177. //
  178. DWORD UpdateIpxAdapterName(PWCHAR AName) {
  179. HRESULT hResult;
  180. GUID Guid;
  181. PWCHAR GuidName = NULL;
  182. PWCHAR PacketName = NULL;
  183. WCHAR SavedAName[MAX_INTEFACE_NAME_LEN];
  184. PWCHAR ptr = NULL;
  185. // Validate parameters
  186. if (!AName) {
  187. PrintMessage(L"Invalid parameter to UpdateIpxAdapterName.\n");
  188. return ERROR_INVALID_PARAMETER;
  189. }
  190. // Adapter names do not have packet types associated with them
  191. if (FindPacketName(AName))
  192. return ERROR_CAN_NOT_COMPLETE;
  193. // Get the guid of the interface name
  194. hResult = (*GetGuid)(AName,&Guid);
  195. if (hResult!=S_OK) {
  196. PrintMessage(L"GetGuid function returned failure.\n");
  197. return ERROR_CAN_NOT_COMPLETE;
  198. }
  199. // Format the guid as a string
  200. if (UuidToStringW(&Guid,&GuidName) != RPC_S_OK) {
  201. PrintMessage(L"Uuid to string failed.\n");
  202. return ERROR_NOT_ENOUGH_MEMORY;
  203. }
  204. // Capitalize the guid string
  205. ptr = GuidName;
  206. while (ptr && *ptr) {
  207. if ((*ptr <= L'z') && (*ptr >= L'a'))
  208. *ptr = towupper(*ptr);
  209. ptr++;
  210. }
  211. // Change the adapter name according to the new mapping
  212. wsprintfW(AName, L"{%s}", GuidName);
  213. // Cleanup
  214. if (GuidName)
  215. RpcStringFreeW(&GuidName);
  216. return NO_ERROR;
  217. }
  218. //
  219. // Update the interface name stored in the adapter info blob
  220. //
  221. DWORD UpdateIpxAdapterInfo(
  222. IN PIPX_ADAPTER_INFO AdapterInfop,
  223. OUT PIPX_ADAPTER_INFO * NewAdapterInfop,
  224. OUT DWORD * NewSize)
  225. {
  226. DWORD dwErr;
  227. // Validate parameters
  228. if (! (AdapterInfop && NewAdapterInfop && NewSize)) {
  229. PrintMessage(L"Invalid params to UpdateIpxAdapterInfo.\n");
  230. return ERROR_INVALID_PARAMETER;
  231. }
  232. // Allocate a new adapter
  233. *NewAdapterInfop = (PIPX_ADAPTER_INFO)
  234. UtlAlloc(sizeof(IPX_ADAPTER_INFO));
  235. if (! (*NewAdapterInfop)) {
  236. PrintMessage(L"Unable to allocate NewAdapterInfo.\n");
  237. return ERROR_NOT_ENOUGH_MEMORY;
  238. }
  239. // Copy into the new interface name
  240. (*NewAdapterInfop)->PacketType = AdapterInfop->PacketType;
  241. wcscpy(
  242. (*NewAdapterInfop)->AdapterName,
  243. AdapterInfop->AdapterName);
  244. // Update the interface name
  245. dwErr = UpdateIpxAdapterName((*NewAdapterInfop)->AdapterName);
  246. if (dwErr != NO_ERROR) {
  247. PrintMessage(L"UpdateIpxAdapterName failed.\n");
  248. return dwErr;
  249. }
  250. *NewSize = sizeof(IPX_ADAPTER_INFO);
  251. return NO_ERROR;
  252. }
  253. //
  254. // Update all of the ipx related interface
  255. // information in the router configuration
  256. //
  257. DWORD UpdateIpxIfData(
  258. IN HANDLE hConfig,
  259. IN HANDLE hInterface)
  260. {
  261. PIPX_ADAPTER_INFO AdapterInfop;
  262. PIPX_ADAPTER_INFO NewAdapterInfop;
  263. DWORD dwErr, dwCount, dwSize, dwNewSize, dwTransSize;
  264. HANDLE hTransport;
  265. LPBYTE pTransInfo = NULL, pNewInfo = NULL;
  266. // Validate parameters
  267. if (!hConfig || !hInterface)
  268. {
  269. PrintMessage(L"Invalid params passed to UpdateIpxIfData.\n");
  270. return ERROR_INVALID_PARAMETER;
  271. }
  272. do {
  273. // Update the ipx interface info since this protocol
  274. // stores interface specific info in the transport
  275. // info blob (shame shame).
  276. dwErr = MprConfigInterfaceTransportGetHandle(
  277. hConfig,
  278. hInterface,
  279. PID_IPX,
  280. &hTransport);
  281. if (dwErr != NO_ERROR)
  282. break;
  283. // Update the adapter info blob
  284. dwErr = MprConfigInterfaceTransportGetInfo(
  285. hConfig,
  286. hInterface,
  287. hTransport,
  288. &pTransInfo,
  289. &dwTransSize);
  290. if (dwErr != NO_ERROR) {
  291. PrintMessage(L"Unable to get transport info for ipx.\n");
  292. break;
  293. }
  294. // Get the adapter info associated with this interface
  295. dwErr = MprInfoBlockFind(
  296. pTransInfo,
  297. IPX_ADAPTER_INFO_TYPE,
  298. &dwSize,
  299. &dwCount,
  300. (LPBYTE*)&AdapterInfop);
  301. if (dwErr != NO_ERROR) {
  302. PrintMessage(L"ERROR - null adapter information.\n");
  303. break;
  304. }
  305. // Change the name of the referenced adapter
  306. dwErr = UpdateIpxAdapterInfo(AdapterInfop, &NewAdapterInfop, &dwNewSize);
  307. if (dwErr != NO_ERROR) {
  308. PrintMessage(L"UpdateIpxAdapterInfo failed.\n");
  309. break;
  310. }
  311. dwErr = MprInfoBlockSet(
  312. pTransInfo,
  313. IPX_ADAPTER_INFO_TYPE,
  314. dwNewSize,
  315. 1,
  316. (LPVOID)NewAdapterInfop,
  317. &pNewInfo);
  318. if (dwErr != NO_ERROR) {
  319. PrintMessage(L"MprInfoBlockSet failed.\n");
  320. break;
  321. }
  322. dwNewSize = ((PRTR_INFO_BLOCK_HEADER)pNewInfo)->Size;
  323. // Commit the change
  324. dwErr = MprConfigInterfaceTransportSetInfo(
  325. hConfig,
  326. hInterface,
  327. hTransport,
  328. pNewInfo,
  329. dwNewSize);
  330. if (dwErr != NO_ERROR) {
  331. PrintMessage(L"Unable to set ipx transport info.\n");
  332. break;
  333. }
  334. } while (FALSE);
  335. // Cleanup
  336. {
  337. if (pTransInfo)
  338. MprConfigBufferFree(pTransInfo);
  339. if (pNewInfo)
  340. MprConfigBufferFree(pNewInfo);
  341. }
  342. return dwErr;
  343. }
  344. //
  345. // Updates the ip interface info
  346. //
  347. DWORD
  348. UpdateIpIfData(
  349. IN HANDLE hConfig,
  350. IN HANDLE hInterface)
  351. {
  352. PMIB_IPFORWARDROW pRoutes;
  353. DWORD dwErr, dwCount, dwSize, dwNewSize, dwTransSize, dwInd;
  354. HANDLE hTransport;
  355. LPBYTE pTransInfo = NULL, pNewInfo = NULL;
  356. pRoutes = NULL;
  357. // Validate parameters
  358. if (!hConfig || !hInterface)
  359. {
  360. PrintMessage(L"Invalid params passed to UpdateIpIfData.\n");
  361. return ERROR_INVALID_PARAMETER;
  362. }
  363. do {
  364. // Update the ipx interface info since this protocol
  365. // stores interface specific info in the transport
  366. // info blob (shame shame).
  367. dwErr = MprConfigInterfaceTransportGetHandle(
  368. hConfig,
  369. hInterface,
  370. PID_IP,
  371. &hTransport);
  372. if (dwErr != NO_ERROR)
  373. break;
  374. // Update the adapter info blob
  375. dwErr = MprConfigInterfaceTransportGetInfo(
  376. hConfig,
  377. hInterface,
  378. hTransport,
  379. &pTransInfo,
  380. &dwTransSize);
  381. if (dwErr != NO_ERROR) {
  382. PrintMessage(L"Unable to get transport info for ip.\n");
  383. break;
  384. }
  385. // Get the adapter info associated with this interface
  386. dwErr = MprInfoBlockFind(
  387. pTransInfo,
  388. IP_ROUTE_INFO,
  389. &dwSize,
  390. &dwCount,
  391. (LPBYTE*)&pRoutes);
  392. if (dwErr != NO_ERROR) {
  393. PrintMessage(L"Unable to find ip route info.\n");
  394. break;
  395. }
  396. // Update the protocol id's
  397. for(dwInd = 0; dwInd < dwCount; dwInd++)
  398. {
  399. if((pRoutes[dwInd].dwForwardProto == MIB_IPPROTO_LOCAL) ||
  400. (pRoutes[dwInd].dwForwardProto == MIB_IPPROTO_NETMGMT))
  401. {
  402. pRoutes[dwInd].dwForwardProto = MIB_IPPROTO_NT_STATIC;
  403. }
  404. }
  405. // Commit the info
  406. dwErr = MprInfoBlockSet(
  407. pTransInfo,
  408. IP_ROUTE_INFO,
  409. dwSize,
  410. dwCount,
  411. (LPVOID)pRoutes,
  412. &pNewInfo);
  413. if (dwErr != NO_ERROR) {
  414. PrintMessage(L"MprInfoBlockSet failed.\n");
  415. break;
  416. }
  417. dwNewSize = ((PRTR_INFO_BLOCK_HEADER)pNewInfo)->Size;
  418. // Commit the change
  419. dwErr = MprConfigInterfaceTransportSetInfo(
  420. hConfig,
  421. hInterface,
  422. hTransport,
  423. pNewInfo,
  424. dwNewSize);
  425. if (dwErr != NO_ERROR) {
  426. PrintMessage(L"Unable to set ip transport info.\n");
  427. break;
  428. }
  429. } while (FALSE);
  430. // Cleanup
  431. {
  432. if (pTransInfo)
  433. MprConfigBufferFree(pTransInfo);
  434. if (pNewInfo)
  435. MprConfigBufferFree(pNewInfo);
  436. }
  437. return dwErr;
  438. }
  439. //
  440. // Flushes the name in given interface name to the registry.
  441. //
  442. DWORD CommitInterfaceNameChange(
  443. IN MPR_INTERFACE_0 * If)
  444. {
  445. DWORD dwErr;
  446. WCHAR c_szInterfaceName[] = L"InterfaceName";
  447. INTERFACECB* pinterface;
  448. // Validate parameters
  449. if (!If) {
  450. PrintMessage(L"Invalid param to CommitInterfaceNameChange.\n");
  451. return ERROR_INVALID_PARAMETER;
  452. }
  453. // Set the name
  454. pinterface = (INTERFACECB*)If->hInterface;
  455. dwErr = RegSetValueExW(
  456. pinterface->hkey,
  457. c_szInterfaceName,
  458. 0,
  459. REG_SZ,
  460. (LPCSTR)(If->wszInterfaceName),
  461. (lstrlen(If->wszInterfaceName)+1)*sizeof(WCHAR));
  462. if (dwErr != ERROR_SUCCESS)
  463. PrintMessage(L"RegSetValueEx err in CommitIfNameChange.\n");
  464. if (dwErr == ERROR_SUCCESS)
  465. return NO_ERROR;
  466. return dwErr;
  467. }
  468. //
  469. // Creates a default ip interface blob
  470. //
  471. DWORD
  472. IpCreateDefaultInterfaceInfo(
  473. OUT LPBYTE* ppInfo,
  474. OUT LPDWORD lpdwSize)
  475. {
  476. PBYTE pInfo = NULL, pNewInfo = NULL;
  477. DWORD dwErr = NO_ERROR;
  478. //MIB_IPFORWARDROW RouteInfo;
  479. INTERFACE_STATUS_INFO StatusInfo;
  480. RTR_DISC_INFO DiscInfo;
  481. do
  482. {
  483. // Create the blob
  484. //
  485. dwErr = MprInfoCreate(RTR_INFO_BLOCK_VERSION, &pInfo);
  486. BREAK_ON_ERROR(dwErr);
  487. // Add an the route info
  488. //
  489. //ZeroMemory(&RouteInfo, sizeof(RouteInfo));
  490. //dwErr = MprInfoBlockAdd(
  491. // pInfo,
  492. // IP_ROUTE_INFO,
  493. // sizeof(MIB_IPFORWARDROW),
  494. // 1,
  495. // (LPBYTE)&RouteInfo,
  496. // &pNewInfo);
  497. //MprConfigBufferFree(pInfo);
  498. //pInfo = pNewInfo;
  499. //pNewInfo = NULL;
  500. //BREAK_ON_ERROR(dwErr);
  501. // Add an the status info
  502. //
  503. ZeroMemory(&StatusInfo, sizeof(StatusInfo));
  504. StatusInfo.dwAdminStatus = MIB_IF_ADMIN_STATUS_UP;
  505. dwErr = MprInfoBlockAdd(
  506. pInfo,
  507. IP_INTERFACE_STATUS_INFO,
  508. sizeof(INTERFACE_STATUS_INFO),
  509. 1,
  510. (LPBYTE)&StatusInfo,
  511. &pNewInfo);
  512. MprConfigBufferFree(pInfo);
  513. pInfo = pNewInfo;
  514. pNewInfo = NULL;
  515. BREAK_ON_ERROR(dwErr);
  516. // Add an the disc info
  517. //
  518. ZeroMemory(&DiscInfo, sizeof(DiscInfo));
  519. DiscInfo.bAdvertise = FALSE;
  520. DiscInfo.wMaxAdvtInterval = DEFAULT_MAX_ADVT_INTERVAL;
  521. DiscInfo.wMinAdvtInterval = (WORD)
  522. (DEFAULT_MIN_ADVT_INTERVAL_RATIO * DEFAULT_MAX_ADVT_INTERVAL);
  523. DiscInfo.wAdvtLifetime = (WORD)
  524. (DEFAULT_ADVT_LIFETIME_RATIO * DEFAULT_MAX_ADVT_INTERVAL);
  525. DiscInfo.lPrefLevel = DEFAULT_PREF_LEVEL;
  526. dwErr = MprInfoBlockAdd(
  527. pInfo,
  528. IP_ROUTER_DISC_INFO,
  529. sizeof(PRTR_DISC_INFO),
  530. 1,
  531. (LPBYTE)&DiscInfo,
  532. &pNewInfo);
  533. MprConfigBufferFree(pInfo);
  534. pInfo = pNewInfo;
  535. pNewInfo = NULL;
  536. BREAK_ON_ERROR(dwErr);
  537. // Assign the return value
  538. //
  539. *ppInfo = pInfo;
  540. *lpdwSize = ((PRTR_INFO_BLOCK_HEADER)pInfo)->Size;
  541. } while (FALSE);
  542. // Cleanup
  543. {
  544. }
  545. return dwErr;
  546. }
  547. //
  548. // Adds an ip interface blob to the given interface
  549. //
  550. DWORD
  551. IpAddDefaultInfoToInterface(
  552. IN HANDLE hConfig,
  553. IN HANDLE hIf)
  554. {
  555. HANDLE hIfTrans = NULL;
  556. LPBYTE pInfo = NULL;
  557. DWORD dwErr = 0, dwSize = 0;
  558. do
  559. {
  560. // If the transport blob already exists, there's
  561. // nothing to do.
  562. //
  563. dwErr = MprConfigInterfaceTransportGetHandle(
  564. hConfig,
  565. hIf,
  566. PID_IP,
  567. &hIfTrans);
  568. if ((dwErr == NO_ERROR) || (hIfTrans != NULL))
  569. {
  570. dwErr = NO_ERROR;
  571. break;
  572. }
  573. // Create the info blob
  574. //
  575. dwErr = IpCreateDefaultInterfaceInfo(&pInfo, &dwSize);
  576. BREAK_ON_ERROR(dwErr);
  577. // Add the ip transport to the interface
  578. //
  579. dwErr = MprConfigInterfaceTransportAdd(
  580. hConfig,
  581. hIf,
  582. PID_IP,
  583. NULL,
  584. pInfo,
  585. dwSize,
  586. &hIfTrans);
  587. BREAK_ON_ERROR(dwErr);
  588. } while (FALSE);
  589. // Cleanup
  590. {
  591. if (pInfo)
  592. {
  593. MprConfigBufferFree(pInfo);
  594. }
  595. }
  596. return dwErr;
  597. }
  598. //
  599. // Function called to add the loopback and internal interfaces which
  600. // are required if IP was installed and which wouldn't be installed
  601. // in nt4.
  602. //
  603. DWORD
  604. IpCreateLoopbackAndInternalIfs(
  605. IN HANDLE hConfig)
  606. {
  607. DWORD dwErr = NO_ERROR;
  608. MPR_INTERFACE_0 If0, *pIf0 = &If0;
  609. HANDLE hIf = NULL;
  610. do
  611. {
  612. // If the loopback interface is not already installed,
  613. // go ahead and create it
  614. //
  615. dwErr = MprConfigInterfaceGetHandle(
  616. hConfig,
  617. (PWCHAR)c_szwLoopbackAdapter,
  618. &hIf);
  619. if (dwErr != NO_ERROR)
  620. {
  621. // Initialize the loopback interface info
  622. //
  623. ZeroMemory(pIf0, sizeof(MPR_INTERFACE_0));
  624. wcscpy(pIf0->wszInterfaceName, c_szwLoopbackAdapter);
  625. pIf0->hInterface = INVALID_HANDLE_VALUE;
  626. pIf0->fEnabled = TRUE;
  627. pIf0->dwIfType = ROUTER_IF_TYPE_LOOPBACK;
  628. // Create the loopback interface
  629. dwErr = MprConfigInterfaceCreate(hConfig, 0, (LPBYTE)pIf0, &hIf);
  630. BREAK_ON_ERROR(dwErr);
  631. }
  632. // Add an ip interface blob to the interface if not already there
  633. //
  634. dwErr = IpAddDefaultInfoToInterface(hConfig, hIf);
  635. BREAK_ON_ERROR(dwErr);
  636. hIf = NULL;
  637. // Make sure internal interface gets installed
  638. // (will be there if IPX was installed)
  639. //
  640. dwErr = MprConfigInterfaceGetHandle(
  641. hConfig,
  642. (PWCHAR)c_szwInternalAdapter,
  643. &hIf);
  644. if (dwErr != NO_ERROR)
  645. {
  646. // Initialize the internal interface info
  647. //
  648. ZeroMemory(pIf0, sizeof(MPR_INTERFACE_0));
  649. wcscpy(pIf0->wszInterfaceName, c_szwInternalAdapter);
  650. pIf0->hInterface = INVALID_HANDLE_VALUE;
  651. pIf0->fEnabled = TRUE;
  652. pIf0->dwIfType = ROUTER_IF_TYPE_INTERNAL;
  653. // Create the internal interface
  654. dwErr = MprConfigInterfaceCreate(hConfig, 0, (LPBYTE)pIf0, &hIf);
  655. BREAK_ON_ERROR(dwErr);
  656. }
  657. // Add an ip interface blob to the interface if not already there
  658. //
  659. dwErr = IpAddDefaultInfoToInterface(hConfig, hIf);
  660. BREAK_ON_ERROR(dwErr);
  661. } while (FALSE);
  662. // Cleanup
  663. {
  664. }
  665. return dwErr;
  666. }
  667. //
  668. // Callback to interface enumeration function that upgrades
  669. // the interface names.
  670. //
  671. // Returns TRUE to continue the enumeration, FALSE to stop
  672. // it.
  673. //
  674. BOOL SteelHeadUpgradeInterface (
  675. IN HANDLE hConfig,
  676. IN MPR_INTERFACE_0 * pIf,
  677. IN HANDLE hUserData)
  678. {
  679. DWORD dwErr;
  680. do {
  681. if (IfNeedsNameUpdate(pIf))
  682. {
  683. // Update the interface name
  684. dwErr = UpdateInterfaceName(pIf->wszInterfaceName);
  685. if (dwErr != NO_ERROR) {
  686. PrintMessage(L"UpdateIfName failed -- returning error.\n");
  687. UtlPrintErr(GetLastError());
  688. break;
  689. }
  690. // Commit the changed interface name
  691. dwErr = CommitInterfaceNameChange(pIf);
  692. if (dwErr != NO_ERROR) {
  693. PrintMessage(L"CommitInterfaceNameChange failed.\n");
  694. break;
  695. }
  696. // Update the ipx data
  697. UpdateIpxIfData(
  698. hConfig,
  699. pIf->hInterface);
  700. }
  701. // Update the ip data
  702. UpdateIpIfData(
  703. hConfig,
  704. pIf->hInterface);
  705. } while (FALSE);
  706. // Cleanup
  707. {
  708. }
  709. return TRUE;
  710. }
  711. //
  712. // Function UpdateIpxInterfaces
  713. //
  714. // Updates all of the interfaces as needed to
  715. // upgrade the router from steelhead to nt5
  716. //
  717. DWORD UpdateInterfaces() {
  718. DWORD dwErr = NO_ERROR;
  719. HANDLE hConfig = NULL;
  720. do
  721. {
  722. // Enumerate the interfaces, upgrading the interface
  723. // names, etc as we go.
  724. //
  725. dwErr = UtlEnumerateInterfaces(
  726. SteelHeadUpgradeInterface,
  727. NULL);
  728. if (dwErr != NO_ERROR)
  729. {
  730. return dwErr;
  731. }
  732. // If ip is installed, we need to add the loopback and
  733. // internal interface for ip.
  734. dwErr = MprConfigServerConnect(NULL, &hConfig);
  735. if (dwErr != NO_ERROR)
  736. {
  737. break;
  738. }
  739. dwErr = IpCreateLoopbackAndInternalIfs(hConfig);
  740. if (dwErr != NO_ERROR)
  741. {
  742. break;
  743. }
  744. } while (FALSE);
  745. // Cleanup
  746. {
  747. if (hConfig)
  748. {
  749. MprConfigServerDisconnect(hConfig);
  750. }
  751. }
  752. return dwErr;
  753. }
  754. // Copy any values that are in hkSrc but not in hkDst into hkDst.
  755. DWORD MergeRegistryValues(HKEY hkDst, HKEY hkSrc) {
  756. DWORD dwErr, dwCount, dwNameSize, dwDataSize;
  757. DWORD dwType, i, dwCurNameSize, dwCurValSize;
  758. PWCHAR pszNameBuf, pszDataBuf;
  759. // Find out how many values there are in the source
  760. dwErr = RegQueryInfoKey (hkSrc,
  761. NULL,
  762. NULL,
  763. NULL,
  764. NULL,
  765. NULL,
  766. NULL,
  767. &dwCount,
  768. &dwNameSize,
  769. &dwDataSize,
  770. NULL,
  771. NULL);
  772. if (dwErr != ERROR_SUCCESS)
  773. return dwErr;
  774. dwNameSize++;
  775. dwDataSize++;
  776. __try {
  777. // Allocate the buffers
  778. pszNameBuf = (PWCHAR) UtlAlloc(dwNameSize * sizeof(WCHAR));
  779. pszDataBuf = (PWCHAR) UtlAlloc(dwDataSize * sizeof(WCHAR));
  780. if (!pszNameBuf || !pszDataBuf)
  781. return ERROR_NOT_ENOUGH_MEMORY;
  782. // Loop through the values
  783. for (i = 0; i < dwCount; i++) {
  784. dwCurNameSize = dwNameSize;
  785. dwCurValSize = dwDataSize;
  786. // Get the current source value
  787. dwErr = RegEnumValueW(
  788. hkSrc,
  789. i,
  790. pszNameBuf,
  791. &dwCurNameSize,
  792. 0,
  793. &dwType,
  794. (LPBYTE)pszDataBuf,
  795. &dwCurValSize);
  796. if (dwErr != ERROR_SUCCESS)
  797. continue;
  798. // Find out if a value of the same name exists
  799. // in the destination key. If it does, we don't
  800. // overwrite it.
  801. dwErr = RegQueryValueExW(
  802. hkDst,
  803. pszNameBuf,
  804. NULL,
  805. NULL,
  806. NULL,
  807. NULL);
  808. if (dwErr == ERROR_SUCCESS)
  809. continue;
  810. // Copy the value over
  811. RegSetValueExW(
  812. hkDst,
  813. pszNameBuf,
  814. 0,
  815. dwType,
  816. (LPBYTE)pszDataBuf,
  817. dwCurValSize);
  818. }
  819. }
  820. __finally {
  821. if (pszNameBuf)
  822. UtlFree(pszNameBuf);
  823. if (pszDataBuf)
  824. UtlFree(pszDataBuf);
  825. }
  826. return NO_ERROR;
  827. }
  828. // Recursively copies all of the subkeys of the given registry source to the
  829. // given registry destination.
  830. DWORD CopyRegistryKey(
  831. IN HKEY hkDst,
  832. IN HKEY hkSrc,
  833. IN PWCHAR pszSubKey,
  834. IN LPSTR pszTempFile)
  835. {
  836. DWORD dwErr;
  837. HKEY hkSrcTemp;
  838. // Open the subkey in the source
  839. dwErr = RegOpenKeyExW(hkSrc, pszSubKey, 0, KEY_ALL_ACCESS, &hkSrcTemp);
  840. if (dwErr != ERROR_SUCCESS)
  841. return dwErr;
  842. // Save off that subkey in a temporary file
  843. if ((dwErr = RegSaveKeyA(hkSrcTemp, pszTempFile, NULL)) != ERROR_SUCCESS)
  844. return dwErr;
  845. // Copy the saved information into the new key
  846. RegRestoreKeyA(hkDst, pszTempFile, 0);
  847. // Close off the temporary source key
  848. RegCloseKey(hkSrcTemp);
  849. // Delete the temp file
  850. DeleteFileA(pszTempFile);
  851. return NO_ERROR;
  852. }
  853. // Filters which subkeys in the router registry hive should be
  854. // overwritten with saved off values during upgrade.
  855. BOOL OverwriteThisSubkey(PWCHAR pszSubKey) {
  856. if (_wcsicmp(pszSubKey, L"Interfaces") == 0)
  857. return TRUE;
  858. if (_wcsicmp(pszSubKey, L"RouterManagers") == 0)
  859. return TRUE;
  860. return FALSE;
  861. }
  862. // Copy all keys that are in hkSrc but not in hkDst into hkDst.
  863. // By copy we mean all subkeys and values are propagated over.
  864. DWORD MergeRegistryKeys(HKEY hkDst, HKEY hkSrc) {
  865. DWORD dwErr, dwCount, dwNameSize, dwType, i;
  866. DWORD dwCurNameSize, dwDisposition;
  867. char pszTempFile[512], pszTempPath[512];
  868. PWCHAR pszNameBuf;
  869. HKEY hkTemp;
  870. // Create the path to the temp file directory
  871. if (!GetTempPathA(512, pszTempPath))
  872. return GetLastError();
  873. // Create the temp file name
  874. if (!GetTempFileNameA(pszTempPath, "rtr", 0, pszTempFile))
  875. return GetLastError();
  876. // Delete the temp file created with GetTempFileName(...)
  877. DeleteFileA(pszTempFile);
  878. // Find out how many keys there are in the source
  879. dwErr = RegQueryInfoKey (
  880. hkSrc,
  881. NULL,
  882. NULL,
  883. NULL,
  884. &dwCount,
  885. &dwNameSize,
  886. NULL,
  887. NULL,
  888. NULL,
  889. NULL,
  890. NULL,
  891. NULL);
  892. if (dwErr != ERROR_SUCCESS)
  893. return dwErr;
  894. dwNameSize++;
  895. __try {
  896. // Allocate the buffers
  897. pszNameBuf = (PWCHAR) UtlAlloc(dwNameSize * sizeof(WCHAR));
  898. if (!pszNameBuf)
  899. return ERROR_NOT_ENOUGH_MEMORY;
  900. // Loop through the keys
  901. for (i = 0; i < dwCount; i++) {
  902. dwCurNameSize = dwNameSize;
  903. // Get the current source key
  904. dwErr = RegEnumKeyExW(
  905. hkSrc,
  906. i,
  907. pszNameBuf,
  908. &dwCurNameSize,
  909. 0,
  910. NULL,
  911. NULL,
  912. NULL);
  913. if (dwErr != ERROR_SUCCESS)
  914. continue;
  915. // Create the new subkey in the destination
  916. dwErr = RegCreateKeyExW(
  917. hkDst,
  918. pszNameBuf,
  919. 0,
  920. NULL,
  921. REG_OPTION_NON_VOLATILE,
  922. KEY_ALL_ACCESS,
  923. NULL,
  924. &hkTemp,
  925. &dwDisposition);
  926. if (dwErr != ERROR_SUCCESS)
  927. continue;
  928. // If the subkey was created (not opened),
  929. // copy over the key from hkSrc
  930. if (dwDisposition == REG_CREATED_NEW_KEY) {
  931. CopyRegistryKey(
  932. hkTemp,
  933. hkSrc,
  934. pszNameBuf,
  935. pszTempFile);
  936. }
  937. // Otherwise, if this is one of the keys that we
  938. // should overwrite, do so now.
  939. else {
  940. if (OverwriteThisSubkey(pszNameBuf)) {
  941. CopyRegistryKey(
  942. hkTemp,
  943. hkSrc,
  944. pszNameBuf,
  945. pszTempFile);
  946. }
  947. }
  948. // Close up the temporary handles
  949. RegCloseKey(hkTemp);
  950. hkTemp = NULL;
  951. }
  952. }
  953. __finally {
  954. if (pszNameBuf)
  955. UtlFree(pszNameBuf);
  956. }
  957. return NO_ERROR;
  958. }
  959. // Restore the registry from from backup
  960. //
  961. DWORD
  962. RestoreRegistrySteelhead(
  963. IN PWCHAR pszBackup)
  964. {
  965. HKEY hkRouter = NULL, hkRestore = NULL;
  966. DWORD dwErr = NO_ERROR, dwDisposition;
  967. PWCHAR pszRestore = L"Temp";
  968. // Merge the router key values and sub keys with the
  969. // remote access key
  970. do
  971. {
  972. // Get access to the router registry key
  973. //
  974. dwErr = UtlAccessRouterKey(&hkRouter);
  975. if (dwErr != NO_ERROR)
  976. {
  977. PrintMessage(L"Unable to access router key.\n");
  978. break;
  979. }
  980. // Load in the saved router settings
  981. //
  982. dwErr = UtlLoadSavedSettings(
  983. hkRouter,
  984. pszRestore,
  985. pszBackup,
  986. &hkRestore);
  987. if (dwErr != NO_ERROR)
  988. {
  989. break;
  990. }
  991. // Merge all of the values in the restored key
  992. //
  993. dwErr = MergeRegistryValues(hkRouter, hkRestore);
  994. if (dwErr != NO_ERROR)
  995. {
  996. break;
  997. }
  998. // Give yourself backup and restore privilege
  999. //
  1000. UtlSetupBackupPrivelege (TRUE);
  1001. UtlSetupRestorePrivilege(TRUE);
  1002. // Merge all of the keys in the restored key
  1003. //
  1004. dwErr = MergeRegistryKeys(hkRouter, hkRestore);
  1005. if (dwErr != NO_ERROR)
  1006. {
  1007. break;
  1008. }
  1009. } while (FALSE);
  1010. // Cleanup
  1011. {
  1012. if (hkRestore)
  1013. {
  1014. UtlDeleteRegistryTree(hkRestore);
  1015. RegCloseKey(hkRestore);
  1016. RegDeleteKey(hkRouter, pszRestore);
  1017. }
  1018. if (hkRouter)
  1019. {
  1020. RegCloseKey(hkRouter);
  1021. }
  1022. UtlSetupBackupPrivelege (FALSE);
  1023. UtlSetupRestorePrivilege(FALSE);
  1024. }
  1025. return NO_ERROR;
  1026. }
  1027. //
  1028. // Upgrades the remoteaccess registry with the router
  1029. // configuration from nt4.
  1030. //
  1031. DWORD SteelheadToNt5Upgrade (PWCHAR BackupFileName) {
  1032. DWORD dwErr = NO_ERROR;
  1033. HANDLE hMapperParam;
  1034. do
  1035. {
  1036. // Prepare the old interface name -> new if name mapper
  1037. dwErr = SeedInterfaceNameMapper(&hMapperParam);
  1038. if (dwErr != NO_ERROR)
  1039. {
  1040. PrintMessage(L"Unable to seed if name mapper.\n");
  1041. }
  1042. else
  1043. {
  1044. // Copy all of registry data that has been backed up.
  1045. dwErr = RestoreRegistrySteelhead(BackupFileName);
  1046. if (dwErr != NO_ERROR)
  1047. {
  1048. PrintMessage(L"Unable to restore registry.\n");
  1049. }
  1050. else
  1051. {
  1052. // Update all of the interfaces accordingly
  1053. dwErr = UpdateInterfaces();
  1054. if (dwErr != NO_ERROR)
  1055. {
  1056. PrintMessage(L"Unable to update interfaces.\n");
  1057. }
  1058. }
  1059. }
  1060. // Add 'router' usage to all ports
  1061. //
  1062. dwErr = MprPortSetUsage(MPRFLAG_PORT_Router);
  1063. if (dwErr != NO_ERROR)
  1064. {
  1065. PrintMessage(L"Unable to update interfaces.\n");
  1066. }
  1067. // Mark the computer as having been configured
  1068. //
  1069. dwErr = UtlMarkRouterConfigured();
  1070. if (dwErr != NO_ERROR)
  1071. {
  1072. PrintMessage(L"Unable to mark router as configured.\n");
  1073. }
  1074. } while (FALSE);
  1075. // Cleanup
  1076. {
  1077. CleanupInterfaceNameMapper(hMapperParam);
  1078. }
  1079. return dwErr;
  1080. }