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.

739 lines
24 KiB

  1. /**************************************************************************
  2. *
  3. * OEMRESET
  4. *
  5. * Microsoft Confidential
  6. * Copyright (c) Microsoft Corporation 1999
  7. * All rights reserved
  8. *
  9. * Main entry point
  10. *
  11. * Command line: /A /Auto: Enduser reboot
  12. * /S : Enduser power-down
  13. * /R : Audit reboot
  14. * /P : Audit power-down
  15. * /H : Hide dialog
  16. * /L : OEM logging enabled (c:\reset.txt)
  17. *
  18. * Revision History:
  19. * 7/00 - Brian Ku (briank) Port from Millennium to Whistler.
  20. * 5/01 - Adrian Cosma (acosma) Remove dead code and integrate more with sysprep.c.
  21. *
  22. *
  23. *************************************************************************/
  24. #include <opklib.h>
  25. #include <tchar.h>
  26. #pragma warning( disable:4001 ) /* Disable new type remark warning */
  27. #pragma warning( disable:4100 ) /* Disable unreferenced formal param */
  28. #include <commctrl.h>
  29. #include <winreg.h>
  30. #include <regstr.h>
  31. #include <shlwapi.h>
  32. #include "sysprep.h"
  33. #include "msg.h"
  34. #include "resource.h"
  35. // Action flags
  36. //
  37. extern BOOL NoSidGen;
  38. extern BOOL SetupClPresent;
  39. extern BOOL bMiniSetup;
  40. extern BOOL PnP;
  41. extern BOOL Reboot;
  42. extern BOOL NoReboot;
  43. extern BOOL ForceShutdown;
  44. extern BOOL bActivated;
  45. extern BOOL Reseal;
  46. extern BOOL Factory;
  47. extern BOOL Audit;
  48. extern BOOL QuietMode;
  49. extern TCHAR g_szLogFile[];
  50. extern BOOL IsProfessionalSKU();
  51. extern BOOL FProcessSwitches();
  52. extern int
  53. MessageBoxFromMessage(
  54. IN DWORD MessageId,
  55. IN DWORD CaptionStringId,
  56. IN UINT Style,
  57. ...
  58. );
  59. //***************************************************************************
  60. //
  61. // Definitions
  62. //
  63. //***************************************************************************
  64. // Audit modes
  65. //
  66. #define MODE_NO_AUDIT 0
  67. #define MODE_RESTORE_AUDIT 2
  68. #define MODE_SIMULATE_ENDUSER 3
  69. // User defined messages
  70. //
  71. #define WM_PROGRESS (WM_USER + 0x0001)
  72. #define WM_FINISHED (WM_USER + 0x0002)
  73. // Flags used for command line parsing
  74. //
  75. #define OEMRESET_AUTO 0x0001 // Auto /A or /AUTO
  76. #define OEMRESET_SHUTDOWN 0x0002 // Shutdown /S
  77. #define OEMRESET_AUDIT 0x0004 // Audit reboot /R
  78. #define OEMRESET_AUDITPD 0x0008 // Audit power-down, when booted back up, you will still be in audit mode
  79. #define OEMRESET_HIDE 0x0010 // Hide dialog /H
  80. #define OEMRESET_LOG 0x0020 // Log enabled /L
  81. #define OEMRESET_OEMRUN 0x0040 // Launch oemrun items
  82. // Configuration files/directories
  83. //
  84. #define DIR_BOOT _T("BootDir")
  85. #define FILE_RESET_LOG _T("RESETLOG.TXT")
  86. #define FILE_AFX_TXT _T("\\OPTIONS\\AFC.TXT")
  87. // Other constants
  88. //
  89. #define REBOOT_SECONDS 30
  90. // Global Variables
  91. //
  92. HWND ghwndOemResetDlg = 0; // HWND for OemReset Dialog
  93. HINSTANCE ghinstEXE = 0;
  94. DWORD gdwCmdlineFlags = 0; // Switches used
  95. BOOL gbHide = FALSE; // Hide all dialogs
  96. BOOL gbLog = FALSE; // Enable logging
  97. HFILE ghf = 0; // Log file handle
  98. HANDLE ghMonitorThread = 0;
  99. DWORD gdwThreadID = 0;
  100. UINT_PTR gTimerID = 1; // Wait timer id
  101. UINT gdwMillSec = 120 * 1000; // Wait millsec
  102. HWND ghwndProgressCtl; // Wait progress controls
  103. /* Local Prototypes */
  104. static HWND CreateOemResetDlg(HINSTANCE hInstance);
  105. static void FlushAndDisableRegistry();
  106. static BOOL FShutdown();
  107. static BOOL ParseCmdLineSwitches(LPTSTR);
  108. static TCHAR* ParseRegistrySwitches();
  109. static void StartMonitorKeyValue();
  110. static void HandleCommandSwitches();
  111. static BOOL VerifySids();
  112. /* Dialog functions */
  113. INT_PTR CALLBACK RemindeOEMDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  114. void uiDialogTopRight(HWND hwndDlg);
  115. //////////////////////////////////////////////////////////////////////////////
  116. // Create the OEMRESET Dialog modeless so we can hide it if necessary
  117. //
  118. HWND CreateOemResetDlg(HINSTANCE hInstance)
  119. {
  120. return CreateDialog(hInstance, MAKEINTRESOURCE(IDD_OEMREMINDER), NULL, (DLGPROC) RemindeOEMDlgProc);
  121. }
  122. //////////////////////////////////////////////////////////////////////////////
  123. // Find the boot drive in the registry
  124. //
  125. void GetBootDrive(TCHAR szBootDrive[])
  126. {
  127. HKEY hKey = 0;
  128. if (RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_CURRENTVERSION_SETUP, &hKey) == ERROR_SUCCESS)
  129. {
  130. DWORD dwSize = MAX_PATH;
  131. RegQueryValueEx(hKey, DIR_BOOT, 0L, NULL, (LPBYTE)szBootDrive, &dwSize);
  132. RegCloseKey(hKey);
  133. }
  134. }
  135. //////////////////////////////////////////////////////////////////////////////
  136. // Sets the flag determined by whether the dialog checkbox is checked or not
  137. //
  138. void SetFlag(HWND hDlg, WPARAM ctlId, BOOL* pfFlag)
  139. {
  140. if (pfFlag) {
  141. if (IsDlgButtonChecked(hDlg, (INT)ctlId))
  142. *pfFlag = TRUE;
  143. else
  144. *pfFlag = FALSE;
  145. }
  146. }
  147. //////////////////////////////////////////////////////////////////////////////
  148. // Sets the flag determined by whether the dialog checkbox is checked or not
  149. //
  150. void SetCheck(HWND hDlg, WPARAM ctlId, BOOL fFlag)
  151. {
  152. if (fFlag)
  153. CheckDlgButton(hDlg, (INT)ctlId, BST_CHECKED);
  154. else
  155. CheckDlgButton(hDlg, (INT)ctlId, BST_UNCHECKED);
  156. }
  157. extern StartWaitThread();
  158. //////////////////////////////////////////////////////////////////////////////
  159. // Put up UI telling the OEM that they still have to execute this.
  160. //
  161. INT_PTR CALLBACK RemindeOEMDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  162. {
  163. switch (msg)
  164. {
  165. case WM_INITDIALOG:
  166. // Quiet is always FALSE when the UI is up.
  167. //
  168. QuietMode = FALSE;
  169. // IA64 always use mini-setup
  170. //
  171. if (IsIA64()) {
  172. SetCheck(hwnd, IDC_MINISETUP, bMiniSetup = TRUE);
  173. EnableWindow(GetDlgItem(hwnd, IDC_MINISETUP), FALSE);
  174. }
  175. else {
  176. // Set check depending on flag
  177. //
  178. SetCheck(hwnd, IDC_MINISETUP, bMiniSetup);
  179. // Only Professional SKU can use both oobe or mini-setup otherwise
  180. // disable the checkbox
  181. //
  182. if (!IsProfessionalSKU())
  183. EnableWindow(GetDlgItem(hwnd, IDC_MINISETUP), FALSE);
  184. }
  185. // Disable the pnp checkbox if mini-setup is not checked.
  186. //
  187. if ( !bMiniSetup )
  188. EnableWindow(GetDlgItem(hwnd, IDC_PNP), FALSE);
  189. else
  190. SetCheck(hwnd, IDC_PNP, PnP);
  191. SetCheck(hwnd, IDC_NOSIDGEN, NoSidGen);
  192. SetCheck(hwnd, IDC_ACTIVATED, bActivated);
  193. // If setupcl.exe is not present and they specified nosidgen
  194. // then we need to disable the checkbox
  195. //
  196. if ( !SetupClPresent && NoSidGen )
  197. EnableWindow(GetDlgItem(hwnd, IDC_NOSIDGEN), FALSE);
  198. // Disable Audit button if we are not in factory mode and change the caption.
  199. //
  200. if ( !RegCheck(HKLM, REGSTR_PATH_SYSTEM_SETUP, REGSTR_VALUE_AUDIT) )
  201. {
  202. EnableWindow(GetDlgItem(hwnd, IDAUDIT), FALSE);
  203. }
  204. // Init the combo box.
  205. //
  206. {
  207. HWND hCombo = NULL;
  208. if (hCombo = GetDlgItem(hwnd, IDC_SHUTDOWN)) {
  209. TCHAR szComboString[MAX_PATH] = _T("");
  210. LRESULT ret = 0;
  211. if ( LoadString(ghinstEXE, IDS_SHUTDOWN, szComboString, sizeof(szComboString)/sizeof(szComboString[0])) &&
  212. ((ret = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szComboString)) != CB_ERR) )
  213. {
  214. SendMessage(hCombo, CB_SETITEMDATA, ret, (LPARAM) NULL);
  215. }
  216. if ( LoadString(ghinstEXE, IDS_REBOOT, szComboString, sizeof(szComboString)/sizeof(szComboString[0])) &&
  217. ((ret = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szComboString)) != CB_ERR) )
  218. {
  219. SendMessage(hCombo, CB_SETITEMDATA, ret, (LPARAM) &Reboot);
  220. }
  221. if ( LoadString(ghinstEXE, IDS_QUIT, szComboString, sizeof(szComboString)/sizeof(szComboString[0])) &&
  222. ((ret = SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szComboString)) != CB_ERR) )
  223. {
  224. SendMessage(hCombo, CB_SETITEMDATA, ret, (LPARAM) &NoReboot);
  225. }
  226. if (NoReboot)
  227. SendMessage(hCombo, CB_SETCURSEL, (WPARAM) 2, 0);
  228. else if (Reboot)
  229. SendMessage(hCombo, CB_SETCURSEL, (WPARAM) 1, 0);
  230. else
  231. SendMessage(hCombo, CB_SETCURSEL, (WPARAM) 0, 0);
  232. }
  233. }
  234. uiDialogTopRight(hwnd);
  235. LockApplication(FALSE);
  236. break;
  237. case WM_CLOSE:
  238. LockApplication(FALSE);
  239. break;
  240. case WM_COMMAND:
  241. switch ( LOWORD(wParam) )
  242. {
  243. case IDCANCEL:
  244. PostQuitMessage(0);
  245. break;
  246. // Action buttons
  247. //
  248. case IDOK: // Reseal
  249. // Check whether SIDS have been regenerated and try to help the user
  250. // make a smart decision about doing it again.
  251. if ( !VerifySids() )
  252. {
  253. SetFocus(GetDlgItem(hwnd, IDC_NOSIDGEN));
  254. return FALSE;
  255. }
  256. if ( !LockApplication(TRUE) )
  257. {
  258. MessageBoxFromMessage( MSG_ALREADY_RUNNING,
  259. IDS_APPTITLE,
  260. MB_OK | MB_ICONERROR | MB_TASKMODAL );
  261. return FALSE;
  262. }
  263. Reseal = TRUE;
  264. // Reseal the machine
  265. //
  266. FProcessSwitches();
  267. LockApplication(FALSE);
  268. break;
  269. case IDAUDIT:
  270. {
  271. // Prepare for pseudo factory but get back to audit
  272. //
  273. TCHAR szFactoryPath[MAX_PATH] = NULLSTR;
  274. if ( !LockApplication(TRUE) )
  275. {
  276. MessageBoxFromMessage( MSG_ALREADY_RUNNING,
  277. IDS_APPTITLE,
  278. MB_OK | MB_ICONERROR | MB_TASKMODAL );
  279. return FALSE;
  280. }
  281. Audit = TRUE;
  282. FProcessSwitches();
  283. LockApplication(FALSE);
  284. }
  285. break;
  286. case IDFACTORY: // Factory
  287. if ( !LockApplication(TRUE) )
  288. {
  289. MessageBoxFromMessage( MSG_ALREADY_RUNNING,
  290. IDS_APPTITLE,
  291. MB_OK | MB_ICONERROR | MB_TASKMODAL );
  292. return FALSE;
  293. }
  294. Factory = TRUE;
  295. // Prepare for factory mode
  296. //
  297. FProcessSwitches();
  298. LockApplication(FALSE);
  299. break;
  300. // Action Flags checkboxes
  301. //
  302. case IDC_MINISETUP:
  303. SetFlag(hwnd, wParam, &bMiniSetup);
  304. // If mini-setup checkbox is set, then enable the PNP checkbox,
  305. // otherwise disable it.
  306. if ( !bMiniSetup ) {
  307. PnP = FALSE;
  308. SetCheck(hwnd, IDC_PNP, PnP);
  309. EnableWindow(GetDlgItem(hwnd, IDC_PNP), FALSE);
  310. }
  311. else {
  312. EnableWindow(GetDlgItem(hwnd, IDC_PNP), TRUE);
  313. }
  314. break;
  315. case IDC_PNP:
  316. SetFlag(hwnd, wParam, &PnP);
  317. break;
  318. case IDC_ACTIVATED:
  319. SetFlag(hwnd, wParam, &bActivated);
  320. break;
  321. case IDC_NOSIDGEN:
  322. SetFlag(hwnd, wParam, &NoSidGen);
  323. break;
  324. case IDC_SHUTDOWN:
  325. if ( CBN_SELCHANGE == HIWORD(wParam) ) {
  326. BOOL *lpbFlag;
  327. // Reset all flags to false first.
  328. //
  329. ForceShutdown = Reboot = NoReboot = FALSE;
  330. // lParam is the HWND of the ComboBox.
  331. //
  332. lpbFlag = (BOOL*) SendMessage((HWND) lParam, CB_GETITEMDATA, (SendMessage((HWND) lParam, CB_GETCURSEL, 0, 0)), 0);
  333. // Set the flag associated with this choice.
  334. //
  335. if ( ((INT_PTR) lpbFlag != CB_ERR) && lpbFlag )
  336. {
  337. *lpbFlag = TRUE;
  338. }
  339. }
  340. break;
  341. default:
  342. break;
  343. }
  344. break;
  345. default:
  346. break;
  347. }
  348. return FALSE;
  349. }
  350. //////////////////////////////////////////////////////////////////////////////
  351. // Shutdown - resets the oemaudit.inf file sections and removes
  352. // HKLM\Software\Microsoft\Windows\CurrentVersion\AuditMode
  353. //
  354. BOOL FShutdown()
  355. {
  356. BOOL fReturn = TRUE;
  357. // Launch sysprep to reseal the machine
  358. //
  359. if (!(fReturn = ResealMachine()))
  360. LogFileStr(g_szLogFile, _T("SYSPREP: Shutdown could not reseal the machine!\r\n"));
  361. return fReturn;
  362. }
  363. //////////////////////////////////////////////////////////////////////////////
  364. // FlushAndDisableRegistry - flushes registry keys
  365. //
  366. void FlushAndDisableRegistry()
  367. {
  368. RegFlushKey(HKEY_LOCAL_MACHINE);
  369. RegFlushKey(HKEY_USERS);
  370. }
  371. //////////////////////////////////////////////////////////////////////////////
  372. // uiDialogTopRight - this was copied over from SETUPX.DLL
  373. //
  374. void uiDialogTopRight(HWND hwndDlg)
  375. {
  376. RECT rc;
  377. int cxDlg;
  378. int cxScreen = GetSystemMetrics( SM_CXSCREEN );
  379. GetWindowRect(hwndDlg,&rc);
  380. cxDlg = rc.right - rc.left;
  381. // Position the dialog.
  382. //
  383. SetWindowPos(hwndDlg, NULL, cxScreen - cxDlg, 8, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  384. }
  385. //////////////////////////////////////////////////////////////////////////////
  386. // ParseRegistrySwitches - checks the registry for oemreset switches
  387. //
  388. TCHAR* ParseRegistrySwitches()
  389. {
  390. static TCHAR szCmdLineArgs[MAX_PATH] = _T("");
  391. HKEY hKey = 0;
  392. if (RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP, &hKey) == ERROR_SUCCESS)
  393. {
  394. DWORD dwSize = MAX_PATH;
  395. RegQueryValueEx(hKey, REGSTR_VAL_OEMRESETSWITCH, 0L, NULL, (LPBYTE)szCmdLineArgs, &dwSize);
  396. RegSetValueEx(hKey, REGSTR_VAL_OEMRESETSWITCH, 0, REG_SZ, (LPBYTE)_T(""), sizeof(_T("")));
  397. RegCloseKey(hKey);
  398. }
  399. return szCmdLineArgs;
  400. }
  401. //////////////////////////////////////////////////////////////////////////////
  402. // ParseCmdLineSwitches - this was copied over from OPKWIZ (JCOHEN)
  403. //
  404. BOOL ParseCmdLineSwitches(LPTSTR lpszCmdLineOrg)
  405. {
  406. LPTSTR lpLine = lpszCmdLineOrg,
  407. lpArg;
  408. TCHAR szTmpBuf[MAX_PATH];
  409. INT i;
  410. BOOL bHandled= FALSE,
  411. bError = FALSE,
  412. bLeftQ = FALSE,
  413. bRegistry = FALSE;
  414. // If we have no command line, then return
  415. //
  416. if ( lpLine == NULL )
  417. return bHandled;
  418. // If empty command line, then try registry.
  419. //
  420. if ( *lpLine == NULLCHR )
  421. {
  422. lpLine = ParseRegistrySwitches();
  423. // If registry is empty then return not handled
  424. if (lpLine == NULL)
  425. return bHandled;
  426. // Registry switches don't have / or - and are separated by semi-colons
  427. bRegistry = TRUE;
  428. };
  429. // Loop through command line.
  430. //
  431. while ( *lpLine != NULLCHR )
  432. {
  433. // Move to first non-white TCHAR.
  434. //
  435. lpArg = lpLine;
  436. while ( isspace((int) *lpArg) )
  437. lpArg = CharNext (lpArg);
  438. if ( *lpArg )
  439. {
  440. // Move to next white TCHAR.
  441. //
  442. lpLine = lpArg;
  443. while ( ( *lpLine != NULLCHR ) && ( *lpLine != _T(';') ) &&
  444. ( ( !bLeftQ && ( !isspace((int) *lpLine) ) ) ||
  445. ( bLeftQ && ( *lpLine != _T('"') ) ) ) )
  446. {
  447. lpLine = CharNext (lpLine);
  448. if ( !bLeftQ && (*lpLine == _T('"')) )
  449. {
  450. lpLine = CharNext (lpLine);
  451. bLeftQ = TRUE;
  452. }
  453. }
  454. // Copy arg to buffer.
  455. //
  456. i = (INT)(lpLine - lpArg + 1); // +1 for NULL.
  457. lstrcpyn( szTmpBuf, lpArg, i );
  458. // Skip semi-colons
  459. if (bRegistry && *lpLine == _T(';'))
  460. lpLine = CharNext(lpLine);
  461. if ( bLeftQ )
  462. {
  463. lpLine = CharNext (lpLine); // skip the " from remander of command line.
  464. bLeftQ = FALSE;
  465. }
  466. // Command line comands starting with either '/' or '-' unless it's from
  467. // the registry
  468. if ( !bRegistry && ( *szTmpBuf != _T('/') ) && ( *szTmpBuf != _T('-') ) )
  469. {
  470. bError = TRUE;
  471. break;
  472. }
  473. else
  474. {
  475. // Skip pass '/' or '-' if not from registry
  476. TCHAR* pszSwitch = NULL;
  477. if (!bRegistry)
  478. pszSwitch = CharNext(szTmpBuf);
  479. else
  480. pszSwitch = szTmpBuf;
  481. // Because we have switches that have multiple chars
  482. // I'm using an if/elseif otherwise I would use
  483. // switch statements
  484. //
  485. if (_tcsicmp(pszSwitch, _T("R")) == 0)
  486. gdwCmdlineFlags |= OEMRESET_AUDIT;
  487. else if ((_tcsicmp(pszSwitch, _T("AUTO")) == 0) ||
  488. (_tcsicmp(pszSwitch, _T("A") ) == 0))
  489. gdwCmdlineFlags |= OEMRESET_AUTO;
  490. else if (_tcsicmp(pszSwitch, _T("S")) == 0)
  491. gdwCmdlineFlags |= OEMRESET_SHUTDOWN;
  492. else if (_tcsicmp(pszSwitch, _T("L")) == 0)
  493. gdwCmdlineFlags |= OEMRESET_LOG;
  494. else if (_tcsicmp(pszSwitch, _T("H")) == 0)
  495. gdwCmdlineFlags |= OEMRESET_HIDE;
  496. else if (_tcsicmp(pszSwitch, _T("P")) == 0)
  497. gdwCmdlineFlags |= OEMRESET_AUDITPD;
  498. else
  499. bError = TRUE;
  500. }
  501. }
  502. else
  503. break;
  504. }
  505. // If we hit an error, display the error and show the help.
  506. //
  507. if ( bError )
  508. {
  509. LPTSTR lpHelp = AllocateString(NULL, IDS_HELP);
  510. MsgBox(NULL, IDS_ERR_BADCMDLINE, IDS_APPNAME, MB_ERRORBOX, lpHelp ? lpHelp : NULLSTR);
  511. FREE(lpHelp);
  512. bHandled = TRUE; // Exit the app if bad command line!
  513. }
  514. return bHandled;
  515. }
  516. //////////////////////////////////////////////////////////////////////////////
  517. // MonitorKeyValueThread - we're monitoring the OEMReset_Switch in the registry
  518. //
  519. //
  520. DWORD WINAPI MonitorKeyValueThread(LPVOID lpv)
  521. {
  522. HKEY hKey;
  523. // Open the key we want to monitor
  524. if (RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP, &hKey) == ERROR_SUCCESS)
  525. {
  526. do
  527. {
  528. ParseCmdLineSwitches(_T("")); // empty so it checks the registry
  529. HandleCommandSwitches();
  530. } while (ERROR_SUCCESS == RegNotifyChangeKeyValue(hKey, FALSE, REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, 0, FALSE));
  531. RegCloseKey(hKey);
  532. }
  533. return 0;
  534. }
  535. //////////////////////////////////////////////////////////////////////////////
  536. // Starts a thread to monitor a registry key for cmdline switches
  537. //
  538. void StartMonitorKeyValue()
  539. {
  540. ghMonitorThread = CreateThread(NULL, 0, MonitorKeyValueThread, 0, 0, &gdwThreadID);
  541. }
  542. //////////////////////////////////////////////////////////////////////////////
  543. // Processes the cmdline switches
  544. //
  545. static void HandleCommandSwitches()
  546. {
  547. // Non-processing flags 1st
  548. if (gdwCmdlineFlags & OEMRESET_HIDE)
  549. {
  550. gbHide = TRUE;
  551. }
  552. if (gdwCmdlineFlags & OEMRESET_LOG)
  553. {
  554. gbLog = TRUE;
  555. }
  556. // Process switches precedence 2nd
  557. if (gdwCmdlineFlags & OEMRESET_SHUTDOWN)
  558. {
  559. if (FShutdown()) // cleanup
  560. ShutdownOrReboot(EWX_SHUTDOWN, SYSPREP_SHUTDOWN_FLAGS); // Powers down using Enduser Path
  561. }
  562. else if (gdwCmdlineFlags & OEMRESET_AUTO)
  563. {
  564. if (FShutdown()) // cleanup
  565. ShutdownOrReboot(EWX_REBOOT, SYSPREP_SHUTDOWN_FLAGS); // Reboots using Enduser Path
  566. }
  567. else if (gdwCmdlineFlags & OEMRESET_AUDIT)
  568. {
  569. ShutdownOrReboot(EWX_REBOOT, SYSPREP_SHUTDOWN_FLAGS); // Reboots using Audit Path
  570. }
  571. else if (gdwCmdlineFlags & OEMRESET_AUDITPD)
  572. {
  573. ShutdownOrReboot(EWX_SHUTDOWN, SYSPREP_SHUTDOWN_FLAGS); // Powers down using Audit Path
  574. }
  575. }
  576. void ShowOemresetDialog(HINSTANCE hInstance)
  577. {
  578. // First instance
  579. ghinstEXE = hInstance;
  580. // Set the error mode to avoid system error pop-ups.
  581. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
  582. // Monitors a registry key for switches for Oemreset
  583. StartMonitorKeyValue();
  584. // Create our modeless dialog
  585. if ((ghwndOemResetDlg = CreateOemResetDlg(hInstance)) != NULL)
  586. {
  587. MSG msg;
  588. // Hide ourself if needed and start a thread which
  589. // monitors the reg key value
  590. if (gbHide)
  591. {
  592. ShowWindow(ghwndOemResetDlg, SW_HIDE);
  593. }
  594. // Message pump
  595. while (GetMessage(&msg, NULL, 0, 0))
  596. {
  597. if (!IsWindow(ghwndOemResetDlg) || !IsDialogMessage(ghwndOemResetDlg, &msg))
  598. {
  599. TranslateMessage(&msg);
  600. DispatchMessage(&msg);
  601. }
  602. }
  603. }
  604. return;
  605. }
  606. // Make sure the user knows what he's doing with the Sids.
  607. BOOL VerifySids()
  608. {
  609. if ( RegExists(HKLM, REGSTR_PATH_SYSPREP, REGSTR_VAL_SIDGEN) )
  610. {
  611. if ( RegCheck(HKLM, REGSTR_PATH_SYSPREP, REGSTR_VAL_SIDGEN) )
  612. {
  613. if ( !NoSidGen )
  614. {
  615. return ( IDOK == MessageBoxFromMessage( MSG_DONT_GEN_SIDS, IDS_APPTITLE,
  616. MB_OKCANCEL | MB_ICONEXCLAMATION | MB_TASKMODAL | MB_DEFBUTTON2) );
  617. }
  618. }
  619. else
  620. {
  621. if ( NoSidGen )
  622. {
  623. return ( IDOK == MessageBoxFromMessage( MSG_DO_GEN_SIDS, IDS_APPTITLE,
  624. MB_OKCANCEL | MB_ICONEXCLAMATION | MB_TASKMODAL | MB_DEFBUTTON2) );
  625. }
  626. }
  627. }
  628. else if ( !NoSidGen ) // If sids have never been regenerated.
  629. {
  630. return ( IDOK == MessageBoxFromMessage( MSG_DONT_GEN_SIDS, IDS_APPTITLE,
  631. MB_OKCANCEL | MB_ICONEXCLAMATION | MB_TASKMODAL | MB_DEFBUTTON2) );
  632. }
  633. // If we fall through to here we must be ok.
  634. //
  635. return TRUE;
  636. }