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.

1561 lines
36 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. upgwiz.c
  5. Abstract:
  6. Implements a stub tool that is designed to run with Win9x-side
  7. upgrade code.
  8. Author:
  9. <full name> (<alias>) <date>
  10. Revision History:
  11. ovidiut 01/14/99 Reverted calls to underlying libs in pCallEntryPoints ()
  12. when Reason == DLL_PROCESS_DETACH
  13. --*/
  14. #include "pch.h"
  15. typedef UINT (GIVEVERSION_PROTOTYPE) (VOID);
  16. typedef GIVEVERSION_PROTOTYPE * GIVEVERSION;
  17. typedef PDATATYPE (GIVEDATATYPELIST_PROTOTYPE)(PUINT Count);
  18. typedef BOOL (GATHERINFOUI_PROTOTYPE)(HINSTANCE LocalDllInstance, UINT DataTypeId);
  19. typedef GATHERINFOUI_PROTOTYPE * GATHERINFOUI;
  20. typedef GIVEDATATYPELIST_PROTOTYPE * GIVEDATATYPELIST;
  21. typedef PDATAOBJECT (GIVEDATAOBJECTLIST_PROTOTYPE)(UINT DataTypeId, PUINT Count);
  22. typedef GIVEDATAOBJECTLIST_PROTOTYPE * GIVEDATAOBJECTLIST;
  23. typedef BOOL (HANDLE_RMOUSE_PROTOTYPE)(HINSTANCE LocalDllInstance, HWND Owner, PDATAOBJECT DataObject, PPOINT pt);
  24. typedef HANDLE_RMOUSE_PROTOTYPE * HANDLE_RMOUSE;
  25. typedef BOOL (DISPLAYOPTIONALUI_PROTOTYPE)(POUTPUTARGS Args);
  26. typedef DISPLAYOPTIONALUI_PROTOTYPE * DISPLAYOPTIONALUI;
  27. typedef BOOL (GENERATEOUTPUT_PROTOTYPE)(POUTPUTARGS Args);
  28. typedef GENERATEOUTPUT_PROTOTYPE * GENERATEOUTPUT;
  29. typedef VOID (WIZTOOLSMAIN_PROTOTYPE)(DWORD Reason);
  30. typedef WIZTOOLSMAIN_PROTOTYPE * WIZTOOLSMAIN;
  31. typedef struct {
  32. UINT Selection;
  33. PDATATYPE *DataTypePtrs;
  34. UINT PtrCount;
  35. BOOL NoSave;
  36. } SELECTDATAARGS, *PSELECTDATAARGS;
  37. typedef struct {
  38. PDATAOBJECT DataObjectArray;
  39. UINT ArraySize;
  40. PCSTR Name;
  41. BOOL SelectOneOnly;
  42. PBOOL StartOverFlag;
  43. } SELECTOBJECTSARGS, *PSELECTOBJECTSARGS;
  44. typedef struct {
  45. PCSTR TextTitle;
  46. PCSTR DescTitle;
  47. PCSTR *NewText;
  48. PCSTR *NewDesc;
  49. UINT MaxSize;
  50. PCSTR DataTypeName;
  51. PCSTR DataObjectName;
  52. BOOL NoDesc;
  53. BOOL ReqDesc;
  54. BOOL NoText;
  55. BOOL ReqText;
  56. PBOOL StartOverFlag;
  57. } SUPPLYTEXTARGS, *PSUPPLYTEXTARGS;
  58. typedef struct {
  59. HANDLE Library;
  60. GIVEVERSION GiveVersion;
  61. GIVEDATATYPELIST GiveDataTypeList;
  62. GATHERINFOUI GatherInfoUI;
  63. GIVEDATAOBJECTLIST GiveDataObjectList;
  64. HANDLE_RMOUSE Handle_RMouse;
  65. DISPLAYOPTIONALUI DisplayOptionalUI;
  66. GENERATEOUTPUT GenerateOutput;
  67. PDATATYPE DataTypes;
  68. UINT DataTypeCount;
  69. PDATAOBJECT DataObjects;
  70. UINT DataObjectCount;
  71. } DGDLL, *PDGDLL;
  72. UINT g_Selections;
  73. CHAR g_Msg[2048];
  74. PCSTR g_DataPath = "\\\\popcorn\\public\\win9xupg";
  75. GROWBUFFER g_DllList;
  76. POOLHANDLE g_DllListData;
  77. PCSTR g_SrcInfPath = NULL;
  78. PCSTR g_DestPath = NULL;
  79. static CHAR g_ModulePath[MAX_MBCHAR_PATH];
  80. static CHAR g_CleanThisDir[MAX_MBCHAR_PATH];
  81. BOOL g_DontSave;
  82. PDGDLL g_CurrentDll = NULL;
  83. WIZTOOLSMAIN g_WizToolsMainProc = NULL;
  84. UINT
  85. pSelectDataType (
  86. IN PDATATYPE *DataTypePtrs,
  87. IN UINT PtrCount,
  88. OUT PBOOL DontSave
  89. );
  90. BOOL
  91. pSelectDataObjects (
  92. IN OUT PDATAOBJECT DataObjectArray,
  93. IN UINT ArraySize,
  94. IN PDATATYPE DataType,
  95. OUT PBOOL StartOverFlag
  96. );
  97. BOOL
  98. pGetOptionalText (
  99. IN PCSTR TextTitle, OPTIONAL
  100. IN PCSTR DescTitle, OPTIONAL
  101. IN PCSTR *NewDesc,
  102. IN PCSTR *Buffer,
  103. IN UINT MaxSize,
  104. IN PDATATYPE DataType,
  105. IN PDATAOBJECT DataObject, OPTIONAL
  106. OUT PBOOL StartOverFlag
  107. );
  108. VOID
  109. pThankYouBox (
  110. IN PBOOL StartOverFlag
  111. );
  112. VOID
  113. pFreeDllList (
  114. IN OUT PGROWBUFFER List,
  115. IN POOLHANDLE Buffer
  116. );
  117. HANDLE g_hHeap;
  118. HINSTANCE g_hInst;
  119. PSTR g_WinDir;
  120. BOOL WINAPI MemDb_Entry (HINSTANCE, DWORD, PVOID);
  121. BOOL WINAPI MigUtil_Entry (HINSTANCE, DWORD, PVOID);
  122. BOOL WINAPI FileEnum_Entry (HINSTANCE, DWORD, PVOID);
  123. BOOL
  124. pCallEntryPoints (
  125. DWORD Reason
  126. )
  127. {
  128. HINSTANCE Instance;
  129. static CHAR WinDir[MAX_PATH];
  130. GetWindowsDirectory (WinDir, MAX_PATH);
  131. g_WinDir = WinDir;
  132. //
  133. // Simulate DllMain
  134. //
  135. Instance = g_hInst;
  136. //
  137. // Initialize the common libs
  138. //
  139. if (Reason == DLL_PROCESS_ATTACH) {
  140. if (!MigUtil_Entry (Instance, Reason, NULL)) {
  141. return FALSE;
  142. }
  143. if (!MemDb_Entry (Instance, Reason, NULL)) {
  144. return FALSE;
  145. }
  146. if (!FileEnum_Entry (Instance, Reason, NULL)) {
  147. return FALSE;
  148. }
  149. } else if (Reason == DLL_PROCESS_DETACH) {
  150. if (!FileEnum_Entry (Instance, Reason, NULL)) {
  151. return FALSE;
  152. }
  153. if (!MemDb_Entry (Instance, Reason, NULL)) {
  154. return FALSE;
  155. }
  156. if (!MigUtil_Entry (Instance, Reason, NULL)) {
  157. return FALSE;
  158. }
  159. }
  160. return TRUE;
  161. }
  162. BOOL CALLBACK
  163. pSetDefGuiFontProc(
  164. IN HWND hwnd,
  165. IN LPARAM lParam)
  166. {
  167. SendMessage(hwnd, WM_SETFONT, lParam, 0L);
  168. return TRUE;
  169. }
  170. void
  171. pSetDefGUIFont(
  172. IN HWND hdlg
  173. )
  174. {
  175. EnumChildWindows(hdlg, pSetDefGuiFontProc, (LPARAM)GetStockObject(DEFAULT_GUI_FONT));
  176. }
  177. BOOL
  178. Init (
  179. VOID
  180. )
  181. {
  182. g_hHeap = GetProcessHeap();
  183. g_hInst = GetModuleHandle (NULL);
  184. return pCallEntryPoints (DLL_PROCESS_ATTACH);
  185. }
  186. VOID
  187. Terminate (
  188. VOID
  189. )
  190. {
  191. if (g_CleanThisDir[0]) {
  192. DeleteDirectoryContents (g_CleanThisDir);
  193. RemoveDirectory (g_CleanThisDir);
  194. }
  195. pCallEntryPoints (DLL_PROCESS_DETACH);
  196. }
  197. BOOL
  198. pLoadDataGatherDlls (
  199. BOOL FirstTimeInit,
  200. BOOL Local
  201. );
  202. VOID
  203. pTryToLoadNewUpgWiz (
  204. VOID
  205. );
  206. BOOL
  207. pDoTheWizard (
  208. VOID
  209. );
  210. VOID
  211. HelpAndExit (
  212. VOID
  213. )
  214. {
  215. printf ("Command Line Syntax:\n\n"
  216. "upgwiz [-l] [-n:path] [-i:src_inf_path] [-d:path]\n\n"
  217. "-l Specifies local mode\n"
  218. "-n Specifies network path\n"
  219. "-i Specifies the source INF path\n"
  220. "-d Specifies destination path\n"
  221. );
  222. exit(1);
  223. }
  224. INT
  225. __cdecl
  226. main (
  227. INT argc,
  228. CHAR *argv[]
  229. )
  230. {
  231. CHAR ModulePath[MAX_MBCHAR_PATH];
  232. BOOL Local = FALSE;
  233. INT i;
  234. PSTR p;
  235. BOOL Loop;
  236. BOOL FirstTimeInit = TRUE;
  237. if (!Init()) {
  238. printf ("Unable to initialize!\n");
  239. return 255;
  240. }
  241. GetCurrentDirectory (MAX_MBCHAR_PATH, ModulePath);
  242. GetModuleFileName (g_hInst, g_ModulePath, MAX_MBCHAR_PATH);
  243. p = _mbsrchr (g_ModulePath, '\\');
  244. *p = 0;
  245. wsprintf (ModulePath, TEXT("%s\\wiztools.dll"), g_ModulePath);
  246. if (DoesFileExist (ModulePath)) {
  247. Local = TRUE;
  248. }
  249. if (GetDriveType (g_ModulePath) == DRIVE_REMOVABLE) {
  250. Local = TRUE;
  251. }
  252. if (StringIMatch (g_ModulePath, g_DataPath)) {
  253. wsprintf (g_Msg, "This tool cannot be run from %s.", g_DataPath);
  254. MessageBox (NULL, g_Msg, NULL, MB_OK);
  255. return 255;
  256. }
  257. for (i = 1 ; i < argc ; i++) {
  258. if (argv[i][0] == '-' || argv[i][0] == '/') {
  259. switch (tolower (argv[i][1])) {
  260. case 'l':
  261. Local = TRUE;
  262. g_DataPath = g_ModulePath;
  263. break;
  264. case 'n':
  265. if (argv[i][2] == ':') {
  266. g_DataPath = &argv[i][3];
  267. } else if (i + 1 < argc) {
  268. g_DataPath = argv[i + 1];
  269. } else {
  270. HelpAndExit();
  271. }
  272. if (!DoesFileExist (g_DataPath)) {
  273. printf ("Can't access %s\n", g_DataPath);
  274. exit (2);
  275. }
  276. break;
  277. case 'i':
  278. if (argv[i][2] == ':') {
  279. g_SrcInfPath = &argv[i][3];
  280. } else if (i + 1 < argc) {
  281. g_SrcInfPath = argv[i + 1];
  282. } else {
  283. HelpAndExit();
  284. }
  285. if (!DoesFileExist (g_SrcInfPath)) {
  286. printf ("Can't access %s\n", g_SrcInfPath);
  287. exit (2);
  288. }
  289. break;
  290. case 'd':
  291. if (argv[i][2] == ':') {
  292. g_DestPath = &argv[i][3];
  293. } else if (i + 1 < argc) {
  294. g_DestPath = argv[i + 1];
  295. } else {
  296. HelpAndExit();
  297. }
  298. if (!DoesFileExist (g_DestPath)) {
  299. printf ("Can't access %s\n", g_DestPath);
  300. exit (2);
  301. }
  302. break;
  303. default:
  304. HelpAndExit();
  305. }
  306. } else {
  307. HelpAndExit();
  308. }
  309. }
  310. if (!g_SrcInfPath) {
  311. g_SrcInfPath = g_DataPath;
  312. }
  313. if (!g_DestPath) {
  314. g_DestPath = g_DataPath;
  315. }
  316. printf ("Src Path: %s\n", g_SrcInfPath);
  317. printf ("Dest Path: %s\n", g_DestPath);
  318. Loop = FALSE;
  319. do {
  320. if (!pLoadDataGatherDlls (FirstTimeInit, Local)) {
  321. wsprintf (g_Msg, "Can't load any DLLs from %s.", g_DataPath);
  322. MessageBox (NULL, g_Msg, NULL, MB_OK);
  323. } else {
  324. FirstTimeInit = FALSE;
  325. Loop = pDoTheWizard();
  326. }
  327. } while (Loop);
  328. Terminate();
  329. if (g_WizToolsMainProc) {
  330. g_WizToolsMainProc (DLL_PROCESS_DETACH);
  331. }
  332. return 0;
  333. }
  334. VOID
  335. pCreateDllList (
  336. OUT PGROWBUFFER List,
  337. OUT POOLHANDLE *Buffer
  338. )
  339. {
  340. ZeroMemory (List, sizeof (GROWBUFFER));
  341. *Buffer = PoolMemInitNamedPool ("DLL List");
  342. }
  343. BOOL
  344. pCopyBinaryToTemp (
  345. IN PCSTR DllPath,
  346. OUT PSTR TempPath
  347. )
  348. {
  349. if (!g_CleanThisDir[0]) {
  350. StringCopy (TempPath, g_WinDir);
  351. StringCopy (AppendWack (TempPath), "upgwiz");
  352. MakeSurePathExists (TempPath, TRUE);
  353. StringCopy (g_CleanThisDir, TempPath);
  354. } else {
  355. StringCopy (TempPath, g_CleanThisDir);
  356. }
  357. StringCopy (AppendWack (TempPath), GetFileNameFromPath (DllPath));
  358. if (DoesFileExist (TempPath)) {
  359. return TRUE;
  360. }
  361. if (!CopyFile (DllPath, TempPath, FALSE)) {
  362. wsprintf (
  363. g_Msg,
  364. "Can't copy %s to %s. If the network is working fine, the file "
  365. "may already have been copied and is running already, or you "
  366. "may need to update your copy of upgwiz.exe.",
  367. DllPath,
  368. TempPath
  369. );
  370. MessageBox (NULL, g_Msg, NULL, MB_OK);
  371. return FALSE;
  372. } else {
  373. printf ("%s copied to %s\n", DllPath, TempPath);
  374. }
  375. return TRUE;
  376. }
  377. BOOL
  378. pPutDllInList (
  379. IN OUT PGROWBUFFER List,
  380. IN OUT POOLHANDLE Buffer,
  381. IN PCSTR DllPath
  382. )
  383. {
  384. DGDLL Dll;
  385. PDGDLL FinalDll;
  386. BOOL b = FALSE;
  387. CHAR TempPath[MAX_MBCHAR_PATH];
  388. ZeroMemory (&Dll, sizeof (Dll));
  389. __try {
  390. pCopyBinaryToTemp (DllPath, TempPath);
  391. Dll.Library = LoadLibraryEx (TempPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
  392. if (!Dll.Library) {
  393. DWORD rc;
  394. rc = GetLastError();
  395. __leave;
  396. }
  397. Dll.GiveVersion = (GIVEVERSION) GetProcAddress (Dll.Library, "GiveVersion");
  398. Dll.GiveDataTypeList = (GIVEDATATYPELIST) GetProcAddress (Dll.Library, "GiveDataTypeList");
  399. Dll.GatherInfoUI = (GATHERINFOUI) GetProcAddress (Dll.Library, "GatherInfoUI");
  400. Dll.GiveDataObjectList = (GIVEDATAOBJECTLIST) GetProcAddress (Dll.Library, "GiveDataObjectList");
  401. Dll.Handle_RMouse = (HANDLE_RMOUSE) GetProcAddress (Dll.Library, "Handle_RMouse");
  402. Dll.DisplayOptionalUI = (DISPLAYOPTIONALUI) GetProcAddress (Dll.Library, "DisplayOptionalUI");
  403. Dll.GenerateOutput = (GENERATEOUTPUT) GetProcAddress (Dll.Library, "GenerateOutput");
  404. if (!Dll.GiveVersion || !Dll.GiveDataTypeList ||
  405. !Dll.GiveDataObjectList || !Dll.GenerateOutput
  406. ) {
  407. __leave;
  408. }
  409. if (Dll.GiveVersion() != UPGWIZ_VERSION) {
  410. __leave;
  411. }
  412. b = TRUE;
  413. }
  414. __finally {
  415. if (!b) {
  416. if (Dll.Library) {
  417. FreeLibrary (Dll.Library);
  418. }
  419. }
  420. }
  421. if (b) {
  422. FinalDll = (PDGDLL) GrowBuffer (List, sizeof (DGDLL));
  423. CopyMemory (FinalDll, &Dll, sizeof (Dll));
  424. }
  425. return b;
  426. }
  427. VOID
  428. pFreeDllList (
  429. IN OUT PGROWBUFFER List,
  430. IN POOLHANDLE Buffer
  431. )
  432. {
  433. UINT Count;
  434. PDGDLL Dll;
  435. Dll = (PDGDLL) List->Buf;
  436. Count = List->End / sizeof (DGDLL);
  437. while (Count > 0) {
  438. Count--;
  439. FreeLibrary (Dll->Library);
  440. Dll++;
  441. }
  442. FreeGrowBuffer (List);
  443. PoolMemDestroyPool (Buffer);
  444. }
  445. BOOL
  446. pLoadDataGatherDlls (
  447. BOOL FirstTimeInit,
  448. BOOL Local
  449. )
  450. {
  451. FILE_ENUM e;
  452. BOOL b = FALSE;
  453. CHAR HelperBin[MAX_MBCHAR_PATH];
  454. CHAR TempPath[MAX_MBCHAR_PATH];
  455. HINSTANCE Library;
  456. CHAR wiztoolsPath[MAX_MBCHAR_PATH];
  457. if (Local || !DoesFileExist (g_DataPath)) {
  458. g_DataPath = g_ModulePath;
  459. }
  460. pCreateDllList (&g_DllList, &g_DllListData);
  461. wsprintf (wiztoolsPath, "%s\\wiztools.dll", g_DataPath);
  462. if (!Local) {
  463. //
  464. // Copy everything that is needed to run this app
  465. //
  466. wsprintf (HelperBin, "%s\\msvcrt.dll", g_DataPath);
  467. pCopyBinaryToTemp (HelperBin, TempPath);
  468. wsprintf (HelperBin, "%s\\twid.exe", g_DataPath);
  469. pCopyBinaryToTemp (HelperBin, TempPath);
  470. wsprintf (HelperBin, "%s\\setupapi.dll", g_DataPath);
  471. pCopyBinaryToTemp (HelperBin, TempPath);
  472. wsprintf (HelperBin, "%s\\cfgmgr32.dll", g_DataPath);
  473. pCopyBinaryToTemp (HelperBin, TempPath);
  474. wsprintf (HelperBin, "%s\\imagehlp.dll", g_DataPath);
  475. pCopyBinaryToTemp (HelperBin, TempPath);
  476. wsprintf (HelperBin, "%s\\wiztools.dll", g_DataPath);
  477. pCopyBinaryToTemp (HelperBin, TempPath);
  478. StringCopy (wiztoolsPath, TempPath);
  479. }
  480. if (FirstTimeInit) {
  481. Library = LoadLibraryEx (wiztoolsPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
  482. g_WizToolsMainProc = (WIZTOOLSMAIN) GetProcAddress (Library, "WizToolsMain");
  483. if (g_WizToolsMainProc) {
  484. g_WizToolsMainProc (DLL_PROCESS_ATTACH);
  485. }
  486. }
  487. if (EnumFirstFile (&e, g_DataPath, "*.dll")) {
  488. do {
  489. if (StringIMatch (e.FileName, "setupapi.dll") ||
  490. StringIMatch (e.FileName, "cfgmgr32.dll") ||
  491. StringIMatch (e.FileName, "wiztools.dll") ||
  492. StringIMatch (e.FileName, "msvcrt.dll") ||
  493. StringIMatch (e.FileName, "imagehlp.dll")
  494. ) {
  495. continue;
  496. }
  497. if (pPutDllInList (&g_DllList, g_DllListData, e.FullPath)) {
  498. b = TRUE;
  499. }
  500. } while (EnumNextFile (&e));
  501. }
  502. if (!b) {
  503. pFreeDllList (&g_DllList, g_DllListData);
  504. g_DllListData = NULL;
  505. }
  506. return b;
  507. }
  508. VOID
  509. pTryToLoadNewUpgWiz (
  510. VOID
  511. )
  512. {
  513. CHAR TempExe[MAX_MBCHAR_PATH];
  514. CHAR PopcornExe[MAX_MBCHAR_PATH];
  515. STARTUPINFO si;
  516. PROCESS_INFORMATION pi;
  517. StringCopy (PopcornExe, g_DataPath);
  518. StringCopy (AppendWack (PopcornExe), "upgwiz.exe");
  519. if (!pCopyBinaryToTemp (PopcornExe, TempExe)) {
  520. return;
  521. }
  522. ZeroMemory (&si, sizeof (si));
  523. si.cb = sizeof (si);
  524. si.dwFlags = STARTF_FORCEOFFFEEDBACK;
  525. CreateProcessA (
  526. NULL,
  527. TempExe,
  528. NULL,
  529. NULL,
  530. FALSE,
  531. CREATE_DEFAULT_ERROR_MODE,
  532. NULL,
  533. g_DataPath,
  534. &si,
  535. &pi
  536. );
  537. }
  538. BOOL
  539. pDoTheWizard (
  540. VOID
  541. )
  542. {
  543. GROWBUFFER DataTypes = GROWBUF_INIT;
  544. UINT Count;
  545. UINT Pos;
  546. PDGDLL Dll;
  547. PDATATYPE DataTypeList;
  548. PDATATYPE *Ptr;
  549. PDATAOBJECT DataObjectList;
  550. UINT DataObjectCount;
  551. UINT DataTypeListSize;
  552. UINT u;
  553. OUTPUTARGS Args;
  554. PDATAOBJECT SelectedDataObject;
  555. BOOL StartOverFlag = FALSE;
  556. BOOL Saved;
  557. ZeroMemory (&Args, sizeof (Args));
  558. Dll = (PDGDLL) g_DllList.Buf;
  559. Count = g_DllList.End / sizeof (DGDLL);
  560. for (Pos = 0 ; Pos < Count ; Pos++) {
  561. DataTypeListSize = 0;
  562. DataTypeList = Dll[Pos].GiveDataTypeList (&DataTypeListSize);
  563. if (!DataTypeList) {
  564. DataTypeListSize = 0;
  565. }
  566. for (u = 0 ; u < DataTypeListSize ; u++) {
  567. Ptr = (PDATATYPE *) GrowBuffer (&DataTypes, sizeof (PDATATYPE));
  568. *Ptr = &DataTypeList[u];
  569. (*Ptr)->Reserved = (PVOID) Pos;
  570. }
  571. }
  572. if (DataTypes.End == 0) {
  573. MessageBox (NULL, "No data type DLLs to select from. There may be network access problems.", NULL, MB_OK);
  574. return FALSE;
  575. }
  576. __try {
  577. //
  578. // User selects data type
  579. //
  580. Pos = pSelectDataType ((PDATATYPE *) DataTypes.Buf, DataTypes.End / sizeof (PDATATYPE), &g_DontSave);
  581. if (Pos == 0xffffffff) {
  582. __leave;
  583. }
  584. DataTypeList = ((PDATATYPE *) DataTypes.Buf)[Pos];
  585. //
  586. // Get the data objects
  587. //
  588. DataObjectCount = 0;
  589. Dll = (PDGDLL) g_DllList.Buf;
  590. Dll += (UINT) DataTypeList->Reserved;
  591. g_CurrentDll = Dll;
  592. //
  593. // Gather Info UI
  594. //
  595. if (Dll->GatherInfoUI) {
  596. if (!Dll->GatherInfoUI (Dll->Library, DataTypeList->DataTypeId)) {
  597. __leave;
  598. }
  599. }
  600. if (!(DataTypeList->Flags & (DTF_NO_DATA_OBJECT))) {
  601. TurnOnWaitCursor();
  602. DataObjectList = Dll->GiveDataObjectList (DataTypeList->DataTypeId, &DataObjectCount);
  603. TurnOffWaitCursor();
  604. if (!DataObjectList || !DataObjectCount) {
  605. MessageBox (NULL, "There are no items of this type to choose from.", NULL, MB_OK);
  606. StartOverFlag = TRUE;
  607. __leave;
  608. }
  609. //
  610. // User selects them here
  611. //
  612. if (!pSelectDataObjects (DataObjectList, DataObjectCount, DataTypeList, &StartOverFlag)) {
  613. __leave;
  614. }
  615. }
  616. //
  617. // Display Optional UI
  618. //
  619. Args.Version = UPGWIZ_VERSION;
  620. Args.InboundInfDir = g_SrcInfPath;
  621. Args.OutboundDir = g_DestPath;
  622. Args.DataTypeId = DataTypeList->DataTypeId;
  623. Args.StartOverFlag = &StartOverFlag;
  624. if (Dll->DisplayOptionalUI) {
  625. if (!Dll->DisplayOptionalUI (&Args)) {
  626. __leave;
  627. }
  628. }
  629. //
  630. // Optional text
  631. //
  632. if (DataTypeList->Flags & (DTF_REQUEST_TEXT|DTF_REQUEST_DESCRIPTION)) {
  633. SelectedDataObject = NULL;
  634. for (u = 0 ; u < DataObjectCount ; u++) {
  635. if (DataObjectList[u].Flags & DOF_SELECTED) {
  636. if (SelectedDataObject) {
  637. SelectedDataObject = NULL;
  638. break;
  639. }
  640. SelectedDataObject = &DataObjectList[u];
  641. }
  642. }
  643. Args.OptionalText = MemAlloc (g_hHeap, 0, DataTypeList->MaxTextSize + 1);
  644. Args.OptionalDescription = MemAlloc (g_hHeap, 0, 81);
  645. if (!pGetOptionalText (
  646. DataTypeList->OptionalTextTitle,
  647. DataTypeList->OptionalDescTitle,
  648. &Args.OptionalDescription,
  649. &Args.OptionalText,
  650. DataTypeList->MaxTextSize,
  651. DataTypeList,
  652. SelectedDataObject,
  653. &StartOverFlag
  654. )) {
  655. __leave;
  656. }
  657. if (*Args.OptionalText == 0) {
  658. MemFree (g_hHeap, 0, Args.OptionalText);
  659. Args.OptionalText = NULL;
  660. }
  661. if (*Args.OptionalDescription == 0) {
  662. MemFree (g_hHeap, 0, Args.OptionalDescription);
  663. Args.OptionalDescription = NULL;
  664. }
  665. }
  666. //
  667. // Generate the output
  668. //
  669. Args.Version = UPGWIZ_VERSION;
  670. Args.InboundInfDir = g_SrcInfPath;
  671. Args.OutboundDir = g_DestPath;
  672. Args.DataTypeId = DataTypeList->DataTypeId;
  673. if (!g_DontSave) {
  674. TurnOnWaitCursor();
  675. if (Dll->GenerateOutput (&Args)) {
  676. Saved = TRUE;
  677. TurnOffWaitCursor();
  678. } else {
  679. TurnOffWaitCursor();
  680. MessageBox (NULL, "An error occurred while trying to save the report information.", "Report Not Saved", MB_OK);
  681. Saved = FALSE;
  682. }
  683. } else {
  684. Saved = TRUE;
  685. }
  686. if (Saved) {
  687. pThankYouBox (&StartOverFlag);
  688. }
  689. if (Args.OptionalText) {
  690. MemFree (g_hHeap, 0, Args.OptionalText);
  691. }
  692. if (Args.OptionalDescription) {
  693. MemFree (g_hHeap, 0, Args.OptionalDescription);
  694. }
  695. g_CurrentDll = NULL;
  696. }
  697. __finally {
  698. //
  699. // Done
  700. //
  701. pFreeDllList (&g_DllList, g_DllListData);
  702. FreeGrowBuffer (&DataTypes);
  703. }
  704. return StartOverFlag;
  705. }
  706. BOOL
  707. CALLBACK
  708. pDataTypeProc (
  709. HWND hdlg,
  710. UINT uMsg,
  711. WPARAM wParam,
  712. LPARAM lParam
  713. )
  714. {
  715. static PSELECTDATAARGS Args;
  716. PDATATYPE DataType;
  717. UINT u;
  718. HWND List;
  719. UINT Index;
  720. switch (uMsg) {
  721. case WM_INITDIALOG:
  722. pSetDefGUIFont(hdlg);
  723. Args = (PSELECTDATAARGS) lParam;
  724. List = GetDlgItem (hdlg, IDC_DT_LIST);
  725. for (u = 0 ; u < Args->PtrCount ; u++) {
  726. DataType = Args->DataTypePtrs[u];
  727. Index = SendMessage (List, LB_ADDSTRING, 0, (LPARAM) DataType->Name);
  728. SendMessage (List, LB_SETITEMDATA, Index, u);
  729. }
  730. CheckDlgButton (hdlg, IDC_DONT_SAVE, Args->NoSave ? BST_CHECKED : BST_UNCHECKED);
  731. EnableWindow (GetDlgItem (hdlg, IDOK), FALSE);
  732. return FALSE;
  733. case WM_COMMAND:
  734. switch (LOWORD (wParam)) {
  735. case IDC_DT_LIST:
  736. if (HIWORD (wParam) == LBN_SELCHANGE) {
  737. EnableWindow (GetDlgItem (hdlg, IDOK), TRUE);
  738. List = GetDlgItem (hdlg, IDC_DT_LIST);
  739. Index = SendMessage (List, LB_GETCURSEL, 0, 0);
  740. u = SendMessage (List, LB_GETITEMDATA, Index, 0);
  741. DataType = Args->DataTypePtrs[u];
  742. SetDlgItemText (hdlg, IDC_DESCRIPTION, DataType->Description);
  743. } else if (HIWORD (wParam) == LBN_DBLCLK) {
  744. PostMessage (hdlg, WM_COMMAND, MAKELPARAM(IDOK,BN_CLICKED), 0);
  745. }
  746. break;
  747. case IDOK:
  748. List = GetDlgItem (hdlg, IDC_DT_LIST);
  749. Index = SendMessage (List, LB_GETCURSEL, 0, 0);
  750. Args->Selection = SendMessage (List, LB_GETITEMDATA, Index, 0);
  751. Args->NoSave = IsDlgButtonChecked (hdlg, IDC_DONT_SAVE);
  752. EndDialog (hdlg, LOWORD (wParam));
  753. break;
  754. case IDCANCEL:
  755. EndDialog (hdlg, LOWORD (wParam));
  756. break;
  757. }
  758. break;
  759. }
  760. return FALSE;
  761. }
  762. UINT
  763. pSelectDataType (
  764. IN PDATATYPE *DataTypePtrs,
  765. IN UINT PtrCount,
  766. IN OUT PBOOL DontSave
  767. )
  768. {
  769. SELECTDATAARGS Args;
  770. Args.Selection = 0xffffffff;
  771. Args.DataTypePtrs = DataTypePtrs;
  772. Args.PtrCount = PtrCount;
  773. Args.NoSave = *DontSave;
  774. DialogBoxParam (g_hInst, MAKEINTRESOURCE(IDD_DATA_TYPE), NULL, pDataTypeProc, (LPARAM) &Args);
  775. *DontSave = Args.NoSave;
  776. return Args.Selection;
  777. }
  778. VOID
  779. pToggleSelection (
  780. HWND TreeView,
  781. HTREEITEM TreeItem,
  782. BOOL OneSelection
  783. )
  784. {
  785. static HTREEITEM LastSet;
  786. UINT State;
  787. PDATAOBJECT DataObject;
  788. TVITEM Item;
  789. Item.mask = TVIF_HANDLE|TVIF_STATE|TVIF_PARAM;
  790. Item.hItem = TreeItem;
  791. Item.stateMask = TVIS_STATEIMAGEMASK;
  792. TreeView_GetItem (TreeView, &Item);
  793. State = Item.state & TVIS_STATEIMAGEMASK;
  794. DataObject = (PDATAOBJECT) Item.lParam;
  795. if (State) {
  796. if (((State >> 12) & 0x03) == 2) {
  797. State = INDEXTOSTATEIMAGEMASK(1);
  798. g_Selections--;
  799. DataObject->Flags &= ~DOF_SELECTED;
  800. } else {
  801. if (OneSelection && g_Selections == 1) {
  802. pToggleSelection (TreeView, LastSet, FALSE);
  803. }
  804. State = INDEXTOSTATEIMAGEMASK(2);
  805. g_Selections++;
  806. DataObject->Flags |= DOF_SELECTED;
  807. LastSet = TreeItem;
  808. }
  809. Item.mask = TVIF_HANDLE|TVIF_STATE;
  810. Item.hItem = TreeItem;
  811. Item.state = State;
  812. Item.stateMask = TVIS_STATEIMAGEMASK;
  813. TreeView_SetItem (TreeView, &Item);
  814. InvalidateRect (TreeView, NULL, TRUE);
  815. }
  816. }
  817. HTREEITEM
  818. TreeView_FindItem (
  819. IN HWND TreeView,
  820. IN PCSTR String,
  821. IN HTREEITEM Parent OPTIONAL
  822. )
  823. {
  824. HTREEITEM Child;
  825. TVITEM Item;
  826. CHAR Buffer[1024];
  827. if (!Parent) {
  828. Child = TreeView_GetRoot (TreeView);
  829. } else {
  830. Child = TreeView_GetChild (TreeView, Parent);
  831. }
  832. while (Child) {
  833. Item.mask = TVIF_TEXT|TVIF_HANDLE;
  834. Item.hItem = Child;
  835. Item.pszText = Buffer;
  836. Item.cchTextMax = 1024;
  837. TreeView_GetItem (TreeView, &Item);
  838. if (StringIMatch (String, Buffer)) {
  839. break;
  840. }
  841. Child = TreeView_GetNextSibling (TreeView, Child);
  842. }
  843. return Child;
  844. }
  845. VOID
  846. pAddSubStringToTreeControl (
  847. IN HWND TreeView,
  848. IN PSTR Path,
  849. IN BOOL Checked,
  850. IN HTREEITEM Parent, OPTIONAL
  851. IN LPARAM lParam
  852. )
  853. {
  854. TVINSERTSTRUCT is;
  855. PSTR p;
  856. HTREEITEM Child;
  857. BOOL CheckThis = FALSE;
  858. BOOL HasBitmap = FALSE;
  859. HTREEITEM ExistingItem;
  860. PDATAOBJECT d = (PDATAOBJECT) lParam;
  861. p = _mbschr (Path, '\\');
  862. if (p && !(d->Flags & DOF_NO_SPLIT_ON_WACK)) {
  863. *p = 0;
  864. } else {
  865. CheckThis = Checked;
  866. HasBitmap = TRUE;
  867. }
  868. RestoreWacks (Path);
  869. is.hParent = Parent;
  870. is.hInsertAfter = d->Flags & DOF_NO_SORT ? TVI_LAST : TVI_SORT;
  871. ExistingItem = TreeView_FindItem (TreeView, Path, Parent);
  872. is.item.mask = 0;
  873. if (!ExistingItem) {
  874. is.item.mask = TVIF_TEXT;
  875. is.item.pszText = Path;
  876. } else {
  877. is.item.mask = TVIF_HANDLE;
  878. is.item.hItem = ExistingItem;
  879. }
  880. if (HasBitmap) {
  881. is.item.mask |= TVIF_STATE|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM;
  882. is.item.iImage = 0;
  883. is.item.iSelectedImage = 1;
  884. is.item.state = CheckThis ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1);
  885. is.item.stateMask = TVIS_STATEIMAGEMASK;
  886. is.item.lParam = lParam;
  887. if (CheckThis) {
  888. g_Selections++;
  889. }
  890. }
  891. if (ExistingItem) {
  892. if (is.item.mask) {
  893. TreeView_SetItem (TreeView, &is.item);
  894. }
  895. Child = ExistingItem;
  896. } else {
  897. Child = TreeView_InsertItem (TreeView, &is);
  898. }
  899. if (p && !(d->Flags & DOF_NO_SPLIT_ON_WACK)) {
  900. pAddSubStringToTreeControl (TreeView, p + 1, Checked, Child, lParam);
  901. }
  902. }
  903. VOID
  904. pAddStringToTreeControl (
  905. IN HWND TreeView,
  906. IN PCSTR Path,
  907. IN BOOL Checked,
  908. IN LPARAM lParam
  909. )
  910. {
  911. PSTR PathCopy;
  912. PathCopy = DuplicateText (Path);
  913. pAddSubStringToTreeControl (TreeView, PathCopy, Checked, NULL, lParam);
  914. FreeText (PathCopy);
  915. }
  916. BOOL
  917. CALLBACK
  918. pDataObjectProc (
  919. HWND hdlg,
  920. UINT uMsg,
  921. WPARAM wParam,
  922. LPARAM lParam
  923. )
  924. {
  925. static PSELECTOBJECTSARGS Args;
  926. static HIMAGELIST ImageList;
  927. static BOOL OneSelection;
  928. UINT u;
  929. HWND TreeView;
  930. LPNMHDR pnmh;
  931. TVHITTESTINFO HitTest;
  932. HTREEITEM TreeItem;
  933. LPNMTVKEYDOWN KeyDown;
  934. TVITEM Item;
  935. PDATAOBJECT DataObject;
  936. POINT pt;
  937. switch (uMsg) {
  938. case WM_INITDIALOG:
  939. pSetDefGUIFont(hdlg);
  940. Args = (PSELECTOBJECTSARGS) lParam;
  941. OneSelection = Args->SelectOneOnly;
  942. if (OneSelection) {
  943. SetDlgItemText (hdlg, IDC_DESCRIPTION, "&Select the Item to Report:");
  944. }
  945. SetWindowText (hdlg, Args->Name);
  946. g_Selections = 0;
  947. TreeView = GetDlgItem (hdlg, IDC_OBJECTS);
  948. ImageList = ImageList_LoadImage (
  949. g_hInst,
  950. MAKEINTRESOURCE(IDB_TREE_IMAGES),
  951. 16,
  952. 0,
  953. CLR_DEFAULT,
  954. IMAGE_BITMAP,
  955. LR_LOADTRANSPARENT
  956. );
  957. TreeView_SetImageList (TreeView, ImageList, TVSIL_STATE);
  958. for (u = 0 ; u < Args->ArraySize ; u++) {
  959. pAddStringToTreeControl (
  960. TreeView,
  961. Args->DataObjectArray[u].NameOrPath,
  962. OneSelection ? FALSE : (Args->DataObjectArray[u].Flags & DOF_SELECTED) ? TRUE : FALSE,
  963. (LPARAM) (&Args->DataObjectArray[u])
  964. );
  965. }
  966. InvalidateRect (TreeView, NULL, TRUE);
  967. EnableWindow (GetDlgItem (hdlg, IDOK), g_Selections != 0);
  968. return FALSE;
  969. case WM_COMMAND:
  970. switch (LOWORD (wParam)) {
  971. case IDC_START_OVER:
  972. *Args->StartOverFlag = TRUE;
  973. EndDialog (hdlg, LOWORD (wParam));
  974. break;
  975. case IDOK:
  976. EndDialog (hdlg, LOWORD (wParam));
  977. break;
  978. case IDCANCEL:
  979. EndDialog (hdlg, LOWORD (wParam));
  980. break;
  981. }
  982. break;
  983. case WM_NOTIFY:
  984. pnmh = (LPNMHDR) lParam;
  985. if (pnmh->code == NM_CLICK) {
  986. GetCursorPos (&HitTest.pt);
  987. ScreenToClient (pnmh->hwndFrom, &HitTest.pt);
  988. TreeView_HitTest (pnmh->hwndFrom, &HitTest);
  989. if (HitTest.flags & TVHT_ONITEMSTATEICON) {
  990. pToggleSelection (pnmh->hwndFrom, HitTest.hItem, OneSelection);
  991. EnableWindow (GetDlgItem (hdlg, IDOK), g_Selections != 0);
  992. }
  993. }
  994. else if (pnmh->code == NM_RCLICK) {
  995. GetCursorPos (&HitTest.pt);
  996. pt.x = HitTest.pt.x;
  997. pt.y = HitTest.pt.y;
  998. ScreenToClient (pnmh->hwndFrom, &HitTest.pt);
  999. TreeView_HitTest (pnmh->hwndFrom, &HitTest);
  1000. Item.mask = TVIF_HANDLE|TVIF_PARAM;
  1001. Item.hItem = HitTest.hItem;
  1002. TreeView_GetItem (pnmh->hwndFrom, &Item);
  1003. TreeView_SelectItem (pnmh->hwndFrom, HitTest.hItem);
  1004. DataObject = (PDATAOBJECT) Item.lParam;
  1005. if (g_CurrentDll->Handle_RMouse) {
  1006. if (g_CurrentDll->Handle_RMouse (g_CurrentDll->Library, pnmh->hwndFrom, DataObject, &pt)) {
  1007. Item.pszText = (PSTR)DataObject->NameOrPath;
  1008. Item.cchTextMax = strlen (DataObject->NameOrPath);
  1009. Item.mask = TVIF_HANDLE|TVIF_TEXT;
  1010. TreeView_SetItem (pnmh->hwndFrom, &Item);
  1011. InvalidateRect (pnmh->hwndFrom, NULL, TRUE);
  1012. }
  1013. }
  1014. }
  1015. //
  1016. // The tree control beeps with keyboard input; we have no way
  1017. // to eat the messages. This codes is disabled.
  1018. //
  1019. else if (pnmh->code == TVN_KEYDOWN && pnmh->code == 0) {
  1020. KeyDown = (LPNMTVKEYDOWN) pnmh;
  1021. if (KeyDown->wVKey == VK_SPACE) {
  1022. TreeItem = TreeView_GetSelection (pnmh->hwndFrom);
  1023. if (TreeItem) {
  1024. pToggleSelection (pnmh->hwndFrom, TreeItem, OneSelection);
  1025. EnableWindow (GetDlgItem (hdlg, IDOK), g_Selections != 0);
  1026. }
  1027. }
  1028. }
  1029. break;
  1030. case WM_DESTROY:
  1031. ImageList_Destroy (ImageList);
  1032. break;
  1033. }
  1034. return FALSE;
  1035. }
  1036. BOOL
  1037. pSelectDataObjects (
  1038. IN OUT PDATAOBJECT DataObjectArray,
  1039. IN UINT ArraySize,
  1040. IN PDATATYPE DataType,
  1041. OUT PBOOL StartOverFlag
  1042. )
  1043. {
  1044. SELECTOBJECTSARGS Args;
  1045. Args.DataObjectArray = DataObjectArray;
  1046. Args.ArraySize = ArraySize;
  1047. Args.Name = DataType->Name;
  1048. Args.SelectOneOnly = (DataType->Flags & DTF_ONE_SELECTION) != 0;
  1049. Args.StartOverFlag = StartOverFlag;
  1050. return IDOK == DialogBoxParam (
  1051. g_hInst,
  1052. MAKEINTRESOURCE(IDD_DATA_OBJECTS),
  1053. NULL,
  1054. pDataObjectProc,
  1055. (LPARAM) &Args
  1056. );
  1057. }
  1058. BOOL
  1059. CALLBACK
  1060. pSupplyTextProc (
  1061. HWND hdlg,
  1062. UINT uMsg,
  1063. WPARAM wParam,
  1064. LPARAM lParam
  1065. )
  1066. {
  1067. static PSUPPLYTEXTARGS Args;
  1068. BOOL b;
  1069. CHAR name[MEMDB_MAX];
  1070. switch (uMsg) {
  1071. case WM_INITDIALOG:
  1072. pSetDefGUIFont(hdlg);
  1073. Args = (PSUPPLYTEXTARGS) lParam;
  1074. if (Args->TextTitle) {
  1075. SetDlgItemText (hdlg, IDC_TEXT_TITLE, Args->TextTitle);
  1076. }
  1077. if (Args->DescTitle) {
  1078. SetDlgItemText (hdlg, IDC_DESC_TITLE, Args->DescTitle);
  1079. }
  1080. SetDlgItemText (hdlg, IDC_DATA_TYPE, Args->DataTypeName);
  1081. if (Args->DataObjectName) {
  1082. StringCopy (name, Args->DataObjectName);
  1083. RestoreWacks(name);
  1084. SetDlgItemText (hdlg, IDC_SELECTION, name);
  1085. }
  1086. SendMessage (GetDlgItem (hdlg, IDC_DESCRIPTION), EM_LIMITTEXT, 80, 0);
  1087. SendMessage (GetDlgItem (hdlg, IDC_TEXT_MSG), EM_LIMITTEXT, Args->MaxSize, 0);
  1088. if (Args->NoText) {
  1089. SetDlgItemText (hdlg, IDC_TEXT_MSG, "(not applicable)");
  1090. EnableWindow (GetDlgItem (hdlg, IDC_TEXT_MSG), FALSE);
  1091. } else if (Args->NoDesc) {
  1092. SetDlgItemText (hdlg, IDC_DESCRIPTION, "(not applicable)");
  1093. EnableWindow (GetDlgItem (hdlg, IDC_DESCRIPTION), FALSE);
  1094. }
  1095. if (Args->ReqDesc || Args->ReqText) {
  1096. EnableWindow (GetDlgItem (hdlg, IDOK), FALSE);
  1097. }
  1098. return FALSE;
  1099. case WM_COMMAND:
  1100. switch (LOWORD (wParam)) {
  1101. case IDC_DESCRIPTION:
  1102. case IDC_TEXT_MSG:
  1103. if (HIWORD (wParam) == EN_CHANGE) {
  1104. b = !Args->ReqDesc || GetWindowTextLength (GetDlgItem (hdlg, IDC_DESCRIPTION)) != 0;
  1105. b &= !Args->ReqText || GetWindowTextLength (GetDlgItem (hdlg, IDC_TEXT_MSG)) != 0;
  1106. EnableWindow (GetDlgItem (hdlg, IDOK), b);
  1107. }
  1108. break;
  1109. case IDC_START_OVER:
  1110. *Args->StartOverFlag = TRUE;
  1111. EndDialog (hdlg, LOWORD (wParam));
  1112. break;
  1113. case IDOK:
  1114. if (Args->NoDesc) {
  1115. *((PSTR) (*Args->NewDesc)) = 0;
  1116. } else {
  1117. GetDlgItemText (hdlg, IDC_DESCRIPTION, (PSTR) (*Args->NewDesc), 81);
  1118. }
  1119. if (Args->NoText) {
  1120. *((PSTR) (*Args->NewText)) = 0;
  1121. } else {
  1122. GetDlgItemText (hdlg, IDC_TEXT_MSG, (PSTR) (*Args->NewText), Args->MaxSize + 1);
  1123. }
  1124. EndDialog (hdlg, LOWORD (wParam));
  1125. break;
  1126. case IDCANCEL:
  1127. EndDialog (hdlg, LOWORD (wParam));
  1128. break;
  1129. }
  1130. break;
  1131. }
  1132. return FALSE;
  1133. }
  1134. BOOL
  1135. pGetOptionalText (
  1136. IN PCSTR TextTitle, OPTIONAL
  1137. IN PCSTR DescTitle,
  1138. IN PCSTR *NewDesc,
  1139. IN PCSTR *NewText,
  1140. IN UINT MaxSize,
  1141. IN PDATATYPE DataType,
  1142. IN PDATAOBJECT DataObject, OPTIONAL
  1143. OUT PBOOL StartOverFlag
  1144. )
  1145. {
  1146. SUPPLYTEXTARGS Args;
  1147. BOOL b = FALSE;
  1148. Args.TextTitle = TextTitle;
  1149. Args.DescTitle = DescTitle;
  1150. Args.NewText = NewText;
  1151. Args.NewDesc = NewDesc;
  1152. Args.MaxSize = MaxSize;
  1153. Args.DataTypeName = DataType->Name;
  1154. if (DataObject) {
  1155. Args.DataObjectName = DataObject->NameOrPath;
  1156. } else {
  1157. Args.DataObjectName = NULL;
  1158. }
  1159. Args.NoDesc = ((DataType->Flags & DTF_REQUEST_DESCRIPTION) == 0);
  1160. Args.NoText = ((DataType->Flags & DTF_REQUEST_TEXT) == 0);
  1161. Args.ReqDesc = ((DataType->Flags & DTF_REQUIRE_TEXT) == DTF_REQUIRE_TEXT);
  1162. Args.ReqText = ((DataType->Flags & DTF_REQUIRE_DESCRIPTION) == DTF_REQUIRE_DESCRIPTION);
  1163. Args.StartOverFlag = StartOverFlag;
  1164. if (IDOK == DialogBoxParam (
  1165. g_hInst,
  1166. MAKEINTRESOURCE(IDD_SUPPLY_TEXT),
  1167. NULL,
  1168. pSupplyTextProc,
  1169. (LPARAM) &Args
  1170. )) {
  1171. b = TRUE;
  1172. }
  1173. return b;
  1174. }
  1175. BOOL
  1176. CALLBACK
  1177. pThankYouProc (
  1178. HWND hdlg,
  1179. UINT uMsg,
  1180. WPARAM wParam,
  1181. LPARAM lParam
  1182. )
  1183. {
  1184. switch (uMsg) {
  1185. case WM_COMMAND:
  1186. switch (LOWORD (wParam)) {
  1187. case IDC_START_OVER:
  1188. EndDialog (hdlg, LOWORD (wParam));
  1189. break;
  1190. case IDCANCEL:
  1191. EndDialog (hdlg, LOWORD (wParam));
  1192. break;
  1193. }
  1194. break;
  1195. }
  1196. return FALSE;
  1197. }
  1198. VOID
  1199. pThankYouBox (
  1200. IN PBOOL StartOverFlag
  1201. )
  1202. {
  1203. if (IDC_START_OVER == DialogBox (g_hInst, MAKEINTRESOURCE(IDD_DONE), NULL, pThankYouProc)) {
  1204. *StartOverFlag = TRUE;
  1205. }
  1206. }