Leaked source code of windows server 2003
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.

430 lines
13 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. misc.c
  5. Abstract:
  6. This module contains misc function for processing section of WINBOM.INI
  7. Author:
  8. Donald McNamara (donaldm) 5/10/2000
  9. Revision History:
  10. --*/
  11. #include "factoryp.h"
  12. #define REG_VAL_COMPREBOOT _T("ComputerNameReboot")
  13. // for run-time loading of GenerateName from syssetup.dll
  14. typedef BOOL (WINAPI *GENERATENAME)
  15. (
  16. PWSTR GeneratedString,
  17. DWORD DesiredStrLen
  18. );
  19. // Local functions
  20. //
  21. VOID SetSetupShutdownRequirement(SHUTDOWN_ACTION sa);
  22. static BOOL SysprepCommands(LPTSTR lpWinBom, LPTSTR lpCommandLine, DWORD cbCommandLine, LPBOOL lpbDefault);
  23. /*++
  24. ===============================================================================
  25. Routine Description:
  26. BOOL ComputerName
  27. This routine will set the computer name to the value specified in WINBOM.INI
  28. Arguments:
  29. lpStateData->lpszWinBOMPath
  30. - pointer to the fully qualifed WINBOM path
  31. Return Value:
  32. TRUE if no error.
  33. lpStateData->bQuit
  34. - TRUE if reboot required.
  35. ===============================================================================
  36. --*/
  37. BOOL ComputerName(LPSTATEDATA lpStateData)
  38. {
  39. LPTSTR pszWinBOMPath = lpStateData->lpszWinBOMPath;
  40. WCHAR szComputerName[100];
  41. WCHAR szScratch[10];
  42. HINSTANCE hInstSysSetup = NULL;
  43. GENERATENAME pGenerateName = NULL;
  44. // See if we already set the computer name and just rebooted.
  45. //
  46. if ( RegCheck(HKLM, REG_FACTORY_STATE, REG_VAL_COMPREBOOT) )
  47. {
  48. RegDelete(HKLM, REG_FACTORY_STATE, REG_VAL_COMPREBOOT);
  49. FacLogFileStr(3, _T("FACTORY::ComputerName() - Already set the computer name, skipping this state (normal if just rebooted)."));
  50. return TRUE;
  51. }
  52. if (GetPrivateProfileString(INI_SEC_WBOM_FACTORY,
  53. INI_KEY_WBOM_FACTCOMPNAME,
  54. L"",
  55. szComputerName,
  56. sizeof(szComputerName)/sizeof(WCHAR),
  57. pszWinBOMPath))
  58. {
  59. // We are setting the computer name, so set this substate in case
  60. // we reboot.
  61. //
  62. RegSetString(HKLM, REG_FACTORY_STATE, REG_VAL_COMPREBOOT, _T("1"));
  63. // See if we should generate a random name
  64. if (szComputerName[0] == L'*')
  65. {
  66. GenUniqueName(szComputerName, 15);
  67. }
  68. // Set the computername
  69. SetComputerNameEx(ComputerNamePhysicalDnsHostname, szComputerName);
  70. // See if we should NOT reboot
  71. if (GetPrivateProfileString(INI_SEC_WBOM_FACTORY,
  72. INI_KEY_WBOM_REBOOTCOMPNAME,
  73. L"No",
  74. szScratch,
  75. sizeof(szScratch)/sizeof(WCHAR),
  76. pszWinBOMPath))
  77. {
  78. // Also we need to work on this computer name code to see if it can be
  79. // done without a reboot needed.
  80. if (LSTRCMPI(szScratch, L"Yes") == 0)
  81. {
  82. // Tells Winlogon that we require a reboot
  83. // even though setup_type was noreboot
  84. //
  85. FacLogFileStr(3, _T("FACTORY::ComputerName() - Rebooting after setting the computer name."));
  86. SetSetupShutdownRequirement(ShutdownReboot);
  87. lpStateData->bQuit = TRUE;
  88. }
  89. }
  90. }
  91. return TRUE;
  92. }
  93. BOOL DisplayComputerName(LPSTATEDATA lpStateData)
  94. {
  95. BOOL bRet = FALSE;
  96. // See if we already set the computer name and just rebooted.
  97. //
  98. if ( !RegCheck(HKLM, REG_FACTORY_STATE, REG_VAL_COMPREBOOT) )
  99. {
  100. // Check to see if the option is set.
  101. //
  102. if ( IniSettingExists(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_FACTORY, INI_KEY_WBOM_FACTCOMPNAME, NULL) )
  103. {
  104. // Always display if there is a computer name to set.
  105. //
  106. bRet = TRUE;
  107. // See if we are going to reboot after.
  108. //
  109. if ( IniSettingExists(lpStateData->lpszWinBOMPath, INI_SEC_WBOM_FACTORY, INI_KEY_WBOM_REBOOTCOMPNAME, INI_VAL_WBOM_YES) )
  110. {
  111. lpStateData->bQuit = TRUE;
  112. }
  113. }
  114. }
  115. return bRet;
  116. }
  117. /*++
  118. Routine Description:
  119. Even though FACTORY.EXE was set as NOREBOOT setup type a system shutdown or
  120. reboot maybe required.
  121. Do this by setting the SetupShutdownRequired key value and
  122. a value that cooresponds to the SHUTDOWN_ACTION enum values
  123. Arguments:
  124. None.
  125. Return Value:
  126. None.
  127. --*/
  128. VOID
  129. SetSetupShutdownRequirement(
  130. SHUTDOWN_ACTION sa
  131. )
  132. {
  133. DWORD ShutdownType = sa;
  134. DWORD dwType, dwSize;
  135. HKEY hKeySetup;
  136. BOOL fError = FALSE;
  137. if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\Setup"), 0,
  138. KEY_READ | KEY_SET_VALUE, &hKeySetup) == ERROR_SUCCESS)
  139. {
  140. if (ERROR_SUCCESS != RegSetValueEx (hKeySetup, TEXT("SetupShutdownRequired"), 0,
  141. REG_DWORD, (CONST LPBYTE)&ShutdownType, sizeof(ShutdownType)))
  142. FacLogFile(0 | LOG_ERR, IDS_ERR_SHUTDNREQREGVAL);
  143. RegCloseKey (hKeySetup);
  144. }
  145. else
  146. FacLogFile(0 | LOG_ERR, IDS_ERR_OPENSETUPREGKEY);
  147. }
  148. BOOL Reseal(LPSTATEDATA lpStateData)
  149. {
  150. TCHAR szSysprep[MAX_PATH],
  151. szCmdLine[MAX_PATH] = NULLSTR;
  152. DWORD dwExitCode = 0;
  153. BOOL fResealDefault = FALSE,
  154. bRet;
  155. // Get the command line to pass sysprep.
  156. //
  157. if ( !SysprepCommands(lpStateData->lpszWinBOMPath, szCmdLine, AS(szCmdLine), &fResealDefault) )
  158. {
  159. FacLogFile(0, IDS_LOG_NOSYSPREP);
  160. return TRUE;
  161. }
  162. // Create the full path to sysprep.
  163. //
  164. lstrcpyn(szSysprep, g_szSysprepDir, AS(szSysprep));
  165. AddPathN(szSysprep, _T("sysprep.exe"), AS ( szSysprep ) );
  166. // Log what we are running in debug builds.
  167. //
  168. FacLogFileStr(3, _T("Reseal command: \"%s %s\""), szSysprep, szCmdLine);
  169. // This actually runs sysprep (it is only hidden if it isn't the default
  170. // sysprep that runs normally).
  171. //
  172. bRet = InvokeExternalApplicationEx(szSysprep, szCmdLine, fResealDefault ? NULL : &dwExitCode, INFINITE, !fResealDefault);
  173. // Only quit if we launched sysprep to do something specific.
  174. //
  175. if ( !fResealDefault )
  176. {
  177. lpStateData->bQuit = TRUE;
  178. }
  179. // Return success if we launched sysprep.
  180. //
  181. return bRet;
  182. }
  183. BOOL DisplayReseal(LPSTATEDATA lpStateData)
  184. {
  185. BOOL bRet,
  186. bDefault;
  187. // The return value will determine if we show this state or not.
  188. //
  189. bRet = SysprepCommands(lpStateData->lpszWinBOMPath, NULL, 0, &bDefault);
  190. // If the default action is going to be executed, then this isn't the last
  191. // state.
  192. //
  193. if ( !bDefault )
  194. {
  195. lpStateData->bQuit = TRUE;
  196. }
  197. return bRet;
  198. }
  199. /*++
  200. ===============================================================================
  201. Routine Description:
  202. TCHAR GetDriveLetter
  203. This routine will determine the drive letter for the first drive of a
  204. specified type.
  205. Arguments:
  206. uDriveType - a specific type of drive present on the system will be
  207. searched for.
  208. Return Value:
  209. Drive letter if there is a drive letter determined.
  210. 0 if the drive letter was not determined.
  211. ===============================================================================
  212. --*/
  213. TCHAR GetDriveLetter(UINT uDriveType)
  214. {
  215. DWORD dwDrives;
  216. TCHAR cDrive = NULLCHR,
  217. szDrive[] = _T("_:\\");
  218. // Loop through all the drives on the system.
  219. //
  220. for ( szDrive[0] = _T('A'), dwDrives = GetLogicalDrives();
  221. ( szDrive[0] <= _T('Z') ) && dwDrives && ( NULLCHR == cDrive );
  222. szDrive[0]++, dwDrives >>= 1 )
  223. {
  224. // First check to see if the first bit is set (which means
  225. // this drive exists in the system). Then make sure it is
  226. // a drive type that we want.
  227. //
  228. if ( ( dwDrives & 0x1 ) &&
  229. ( GetDriveType(szDrive) == uDriveType ) )
  230. {
  231. cDrive = szDrive[0];
  232. }
  233. }
  234. return cDrive;
  235. }
  236. static BOOL SysprepCommands(LPTSTR lpWinBom, LPTSTR lpCommandLine, DWORD cbCommandLine, LPBOOL lpbDefault)
  237. {
  238. TCHAR szBuffer[256],
  239. szCmdLine[MAX_PATH] = NULLSTR;
  240. BOOL bCmdLine = ( lpCommandLine && cbCommandLine );
  241. // Init the default to false.
  242. //
  243. *lpbDefault = FALSE;
  244. // If Reseal key is empty we do the default which is to launch sysprep.exe -quiet
  245. // and not wait for the exit code
  246. //
  247. szBuffer[0] = NULLCHR;
  248. GetPrivateProfileString(INI_SEC_WBOM_FACTORY, INI_KEY_WBOM_FACTORY_RESEAL, _T(""), szBuffer, AS(szBuffer), lpWinBom);
  249. // ISSUE-2002/02/25-acosma,robertko - Use WBOM_YES.
  250. //
  251. if ( ( LSTRCMPI(szBuffer, _T("YES")) == 0 ) || ( LSTRCMPI(szBuffer, INI_VAL_WBOM_SHUTDOWN) == 0 ) )
  252. {
  253. // Set the initial command line for sysprep.exe to reseal
  254. //
  255. lstrcpyn(szCmdLine, _T("-quiet"), AS ( szCmdLine ) );
  256. }
  257. else if ( LSTRCMPI(szBuffer, INI_VAL_WBOM_REBOOT) == 0 )
  258. {
  259. // Set initial command line for sysprep.exe to reseal and reboot
  260. lstrcpyn(szCmdLine, _T("-quiet -reboot"), AS ( szCmdLine ) );
  261. }
  262. else if ( LSTRCMPI(szBuffer, INI_VAL_WBOM_FORCESHUTDOWN) == 0 )
  263. {
  264. // Set initial command line for sysprep.exe to reseale and force SHUTDOWN instead of POWEROFF
  265. lstrcpyn(szCmdLine, _T("-quiet -forceshutdown"), AS ( szCmdLine ) );
  266. }
  267. // ISSUE-2002/02/25-acosma,robertko - Use WBOM_NO.
  268. //
  269. else if ( LSTRCMPI(szBuffer, _T("NO")) == 0 )
  270. {
  271. // Don't run sysprep and return false so the caller knows we don't want to run it.
  272. //
  273. return FALSE;
  274. }
  275. else
  276. {
  277. // Default Reseal is to just launch sysprep.exe -quiet
  278. //
  279. if ( bCmdLine )
  280. {
  281. lstrcpyn(lpCommandLine, _T("-quiet"), cbCommandLine);
  282. }
  283. // This is the default, so just return now.
  284. //
  285. *lpbDefault = TRUE;
  286. return TRUE;
  287. }
  288. // See if we should pass the -mini or -factory flag to sysprep.exe.
  289. //
  290. if ( bCmdLine )
  291. {
  292. szBuffer[0] = NULLCHR;
  293. GetPrivateProfileString(INI_SEC_WBOM_FACTORY, INI_KEY_WBOM_FACTORY_RESEALMODE, INI_VAL_WBOM_OOBE, szBuffer, AS(szBuffer), lpWinBom);
  294. if ( ( LSTRCMPI(szBuffer, INI_VAL_WBOM_MINI) == 0 ) ||
  295. ( LSTRCMPI(szBuffer, INI_VAL_WBOM_MINISETUP) == 0 ) )
  296. {
  297. // Append -mini to the command line.
  298. //
  299. if ( FAILED ( StringCchCat ( szCmdLine, AS ( szCmdLine ), _T(" -reseal -mini")) ) )
  300. {
  301. FacLogFileStr(3, _T("StringCchCat failed %s %s\n"), szCmdLine, _T(" -reseal -mini") ) ;
  302. }
  303. }
  304. else if ( LSTRCMPI(szBuffer, INI_VAL_WBOM_FACTORY) == 0 )
  305. {
  306. // Go into factory mode again by appending -factory to the command line.
  307. //
  308. if ( FAILED ( StringCchCat ( szCmdLine, AS ( szCmdLine ), _T(" -factory")) ) )
  309. {
  310. FacLogFileStr(3, _T("StringCchCat failed %s %s\n"), szCmdLine, _T(" -factory") ) ;
  311. }
  312. }
  313. else if ( LSTRCMPI(szBuffer, INI_VAL_WBOM_AUDIT) == 0 )
  314. {
  315. // Go into audit mode, by appending -audit to the command line.
  316. //
  317. if ( FAILED ( StringCchCat ( szCmdLine, AS ( szCmdLine ), _T(" -audit")) ) )
  318. {
  319. FacLogFileStr(3, _T("StringCchCat failed %s %s\n"), szCmdLine, _T(" -audit") ) ;
  320. }
  321. }
  322. else
  323. {
  324. // Go into OOBE by default by just appending -reseal to the command line.
  325. //
  326. if ( FAILED ( StringCchCat ( szCmdLine, AS ( szCmdLine ), _T(" -reseal")) ) )
  327. {
  328. FacLogFileStr(3, _T("StringCchCat failed %s %s\n"), szCmdLine, _T(" -reseal") ) ;
  329. }
  330. }
  331. // Append the ResealFlags to szCmdLine for Sysprep
  332. //
  333. szBuffer[0] = NULLCHR;
  334. GetPrivateProfileString(INI_SEC_WBOM_FACTORY, INI_KEY_WBOM_FACTORY_RESEALFLAGS, NULLSTR, szBuffer, AS(szBuffer), lpWinBom);
  335. if ( szBuffer[0] )
  336. {
  337. if ( FAILED ( StringCchCat ( szCmdLine, AS ( szCmdLine ), _T(" ")) ) )
  338. {
  339. FacLogFileStr(3, _T("StringCchCat failed %s %s\n"), szCmdLine, _T(" ") ) ;
  340. }
  341. if ( FAILED ( StringCchCat ( szCmdLine, AS ( szCmdLine ), szBuffer) ) )
  342. {
  343. FacLogFileStr(3, _T("StringCchCat failed %s %s\n"), szCmdLine, szBuffer ) ;
  344. }
  345. }
  346. // Now return the command line.
  347. //
  348. lstrcpyn(lpCommandLine, szCmdLine, cbCommandLine);
  349. }
  350. return TRUE;
  351. }