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.

1176 lines
28 KiB

  1. in DRIVER_ENTRY
  2. }
  3. DeviceExtension->CommandPhase = ScrIdle;
  4. NTSTATUS
  5. ScreenInitializeDevice(
  6. IN PDEVICE_EXTENSION DeviceExtension
  7. )
  8. /*++
  9. Routine Description:
  10. Arguments:
  11. DeviceObject - Pointer to the device object for this driver.
  12. Return Value:
  13. The function value is the status of the operation.
  14. --*/
  15. {
  16. NTSTATUS Status;
  17. //
  18. // determine hardware configuration.
  19. //
  20. UCHAR videoType; // possible VGA video type
  21. KIRQL OldIrql;
  22. UCHAR Color = TRUE; // assume color adapter present
  23. //
  24. // Start by assuming there is no adapter
  25. //
  26. DeviceExtension->VideoHardware.fVideoType = VDHERROR_NO_ADAPTER;
  27. //
  28. // Determine which adapter is present by testing the presence of memory.
  29. // A0000 isn't accessible because EGA and VGA come up in character mode.
  30. // put it in graphics mode and then test for memory at A0000.
  31. //
  32. KeRaiseIrql(POWER_LEVEL,
  33. &OldIrql);
  34. EnableA0000();
  35. KeLowerIrql(OldIrql);
  36. if (MemoryPresent(MEM_EGA_OR_VGA)) {
  37. //
  38. // A0000 is present so we must either have an EGA or a VGA.
  39. // We must now determine which one it is.
  40. //
  41. videoType = VGA_COLOR;
  42. if (videoType == VGA_CANNOT_DETERMINE) {
  43. } else { // We are in VGA mode
  44. //
  45. // determine and record VGA information; always 256K
  46. //
  47. DeviceExtension->VideoHardware.memory = 256L * 1024L;
  48. switch (videoType) {
  49. case VGA_COLOR:
  50. DeviceExtension->VideoHardware.display = Color8512_8513;
  51. DeviceExtension->VideoHardware.popupMode = ModeIndex_VGA3p;
  52. DeviceExtension->VideoHardware.fVideoType ^= VGC_BIT;
  53. break;
  54. case VGA_MONO:
  55. DeviceExtension->VideoHardware.display = Color8512_8513;
  56. DeviceExtension->VideoHardware.popupMode = ModeIndex_VGA3p;
  57. DeviceExtension->VideoHardware.fVideoType ^= VGC_BIT;
  58. break;
  59. case VGA_NODISPLAY:
  60. DeviceExtension->VideoHardware.display = NoDisplay;
  61. DeviceExtension->VideoHardware.popupMode = ModeIndex_VGA3p;
  62. DeviceExtension->VideoHardware.fVideoType = NODISPLAY_BIT;
  63. break;
  64. }
  65. }
  66. }
  67. KeRaiseIrql(POWER_LEVEL,
  68. &OldIrql);
  69. DisableA0000(Color);
  70. KeLowerIrql(OldIrql);
  71. if (DeviceExtension->VideoHardware.fVideoType == NODISPLAY_BIT) {
  72. return STATUS_NO_SUCH_DEVICE;
  73. }
  74. //
  75. // set up the ROM font addresses
  76. //
  77. InitializeFonts(DeviceExtension);
  78. //
  79. // set the mode.
  80. //
  81. Status = PrepareForSetMode(DeviceExtension,
  82. DeviceExtension->VideoHardware.popupMode);
  83. if (!NT_SUCCESS(Status)) {
  84. return Status;
  85. }
  86. KeRaiseIrql(POWER_LEVEL,
  87. &OldIrql);
  88. SetHWMode(DeviceExtension,
  89. DeviceExtension->VideoHardware.popupMode,
  90. TRUE);
  91. //
  92. // Setting up the cursor position and initializing the CLUT only needs
  93. // to be done for VGA mode.
  94. //
  95. //
  96. // set up the cursor position and type
  97. //
  98. {
  99. SCREEN_CURSOR_POSITION CursorPosition;
  100. SCREEN_CURSOR_TYPE CursorType;
  101. CursorPosition.Column = 0;
  102. CursorPosition.Row = 0;
  103. SetCursorPosition(DeviceExtension,
  104. &CursorPosition);
  105. CursorType.TopScanLine = (USHORT)
  106. (Fonts[DeviceExtension->RomFontIndex].PelRows-2);
  107. CursorType.BottomScanLine = 31;
  108. CursorType.CursorVisible = TRUE;
  109. SetCursorType(DeviceExtension,
  110. &CursorType);
  111. }
  112. //
  113. // initialize the CLUT.
  114. //
  115. SetColorLookup(DeviceExtension,
  116. (PSCREEN_CLUT) &InitialClutVGA,
  117. TRUE);
  118. //
  119. // initialize the palette registers.
  120. //
  121. SetPaletteReg(DeviceExtension,
  122. (PSCREEN_PALETTE_DATA) &InitialPaletteVGA,
  123. TRUE);
  124. KeLowerIrql(OldIrql);
  125. return STATUS_SUCCESS;
  126. }
  127. BOOLEAN
  128. MemoryPresent(
  129. IN ULONG Address
  130. )
  131. /*++
  132. Routine Description:
  133. This routine returns TRUE if the specified memory is present. It
  134. maps a view of the requested address, reads the original ulong, writes
  135. a different one, reads it to make sure its the written value, then
  136. restores the original value.
  137. Arguments:
  138. Address - Physical address to check
  139. Return Value:
  140. TRUE if specified memory is present, FALSE if not.
  141. --*/
  142. {
  143. BOOLEAN GoodMemory = FALSE; // assume no memory at location
  144. volatile PULONG VideoMemory;
  145. ULONG TestValue; // memory read/write test value
  146. ULONG OriginalValue; // original value at tested location
  147. PVOID Base;
  148. Base = MmMapIoSpace((PHYSICAL_ADDRESS) Address,
  149. sizeof (ULONG),
  150. FALSE);
  151. //
  152. // Read a ulong from the address and save it. write
  153. // a different ulong to the address. read from the address and see if
  154. // it matches the written ulong.
  155. //
  156. VideoMemory = (PULONG) Base;
  157. TestValue = 0xBBBBBBBB;
  158. if ((OriginalValue = *VideoMemory) == 0xBBBBBBBB) {
  159. TestValue >>= 1;
  160. }
  161. *VideoMemory = TestValue; // write out a test value
  162. if (GoodMemory = (BOOLEAN) (*VideoMemory == TestValue) ) {
  163. *VideoMemory = OriginalValue; // restore value
  164. }
  165. MmUnmapIoSpace(Base,
  166. sizeof (ULONG));
  167. return GoodMemory;
  168. }
  169. VOID
  170. InitializeFonts(
  171. IN PDEVICE_EXTENSION DeviceExtension
  172. )
  173. /*++
  174. Routine Description:
  175. This routine determines the addresses of the ROM fonts.
  176. Arguments:
  177. DeviceExtension - pointer to device extension for this driver
  178. Return Value:
  179. none
  180. --*/
  181. {
  182. PHYSICAL_ADDRESS PVB;
  183. PUCHAR RomPtr;
  184. ULONG RomFontLen,ROMSrchLen;
  185. ULONG i;
  186. //
  187. // Search through ROM to find 8x8, 8x14, 8x16, 9x14, and 9x16 fonts
  188. // ROM fonts are located at physical addresses:
  189. // C0000 - EGA and PS/2 Adapter
  190. // E0000 - VGA
  191. //
  192. for (PVB = 0xE0000, RomFontLen = 0xFFFF, ROMSrchLen = 0xFFF0;
  193. PVB >= 0xC0000;
  194. PVB -= 0x20000, RomFontLen -= 0x8000, ROMSrchLen = 0x7FF0 ) {
  195. RomPtr = MmMapIoSpace(PVB, RomFontLen, FALSE);
  196. //
  197. // Locate 8x8 ROM font on EGA and VGA
  198. //
  199. for (i = 0; i < ROMSrchLen; i++) {
  200. while ( (i < ROMSrchLen) && (RomPtr[i] != (UCHAR)0x7E) ) {
  201. i++;
  202. }
  203. if ( i < ROMSrchLen) {
  204. if ( (RomPtr[i+1] == (UCHAR)0x81) &&
  205. (RomPtr[i+2] == (UCHAR)0xA5) &&
  206. (RomPtr[i+3] == (UCHAR)0x81) ) {
  207. if (!Fonts[ROM_FONT_8x8].PVB && RomPtr[i+4] ==
  208. (UCHAR)0xBD) {
  209. Fonts[ROM_FONT_8x8].PVB = PVB + i - 8;
  210. } else {
  211. //
  212. // Locate 8x14 ROM font on EGA, VGA, and PS/2 adapter only
  213. //
  214. if ( (RomPtr[i+4] == (UCHAR)0x81) &&
  215. (RomPtr[i+5] == (UCHAR)0xBD) &&
  216. (RomPtr[i+6] == (UCHAR)0x99) &&
  217. (RomPtr[i+7] == (UCHAR)0x81) ) {
  218. // e3f40
  219. if (!Fonts[ROM_FONT_8x14].PVB &&
  220. RomPtr[i+8] != (UCHAR)0x81) {
  221. Fonts[ROM_FONT_8x14].PVB = PVB + i- 16;
  222. } else {
  223. //
  224. // Locate 8x16 ROM font on VGA, and PS/2 adapter only
  225. //
  226. // e3e04
  227. if ( !Fonts[ROM_FONT_8x16].PVB &&
  228. RomPtr[i+8] == (UCHAR)0x81 ) {
  229. Fonts[ROM_FONT_8x16].PVB = PVB + i - 18;
  230. }
  231. }
  232. } // if ( (RomPtr[i+4] == (UCHAR)0x81) &&
  233. } // if (!Fonts[ROM_FONT_8x8].PVB && RomPtr[i+4]
  234. } // if ( (RomPtr[i+1] == (UCHAR)0x81) &&
  235. } // if ( i < ROMSrchLen)
  236. } // end for loop Locate 8x8, 8x14, 8x16
  237. //
  238. // Locate 9x14 ROM font on EGA, VGA, and PS/2 adapter only
  239. //
  240. for ( i = 0; i < ROMSrchLen; i++ ) {
  241. while ( (i < ROMSrchLen) && (RomPtr[i] != (UCHAR)0x1D) ) {
  242. i++;
  243. }
  244. if ( i < ROMSrchLen) {
  245. if ( ( RomPtr[i+1] == (UCHAR)0x00 ) &&
  246. ( RomPtr[i+2] == (UCHAR)0x00 ) &&
  247. ( RomPtr[i+3] == (UCHAR)0x00 ) &&
  248. ( RomPtr[i+4] == (UCHAR)0x00 ) ) {
  249. if ( !Fonts[ROM_FONT_9x14].PVB &&
  250. ( RomPtr[i+5] == (UCHAR)0x24 ) &&
  251. ( RomPtr[i+6] == (UCHAR)0x66 ) ) {
  252. Fonts[ROM_FONT_9x14].PVB = PVB + i;
  253. }
  254. //
  255. // Locate 9x16 ROM font on VGA, and PS/2 adapter only
  256. //
  257. if (!Fonts[ROM_FONT_9x16].PVB &&
  258. (RomPtr[i+5] == (UCHAR)0x00) &&
  259. (RomPtr[i+6] == (UCHAR)0x24) ) {
  260. Fonts[ROM_FONT_9x16].PVB = PVB + i;
  261. }
  262. }
  263. }
  264. } /* Locate 9x14, 9x16 */
  265. MmUnmapIoSpace(RomPtr,RomFontLen);
  266. } // Search next ROM area for fonts */
  267. if (!Fonts[ROM_FONT_8x8].PVB)
  268. Dprint(1, ("Fonts[ROM_FONT_8x8] not found\n"));
  269. if (!Fonts[ROM_FONT_8x14].PVB)
  270. Dprint(1, ("Fonts[ROM_FONT_8x14] not found \n"));
  271. if (!Fonts[ROM_FONT_8x16].PVB)
  272. Dprint(1, ("Fonts[ROM_FONT_8x16] not found \n"));
  273. if (!Fonts[ROM_FONT_9x14].PVB)
  274. Dprint(1, ("Fonts[ROM_FONT_9x14] not found \n"));
  275. if (!Fonts[ROM_FONT_9x16].PVB)
  276. Dprint(1, ("Fonts[ROM_FONT_9x16] not found \n"));
  277. //
  278. // we happen to know that the 8x8 font is loaded during boot. we can't
  279. // call SetFont at this point because it requires data initialized by
  280. // SetMode. But SetMode requires data initialized by SetFont. so we
  281. // just set up RomFontIndex here manually.
  282. //
  283. DeviceExtension->RomFontIndex = 1;
  284. }
  285. NTSTATUS
  286. ScreenDispatch(
  287. NTSTATUS Status;
  288. PIO_STACK_LOCATION IrpSp;
  289. KIRQL OldIrql;
  290. PDEVICE_EXTENSION DeviceExtension;
  291. BOOLEAN PowerFailed = FALSE;
  292. PVOID SystemBuffer;
  293. case IRP_MJ_CLOSE:
  294. Dprint(2, ("VgaDispatch - CLose\n"));
  295. Status = ZwUnmapViewOfSection(NtCurrentProcess(),
  296. DeviceExtension->RealFrameBase);
  297. if (NT_SUCCESS(Status)) {
  298. ZwClose(DeviceExtension->FrameSection);
  299. }
  300. break;
  301. case IOCTL_SCR_QUERY_FRAME_BUFFER:
  302. Dprint(2, ("VgaDispatch - QueryFrameBuffer\n"));
  303. //
  304. // check for adequate buffer length
  305. //
  306. if (RequestPacket->OutputBufferLength <
  307. sizeof(SCREEN_FRAME_BUFFER_INFO)) {
  308. Status = STATUS_BUFFER_TOO_SMALL;
  309. } else {
  310. //
  311. // everything's ok, return the info.
  312. //
  313. ((PSCREEN_FRAME_BUFFER_INFO) SystemBuffer)->FrameBase =
  314. DeviceExtension->FrameBase;
  315. ((PSCREEN_FRAME_BUFFER_INFO) SystemBuffer)->FrameLength =
  316. DeviceExtension->FrameLength;
  317. Status = STATUS_SUCCESS;
  318. Irp->IoStatus.Information = sizeof(SCREEN_FRAME_BUFFER_INFO);
  319. }
  320. break;
  321. case IOCTL_SCR_QUERY_AVAIL_MODES:
  322. Dprint(2, ("VgaDispatch - QueryAvailableModes\n"));
  323. Status = GetAvailableModes(DeviceExtension,
  324. RequestPacket->OutputBufferLength,
  325. SystemBuffer,
  326. &Irp->IoStatus.Information);
  327. break;
  328. case IOCTL_SCR_QUERY_NUM_AVAIL_MODES:
  329. Dprint(2, ("VgaDispatch - QueryNumAvailableModes\n"));
  330. if (RequestPacket->OutputBufferLength <
  331. sizeof(SCREEN_NUM_MODES)) {
  332. Status = STATUS_BUFFER_TOO_SMALL;
  333. } else {
  334. Status = GetNumberOfAvailableModes(DeviceExtension,
  335. &(((PSCREEN_NUM_MODES)SystemBuffer)->NumModes));
  336. Irp->IoStatus.Information = sizeof(SCREEN_NUM_MODES);
  337. }
  338. break;
  339. case IOCTL_SCR_QUERY_CURRENT_MODE:
  340. Dprint(2, ("VgaDispatch - QueryCurrentMode\n"));
  341. //
  342. // Statistics compilation
  343. //
  344. ScreenIoctlStats.QueryCurrentMode++;
  345. if (RequestPacket->OutputBufferLength <
  346. sizeof(SCREEN_MODE_INFORMATION)) {
  347. Status = STATUS_BUFFER_TOO_SMALL;
  348. } else {
  349. Status = GetCurrentMode(DeviceExtension,
  350. RequestPacket->OutputBufferLength,
  351. SystemBuffer);
  352. Irp->IoStatus.Information = sizeof(SCREEN_MODE_INFORMATION);
  353. }
  354. break;
  355. case IOCTL_SCR_SET_CURRENT_MODE:
  356. Dprint(2, ("VgaDispatch - SetCurrentModes\n"));
  357. if (RequestPacket->InputBufferLength <
  358. sizeof(ULONG)) {
  359. Status = STATUS_BUFFER_TOO_SMALL;
  360. } else {
  361. //
  362. // validate mode and set up device extension variables
  363. //
  364. Status = PrepareForSetMode(DeviceExtension,
  365. *((PULONG) SystemBuffer));
  366. if (NT_SUCCESS(Status)) {
  367. //
  368. // unmap old frame buffer and set up new one.
  369. //
  370. Status = UpdateFrameBuffer(DeviceExtension,
  371. TRUE,
  372. *((PULONG) SystemBuffer));
  373. if (NT_SUCCESS(Status)) {
  374. //
  375. // update hardware
  376. //
  377. SetHWMode(DeviceExtension,
  378. *((PULONG) SystemBuffer),
  379. TRUE);
  380. }
  381. }
  382. }
  383. break;
  384. case IOCTL_SCR_QUERY_AVAIL_FONTS:
  385. Dprint(2, ("VgaDispatch - QueryAvailableFont\n"));
  386. if (DeviceExtension->CurrentMode->fbType & SCREEN_MODE_GRAPHICS) {
  387. //
  388. // Text mode only
  389. //
  390. Status = STATUS_INVALID_PARAMETER;
  391. } else {
  392. Status = GetAvailableFonts(DeviceExtension,
  393. RequestPacket->OutputBufferLength,
  394. SystemBuffer,
  395. &Irp->IoStatus.Information);
  396. }
  397. break;
  398. case IOCTL_SCR_QUERY_NUM_AVAIL_FONTS:
  399. Dprint(2, ("VgaDispatch - QueryNumAvailableFonts\n"));
  400. if (RequestPacket->OutputBufferLength <
  401. sizeof(SCREEN_NUM_FONTS)) {
  402. Status = STATUS_BUFFER_TOO_SMALL;
  403. } else {
  404. if (DeviceExtension->CurrentMode->fbType &
  405. SCREEN_MODE_GRAPHICS) { // Text mode only
  406. Status = STATUS_INVALID_PARAMETER;
  407. } else {
  408. Status = GetNumberOfAvailableFonts(DeviceExtension,
  409. &((PSCREEN_NUM_FONTS)SystemBuffer)->NumFonts);
  410. Irp->IoStatus.Information = sizeof(SCREEN_NUM_FONTS);
  411. }
  412. }
  413. break;
  414. case IOCTL_SCR_QUERY_CURRENT_FONT:
  415. Dprint(2, ("VgaDispatch - QueryCurrentFont\n"));
  416. if (RequestPacket->OutputBufferLength <
  417. sizeof(SCREEN_FONT_INFORMATION)) {
  418. Status = STATUS_BUFFER_TOO_SMALL;
  419. } else {
  420. if (DeviceExtension->CurrentMode->fbType &
  421. SCREEN_MODE_GRAPHICS) { // Text mode only
  422. Status = STATUS_INVALID_PARAMETER;
  423. } else {
  424. Status = GetCurrentFont(DeviceExtension,
  425. SystemBuffer);
  426. Irp->IoStatus.Information =
  427. sizeof(SCREEN_FONT_INFORMATION);
  428. }
  429. }
  430. break;
  431. case IOCTL_SCR_SET_CURRENT_FONT:
  432. Dprint(2, ("VgaDispatch - SetCurrentFont\n"));
  433. if (RequestPacket->InputBufferLength <
  434. sizeof(ULONG)) {
  435. Status = STATUS_BUFFER_TOO_SMALL;
  436. } else {
  437. if ( ((*(PULONG)SystemBuffer) > ROM_FONTS_VGA) ||
  438. ((*(PULONG)SystemBuffer) == 0) ||
  439. (DeviceExtension->CurrentMode->fbType &
  440. SCREEN_MODE_GRAPHICS)) { // Text mode only
  441. Status = STATUS_INVALID_PARAMETER;
  442. } else {
  443. SCREEN_SET_FONT_INFORMATION FontInformation;
  444. Status = SetFontSetUp(DeviceExtension,
  445. *(PULONG)SystemBuffer,
  446. &FontInformation);
  447. SetFont(DeviceExtension,
  448. FontInformation);
  449. Status = SetFontCleanUp(*(PULONG)SystemBuffer,
  450. &FontInformation);
  451. }
  452. }
  453. break;
  454. case IOCTL_SCR_QUERY_CURSOR_POSITION:
  455. Dprint(2, ("VgaDispatch - QueryCursorPosition\n"));
  456. if (RequestPacket->OutputBufferLength <
  457. sizeof(SCREEN_CURSOR_POSITION)) {
  458. Status = STATUS_BUFFER_TOO_SMALL;
  459. } else {
  460. if (DeviceExtension->CurrentMode->fbType &
  461. SCREEN_MODE_GRAPHICS) { // Text mode only
  462. Status = STATUS_INVALID_PARAMETER;
  463. } else {
  464. Status = GetCursorPosition(DeviceExtension,
  465. SystemBuffer);
  466. Irp->IoStatus.Information =
  467. sizeof(SCREEN_CURSOR_POSITION);
  468. }
  469. }
  470. break;
  471. case IOCTL_SCR_SET_CURSOR_POSITION:
  472. Dprint(2, ("VgaDispatch - SetCursorPosition\n"));
  473. if (RequestPacket->InputBufferLength <
  474. sizeof(SCREEN_CURSOR_POSITION)) {
  475. Status = STATUS_BUFFER_TOO_SMALL;
  476. } else {
  477. if ((DeviceExtension->CurrentMode->fbType &
  478. SCREEN_MODE_GRAPHICS) || // Text mode only
  479. (!CheckCursorPosition(SystemBuffer,
  480. DeviceExtension))) {
  481. Status = STATUS_INVALID_PARAMETER;
  482. } else {
  483. Status = STATUS_SUCCESS;
  484. ???? SetCursorPosition(DeviceExtension,
  485. (PSCREEN_CURSOR_POSITION) SystemBuffer);
  486. }
  487. }
  488. break;
  489. case IOCTL_SCR_QUERY_CURSOR_TYPE:
  490. Dprint(2, ("VgaDispatch - QueryCursorType\n"));
  491. if (RequestPacket->OutputBufferLength <
  492. sizeof(SCREEN_CURSOR_TYPE)) {
  493. Status = STATUS_BUFFER_TOO_SMALL;
  494. } else {
  495. if (DeviceExtension->CurrentMode->fbType &
  496. SCREEN_MODE_GRAPHICS) { // Text mode only
  497. Status = STATUS_INVALID_PARAMETER;
  498. } else {
  499. Status = GetCursorType(DeviceExtension,
  500. SystemBuffer);
  501. Irp->IoStatus.Information = sizeof(SCREEN_CURSOR_TYPE);
  502. }
  503. }
  504. break;
  505. case IOCTL_SCR_SET_CURSOR_TYPE:
  506. Dprint(2, ("VgaDispatch - SetCursorType\n"));
  507. if (RequestPacket->InputBufferLength <
  508. sizeof(SCREEN_CURSOR_TYPE)) {
  509. Status = STATUS_BUFFER_TOO_SMALL;
  510. } else {
  511. if ((DeviceExtension->CurrentMode->fbType &
  512. SCREEN_MODE_GRAPHICS) || // Text mode only
  513. (!CheckCursorType(SystemBuffer,
  514. DeviceExtension))) {
  515. Status = STATUS_INVALID_PARAMETER;
  516. } else {
  517. Status = STATUS_SUCCESS;
  518. SetCursorType(DeviceExtension,
  519. (PSCREEN_CURSOR_TYPE) SystemBuffer);
  520. }
  521. }
  522. break;
  523. case IOCTL_SCR_SET_PALETTE_REGISTERS:
  524. Dprint(2, ("VgaDispatch - SetPaletteRegs\n"));
  525. Status = STATUS_SUCCESS;
  526. if (RequestPacket->InputBufferLength <
  527. (sizeof(SCREEN_PALETTE_DATA) + (sizeof(USHORT) *
  528. (((PSCREEN_PALETTE_DATA)SystemBuffer)->NumEntries-1)))) {
  529. Status = STATUS_BUFFER_TOO_SMALL;
  530. } else {
  531. if ((((PSCREEN_PALETTE_DATA)SystemBuffer)->FirstEntry >
  532. SCREEN_MAX_PALETTE_COLORS ) || // valid 1st entry
  533. (((PSCREEN_PALETTE_DATA)SystemBuffer)->NumEntries ==
  534. 0) || // Non-zero amount
  535. (((PSCREEN_PALETTE_DATA)SystemBuffer)->FirstEntry +
  536. ((PSCREEN_PALETTE_DATA)SystemBuffer)->NumEntries >
  537. SCREEN_MAX_PALETTE_COLORS+1)) {
  538. Status = STATUS_INVALID_PARAMETER;
  539. } else {
  540. SetPaletteReg(DeviceExtension,
  541. (PSCREEN_PALETTE_DATA) SystemBuffer,
  542. TRUE);
  543. }
  544. }
  545. break;
  546. case IOCTL_SCR_SET_COLOR_REGISTERS:
  547. Dprint(2, ("VgaDispatch - SetColorRegs\n"));
  548. Status = STATUS_SUCCESS;
  549. if (RequestPacket->InputBufferLength <
  550. (sizeof(SCREEN_CLUT) + (sizeof(ULONG) *
  551. (((PSCREEN_CLUT)SystemBuffer)->NumEntries-1)))) {
  552. Status = STATUS_BUFFER_TOO_SMALL;
  553. } else {
  554. if ((((PSCREEN_CLUT)SystemBuffer)->NumEntries == 0) ||
  555. (((PSCREEN_CLUT)SystemBuffer)->FirstEntry >
  556. SCREEN_MAX_COLOR_REGISTERS) ||
  557. (((PSCREEN_CLUT)SystemBuffer)->FirstEntry +
  558. ((PSCREEN_CLUT)SystemBuffer)->NumEntries >
  559. SCREEN_MAX_COLOR_REGISTERS+1)) {
  560. Status = STATUS_INVALID_PARAMETER;
  561. } else {
  562. SetColorLookup(DeviceExtension,
  563. (PSCREEN_CLUT) SystemBuffer,
  564. TRUE);
  565. }
  566. }
  567. break;
  568. }
  569. break;
  570. }
  571. Irp->IoStatus.Status = Status;
  572. if (PowerFailed) {
  573. Status = STATUS_PENDING;
  574. } else {
  575. DeviceExtension->CommandPhase = ScrIdle; // this is only necessary
  576. // for KeSynchronize ioctls
  577. KeSetEvent(&DeviceExtension->Event,0,FALSE);
  578. KeRaiseIrql( DISPATCH_LEVEL, &OldIrql );
  579. IoCompleteRequest( Irp, IO_VIDEO_INCREMENT );
  580. KeLowerIrql( OldIrql );
  581. }
  582. return Status;
  583. }
  584. BOOLEAN
  585. ScreenResetDevice(
  586. IN PDEVICE_EXTENSION DeviceExtension
  587. )
  588. /*++
  589. Routine Description:
  590. This routine resets the device after a powerfail. It sets the mode to
  591. the current mode and the palette and color registers to what they were
  592. before the powerfail.
  593. Arguments:
  594. DeviceObject - Pointer to the device object for this driver.
  595. Return Value:
  596. For now simply return TRUE.
  597. --*/
  598. {
  599. KIRQL OldIrql;
  600. KeRaiseIrql(POWER_LEVEL,
  601. &OldIrql);
  602. #ifdef SCREEN_POWER_RECOVERY
  603. if (DeviceExtension->ScreenPowerFailed == TRUE) {
  604. KeLowerIrql( OldIrql );
  605. return TRUE;
  606. }
  607. #endif // POWER_RECOVERY
  608. SetHWMode(DeviceExtension,
  609. DeviceExtension->ModeIndex,
  610. FALSE);
  611. if (!( DeviceExtension->CurrentMode->fbType & SCREEN_MODE_GRAPHICS ) ) {
  612. SetHWFontRegs(DeviceExtension,
  613. Fonts[DeviceExtension->RomFontIndex].PelRows);
  614. SetCursorPosition(DeviceExtension,
  615. &DeviceExtension->CursorPosition);
  616. SetCursorType(DeviceExtension,
  617. &DeviceExtension->CursorType);
  618. }
  619. SetColorLookup(DeviceExtension,
  620. (PSCREEN_CLUT) &DeviceExtension->Clut,
  621. FALSE);
  622. SetPaletteReg(DeviceExtension,
  623. (PSCREEN_PALETTE_DATA) &DeviceExtension->Palette,
  624. FALSE);
  625. KeLowerIrql(OldIrql);
  626. return TRUE;
  627. }
  628. static
  629. VOID
  630. ScreenUnload (
  631. IN PDRIVER_OBJECT DriverObject
  632. )
  633. /*++
  634. Routine Description:
  635. This routine is the unload routine for the screen disk device driver.
  636. It performs no operation.
  637. Arguments:
  638. DriverObject - Supplies a pointer to the driver object that describes
  639. this driver.
  640. Return Value:
  641. None.
  642. --*/
  643. {
  644. DBG_UNREFERENCED_PARAMETER(DriverObject);
  645. return;
  646. }
  647. #ifdef SCREEN_POWER_RECOVERY
  648. VOID
  649. ScreenPowerFail(
  650. IN PKDPC Dpc,
  651. IN PDEVICE_OBJECT DeviceObject,
  652. IN PIRP Irp,
  653. IN PVOID Context
  654. )
  655. /*++
  656. Routine Description:
  657. This routine is called when the power fails. It calls the routine
  658. to reset the device and restart any operations that write to the
  659. device. It also completes any operations that were pending due to
  660. a powerfail.
  661. Arguments:
  662. Dpc - Pointer to DPC object.
  663. DeviceObject - Pointer to the device object.
  664. Irp - Pointer to Irp.
  665. Context - Action to take in DCP.
  666. Return Value:
  667. None.
  668. --*/
  669. {
  670. BOOLEAN PowerFailed;
  671. PDEVICE_EXTENSION DeviceExtension;
  672. KIRQL OldIrql;
  673. DeviceExtension = DeviceObject->DeviceExtension;
  674. //
  675. // set ScreenPowerFailed to FALSE.
  676. //
  677. KeRaiseIrql(POWER_LEVEL,
  678. &OldIrql);
  679. DeviceExtension->ScreenPowerFailed = FALSE;
  680. KeLowerIrql( OldIrql );
  681. PowerFailed = KeSynchronizeExecution(
  682. &DeviceExtension->ScreenInterruptObject,
  683. ScreenPowerReset,
  684. DeviceExtension);
  685. if (PowerFailed == FALSE) {
  686. DeviceExtension->CommandPhase = ScrIdle;
  687. KeSetEvent(&DeviceExtension->Event,
  688. 0,
  689. FALSE);
  690. KeRaiseIrql(DISPATCH_LEVEL,
  691. &OldIrql);
  692. IoCompleteRequest(Irp,
  693. IO_VIDEO_INCREMENT);
  694. KeLowerIrql(OldIrql);
  695. }
  696. }
  697. BOOLEAN
  698. ScreenPowerReset(
  699. IN PDEVICE_OBJECT DeviceObject
  700. )
  701. /*++
  702. Routine Description:
  703. This routine reinitializes the device after a powerfail and restarts
  704. any operation that was writing to the device.
  705. Arguments:
  706. DeviceObject - Pointer to the device object for this driver.
  707. Return Value:
  708. Whether the power failed during the reset.
  709. --*/
  710. {
  711. PDEVICE_EXTENSION DeviceExtension;
  712. BOOLEAN PowerFailed;
  713. DeviceExtension = DeviceObject->DeviceExtension;
  714. //
  715. // reset the device. this sets the mode, palette regs, and CLUT to what
  716. // they were before the powerfail.
  717. //
  718. PowerFailed = ScreenResetDevice(DeviceExtension);
  719. if (PowerFailed) {
  720. return TRUE;
  721. }
  722. //
  723. // restart operation
  724. //
  725. if (DeviceExtension->CommandPhase != ScrIdle) {
  726. return WriteToDevice(DeviceObject);
  727. }
  728. return FALSE;
  729. }
  730. #endif // POWER_RECOVERY