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.

388 lines
13 KiB

  1. /****************************************************************************\
  2. CREATE.C / OPK Wizard (OPKWIZ.EXE)
  3. Microsoft Confidential
  4. Copyright (c) Microsoft Corporation 1998
  5. All rights reserved
  6. Source file for the OPK Wizard that contains the external and internal
  7. functions used by the "create directory" wizard page.
  8. 4/99 - Jason Cohen (JCOHEN)
  9. Added this new source file for the OPK Wizard as part of the
  10. Millennium rewrite.
  11. 09/2000 - Stephen Lodwick (STELO)
  12. Ported OPK Wizard to Whistler
  13. \****************************************************************************/
  14. //
  15. // Include File(s):
  16. //
  17. #include "pch.h"
  18. #include "wizard.h"
  19. #include "resource.h"
  20. //
  21. // Internal Defined Value(s):
  22. //
  23. //
  24. // Internal Global Variable(s):
  25. //
  26. HANDLE g_hThread;
  27. HANDLE g_hEvent = NULL;
  28. //
  29. // Internal Function Prototype(s):
  30. //
  31. static DWORD CreateConfigDir(HWND);
  32. //
  33. // External Function(s):
  34. //
  35. BOOL CALLBACK CreateDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  36. {
  37. switch (uMsg)
  38. {
  39. case WM_INITDIALOG:
  40. SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETSTEP, 1, 0L);
  41. return FALSE;
  42. case WM_DESTROY:
  43. //
  44. // Close the cancellation event
  45. //
  46. if ( g_hEvent )
  47. {
  48. CloseHandle( g_hEvent );
  49. g_hEvent = NULL;
  50. }
  51. return 0;
  52. case WM_NOTIFY:
  53. switch ( ((NMHDR FAR *) lParam)->code )
  54. {
  55. case PSN_KILLACTIVE:
  56. case PSN_RESET:
  57. case PSN_WIZBACK:
  58. case PSN_WIZFINISH:
  59. case PSN_WIZNEXT:
  60. break;
  61. case PSN_QUERYCANCEL:
  62. SuspendThread(g_hThread);
  63. if ( !WIZ_CANCEL(hwnd) )
  64. ResumeThread(g_hThread);
  65. else
  66. {
  67. // Signal the thread termination event if it exists...
  68. //
  69. if ( g_hEvent )
  70. SetEvent( g_hEvent );
  71. }
  72. break;
  73. case PSN_HELP:
  74. WIZ_HELP();
  75. break;
  76. case PSN_SETACTIVE:
  77. g_App.dwCurrentHelp = IDH_DEFAULT;
  78. if ( GET_FLAG(OPK_CREATED) )
  79. WIZ_SKIP(hwnd);
  80. else
  81. {
  82. DWORD dwThreadId;
  83. WIZ_BUTTONS(hwnd, 0);
  84. //
  85. // Initialize the event we will use for cancellations
  86. //
  87. if ( NULL == g_hEvent )
  88. {
  89. g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  90. }
  91. else
  92. {
  93. ResetEvent( g_hEvent );
  94. }
  95. //
  96. // Now create the worker thread...
  97. //
  98. g_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) CreateConfigDir, (LPVOID) hwnd, 0, &dwThreadId);
  99. }
  100. break;
  101. default:
  102. return FALSE;
  103. }
  104. break;
  105. default:
  106. return FALSE;
  107. }
  108. return TRUE;
  109. }
  110. //
  111. // Internal Function(s):
  112. //
  113. static DWORD CreateConfigDir(HWND hwnd)
  114. {
  115. TCHAR szConfigDir[MAX_PATH];
  116. DWORD dwNum;
  117. // If this is maintenance mode, we need to save the existing dir.
  118. //
  119. if ( GET_FLAG(OPK_MAINTMODE) )
  120. lstrcpyn(szConfigDir, g_App.szTempDir,AS(szConfigDir));
  121. else
  122. szConfigDir[0] = NULLCHR;
  123. // Make sure our configuration directory exists.
  124. //
  125. if ( !DirectoryExists(g_App.szConfigSetsDir) )
  126. CreatePath(g_App.szConfigSetsDir);
  127. // Create the temporary directory.
  128. //
  129. if ( GetTempFileName(g_App.szConfigSetsDir, _T("CFG"), 0, g_App.szTempDir) &&
  130. DeleteFile(g_App.szTempDir) &&
  131. CreatePath(g_App.szTempDir) )
  132. {
  133. // Make sure there is a trailing backslash.
  134. //
  135. AddPathN(g_App.szTempDir, NULLSTR,AS(g_App.szTempDir));
  136. // Now create the file set in the directory. Either from an exising
  137. // config set, or from the files in the wizard directory.
  138. //
  139. if ( szConfigDir[0] )
  140. {
  141. //
  142. // Use the existing config set for all the default files.
  143. //
  144. // Get the count of the files for the progress bar.
  145. //
  146. dwNum = FileCount(szConfigDir);
  147. // Now setup the progress bar.
  148. //
  149. ShowWindow(GetDlgItem(hwnd, IDC_PROGRESS), dwNum ? SW_SHOW : SW_HIDE);
  150. SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETRANGE32, 0, (LPARAM) dwNum);
  151. // Copy all the files from the existing config directory into
  152. // the temp directory.
  153. //
  154. CopyDirectoryProgressCancel(GetDlgItem(hwnd, IDC_PROGRESS), g_hEvent, szConfigDir, g_App.szTempDir);
  155. }
  156. else
  157. {
  158. //
  159. // Use the wizard directory to get the default files.
  160. //
  161. HINF hInf;
  162. INFCONTEXT InfContext;
  163. BOOL bLoop;
  164. DWORD dwErr;
  165. if ( (hInf = SetupOpenInfFile(g_App.szOpkInputInfFile, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, &dwErr)) != INVALID_HANDLE_VALUE )
  166. {
  167. // Get the number of files so we can setup the progress bar.
  168. //
  169. dwNum = SetupGetLineCount(hInf, INF_SEC_COPYFILES);
  170. // Now setup the progress bar.
  171. //
  172. ShowWindow(GetDlgItem(hwnd, IDC_PROGRESS), dwNum ? SW_SHOW : SW_HIDE);
  173. SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETRANGE32, 0, (LPARAM) dwNum);
  174. for ( bLoop = SetupFindFirstLine(hInf, INF_SEC_COPYFILES, NULL, &InfContext);
  175. bLoop;
  176. bLoop = SetupFindNextLine(&InfContext, &InfContext) )
  177. {
  178. DWORD dwFlags = 0;
  179. TCHAR szFile[MAX_PATH] = NULLSTR,
  180. szSubDir[MAX_PATH] = NULLSTR,
  181. szSrc[MAX_PATH],
  182. szDst[MAX_PATH];
  183. // Get the source filename.
  184. //
  185. if ( SetupGetStringField(&InfContext, 1, szFile, AS(szFile), NULL) && szFile[0] )
  186. {
  187. // Get any flags passed in.
  188. //
  189. if ( !SetupGetIntField(&InfContext, 2, &dwFlags) )
  190. dwFlags = 0;
  191. // Get the optional destination sub directory.
  192. //
  193. if ( !SetupGetStringField(&InfContext, 3, szSubDir, AS(szSubDir), NULL) )
  194. szSubDir[0] = NULLCHR;
  195. // If we're in batch mode, overwrite the necessary files
  196. //
  197. if ( ( GET_FLAG(OPK_BATCHMODE) ) &&
  198. ( LSTRCMPI(szFile, FILE_OPKWIZ_INI) == 0 ) )
  199. {
  200. // Use this FILE_OPKWIZ_INI.
  201. //
  202. lstrcpyn(szSrc, g_App.szOpkWizIniFile, AS(szSrc));
  203. dwFlags |= 0x1;
  204. }
  205. else if ( ( GET_FLAG(OPK_INSMODE) ) &&
  206. ( LSTRCMPI(szFile, FILE_INSTALL_INS) == 0 ) )
  207. {
  208. // Use this FILE_INSTALL_INS.
  209. //
  210. lstrcpyn(szSrc, g_App.szInstallInsFile,AS(szSrc));
  211. dwFlags |= 0x1;
  212. }
  213. else
  214. {
  215. // Must not be in batch mode... so now create the full
  216. // path to the source file as if it exists in the
  217. // language specific directory.
  218. //
  219. lstrcpyn(szSrc, g_App.szLangDir,AS(szSrc));
  220. AddPathN(szSrc, g_App.szLangName,AS(szSrc));
  221. AddPathN(szSrc, DIR_WIZARDFILES,AS(szSrc));
  222. AddPathN(szSrc, szFile,AS(szSrc));
  223. // Check to see if the language specific version of this
  224. // file is there.
  225. //
  226. if ( ( g_App.szLangName[0] == NULLCHR ) || !FileExists(szSrc) )
  227. {
  228. // Nope, so get the full path to the source file in
  229. // the normal wizard directory.
  230. //
  231. lstrcpyn(szSrc, g_App.szWizardDir,AS(szSrc));
  232. AddPathN(szSrc, szFile,AS(szSrc));
  233. }
  234. }
  235. // Get the full path to the destination file.
  236. //
  237. lstrcpyn(szDst, g_App.szTempDir,AS(szDst));
  238. if ( szSubDir[0] )
  239. {
  240. AddPathN(szDst, szSubDir,AS(szDst));
  241. if ( !DirectoryExists(szDst) )
  242. CreatePath(szDst);
  243. }
  244. AddPathN(szDst, szFile,AS(szDst));
  245. // Copy the file.
  246. //
  247. if ( !CopyFile(szSrc, szDst, FALSE) )
  248. {
  249. // See if it is OK to fail the copy or not.
  250. //
  251. if ( dwFlags & 0x1 )
  252. {
  253. // Must now fail and error out because this file is required.
  254. //
  255. MsgBox(GetParent(hwnd), IDS_MISSINGFILE, IDS_APPNAME, MB_ERRORBOX, szFile);
  256. WIZ_EXIT(hwnd);
  257. }
  258. else if ( dwFlags & 0x2 )
  259. {
  260. // We must try and create the (in Unicode) because it does not exist
  261. //
  262. CreateUnicodeFile(szDst);
  263. }
  264. }
  265. else
  266. {
  267. // Reset the file attributes on the destination file.
  268. //
  269. SetFileAttributes(szDst, FILE_ATTRIBUTE_NORMAL);
  270. }
  271. }
  272. // Increase the progress bar.
  273. //
  274. SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_STEPIT, 0, 0L);
  275. // Check if the cancellation event has been signalled
  276. //
  277. if ( g_hEvent && ( WaitForSingleObject(g_hEvent, 0) != WAIT_TIMEOUT ) )
  278. {
  279. bLoop = FALSE;
  280. WIZ_EXIT(hwnd);
  281. }
  282. }
  283. }
  284. else
  285. {
  286. // If we can't open the INF file, then we must fail.
  287. //
  288. MsgBox(GetParent(hwnd), IDS_MISSINGFILE, IDS_APPNAME, MB_ERRORBOX, g_App.szOpkInputInfFile);
  289. WIZ_EXIT(hwnd);
  290. }
  291. }
  292. // Make sure the progress bar is at 100%.
  293. //
  294. SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, (WPARAM) dwNum, 0L);
  295. // Setup the full paths to all the config files.
  296. //
  297. SetConfigPath(g_App.szTempDir);
  298. // Delete the finished value from the ini file so that we know this is a
  299. // config set in progress.
  300. //
  301. WritePrivateProfileString(INI_SEC_CONFIGSET, INI_KEY_FINISHED, NULL, g_App.szOpkWizIniFile);
  302. // In maint mode we need to setup the path to the lang dir
  303. // and sku dir.
  304. //
  305. if ( szConfigDir[0] )
  306. {
  307. GetPrivateProfileString(INI_SEC_WINPE, INI_KEY_WINPE_LANG, NULLSTR, g_App.szLangName, STRSIZE(g_App.szLangName), GET_FLAG(OPK_BATCHMODE) ? g_App.szOpkWizIniFile : g_App.szWinBomIniFile);
  308. GetPrivateProfileString(INI_SEC_WINPE, INI_KEY_WBOM_WINPE_SKU, NULLSTR, g_App.szSkuName, STRSIZE(g_App.szSkuName), GET_FLAG(OPK_BATCHMODE) ? g_App.szOpkWizIniFile : g_App.szWinBomIniFile);
  309. }
  310. // Set the flag so we know we have created a directory.
  311. //
  312. SET_FLAG(OPK_CREATED, TRUE);
  313. }
  314. else
  315. {
  316. // We couldn't get a temp directory, zero out the string.
  317. //
  318. g_App.szTempDir[0] = NULLCHR;
  319. MsgBox(GetParent(hwnd), IDS_ERR_WIZBAD, IDS_APPNAME, MB_ERRORBOX);
  320. WIZ_EXIT(hwnd);
  321. }
  322. // Jump to next page.
  323. //
  324. WIZ_PRESS(hwnd, ( GET_FLAG(OPK_MAINTMODE) ? PSBTN_FINISH : PSBTN_NEXT ));
  325. return 0;
  326. }