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.

396 lines
8.6 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. main.c
  5. Abstract:
  6. This module implements the main startup code.
  7. Author:
  8. Wesley Witt (wesw) 21-Oct-1998
  9. Revision History:
  10. --*/
  11. #include "cmdcons.h"
  12. #pragma hdrstop
  13. BOOLEAN
  14. RcOpenSoftwareHive(
  15. VOID
  16. );
  17. //
  18. // Pointer to block of interesting values and other stuff
  19. // passed to us by setupdd.sys.
  20. //
  21. PCMDCON_BLOCK _CmdConsBlock;
  22. //
  23. // Address where we were loaded.
  24. //
  25. PVOID ImageBase;
  26. VOID
  27. RcPrintPrompt(
  28. VOID
  29. );
  30. ULONG
  31. GetTimestampForDriver(
  32. ULONG_PTR Module
  33. )
  34. {
  35. PIMAGE_DOS_HEADER DosHdr;
  36. ULONG dwTimeStamp;
  37. __try {
  38. DosHdr = (PIMAGE_DOS_HEADER) Module;
  39. if (DosHdr->e_magic == IMAGE_DOS_SIGNATURE) {
  40. dwTimeStamp = ((PIMAGE_NT_HEADERS32) ((LPBYTE)Module + DosHdr->e_lfanew))->FileHeader.TimeDateStamp;
  41. } else if (DosHdr->e_magic == IMAGE_NT_SIGNATURE) {
  42. dwTimeStamp = ((PIMAGE_NT_HEADERS32) DosHdr)->FileHeader.TimeDateStamp;
  43. } else {
  44. dwTimeStamp = 0;
  45. }
  46. } __except (EXCEPTION_EXECUTE_HANDLER) {
  47. dwTimeStamp = 0;
  48. }
  49. return dwTimeStamp;
  50. }
  51. void
  52. FormatTime(
  53. ULONG TimeStamp,
  54. LPWSTR TimeBuf
  55. )
  56. {
  57. static WCHAR mnames[] = { L"JanFebMarAprMayJunJulAugSepOctNovDec" };
  58. LARGE_INTEGER MyTime;
  59. TIME_FIELDS TimeFields;
  60. RtlSecondsSince1970ToTime( TimeStamp, &MyTime );
  61. ExSystemTimeToLocalTime( &MyTime, &MyTime );
  62. RtlTimeToTimeFields( &MyTime, &TimeFields );
  63. wcsncpy( TimeBuf, &mnames[(TimeFields.Month - 1) * 3], 3 );
  64. swprintf(
  65. &TimeBuf[3],
  66. L" %02d, %04d @ %02d:%02d:%02d",
  67. TimeFields.Day,
  68. TimeFields.Year,
  69. TimeFields.Hour,
  70. TimeFields.Minute,
  71. TimeFields.Second
  72. );
  73. }
  74. BOOLEAN
  75. LoadNonDefaultLayout(
  76. IN LPCWSTR BootDevicePath,
  77. IN LPCWSTR DirOnBootDevice,
  78. IN PVOID SifHandle
  79. )
  80. /*++
  81. Routine Description:
  82. Loads the non-default keyboard layout at users request
  83. Arguments:
  84. BootDevicePath - NT/Arc boot device path
  85. DirOnBootDevice - Directory on boot device (e.g. i386)
  86. SifHandle - Handle to txtsetup.sif
  87. Return Value:
  88. TRUE, if user selected a keyboard layout and its was loaded.
  89. Otherwise FALSE
  90. --*/
  91. {
  92. BOOLEAN ShowMenu = FALSE;
  93. ULONG KeyPressed = 0;
  94. LARGE_INTEGER Delay;
  95. LONG SecondsToDelay = 5;
  96. WCHAR DevicePath[MAX_PATH] = {0};
  97. if (BootDevicePath) {
  98. wcscpy(DevicePath, BootDevicePath);
  99. SpStringToLower(DevicePath);
  100. //
  101. // All KBD dlls are not present on floppies
  102. //
  103. if (!wcsstr(DevicePath, L"floppy")) {
  104. SpInputDrain();
  105. SpCmdConsEnableStatusText(TRUE);
  106. Delay.HighPart = -1;
  107. Delay.LowPart = -10000000;
  108. do {
  109. //
  110. // prompt the user
  111. //
  112. SpDisplayStatusText(SP_KBDLAYOUT_PROMPT,
  113. (UCHAR)(ATT_FG_BLACK | ATT_BG_WHITE),
  114. SecondsToDelay);
  115. //
  116. // sleep for a second
  117. //
  118. KeDelayExecutionThread(ExGetPreviousMode(), FALSE, &Delay);
  119. SecondsToDelay--;
  120. if (SpInputIsKeyWaiting())
  121. KeyPressed = SpInputGetKeypress();
  122. }
  123. while (SecondsToDelay && KeyPressed != ASCI_CR && KeyPressed != ASCI_ESC);
  124. if (KeyPressed == ASCI_CR)
  125. ShowMenu = TRUE;
  126. if (!ShowMenu) {
  127. //
  128. // clear status text
  129. //
  130. SpDisplayStatusOptions(DEFAULT_ATTRIBUTE, 0);
  131. } else {
  132. //
  133. // allow the user to select a particular layout dll and load it
  134. //
  135. pRcCls();
  136. SpSelectAndLoadLayoutDll((PWSTR)DirOnBootDevice, SifHandle, TRUE);
  137. }
  138. SpCmdConsEnableStatusText(FALSE);
  139. }
  140. }
  141. return ShowMenu;
  142. }
  143. ULONG
  144. CommandConsole(
  145. IN PCMDCON_BLOCK CmdConsBlock
  146. )
  147. /*++
  148. Routine Description:
  149. Top-level entry point for the command interpreter.
  150. Initializes global data and then goes into the processing loop.
  151. When the processing loop terminates, cleans up and exits.
  152. Arguments:
  153. CmdConsBlock - supplies interesting values from setupdd.sys.
  154. Return Value:
  155. None.
  156. --*/
  157. {
  158. PTOKENIZED_LINE TokenizedLine;
  159. BOOLEAN b = FALSE;
  160. ULONG rVal;
  161. WCHAR buf[64];
  162. NTSTATUS Status;
  163. SpdInitialize();
  164. _CmdConsBlock = CmdConsBlock;
  165. //
  166. // Make sure temporary buffer is large enough to hold a line of input
  167. // from the console.
  168. //
  169. ASSERT(_CmdConsBlock->TemporaryBufferSize > ((RC_MAX_LINE_LEN+1) * sizeof(WCHAR)));
  170. RcConsoleInit();
  171. RcInitializeCurrentDirectories();
  172. FormatTime( GetTimestampForDriver( (ULONG_PTR)ImageBase ), buf );
  173. RcMessageOut( MSG_SIGNON );
  174. if (LoadNonDefaultLayout(_CmdConsBlock->BootDevicePath,
  175. _CmdConsBlock->DirectoryOnBootDevice, _CmdConsBlock->SifHandle)){
  176. pRcCls();
  177. RcMessageOut( MSG_SIGNON );
  178. }
  179. RedirectToNULL = TRUE;
  180. rVal = pRcExecuteBatchFile( L"\\cmdcons\\cmdcons.txt", L"\\cmdcons\\cmdcons.log", TRUE );
  181. RedirectToNULL = FALSE;
  182. if(0 == rVal || 2 == rVal) {
  183. goto exit;
  184. }
  185. if (SelectedInstall == NULL) {
  186. if (RcCmdLogon( NULL ) == FALSE) {
  187. rVal = 0;
  188. goto exit;
  189. }
  190. }
  191. Status = RcIsNetworkDrive((PWSTR)(_CmdConsBlock->BootDevicePath));
  192. if (!NT_SUCCESS(Status)) {
  193. RcDisableCommand(RcCmdNet);
  194. }
  195. //
  196. // Disable non ARC commands
  197. //
  198. if (RcIsArc()) {
  199. RcDisableCommand(RcCmdFixBootSect);
  200. RcDisableCommand(RcCmdFixMBR);
  201. }
  202. do {
  203. RcPrintPrompt();
  204. RcLineIn(_CmdConsBlock->TemporaryBuffer,RC_MAX_LINE_LEN);
  205. TokenizedLine = RcTokenizeLine(_CmdConsBlock->TemporaryBuffer);
  206. if(TokenizedLine->TokenCount) {
  207. rVal = RcDispatchCommand(TokenizedLine);
  208. if (rVal == 0 || rVal == 2) {
  209. b = FALSE;
  210. } else {
  211. b = TRUE;
  212. }
  213. RcTextOut(L"\r\n");
  214. } else {
  215. b = TRUE;
  216. }
  217. RcFreeTokenizedLine(&TokenizedLine);
  218. } while(b);
  219. exit:
  220. SpdTerminate();
  221. RcTerminateCurrentDirectories();
  222. RcConsoleTerminate();
  223. return rVal == 2 ? 1 : 0;
  224. }
  225. VOID
  226. RcPrintPrompt(
  227. VOID
  228. )
  229. {
  230. RcGetCurrentDriveAndDir(_CmdConsBlock->TemporaryBuffer);
  231. wcscat(_CmdConsBlock->TemporaryBuffer,L">");
  232. RcRawTextOut(_CmdConsBlock->TemporaryBuffer,-1);
  233. }
  234. VOID
  235. RcNtError(
  236. IN NTSTATUS Status,
  237. IN ULONG FallbackMessageId,
  238. ...
  239. )
  240. {
  241. va_list arglist;
  242. //
  243. // Some NT errors receive special treatment.
  244. //
  245. switch(Status) {
  246. case STATUS_NO_SUCH_FILE:
  247. RcMessageOut(MSG_NO_FILES);
  248. return;
  249. case STATUS_NO_MEDIA_IN_DEVICE:
  250. RcMessageOut(MSG_NO_MEDIA_IN_DEVICE);
  251. return;
  252. case STATUS_ACCESS_DENIED:
  253. case STATUS_CANNOT_DELETE:
  254. RcMessageOut(MSG_ACCESS_DENIED);
  255. return;
  256. case STATUS_OBJECT_NAME_COLLISION:
  257. va_start(arglist,FallbackMessageId);
  258. vRcMessageOut(MSG_ALREADY_EXISTS,&arglist);
  259. va_end(arglist);
  260. return;
  261. case STATUS_OBJECT_NAME_INVALID:
  262. RcMessageOut(MSG_INVALID_NAME);
  263. return;
  264. case STATUS_OBJECT_NAME_NOT_FOUND:
  265. case STATUS_OBJECT_PATH_NOT_FOUND:
  266. RcMessageOut(MSG_FILE_NOT_FOUND);
  267. return;
  268. case STATUS_DIRECTORY_NOT_EMPTY:
  269. RcMessageOut(MSG_DIR_NOT_EMPTY);
  270. return;
  271. case STATUS_NOT_A_DIRECTORY:
  272. RcMessageOut(MSG_NOT_DIRECTORY);
  273. return;
  274. case STATUS_SHARING_VIOLATION:
  275. RcMessageOut(MSG_SHARING_VIOLATION);
  276. return;
  277. case STATUS_CONNECTION_IN_USE:
  278. RcMessageOut(MSG_CONNECTION_IN_USE);
  279. return;
  280. }
  281. //
  282. // Not a apecial case, print backup message.
  283. //
  284. va_start(arglist,FallbackMessageId);
  285. vRcMessageOut(FallbackMessageId,&arglist);
  286. va_end(arglist);
  287. }
  288. VOID
  289. RcDriverUnLoad(
  290. IN PDRIVER_OBJECT DriverObject
  291. )
  292. {
  293. }
  294. ULONG
  295. DriverEntry(
  296. IN PDRIVER_OBJECT DriverObject,
  297. IN PUNICODE_STRING RegistryPath
  298. )
  299. {
  300. //
  301. // All we do here is to call back into setupdd.sys, providing the address
  302. // of our main entry point, which it will call later. We also save away
  303. // our image base.
  304. //
  305. DriverObject->DriverUnload = RcDriverUnLoad;
  306. CommandConsoleInterface(CommandConsole);
  307. ImageBase = DriverObject->DriverStart;
  308. return(0);
  309. }