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.

629 lines
14 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. osloader.c
  5. Abstract:
  6. This module contains the code that implements the NT operating system
  7. loader.
  8. Author:
  9. David N. Cutler (davec) 10-May-1991
  10. Revision History:
  11. --*/
  12. #include "bldr.h"
  13. #include "haldtect.h"
  14. #include "parseini.h"
  15. #include "setupbat.h"
  16. #include "ctype.h"
  17. #include "stdio.h"
  18. #include "string.h"
  19. #include "msg.h"
  20. #include <netboot.h>
  21. #if defined(REMOTE_BOOT)
  22. extern BOOLEAN NetFS_Cache;
  23. UCHAR szRemoteBootCfgFile[] = "RemoteBoot.cfg";
  24. CHAR KernelFileName[8+1+3+1]="ntoskrnl.exe";
  25. CHAR HalFileName[8+1+3+1]="hal.dll";
  26. VOID
  27. BlWarnAboutFormat(
  28. IN BOOLEAN SecretValid,
  29. IN PUCHAR OsLoader
  30. );
  31. ARC_STATUS
  32. BlCheckMachineReplacement (
  33. IN PCHAR SystemDevice,
  34. IN ULONG SystemDeviceId,
  35. IN ULONGLONG NetRebootParameter,
  36. IN PUCHAR OsLoader
  37. )
  38. /*++
  39. Routine Description:
  40. This routine checks to see if a part of the machine has been replaced. Specifically,
  41. it checks if:
  42. - Hal is different.
  43. - Physical Disk is different.
  44. If it finds either case, then it creates at SETUP_LOADER_BLOCK and sets the flags
  45. to pass to the kernel.
  46. Note: NetFS_Cache is a boolean which is used to turn on/off client side caching in the loader.
  47. When set to FALSE, the cache is turned off.
  48. Arguments:
  49. SystemDevice - Character string of the ARC name of the system.
  50. SystemDeviceId - Handle to the server share where this machine account exists.
  51. NetRebootParameter - Any parameter that may have been passed during a soft reboot of the PC.
  52. OsLoader - TFTP path to osloader.exe
  53. Return Value:
  54. Success or not. Failure means to quit loading.
  55. --*/
  56. {
  57. ARC_DISK_SIGNATURE Signature;
  58. ARC_STATUS Status;
  59. BOOLEAN NetBootRequiresFormat = FALSE;
  60. BOOLEAN NetBootClientCacheStale = FALSE;
  61. BOOLEAN NetBootDisconnected = FALSE;
  62. BOOLEAN SkipHalCheck;
  63. ULONG FileId;
  64. ULONG CacheBootSerialNumber;
  65. ULONG CacheDiskSignature;
  66. ULONG ServerBootSerialNumber;
  67. ULONG ServerDiskSignature;
  68. UCHAR NetBootHalName[MAX_HAL_NAME_LENGTH + 1];
  69. PUCHAR NetBootDetectedHalName;
  70. UCHAR OutputBuffer[256];
  71. UCHAR DiskName[80];
  72. PUCHAR p;
  73. PUCHAR Guid;
  74. ULONG GuidLength;
  75. //
  76. // Detect which HAL we want to use.
  77. //
  78. NetBootDetectedHalName = SlDetectHal();
  79. SkipHalCheck = (NetBootDetectedHalName == NULL);
  80. if (!NetworkBootRom) {
  81. NetBootDisconnected = TRUE;
  82. goto EndTesting;
  83. }
  84. strcpy(OutputBuffer, NetBootPath);
  85. strcat(OutputBuffer, szRemoteBootCfgFile);
  86. if (BlOpen(SystemDeviceId, OutputBuffer, ArcOpenReadOnly, &FileId) == ESUCCESS) {
  87. Status = BlReadAtOffset(FileId, 0, sizeof(ULONG), &CacheBootSerialNumber);
  88. BlClose(FileId);
  89. if (Status != ESUCCESS) {
  90. NetBootClientCacheStale = TRUE;
  91. NetBootRequiresFormat = TRUE;
  92. NetFS_Cache = FALSE;
  93. goto EndTesting;
  94. }
  95. NetFS_Cache = FALSE;
  96. if (BlOpen(SystemDeviceId, OutputBuffer, ArcOpenReadOnly, &FileId) == ESUCCESS) {
  97. // Get parameters from each file
  98. Status = BlReadAtOffset(FileId, 0, sizeof(ULONG), &ServerBootSerialNumber);
  99. if (Status != ESUCCESS) {
  100. NetBootClientCacheStale = TRUE;
  101. NetBootRequiresFormat = TRUE;
  102. BlClose(FileId);
  103. goto EndTesting;
  104. }
  105. Status = BlReadAtOffset(FileId, sizeof(ULONG), sizeof(ULONG), &ServerDiskSignature);
  106. if (Status != ESUCCESS) {
  107. NetBootClientCacheStale = TRUE;
  108. NetBootRequiresFormat = TRUE;
  109. BlClose(FileId);
  110. goto EndTesting;
  111. }
  112. Signature.ArcName = OutputBuffer;
  113. strcpy(DiskName, NetBootActivePartitionName);
  114. p = strstr(DiskName, "partition");
  115. ASSERT( p != NULL );
  116. *p = '\0';
  117. if (!BlGetDiskSignature(DiskName,
  118. FALSE,
  119. &Signature
  120. )) {
  121. // Assume diskless PC
  122. BlClose(FileId);
  123. goto EndTesting;
  124. }
  125. CacheDiskSignature = Signature.Signature;
  126. if (CacheBootSerialNumber < ServerBootSerialNumber) {
  127. NetBootClientCacheStale = TRUE;
  128. }
  129. if (CacheDiskSignature != ServerDiskSignature) {
  130. NetBootClientCacheStale = TRUE;
  131. NetBootRequiresFormat = TRUE;
  132. BlClose(FileId);
  133. goto EndTesting;
  134. }
  135. Status = BlReadAtOffset(FileId,
  136. sizeof(ULONG) + sizeof(ULONG),
  137. sizeof(char) * (MAX_HAL_NAME_LENGTH+1),
  138. NetBootHalName
  139. );
  140. if (Status != ESUCCESS) {
  141. NetBootClientCacheStale = TRUE;
  142. NetBootRequiresFormat = TRUE;
  143. BlClose(FileId);
  144. goto EndTesting;
  145. }
  146. GetGuid(&Guid, &GuidLength);
  147. if (!SkipHalCheck && strncmp(NetBootHalName, NetBootDetectedHalName, MAX_HAL_NAME_LENGTH)) {
  148. if (!NT_SUCCESS(NetCopyHalAndKernel(NetBootDetectedHalName,
  149. Guid,
  150. GuidLength))) {
  151. Status = EMFILE;
  152. goto CleanUp;
  153. }
  154. NetBootClientCacheStale = TRUE;
  155. }
  156. BlClose(FileId);
  157. } else {
  158. // Running disconnected. Assume everything is ok.
  159. NetBootDisconnected = TRUE;
  160. }
  161. if (!NetBootClientCacheStale) {
  162. NetFS_Cache = TRUE;
  163. }
  164. } else {
  165. NetFS_Cache = FALSE;
  166. NetBootClientCacheStale = TRUE;
  167. NetBootRequiresFormat = TRUE;
  168. }
  169. EndTesting:
  170. Status = ESUCCESS;
  171. if (NetBootRequiresFormat) {
  172. BlWarnAboutFormat((BOOLEAN)(NetRebootParameter == NET_REBOOT_SECRET_VALID), OsLoader);
  173. }
  174. BlLoaderBlock->SetupLoaderBlock->Flags |= SETUPBLK_FLAGS_IS_REMOTE_BOOT;
  175. if (NetBootClientCacheStale) {
  176. NetBootRepin = TRUE;
  177. }
  178. if ( NetBootDisconnected ) {
  179. BlLoaderBlock->SetupLoaderBlock->Flags |= SETUPBLK_FLAGS_DISCONNECTED;
  180. }
  181. if ( NetBootRequiresFormat ) {
  182. BlLoaderBlock->SetupLoaderBlock->Flags |= SETUPBLK_FLAGS_FORMAT_NEEDED;
  183. }
  184. memcpy(BlLoaderBlock->SetupLoaderBlock->NetBootHalName,
  185. NetBootDetectedHalName,
  186. sizeof(BlLoaderBlock->SetupLoaderBlock->NetBootHalName)
  187. );
  188. BlLoaderBlock->SetupLoaderBlock->NetBootHalName[MAX_HAL_NAME_LENGTH] = '\0';
  189. CleanUp:
  190. return Status;
  191. }
  192. VOID
  193. BlWarnAboutFormat(
  194. IN BOOLEAN SecretValid,
  195. IN PUCHAR OsLoader
  196. )
  197. /*++
  198. Routine Description:
  199. This routine provides the user-interface for warning the user that
  200. a new harddisk has been detected and will be formatted.
  201. Arguments:
  202. SecretValid - If TRUE, then return because there is no message for the user,
  203. otherwise display a message that the user must logon and the disk will be wiped out.
  204. OsLoader - Path for TFTP to the osloader.exe image.
  205. Return Value:
  206. None.
  207. --*/
  208. {
  209. ULONG HeaderLines;
  210. ULONG TrailerLines;
  211. ULONG Count;
  212. UCHAR Key;
  213. PCHAR MenuHeader;
  214. PCHAR MenuTrailer;
  215. PCHAR Temp;
  216. ULONG DisplayLines;
  217. ULONG CurrentSelection = 0;
  218. UCHAR Buffer[16];
  219. if (SecretValid) {
  220. // We don't present the user with a screen in this case because we have already forced
  221. // a logon and a rewrite of the secret.
  222. return;
  223. } else {
  224. MenuHeader = BlFindMessage(BL_FORCELOGON_HEADER);
  225. }
  226. MenuTrailer = BlFindMessage(BL_WARNFORMAT_TRAILER);
  227. sprintf(Buffer, "%s%s", ASCI_CSI_OUT, ";44;37m"); // White on Blue
  228. ArcWrite(BlConsoleOutDeviceId, Buffer, strlen(Buffer), &Count);
  229. BlClearScreen();
  230. sprintf(Buffer, "%s%s", ASCI_CSI_OUT, ";37;44m"); // Blue on white
  231. ArcWrite(BlConsoleOutDeviceId, Buffer, strlen(Buffer), &Count);
  232. //
  233. // Count the number of lines in the header.
  234. //
  235. HeaderLines=BlCountLines(MenuHeader);
  236. //
  237. // Display the menu header.
  238. //
  239. ArcWrite(BlConsoleOutDeviceId,
  240. MenuHeader,
  241. strlen(MenuHeader),
  242. &Count);
  243. //
  244. // Count the number of lines in the trailer.
  245. //
  246. TrailerLines=BlCountLines(MenuTrailer);
  247. BlPositionCursor(1, ScreenHeight-TrailerLines);
  248. ArcWrite(BlConsoleOutDeviceId,
  249. MenuTrailer,
  250. strlen(MenuTrailer),
  251. &Count);
  252. //
  253. // Compute number of selections that can be displayed
  254. //
  255. DisplayLines = ScreenHeight-HeaderLines-TrailerLines-3;
  256. //
  257. // Start menu selection loop.
  258. //
  259. do {
  260. Temp = BlFindMessage(BL_WARNFORMAT_CONTINUE);
  261. if (Temp != NULL) {
  262. BlPositionCursor(5, HeaderLines+3);
  263. BlSetInverseMode(TRUE);
  264. ArcWrite(BlConsoleOutDeviceId,
  265. Temp,
  266. strlen(Temp),
  267. &Count);
  268. BlSetInverseMode(FALSE);
  269. }
  270. //
  271. // Loop waiting for keypress or time change.
  272. //
  273. do {
  274. if (ArcGetReadStatus(ARC_CONSOLE_INPUT) == ESUCCESS) {
  275. BlPositionCursor(1,ScreenHeight);
  276. BlClearToEndOfLine();
  277. ArcRead(ARC_CONSOLE_INPUT,
  278. &Key,
  279. sizeof(Key),
  280. &Count);
  281. break;
  282. }
  283. } while ( TRUE );
  284. switch (Key) {
  285. case ASCI_CSI_IN:
  286. ArcRead(ARC_CONSOLE_INPUT,
  287. &Key,
  288. sizeof(Key),
  289. &Count);
  290. break;
  291. default:
  292. break;
  293. }
  294. } while ( (Key != ASCII_CR) && (Key != ASCII_LF) );
  295. BlClearScreen();
  296. if (!SecretValid) {
  297. while ( TRUE ) {
  298. NetSoftReboot(
  299. #if defined(_ALPHA_)
  300. #if defined(_AXP64_)
  301. "OSChooser\\axp64\\startrom.com",
  302. #else
  303. "OSChooser\\alpha\\startrom.com",
  304. #endif
  305. #endif
  306. #if defined(_MIPS_)
  307. "OSChooser\\mips\\startrom.com",
  308. #endif
  309. #if defined(_PPC_)
  310. "OSChooser\\ppc\\startrom.com",
  311. #endif
  312. #if defined(_IA64_)
  313. "OSChooser\\ia64\\startrom.com",
  314. #endif
  315. #if defined(_X86_)
  316. "OSChooser\\i386\\startrom.com",
  317. #endif
  318. NET_REBOOT_WRITE_SECRET_ONLY,
  319. OsLoader,
  320. NULL, // SIF file
  321. NULL, // user
  322. NULL, // domain
  323. NULL // password
  324. );
  325. }
  326. }
  327. }
  328. #endif // defined(REMOTE_BOOT)
  329. //
  330. // NOTE: [bassamt] Stubs for TextMode setup funtions. These
  331. // are needed so that we can call SlDetectHal during regular boot.
  332. //
  333. PVOID InfFile = NULL;
  334. PVOID WinntSifHandle = NULL;
  335. BOOLEAN DisableACPI = FALSE;
  336. VOID
  337. SlNoMemError(
  338. IN ULONG Line,
  339. IN PCHAR File
  340. )
  341. /*++
  342. Routine Description:
  343. This routine does nothing.
  344. Arguments:
  345. Line - Line number of the error.
  346. File - Name of the file with the error.
  347. Return Value:
  348. None.
  349. --*/
  350. {
  351. UNREFERENCED_PARAMETER( Line );
  352. UNREFERENCED_PARAMETER( File );
  353. return;
  354. }
  355. VOID
  356. SlBadInfLineError(
  357. IN ULONG Line,
  358. IN PCHAR INFFile
  359. )
  360. /*++
  361. Routine Description:
  362. This routine does nothing.
  363. Arguments:
  364. Line - Line number of the error.
  365. INFFile - Supplies a pointer to the INF filename.
  366. Return Value:
  367. None.
  368. --*/
  369. {
  370. UNREFERENCED_PARAMETER( Line );
  371. UNREFERENCED_PARAMETER( INFFile );
  372. return;
  373. }
  374. VOID
  375. SlErrorBox(
  376. IN ULONG MessageId,
  377. IN ULONG Line,
  378. IN PCHAR File
  379. )
  380. /*++
  381. Routine Description:
  382. This routine does nothing.
  383. Arguments:
  384. MessageId - Id of the text to display.
  385. Line - Line number of the of the warning.
  386. File - Name of the file where warning is coming from.
  387. Return Value:
  388. None.
  389. --*/
  390. {
  391. UNREFERENCED_PARAMETER( MessageId );
  392. UNREFERENCED_PARAMETER( Line );
  393. UNREFERENCED_PARAMETER( File );
  394. return;
  395. }
  396. VOID
  397. SlFriendlyError(
  398. IN ULONG uStatus,
  399. IN PCHAR pchBadFile,
  400. IN ULONG uLine,
  401. IN PCHAR pchCodeFile
  402. )
  403. /*++
  404. Routine Description:
  405. This routine does nothing.
  406. Arguments:
  407. uStatus - ARC error code
  408. pchBadFile - Name of file causing error (Must be given for handled
  409. ARC codes. Optional for unhandled codes.)
  410. uLine - Line # in source code file where error occurred (only
  411. used for unhandled codes.)
  412. pchCodeFile - Name of souce code file where error occurred (only
  413. used for unhandled codes.)
  414. Return Value:
  415. None.
  416. --*/
  417. {
  418. UNREFERENCED_PARAMETER( uStatus );
  419. UNREFERENCED_PARAMETER( pchBadFile );
  420. UNREFERENCED_PARAMETER( uLine );
  421. UNREFERENCED_PARAMETER( pchCodeFile );
  422. return;
  423. }
  424. VOID
  425. SlFatalError(
  426. IN ULONG MessageId,
  427. ...
  428. )
  429. /*++
  430. Routine Description:
  431. This routine does nothing. In the context of dynamic HAL detection, we just ignore the
  432. error and hope everything is ok.
  433. Arguments:
  434. MessageId - Supplies ID of message box to be presented.
  435. any sprintf-compatible arguments to be inserted in the
  436. message box.
  437. Return Value:
  438. None.
  439. --*/
  440. {
  441. UNREFERENCED_PARAMETER( MessageId );
  442. return;
  443. }
  444. ULONG
  445. SlGetChar(
  446. VOID
  447. )
  448. {
  449. return 0;
  450. }
  451. VOID
  452. SlPrint(
  453. IN PTCHAR FormatString,
  454. ...
  455. )
  456. {
  457. UNREFERENCED_PARAMETER( FormatString );
  458. return;
  459. }
  460.