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.

1048 lines
22 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. caller.c
  5. Abstract:
  6. Calls the entry points for a specific DLL.
  7. Author:
  8. Jim Schmidt (jimschm) 14-Jan-1998
  9. Revision History:
  10. jimschm 23-Sep-1998 Updated for new IPC mechanism
  11. --*/
  12. #include "pch.h"
  13. #include "plugin.h"
  14. #include "migdllp.h"
  15. #define DBG_MIGDLLS "MigDLLs"
  16. //
  17. // Globals
  18. //
  19. PBYTE g_Data;
  20. DWORD g_DataSize;
  21. BOOL g_UseMigIsol = TRUE;
  22. TCHAR g_OldDirectory[MAX_TCHAR_PATH];
  23. HINSTANCE g_MigDllLib;
  24. P_QUERY_VERSION TestQueryVersion;
  25. P_INITIALIZE_9X TestInitialize9x;
  26. P_MIGRATE_USER_9X TestMigrateUser9x;
  27. P_MIGRATE_SYSTEM_9X TestMigrateSystem9x;
  28. P_INITIALIZE_NT TestInitializeNT;
  29. P_MIGRATE_USER_NT TestMigrateUserNT;
  30. P_MIGRATE_SYSTEM_NT TestMigrateSystemNT;
  31. PCSTR g_DllName;
  32. CHAR g_DllPath[MAX_MBCHAR_PATH];
  33. //
  34. // Local prototypes
  35. //
  36. VOID
  37. pFreeGlobalIpcBuffer (
  38. VOID
  39. );
  40. DWORD
  41. pFinishHandshake9x(
  42. VOID
  43. );
  44. //
  45. // Implementation
  46. //
  47. BOOL
  48. OpenMigrationDll (
  49. IN PCSTR MigrationDllPath,
  50. IN PCSTR WorkingDir
  51. )
  52. {
  53. CHAR MigIsolPath[MAX_MBCHAR_PATH];
  54. PCSTR TempDir;
  55. StringCopyA (g_DllPath, MigrationDllPath);
  56. if (!g_DllName) {
  57. g_DllName = g_DllPath;
  58. }
  59. GetCurrentDirectory (MAX_TCHAR_PATH, g_OldDirectory);
  60. if (!g_UseMigIsol) {
  61. //
  62. // Load the library and verify that all required functions exist
  63. //
  64. g_MigDllLib = LoadLibrary (MigrationDllPath);
  65. if (!g_MigDllLib) {
  66. return FALSE;
  67. }
  68. TestQueryVersion = (P_QUERY_VERSION) GetProcAddress (g_MigDllLib, PLUGIN_QUERY_VERSION);
  69. TestInitialize9x = (P_INITIALIZE_9X) GetProcAddress (g_MigDllLib, PLUGIN_INITIALIZE_9X);
  70. TestMigrateUser9x = (P_MIGRATE_USER_9X) GetProcAddress (g_MigDllLib, PLUGIN_MIGRATE_USER_9X);
  71. TestMigrateSystem9x = (P_MIGRATE_SYSTEM_9X) GetProcAddress (g_MigDllLib, PLUGIN_MIGRATE_SYSTEM_9X);
  72. TestInitializeNT = (P_INITIALIZE_NT) GetProcAddress (g_MigDllLib, PLUGIN_INITIALIZE_NT);
  73. TestMigrateUserNT = (P_MIGRATE_USER_NT) GetProcAddress (g_MigDllLib, PLUGIN_MIGRATE_USER_NT);
  74. TestMigrateSystemNT = (P_MIGRATE_SYSTEM_NT) GetProcAddress (g_MigDllLib, PLUGIN_MIGRATE_SYSTEM_NT);
  75. if (!TestQueryVersion ||
  76. !TestInitialize9x ||
  77. !TestMigrateUser9x ||
  78. !TestMigrateSystem9x ||
  79. !TestInitializeNT ||
  80. !TestMigrateUserNT ||
  81. !TestMigrateSystemNT
  82. ) {
  83. FreeLibrary (g_MigDllLib);
  84. g_MigDllLib = NULL;
  85. return FALSE;
  86. }
  87. } else {
  88. //
  89. // Generate path to migisol.exe, installed by the copy thread in UI
  90. //
  91. TempDir = ConvertAtoT (g_TempDir);
  92. MYASSERT (TempDir);
  93. wsprintfA (MigIsolPath, "%s\\%s", TempDir, S_MIGISOL_EXE);
  94. FreeAtoT (TempDir);
  95. if (!OpenIpc (
  96. TRUE, // TRUE: Win95 side
  97. MigIsolPath,
  98. MigrationDllPath,
  99. WorkingDir
  100. )) {
  101. LOG ((
  102. LOG_WARNING,
  103. "Can't establish IPC connection for %s",
  104. MigrationDllPath
  105. ));
  106. return FALSE;
  107. }
  108. }
  109. return TRUE;
  110. }
  111. VOID
  112. CloseMigrationDll (
  113. VOID
  114. )
  115. {
  116. if (!g_UseMigIsol) {
  117. if (g_MigDllLib) {
  118. FreeLibrary (g_MigDllLib);
  119. g_MigDllLib = NULL;
  120. }
  121. SetCurrentDirectory (g_OldDirectory);
  122. } else {
  123. CloseIpc();
  124. }
  125. pFreeGlobalIpcBuffer();
  126. }
  127. BOOL
  128. pValidateBinary (
  129. IN PBYTE Data,
  130. IN UINT Size
  131. )
  132. {
  133. BYTE Remember;
  134. if (!Data || !Size) {
  135. return TRUE;
  136. }
  137. __try {
  138. Remember = Data[0];
  139. Data[0] = Remember;
  140. Remember = Data[Size - 1];
  141. Data[Size - 1] = Remember;
  142. }
  143. __except (TRUE) {
  144. DEBUGMSG ((DBG_MIGDLLS, "pValidateBinary failed for %u bytes", Size));
  145. return FALSE;
  146. }
  147. return TRUE;
  148. }
  149. BOOL
  150. pValidateNonNullString (
  151. IN PCSTR String
  152. )
  153. {
  154. __try {
  155. SizeOfStringA (String);
  156. if (*String == 0) {
  157. DEBUGMSG ((DBG_MIGDLLS, "pValidateNonNullString found zero-length string"));
  158. return FALSE;
  159. }
  160. }
  161. __except (TRUE) {
  162. DEBUGMSG ((DBG_MIGDLLS, "pValidateNonNullString failed"));
  163. return FALSE;
  164. }
  165. return TRUE;
  166. }
  167. BOOL
  168. pValidateIntArray (
  169. IN PINT Array
  170. )
  171. {
  172. PINT End;
  173. if (!Array) {
  174. return TRUE;
  175. }
  176. __try {
  177. End = Array;
  178. while (*End != -1) {
  179. End++;
  180. }
  181. }
  182. __except (TRUE) {
  183. DEBUGMSG ((DBG_MIGDLLS, "Int Array is invalid (or not terminated with -1)"));
  184. return FALSE;
  185. }
  186. return TRUE;
  187. }
  188. BOOL
  189. pValidateMultiString (
  190. IN PCSTR Strings
  191. )
  192. {
  193. if (!Strings) {
  194. return TRUE;
  195. }
  196. __try {
  197. while (*Strings) {
  198. Strings = GetEndOfStringA (Strings) + 1;
  199. }
  200. }
  201. __except (TRUE) {
  202. DEBUGMSG ((DBG_MIGDLLS, "pValidateMultiString failed"));
  203. return FALSE;
  204. }
  205. return TRUE;
  206. }
  207. DWORD
  208. pRemoteQueryVersion(
  209. OUT PCSTR *ProductId,
  210. OUT PUINT DllVersion,
  211. OUT PDWORD *CodePageArray,
  212. OUT PCSTR *ExeNamesBuf,
  213. IN PCSTR WorkingDir,
  214. OUT PVENDORINFO *VendorInfo
  215. )
  216. {
  217. PBYTE DataPtr;
  218. INT ReturnArraySize;
  219. PDWORD ReturnArray;
  220. DWORD rc = ERROR_SUCCESS;
  221. GROWBUFFER GrowBuf = GROWBUF_INIT;
  222. PCTSTR p;
  223. DWORD DataSize;
  224. //
  225. // Free any previous data... but do not free before we return, because the
  226. // new data buffer will be used directly by the caller. (The caller will
  227. // make copies of all the settings.)
  228. //
  229. pFreeGlobalIpcBuffer();
  230. __try {
  231. //
  232. // Send the working directory, since migisol will need to set this before
  233. // calling QueryVersion.
  234. //
  235. MultiSzAppendA (&GrowBuf, WorkingDir);
  236. DEBUGMSG ((DBG_MIGDLLS, "Calling QueryVersion via migisol.exe"));
  237. if (!SendIpcCommand (
  238. IPC_QUERY,
  239. GrowBuf.Buf,
  240. GrowBuf.End
  241. )) {
  242. LOG ((LOG_ERROR,"pRemoteQueryVersion failed to send command"));
  243. rc = GetLastError();
  244. __leave;
  245. }
  246. //
  247. // Finish transaction. Caller will interpret return code.
  248. //
  249. DEBUGMSG ((DBG_MIGDLLS, "Getting results from migisol.exe"));
  250. rc = pFinishHandshake9x();
  251. //
  252. // Unpack the buffer, if received.
  253. //
  254. if (g_Data) {
  255. DEBUGMSG ((DBG_MIGDLLS, "Parsing QueryVersion return data"));
  256. __try {
  257. DataPtr = g_Data;
  258. //
  259. // Unpack product ID
  260. //
  261. *ProductId = DataPtr;
  262. DataPtr = GetEndOfStringA ((PCSTR) DataPtr) + 1;
  263. //
  264. // Unpack DLL version
  265. //
  266. *DllVersion = *((PINT) DataPtr);
  267. DataPtr += sizeof(INT);
  268. //
  269. // Unpack the CP array
  270. //
  271. ReturnArraySize = *((PINT) DataPtr);
  272. DataPtr += sizeof(INT);
  273. if (ReturnArraySize) {
  274. ReturnArray = (PDWORD) DataPtr;
  275. DataPtr += ReturnArraySize * sizeof (DWORD);
  276. } else {
  277. ReturnArray = NULL;
  278. }
  279. *CodePageArray = ReturnArray;
  280. //
  281. // Unpack Exe name buffer
  282. //
  283. *ExeNamesBuf = (PCSTR) DataPtr;
  284. p = *ExeNamesBuf;
  285. while (*p) {
  286. p = GetEndOfStringA (p) + 1;
  287. }
  288. DataPtr = (PBYTE) (p + 1);
  289. *VendorInfo = *((PVENDORINFO *) DataPtr);
  290. DataPtr += sizeof (PVENDORINFO);
  291. DEBUGMSG ((DBG_MIGDLLS, "Unpacked VendorInfo pointer is 0x%X", *VendorInfo));
  292. if (*VendorInfo) {
  293. DataSize = *((PDWORD) DataPtr);
  294. DataPtr += sizeof (DWORD);
  295. MYASSERT (DataSize == sizeof (VENDORINFO));
  296. *VendorInfo = (PVENDORINFO) PoolMemDuplicateMemory (g_MigDllPool, DataPtr, sizeof (VENDORINFO));
  297. DataPtr += sizeof (VENDORINFO);
  298. }
  299. DEBUGMSG ((DBG_MIGDLLS, "QueryVersion is complete, rc=%u", rc));
  300. }
  301. __except(TRUE) {
  302. LOG ((LOG_ERROR, "An error occurred while unpacking params"));
  303. rc = ERROR_INVALID_PARAMETER;
  304. }
  305. } else {
  306. DEBUGMSG ((DBG_WARNING, "pRemoteQueryVersion: No OUT params received"));
  307. //
  308. // We should never return ERROR_SUCCESS if no buffer is received.
  309. //
  310. if (rc == ERROR_SUCCESS) {
  311. rc = ERROR_INVALID_PARAMETER;
  312. }
  313. }
  314. }
  315. __finally {
  316. FreeGrowBuffer (&GrowBuf);
  317. }
  318. return rc;
  319. }
  320. DWORD
  321. pRemoteInitialize9x(
  322. IN PCSTR WorkingDir,
  323. IN PCSTR SourceDirs,
  324. PVOID *Reserved,
  325. DWORD SizeOfReserved
  326. )
  327. {
  328. DWORD rc = ERROR_SUCCESS;
  329. GROWBUFFER GrowBuf = GROWBUF_INIT;
  330. PCSTR p;
  331. PBYTE Data;
  332. DWORD ReturnSize;
  333. pFreeGlobalIpcBuffer();
  334. __try {
  335. //
  336. // Send working dir and source dirs
  337. //
  338. MultiSzAppendA (&GrowBuf, WorkingDir);
  339. for (p = SourceDirs ; *p ; p = GetEndOfStringA (p) + 1) {
  340. MultiSzAppendA (&GrowBuf, p);
  341. }
  342. MultiSzAppendA (&GrowBuf, p);
  343. GrowBufAppendDword (&GrowBuf, SizeOfReserved);
  344. if (SizeOfReserved) {
  345. Data = GrowBuffer (&GrowBuf, SizeOfReserved);
  346. CopyMemory (Data, *Reserved, SizeOfReserved);
  347. }
  348. //
  349. // Send command to migisol
  350. //
  351. if (!SendIpcCommand (
  352. IPC_INITIALIZE,
  353. GrowBuf.Buf,
  354. GrowBuf.End
  355. )) {
  356. LOG ((LOG_ERROR,"pRemoteInitialize9x failed to send command"));
  357. rc = GetLastError();
  358. __leave;
  359. }
  360. //
  361. // Finish transaction. Caller will interpret return code.
  362. //
  363. rc = pFinishHandshake9x();
  364. //
  365. // The reserved parameter may come back
  366. //
  367. if (g_Data) {
  368. Data = g_Data;
  369. ReturnSize = *((PDWORD) Data);
  370. if (ReturnSize) {
  371. Data += sizeof (DWORD);
  372. CopyMemory (*Reserved, Data, ReturnSize);
  373. } else if (SizeOfReserved) {
  374. ZeroMemory (*Reserved, SizeOfReserved);
  375. }
  376. }
  377. }
  378. __finally {
  379. FreeGrowBuffer (&GrowBuf);
  380. }
  381. return rc;
  382. }
  383. VOID
  384. pGetParentWindowTitleAndId (
  385. IN HWND ParentWnd,
  386. OUT PSTR TitleBuf,
  387. OUT PDWORD IdPtr
  388. )
  389. {
  390. *IdPtr = 0;
  391. if (ParentWnd) {
  392. GetWindowTextA (ParentWnd, TitleBuf, MAX_PATH);
  393. GetWindowThreadProcessId (ParentWnd, IdPtr);
  394. } else {
  395. TitleBuf[0] = 0;
  396. }
  397. }
  398. DWORD
  399. pRemoteMigrateUser9x (
  400. IN HWND ParentWnd, OPTIONAL
  401. IN PCSTR UnattendFile,
  402. IN PCSTR RootKey,
  403. IN PCSTR User OPTIONAL
  404. )
  405. {
  406. DWORD rc = ERROR_SUCCESS;
  407. GROWBUFFER GrowBuf = GROWBUF_INIT;
  408. CHAR ParentWindowTitle[MAX_PATH];
  409. DWORD ProcessId;
  410. pGetParentWindowTitleAndId (ParentWnd, ParentWindowTitle, &ProcessId);
  411. pFreeGlobalIpcBuffer();
  412. __try {
  413. MultiSzAppendA (&GrowBuf, ParentWindowTitle);
  414. GrowBufAppendDword (&GrowBuf, ProcessId);
  415. MultiSzAppendA (&GrowBuf, UnattendFile);
  416. MultiSzAppendA (&GrowBuf, RootKey);
  417. MultiSzAppendA (&GrowBuf, (NULL == User ? S_EMPTY : User));
  418. if (!SendIpcCommand (
  419. IPC_MIGRATEUSER,
  420. GrowBuf.Buf,
  421. GrowBuf.End
  422. )) {
  423. LOG ((LOG_ERROR, "pRemoteMigrateUser9x failed to send command"));
  424. rc = GetLastError();
  425. __leave;
  426. }
  427. //
  428. // Complete the transaction. The caller will interpret the return
  429. // value.
  430. //
  431. rc = pFinishHandshake9x();
  432. //
  433. // No data buffer is coming back at this time
  434. //
  435. }
  436. __finally {
  437. FreeGrowBuffer (&GrowBuf);
  438. }
  439. return rc;
  440. }
  441. DWORD
  442. pRemoteMigrateSystem9x (
  443. IN HWND ParentWnd, OPTIONAL
  444. IN PCSTR UnattendFile
  445. )
  446. {
  447. DWORD rc = ERROR_SUCCESS;
  448. GROWBUFFER GrowBuf = GROWBUF_INIT;
  449. CHAR ParentWindowTitle[MAX_PATH];
  450. DWORD ProcessId;
  451. pGetParentWindowTitleAndId (ParentWnd, ParentWindowTitle, &ProcessId);
  452. pFreeGlobalIpcBuffer();
  453. __try {
  454. MultiSzAppendA (&GrowBuf, ParentWindowTitle);
  455. GrowBufAppendDword (&GrowBuf, ProcessId);
  456. MultiSzAppendA (&GrowBuf, UnattendFile);
  457. if (!SendIpcCommand (
  458. IPC_MIGRATESYSTEM,
  459. GrowBuf.Buf,
  460. GrowBuf.End
  461. )) {
  462. LOG ((LOG_ERROR,"pRemoteMigrateSystem9x failed to send command"));
  463. rc = GetLastError();
  464. __leave;
  465. }
  466. //
  467. // Finish transaction. Caller will interpret return value.
  468. //
  469. rc = pFinishHandshake9x();
  470. //
  471. // No data buffer is coming back at this time
  472. //
  473. }
  474. __finally {
  475. FreeGrowBuffer (&GrowBuf);
  476. }
  477. return rc;
  478. }
  479. VOID
  480. pFreeGlobalIpcBuffer (
  481. VOID
  482. )
  483. {
  484. //
  485. // Free old return param buffer
  486. //
  487. if (g_Data) {
  488. MemFree (g_hHeap, 0, g_Data);
  489. g_Data = NULL;
  490. }
  491. g_DataSize = 0;
  492. }
  493. DWORD
  494. pFinishHandshake9x(
  495. VOID
  496. )
  497. {
  498. DWORD TechnicalLogId;
  499. DWORD GuiLogId;
  500. DWORD rc = ERROR_SUCCESS;
  501. DWORD DataSize = 0;
  502. PBYTE Data = NULL;
  503. BOOL b;
  504. pFreeGlobalIpcBuffer();
  505. do {
  506. b = GetIpcCommandResults (
  507. IPC_GET_RESULTS_WIN9X,
  508. &Data,
  509. &DataSize,
  510. &rc,
  511. &TechnicalLogId,
  512. &GuiLogId
  513. );
  514. if (g_AbortDllEvent) {
  515. if (WaitForSingleObject (g_AbortDllEvent, 0) == WAIT_OBJECT_0) {
  516. rc = ERROR_CANCELLED;
  517. break;
  518. }
  519. }
  520. //
  521. // Loop if no data received, but process is alive
  522. //
  523. if (!b) {
  524. if (!IsIpcProcessAlive()) {
  525. rc = ERROR_NOACCESS;
  526. break;
  527. }
  528. if (*g_CancelFlagPtr) {
  529. rc = ERROR_CANCELLED;
  530. break;
  531. }
  532. }
  533. } while (!b);
  534. if (b) {
  535. //
  536. // Save return param block and loop back for IPC_LOG or IPC_DONE
  537. //
  538. g_DataSize = DataSize;
  539. g_Data = Data;
  540. //
  541. // Recognize log messages
  542. //
  543. if (!CANCELLED()) {
  544. if (TechnicalLogId) {
  545. //
  546. // LOG message with three args: DllDesc, DllPath, User
  547. //
  548. LOG ((
  549. LOG_ERROR,
  550. (PCSTR) TechnicalLogId,
  551. g_DllPath,
  552. g_DllName,
  553. S_EMPTY,
  554. S_EMPTY
  555. ));
  556. }
  557. if (GuiLogId) {
  558. LOG ((
  559. LOG_ERROR,
  560. (PCSTR) GuiLogId,
  561. g_DllPath,
  562. g_DllName,
  563. S_EMPTY,
  564. S_EMPTY
  565. ));
  566. }
  567. }
  568. }
  569. return rc;
  570. }
  571. BOOL
  572. pIsCodePageArrayValid (
  573. IN PDWORD CodePageArray
  574. )
  575. {
  576. DWORD CodePage;
  577. UINT u;
  578. if (!CodePageArray) {
  579. return TRUE;
  580. }
  581. //
  582. // Scan system's code pages
  583. //
  584. CodePage = GetACP();
  585. __try {
  586. for (u = 0 ; CodePageArray[u] != -1 ; u++) {
  587. if (CodePage == CodePageArray[u]) {
  588. return TRUE;
  589. }
  590. }
  591. }
  592. __except (TRUE) {
  593. LOG ((LOG_ERROR, "Caugh an exception while validating array of code pages."));
  594. }
  595. return FALSE;
  596. }
  597. LONG
  598. CallQueryVersion (
  599. IN PCSTR WorkingDir,
  600. OUT PCSTR *ProductId,
  601. OUT PUINT DllVersion,
  602. OUT PCSTR *ExeNamesBuf,
  603. OUT PVENDORINFO *VendorInfo
  604. )
  605. {
  606. PDWORD CodePageArray = NULL;
  607. LONG rc;
  608. if (!g_UseMigIsol) {
  609. //
  610. // Call the entry point directly
  611. //
  612. MYASSERT (TestQueryVersion);
  613. *ProductId = NULL;
  614. *DllVersion = 1;
  615. *ExeNamesBuf = NULL;
  616. *VendorInfo = NULL;
  617. SetCurrentDirectory (WorkingDir);
  618. rc = TestQueryVersion (
  619. ProductId,
  620. DllVersion,
  621. &CodePageArray,
  622. ExeNamesBuf,
  623. VendorInfo
  624. );
  625. } else {
  626. rc = pRemoteQueryVersion (
  627. ProductId,
  628. DllVersion,
  629. &CodePageArray,
  630. ExeNamesBuf,
  631. WorkingDir,
  632. VendorInfo
  633. );
  634. }
  635. DEBUGMSG ((DBG_MIGDLLS, "VendorInfo pointer is 0x%X", *VendorInfo));
  636. if (rc == ERROR_SUCCESS) {
  637. //
  638. // Trim whitespace off of product ID
  639. //
  640. if (pValidateNonNullString (*ProductId)) {
  641. *ProductId = SkipSpace (*ProductId);
  642. if (pValidateBinary ((PBYTE) (*ProductId), SizeOfStringA (*ProductId))) {
  643. TruncateTrailingSpace ((PSTR) (*ProductId));
  644. }
  645. }
  646. //
  647. // Validate inbound parameters
  648. //
  649. if (!pValidateNonNullString (*ProductId) ||
  650. !pValidateIntArray (CodePageArray) ||
  651. !pValidateMultiString (*ExeNamesBuf) ||
  652. !pValidateBinary ((PBYTE) (*VendorInfo), sizeof (VENDORINFO))
  653. ) {
  654. LOG ((LOG_ERROR, "One or more parameters from the DLL are invalid."));
  655. return ERROR_NOT_INSTALLED;
  656. }
  657. if (!pIsCodePageArrayValid (CodePageArray)) {
  658. return ERROR_NOT_INSTALLED;
  659. }
  660. //
  661. // Trim the product ID
  662. //
  663. if (ByteCountA (*ProductId) > MAX_PATH) {
  664. *CharCountToPointerA (*ProductId, MAX_PATH) = 0;
  665. }
  666. //
  667. // Make sure VENDORINFO is valid
  668. //
  669. if (!(*VendorInfo)) {
  670. LOG ((LOG_ERROR, "DLL %s did not provide a VENDORINFO struct", *ProductId));
  671. return ERROR_NOT_INSTALLED;
  672. }
  673. g_DllName = *ProductId;
  674. }
  675. return rc;
  676. }
  677. LONG
  678. CallInitialize9x (
  679. IN PCSTR WorkingDir,
  680. IN PCSTR SourceDirList,
  681. IN OUT PVOID Reserved,
  682. IN DWORD ReservedSize
  683. )
  684. {
  685. LONG rc;
  686. CHAR WorkingDirCopy[MAX_MBCHAR_PATH];
  687. PSTR SourceDirListCopy = NULL;
  688. PCSTR p;
  689. PVOID CopyOfReserved;
  690. if (!g_UseMigIsol) {
  691. //
  692. // Call the entry point directly
  693. //
  694. MYASSERT (TestInitialize9x);
  695. SetCurrentDirectory (WorkingDir);
  696. //
  697. // Make a copy of all the supplied params, so if the migration DLL changes
  698. // them, the rest of the upgrade isn't changed.
  699. //
  700. StringCopyA (WorkingDirCopy, WorkingDir);
  701. p = SourceDirList;
  702. while (*p) {
  703. p = GetEndOfStringA (p) + 1;
  704. }
  705. p++;
  706. SourceDirListCopy = AllocText (p - SourceDirList);
  707. MYASSERT (SourceDirListCopy);
  708. if (SourceDirListCopy) {
  709. CopyMemory (SourceDirListCopy, SourceDirList, p - SourceDirList);
  710. }
  711. //
  712. // Call the entry point
  713. //
  714. rc = TestInitialize9x (
  715. WorkingDirCopy,
  716. SourceDirListCopy,
  717. Reserved
  718. );
  719. FreeText (SourceDirListCopy);
  720. } else {
  721. //
  722. // Call the entry point via migisol.exe. Make a copy of the
  723. // reserved because currently reserved is only an IN (an
  724. // undocumented feature actually).
  725. //
  726. CopyOfReserved = MemAlloc (g_hHeap, 0, ReservedSize);
  727. CopyMemory (CopyOfReserved, Reserved, ReservedSize);
  728. rc = pRemoteInitialize9x (
  729. WorkingDir,
  730. SourceDirList,
  731. &CopyOfReserved,
  732. ReservedSize
  733. );
  734. //
  735. // CopyOfReserved now has the return value. We don't
  736. // use it currently.
  737. //
  738. MemFree (g_hHeap, 0, CopyOfReserved);
  739. }
  740. return rc;
  741. }
  742. LONG
  743. CallMigrateUser9x (
  744. IN HWND ParentWnd,
  745. IN PCSTR UserName,
  746. IN PCSTR UnattendTxt,
  747. IN OUT PVOID Reserved,
  748. IN DWORD ReservedSize
  749. )
  750. {
  751. LONG rc;
  752. CHAR UserNameBuf[MAX_USER_NAME];
  753. CHAR UnattendTxtCopy[MAX_USER_NAME];
  754. PSTR UserNameCopy = NULL;
  755. HKEY UserHandle;
  756. if (!g_UseMigIsol) {
  757. //
  758. // Call the entry point directly
  759. //
  760. MYASSERT (TestMigrateUser9x);
  761. //
  762. // Prepare copies of params
  763. //
  764. if (UserName && *UserName) {
  765. UserNameCopy = UserNameBuf;
  766. StringCopyA (UserNameCopy, UserName);
  767. }
  768. StringCopyA (UnattendTxtCopy, UnattendTxt);
  769. MYASSERT(g_UserKey);
  770. if (!g_UserKey) {
  771. g_UserKey = S_EMPTY;
  772. }
  773. UserHandle = OpenRegKeyStr (g_UserKey);
  774. if (!UserHandle) {
  775. DEBUGMSG ((DBG_WHOOPS, "Cannot open %s", g_UserKey));
  776. return FALSE;
  777. }
  778. //
  779. // Call the migration DLL
  780. //
  781. rc = TestMigrateUser9x (
  782. ParentWnd,
  783. UnattendTxtCopy,
  784. UserHandle,
  785. UserNameCopy,
  786. Reserved
  787. );
  788. } else {
  789. //
  790. // Call the entry point via migisol.exe
  791. //
  792. rc = pRemoteMigrateUser9x (
  793. ParentWnd,
  794. UnattendTxt,
  795. g_UserKey,
  796. UserName
  797. );
  798. }
  799. return rc;
  800. }
  801. LONG
  802. CallMigrateSystem9x (
  803. IN HWND ParentWnd,
  804. IN PCSTR UnattendTxt,
  805. IN PVOID Reserved,
  806. IN DWORD ReservedSize
  807. )
  808. {
  809. LONG rc;
  810. CHAR UnattendTxtCopy[MAX_MBCHAR_PATH];
  811. if (!g_UseMigIsol) {
  812. //
  813. // Call the entry point directly
  814. //
  815. MYASSERT (TestMigrateSystem9x);
  816. StringCopyA (UnattendTxtCopy, UnattendTxt);
  817. rc = TestMigrateSystem9x (
  818. ParentWnd,
  819. UnattendTxtCopy,
  820. Reserved
  821. );
  822. } else {
  823. rc = pRemoteMigrateSystem9x (
  824. ParentWnd,
  825. UnattendTxt
  826. );
  827. }
  828. g_DllName = NULL;
  829. return rc;
  830. }