1177 lines
28 KiB
C
1177 lines
28 KiB
C
|
||
in DRIVER_ENTRY
|
||
}
|
||
|
||
DeviceExtension->CommandPhase = ScrIdle;
|
||
|
||
|
||
|
||
NTSTATUS
|
||
ScreenInitializeDevice(
|
||
IN PDEVICE_EXTENSION DeviceExtension
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Arguments:
|
||
|
||
DeviceObject - Pointer to the device object for this driver.
|
||
|
||
Return Value:
|
||
|
||
The function value is the status of the operation.
|
||
|
||
--*/
|
||
|
||
{
|
||
NTSTATUS Status;
|
||
|
||
//
|
||
// determine hardware configuration.
|
||
//
|
||
|
||
UCHAR videoType; // possible VGA video type
|
||
|
||
KIRQL OldIrql;
|
||
|
||
UCHAR Color = TRUE; // assume color adapter present
|
||
|
||
//
|
||
// Start by assuming there is no adapter
|
||
//
|
||
|
||
DeviceExtension->VideoHardware.fVideoType = VDHERROR_NO_ADAPTER;
|
||
|
||
//
|
||
// Determine which adapter is present by testing the presence of memory.
|
||
// A0000 isn't accessible because EGA and VGA come up in character mode.
|
||
// put it in graphics mode and then test for memory at A0000.
|
||
//
|
||
|
||
KeRaiseIrql(POWER_LEVEL,
|
||
&OldIrql);
|
||
EnableA0000();
|
||
KeLowerIrql(OldIrql);
|
||
|
||
if (MemoryPresent(MEM_EGA_OR_VGA)) {
|
||
|
||
//
|
||
// A0000 is present so we must either have an EGA or a VGA.
|
||
// We must now determine which one it is.
|
||
//
|
||
|
||
|
||
videoType = VGA_COLOR;
|
||
|
||
|
||
|
||
if (videoType == VGA_CANNOT_DETERMINE) {
|
||
|
||
|
||
} else { // We are in VGA mode
|
||
|
||
//
|
||
// determine and record VGA information; always 256K
|
||
//
|
||
|
||
DeviceExtension->VideoHardware.memory = 256L * 1024L;
|
||
|
||
switch (videoType) {
|
||
|
||
case VGA_COLOR:
|
||
|
||
DeviceExtension->VideoHardware.display = Color8512_8513;
|
||
DeviceExtension->VideoHardware.popupMode = ModeIndex_VGA3p;
|
||
DeviceExtension->VideoHardware.fVideoType ^= VGC_BIT;
|
||
|
||
break;
|
||
|
||
case VGA_MONO:
|
||
|
||
DeviceExtension->VideoHardware.display = Color8512_8513;
|
||
DeviceExtension->VideoHardware.popupMode = ModeIndex_VGA3p;
|
||
DeviceExtension->VideoHardware.fVideoType ^= VGC_BIT;
|
||
|
||
break;
|
||
|
||
case VGA_NODISPLAY:
|
||
|
||
DeviceExtension->VideoHardware.display = NoDisplay;
|
||
DeviceExtension->VideoHardware.popupMode = ModeIndex_VGA3p;
|
||
|
||
DeviceExtension->VideoHardware.fVideoType = NODISPLAY_BIT;
|
||
|
||
break;
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
KeRaiseIrql(POWER_LEVEL,
|
||
&OldIrql);
|
||
DisableA0000(Color);
|
||
KeLowerIrql(OldIrql);
|
||
|
||
if (DeviceExtension->VideoHardware.fVideoType == NODISPLAY_BIT) {
|
||
|
||
return STATUS_NO_SUCH_DEVICE;
|
||
|
||
}
|
||
|
||
//
|
||
// set up the ROM font addresses
|
||
//
|
||
|
||
InitializeFonts(DeviceExtension);
|
||
|
||
//
|
||
// set the mode.
|
||
//
|
||
|
||
Status = PrepareForSetMode(DeviceExtension,
|
||
DeviceExtension->VideoHardware.popupMode);
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
|
||
return Status;
|
||
|
||
}
|
||
|
||
KeRaiseIrql(POWER_LEVEL,
|
||
&OldIrql);
|
||
|
||
SetHWMode(DeviceExtension,
|
||
DeviceExtension->VideoHardware.popupMode,
|
||
TRUE);
|
||
|
||
//
|
||
// Setting up the cursor position and initializing the CLUT only needs
|
||
// to be done for VGA mode.
|
||
//
|
||
|
||
//
|
||
// set up the cursor position and type
|
||
//
|
||
{
|
||
SCREEN_CURSOR_POSITION CursorPosition;
|
||
SCREEN_CURSOR_TYPE CursorType;
|
||
|
||
CursorPosition.Column = 0;
|
||
CursorPosition.Row = 0;
|
||
SetCursorPosition(DeviceExtension,
|
||
&CursorPosition);
|
||
|
||
CursorType.TopScanLine = (USHORT)
|
||
(Fonts[DeviceExtension->RomFontIndex].PelRows-2);
|
||
CursorType.BottomScanLine = 31;
|
||
CursorType.CursorVisible = TRUE;
|
||
SetCursorType(DeviceExtension,
|
||
&CursorType);
|
||
}
|
||
|
||
//
|
||
// initialize the CLUT.
|
||
//
|
||
|
||
SetColorLookup(DeviceExtension,
|
||
(PSCREEN_CLUT) &InitialClutVGA,
|
||
TRUE);
|
||
|
||
//
|
||
// initialize the palette registers.
|
||
//
|
||
|
||
SetPaletteReg(DeviceExtension,
|
||
(PSCREEN_PALETTE_DATA) &InitialPaletteVGA,
|
||
TRUE);
|
||
|
||
KeLowerIrql(OldIrql);
|
||
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
|
||
BOOLEAN
|
||
MemoryPresent(
|
||
IN ULONG Address
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine returns TRUE if the specified memory is present. It
|
||
maps a view of the requested address, reads the original ulong, writes
|
||
a different one, reads it to make sure its the written value, then
|
||
restores the original value.
|
||
|
||
Arguments:
|
||
|
||
Address - Physical address to check
|
||
|
||
Return Value:
|
||
|
||
TRUE if specified memory is present, FALSE if not.
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOLEAN GoodMemory = FALSE; // assume no memory at location
|
||
volatile PULONG VideoMemory;
|
||
ULONG TestValue; // memory read/write test value
|
||
ULONG OriginalValue; // original value at tested location
|
||
PVOID Base;
|
||
|
||
Base = MmMapIoSpace((PHYSICAL_ADDRESS) Address,
|
||
sizeof (ULONG),
|
||
FALSE);
|
||
|
||
//
|
||
// Read a ulong from the address and save it. write
|
||
// a different ulong to the address. read from the address and see if
|
||
// it matches the written ulong.
|
||
//
|
||
|
||
VideoMemory = (PULONG) Base;
|
||
TestValue = 0xBBBBBBBB;
|
||
|
||
if ((OriginalValue = *VideoMemory) == 0xBBBBBBBB) {
|
||
|
||
TestValue >>= 1;
|
||
|
||
}
|
||
|
||
*VideoMemory = TestValue; // write out a test value
|
||
|
||
if (GoodMemory = (BOOLEAN) (*VideoMemory == TestValue) ) {
|
||
|
||
*VideoMemory = OriginalValue; // restore value
|
||
|
||
}
|
||
|
||
MmUnmapIoSpace(Base,
|
||
sizeof (ULONG));
|
||
|
||
return GoodMemory;
|
||
}
|
||
|
||
|
||
VOID
|
||
InitializeFonts(
|
||
IN PDEVICE_EXTENSION DeviceExtension
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine determines the addresses of the ROM fonts.
|
||
|
||
Arguments:
|
||
|
||
DeviceExtension - pointer to device extension for this driver
|
||
|
||
Return Value:
|
||
|
||
none
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
PHYSICAL_ADDRESS PVB;
|
||
PUCHAR RomPtr;
|
||
ULONG RomFontLen,ROMSrchLen;
|
||
ULONG i;
|
||
|
||
//
|
||
// Search through ROM to find 8x8, 8x14, 8x16, 9x14, and 9x16 fonts
|
||
// ROM fonts are located at physical addresses:
|
||
// C0000 - EGA and PS/2 Adapter
|
||
// E0000 - VGA
|
||
//
|
||
|
||
for (PVB = 0xE0000, RomFontLen = 0xFFFF, ROMSrchLen = 0xFFF0;
|
||
PVB >= 0xC0000;
|
||
PVB -= 0x20000, RomFontLen -= 0x8000, ROMSrchLen = 0x7FF0 ) {
|
||
|
||
RomPtr = MmMapIoSpace(PVB, RomFontLen, FALSE);
|
||
|
||
//
|
||
// Locate 8x8 ROM font on EGA and VGA
|
||
//
|
||
|
||
for (i = 0; i < ROMSrchLen; i++) {
|
||
|
||
while ( (i < ROMSrchLen) && (RomPtr[i] != (UCHAR)0x7E) ) {
|
||
|
||
i++;
|
||
|
||
}
|
||
|
||
if ( i < ROMSrchLen) {
|
||
|
||
if ( (RomPtr[i+1] == (UCHAR)0x81) &&
|
||
(RomPtr[i+2] == (UCHAR)0xA5) &&
|
||
(RomPtr[i+3] == (UCHAR)0x81) ) {
|
||
|
||
if (!Fonts[ROM_FONT_8x8].PVB && RomPtr[i+4] ==
|
||
(UCHAR)0xBD) {
|
||
|
||
Fonts[ROM_FONT_8x8].PVB = PVB + i - 8;
|
||
|
||
} else {
|
||
|
||
//
|
||
// Locate 8x14 ROM font on EGA, VGA, and PS/2 adapter only
|
||
//
|
||
|
||
if ( (RomPtr[i+4] == (UCHAR)0x81) &&
|
||
(RomPtr[i+5] == (UCHAR)0xBD) &&
|
||
(RomPtr[i+6] == (UCHAR)0x99) &&
|
||
(RomPtr[i+7] == (UCHAR)0x81) ) {
|
||
|
||
// e3f40
|
||
|
||
if (!Fonts[ROM_FONT_8x14].PVB &&
|
||
RomPtr[i+8] != (UCHAR)0x81) {
|
||
|
||
Fonts[ROM_FONT_8x14].PVB = PVB + i- 16;
|
||
|
||
} else {
|
||
|
||
//
|
||
// Locate 8x16 ROM font on VGA, and PS/2 adapter only
|
||
//
|
||
|
||
// e3e04
|
||
if ( !Fonts[ROM_FONT_8x16].PVB &&
|
||
RomPtr[i+8] == (UCHAR)0x81 ) {
|
||
|
||
Fonts[ROM_FONT_8x16].PVB = PVB + i - 18;
|
||
|
||
}
|
||
}
|
||
|
||
} // if ( (RomPtr[i+4] == (UCHAR)0x81) &&
|
||
|
||
} // if (!Fonts[ROM_FONT_8x8].PVB && RomPtr[i+4]
|
||
|
||
} // if ( (RomPtr[i+1] == (UCHAR)0x81) &&
|
||
|
||
} // if ( i < ROMSrchLen)
|
||
|
||
} // end for loop Locate 8x8, 8x14, 8x16
|
||
|
||
|
||
//
|
||
// Locate 9x14 ROM font on EGA, VGA, and PS/2 adapter only
|
||
//
|
||
|
||
for ( i = 0; i < ROMSrchLen; i++ ) {
|
||
|
||
while ( (i < ROMSrchLen) && (RomPtr[i] != (UCHAR)0x1D) ) {
|
||
|
||
i++;
|
||
|
||
}
|
||
|
||
if ( i < ROMSrchLen) {
|
||
|
||
if ( ( RomPtr[i+1] == (UCHAR)0x00 ) &&
|
||
( RomPtr[i+2] == (UCHAR)0x00 ) &&
|
||
( RomPtr[i+3] == (UCHAR)0x00 ) &&
|
||
( RomPtr[i+4] == (UCHAR)0x00 ) ) {
|
||
|
||
if ( !Fonts[ROM_FONT_9x14].PVB &&
|
||
( RomPtr[i+5] == (UCHAR)0x24 ) &&
|
||
( RomPtr[i+6] == (UCHAR)0x66 ) ) {
|
||
|
||
Fonts[ROM_FONT_9x14].PVB = PVB + i;
|
||
}
|
||
|
||
//
|
||
// Locate 9x16 ROM font on VGA, and PS/2 adapter only
|
||
//
|
||
|
||
if (!Fonts[ROM_FONT_9x16].PVB &&
|
||
(RomPtr[i+5] == (UCHAR)0x00) &&
|
||
(RomPtr[i+6] == (UCHAR)0x24) ) {
|
||
|
||
Fonts[ROM_FONT_9x16].PVB = PVB + i;
|
||
|
||
}
|
||
}
|
||
}
|
||
} /* Locate 9x14, 9x16 */
|
||
|
||
MmUnmapIoSpace(RomPtr,RomFontLen);
|
||
|
||
} // Search next ROM area for fonts */
|
||
|
||
if (!Fonts[ROM_FONT_8x8].PVB)
|
||
Dprint(1, ("Fonts[ROM_FONT_8x8] not found\n"));
|
||
if (!Fonts[ROM_FONT_8x14].PVB)
|
||
Dprint(1, ("Fonts[ROM_FONT_8x14] not found \n"));
|
||
if (!Fonts[ROM_FONT_8x16].PVB)
|
||
Dprint(1, ("Fonts[ROM_FONT_8x16] not found \n"));
|
||
if (!Fonts[ROM_FONT_9x14].PVB)
|
||
Dprint(1, ("Fonts[ROM_FONT_9x14] not found \n"));
|
||
if (!Fonts[ROM_FONT_9x16].PVB)
|
||
Dprint(1, ("Fonts[ROM_FONT_9x16] not found \n"));
|
||
|
||
//
|
||
// we happen to know that the 8x8 font is loaded during boot. we can't
|
||
// call SetFont at this point because it requires data initialized by
|
||
// SetMode. But SetMode requires data initialized by SetFont. so we
|
||
// just set up RomFontIndex here manually.
|
||
//
|
||
|
||
DeviceExtension->RomFontIndex = 1;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
NTSTATUS
|
||
ScreenDispatch(
|
||
|
||
NTSTATUS Status;
|
||
PIO_STACK_LOCATION IrpSp;
|
||
KIRQL OldIrql;
|
||
PDEVICE_EXTENSION DeviceExtension;
|
||
BOOLEAN PowerFailed = FALSE;
|
||
PVOID SystemBuffer;
|
||
|
||
case IRP_MJ_CLOSE:
|
||
|
||
Dprint(2, ("VgaDispatch - CLose\n"));
|
||
|
||
Status = ZwUnmapViewOfSection(NtCurrentProcess(),
|
||
DeviceExtension->RealFrameBase);
|
||
|
||
if (NT_SUCCESS(Status)) {
|
||
|
||
ZwClose(DeviceExtension->FrameSection);
|
||
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_QUERY_FRAME_BUFFER:
|
||
|
||
Dprint(2, ("VgaDispatch - QueryFrameBuffer\n"));
|
||
|
||
//
|
||
// check for adequate buffer length
|
||
//
|
||
|
||
if (RequestPacket->OutputBufferLength <
|
||
sizeof(SCREEN_FRAME_BUFFER_INFO)) {
|
||
|
||
Status = STATUS_BUFFER_TOO_SMALL;
|
||
|
||
} else {
|
||
|
||
//
|
||
// everything's ok, return the info.
|
||
//
|
||
|
||
((PSCREEN_FRAME_BUFFER_INFO) SystemBuffer)->FrameBase =
|
||
DeviceExtension->FrameBase;
|
||
|
||
((PSCREEN_FRAME_BUFFER_INFO) SystemBuffer)->FrameLength =
|
||
DeviceExtension->FrameLength;
|
||
|
||
Status = STATUS_SUCCESS;
|
||
Irp->IoStatus.Information = sizeof(SCREEN_FRAME_BUFFER_INFO);
|
||
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_QUERY_AVAIL_MODES:
|
||
|
||
Dprint(2, ("VgaDispatch - QueryAvailableModes\n"));
|
||
|
||
Status = GetAvailableModes(DeviceExtension,
|
||
RequestPacket->OutputBufferLength,
|
||
SystemBuffer,
|
||
&Irp->IoStatus.Information);
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_QUERY_NUM_AVAIL_MODES:
|
||
|
||
Dprint(2, ("VgaDispatch - QueryNumAvailableModes\n"));
|
||
|
||
if (RequestPacket->OutputBufferLength <
|
||
sizeof(SCREEN_NUM_MODES)) {
|
||
|
||
Status = STATUS_BUFFER_TOO_SMALL;
|
||
|
||
} else {
|
||
|
||
Status = GetNumberOfAvailableModes(DeviceExtension,
|
||
&(((PSCREEN_NUM_MODES)SystemBuffer)->NumModes));
|
||
|
||
Irp->IoStatus.Information = sizeof(SCREEN_NUM_MODES);
|
||
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_QUERY_CURRENT_MODE:
|
||
|
||
Dprint(2, ("VgaDispatch - QueryCurrentMode\n"));
|
||
|
||
|
||
//
|
||
// Statistics compilation
|
||
//
|
||
|
||
ScreenIoctlStats.QueryCurrentMode++;
|
||
|
||
if (RequestPacket->OutputBufferLength <
|
||
sizeof(SCREEN_MODE_INFORMATION)) {
|
||
|
||
Status = STATUS_BUFFER_TOO_SMALL;
|
||
|
||
} else {
|
||
|
||
Status = GetCurrentMode(DeviceExtension,
|
||
RequestPacket->OutputBufferLength,
|
||
SystemBuffer);
|
||
|
||
Irp->IoStatus.Information = sizeof(SCREEN_MODE_INFORMATION);
|
||
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_SET_CURRENT_MODE:
|
||
|
||
Dprint(2, ("VgaDispatch - SetCurrentModes\n"));
|
||
|
||
if (RequestPacket->InputBufferLength <
|
||
sizeof(ULONG)) {
|
||
|
||
Status = STATUS_BUFFER_TOO_SMALL;
|
||
|
||
} else {
|
||
|
||
//
|
||
// validate mode and set up device extension variables
|
||
//
|
||
|
||
Status = PrepareForSetMode(DeviceExtension,
|
||
*((PULONG) SystemBuffer));
|
||
|
||
if (NT_SUCCESS(Status)) {
|
||
|
||
//
|
||
// unmap old frame buffer and set up new one.
|
||
//
|
||
|
||
Status = UpdateFrameBuffer(DeviceExtension,
|
||
TRUE,
|
||
*((PULONG) SystemBuffer));
|
||
|
||
if (NT_SUCCESS(Status)) {
|
||
|
||
//
|
||
// update hardware
|
||
//
|
||
|
||
SetHWMode(DeviceExtension,
|
||
*((PULONG) SystemBuffer),
|
||
TRUE);
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_QUERY_AVAIL_FONTS:
|
||
|
||
Dprint(2, ("VgaDispatch - QueryAvailableFont\n"));
|
||
|
||
if (DeviceExtension->CurrentMode->fbType & SCREEN_MODE_GRAPHICS) {
|
||
|
||
//
|
||
// Text mode only
|
||
//
|
||
|
||
Status = STATUS_INVALID_PARAMETER;
|
||
|
||
} else {
|
||
|
||
Status = GetAvailableFonts(DeviceExtension,
|
||
RequestPacket->OutputBufferLength,
|
||
SystemBuffer,
|
||
&Irp->IoStatus.Information);
|
||
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_QUERY_NUM_AVAIL_FONTS:
|
||
|
||
Dprint(2, ("VgaDispatch - QueryNumAvailableFonts\n"));
|
||
|
||
if (RequestPacket->OutputBufferLength <
|
||
sizeof(SCREEN_NUM_FONTS)) {
|
||
|
||
Status = STATUS_BUFFER_TOO_SMALL;
|
||
|
||
} else {
|
||
|
||
if (DeviceExtension->CurrentMode->fbType &
|
||
SCREEN_MODE_GRAPHICS) { // Text mode only
|
||
|
||
Status = STATUS_INVALID_PARAMETER;
|
||
|
||
} else {
|
||
|
||
Status = GetNumberOfAvailableFonts(DeviceExtension,
|
||
&((PSCREEN_NUM_FONTS)SystemBuffer)->NumFonts);
|
||
|
||
Irp->IoStatus.Information = sizeof(SCREEN_NUM_FONTS);
|
||
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_QUERY_CURRENT_FONT:
|
||
|
||
Dprint(2, ("VgaDispatch - QueryCurrentFont\n"));
|
||
|
||
if (RequestPacket->OutputBufferLength <
|
||
sizeof(SCREEN_FONT_INFORMATION)) {
|
||
|
||
Status = STATUS_BUFFER_TOO_SMALL;
|
||
|
||
} else {
|
||
|
||
if (DeviceExtension->CurrentMode->fbType &
|
||
SCREEN_MODE_GRAPHICS) { // Text mode only
|
||
|
||
Status = STATUS_INVALID_PARAMETER;
|
||
|
||
} else {
|
||
|
||
Status = GetCurrentFont(DeviceExtension,
|
||
SystemBuffer);
|
||
|
||
Irp->IoStatus.Information =
|
||
sizeof(SCREEN_FONT_INFORMATION);
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_SET_CURRENT_FONT:
|
||
|
||
Dprint(2, ("VgaDispatch - SetCurrentFont\n"));
|
||
|
||
if (RequestPacket->InputBufferLength <
|
||
sizeof(ULONG)) {
|
||
|
||
Status = STATUS_BUFFER_TOO_SMALL;
|
||
|
||
} else {
|
||
|
||
if ( ((*(PULONG)SystemBuffer) > ROM_FONTS_VGA) ||
|
||
((*(PULONG)SystemBuffer) == 0) ||
|
||
(DeviceExtension->CurrentMode->fbType &
|
||
SCREEN_MODE_GRAPHICS)) { // Text mode only
|
||
|
||
Status = STATUS_INVALID_PARAMETER;
|
||
|
||
} else {
|
||
|
||
SCREEN_SET_FONT_INFORMATION FontInformation;
|
||
|
||
Status = SetFontSetUp(DeviceExtension,
|
||
*(PULONG)SystemBuffer,
|
||
&FontInformation);
|
||
|
||
SetFont(DeviceExtension,
|
||
FontInformation);
|
||
|
||
Status = SetFontCleanUp(*(PULONG)SystemBuffer,
|
||
&FontInformation);
|
||
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_QUERY_CURSOR_POSITION:
|
||
|
||
Dprint(2, ("VgaDispatch - QueryCursorPosition\n"));
|
||
|
||
if (RequestPacket->OutputBufferLength <
|
||
sizeof(SCREEN_CURSOR_POSITION)) {
|
||
|
||
Status = STATUS_BUFFER_TOO_SMALL;
|
||
|
||
} else {
|
||
|
||
if (DeviceExtension->CurrentMode->fbType &
|
||
SCREEN_MODE_GRAPHICS) { // Text mode only
|
||
|
||
Status = STATUS_INVALID_PARAMETER;
|
||
|
||
} else {
|
||
|
||
Status = GetCursorPosition(DeviceExtension,
|
||
SystemBuffer);
|
||
|
||
Irp->IoStatus.Information =
|
||
sizeof(SCREEN_CURSOR_POSITION);
|
||
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_SET_CURSOR_POSITION:
|
||
|
||
Dprint(2, ("VgaDispatch - SetCursorPosition\n"));
|
||
|
||
if (RequestPacket->InputBufferLength <
|
||
sizeof(SCREEN_CURSOR_POSITION)) {
|
||
|
||
Status = STATUS_BUFFER_TOO_SMALL;
|
||
|
||
} else {
|
||
|
||
if ((DeviceExtension->CurrentMode->fbType &
|
||
SCREEN_MODE_GRAPHICS) || // Text mode only
|
||
(!CheckCursorPosition(SystemBuffer,
|
||
DeviceExtension))) {
|
||
|
||
Status = STATUS_INVALID_PARAMETER;
|
||
|
||
} else {
|
||
|
||
Status = STATUS_SUCCESS;
|
||
|
||
???? SetCursorPosition(DeviceExtension,
|
||
(PSCREEN_CURSOR_POSITION) SystemBuffer);
|
||
|
||
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_QUERY_CURSOR_TYPE:
|
||
|
||
Dprint(2, ("VgaDispatch - QueryCursorType\n"));
|
||
|
||
if (RequestPacket->OutputBufferLength <
|
||
sizeof(SCREEN_CURSOR_TYPE)) {
|
||
|
||
Status = STATUS_BUFFER_TOO_SMALL;
|
||
|
||
} else {
|
||
|
||
if (DeviceExtension->CurrentMode->fbType &
|
||
SCREEN_MODE_GRAPHICS) { // Text mode only
|
||
|
||
Status = STATUS_INVALID_PARAMETER;
|
||
|
||
} else {
|
||
|
||
Status = GetCursorType(DeviceExtension,
|
||
SystemBuffer);
|
||
|
||
Irp->IoStatus.Information = sizeof(SCREEN_CURSOR_TYPE);
|
||
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_SET_CURSOR_TYPE:
|
||
|
||
Dprint(2, ("VgaDispatch - SetCursorType\n"));
|
||
|
||
if (RequestPacket->InputBufferLength <
|
||
sizeof(SCREEN_CURSOR_TYPE)) {
|
||
|
||
Status = STATUS_BUFFER_TOO_SMALL;
|
||
|
||
} else {
|
||
|
||
if ((DeviceExtension->CurrentMode->fbType &
|
||
SCREEN_MODE_GRAPHICS) || // Text mode only
|
||
(!CheckCursorType(SystemBuffer,
|
||
DeviceExtension))) {
|
||
|
||
Status = STATUS_INVALID_PARAMETER;
|
||
|
||
} else {
|
||
|
||
Status = STATUS_SUCCESS;
|
||
|
||
SetCursorType(DeviceExtension,
|
||
(PSCREEN_CURSOR_TYPE) SystemBuffer);
|
||
|
||
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_SET_PALETTE_REGISTERS:
|
||
|
||
Dprint(2, ("VgaDispatch - SetPaletteRegs\n"));
|
||
|
||
Status = STATUS_SUCCESS;
|
||
|
||
if (RequestPacket->InputBufferLength <
|
||
(sizeof(SCREEN_PALETTE_DATA) + (sizeof(USHORT) *
|
||
(((PSCREEN_PALETTE_DATA)SystemBuffer)->NumEntries-1)))) {
|
||
|
||
Status = STATUS_BUFFER_TOO_SMALL;
|
||
|
||
} else {
|
||
|
||
if ((((PSCREEN_PALETTE_DATA)SystemBuffer)->FirstEntry >
|
||
SCREEN_MAX_PALETTE_COLORS ) || // valid 1st entry
|
||
(((PSCREEN_PALETTE_DATA)SystemBuffer)->NumEntries ==
|
||
0) || // Non-zero amount
|
||
(((PSCREEN_PALETTE_DATA)SystemBuffer)->FirstEntry +
|
||
((PSCREEN_PALETTE_DATA)SystemBuffer)->NumEntries >
|
||
SCREEN_MAX_PALETTE_COLORS+1)) {
|
||
|
||
Status = STATUS_INVALID_PARAMETER;
|
||
|
||
} else {
|
||
|
||
SetPaletteReg(DeviceExtension,
|
||
(PSCREEN_PALETTE_DATA) SystemBuffer,
|
||
TRUE);
|
||
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case IOCTL_SCR_SET_COLOR_REGISTERS:
|
||
|
||
Dprint(2, ("VgaDispatch - SetColorRegs\n"));
|
||
|
||
Status = STATUS_SUCCESS;
|
||
|
||
if (RequestPacket->InputBufferLength <
|
||
(sizeof(SCREEN_CLUT) + (sizeof(ULONG) *
|
||
(((PSCREEN_CLUT)SystemBuffer)->NumEntries-1)))) {
|
||
|
||
Status = STATUS_BUFFER_TOO_SMALL;
|
||
|
||
} else {
|
||
|
||
if ((((PSCREEN_CLUT)SystemBuffer)->NumEntries == 0) ||
|
||
(((PSCREEN_CLUT)SystemBuffer)->FirstEntry >
|
||
SCREEN_MAX_COLOR_REGISTERS) ||
|
||
(((PSCREEN_CLUT)SystemBuffer)->FirstEntry +
|
||
((PSCREEN_CLUT)SystemBuffer)->NumEntries >
|
||
SCREEN_MAX_COLOR_REGISTERS+1)) {
|
||
|
||
Status = STATUS_INVALID_PARAMETER;
|
||
|
||
} else {
|
||
|
||
SetColorLookup(DeviceExtension,
|
||
(PSCREEN_CLUT) SystemBuffer,
|
||
TRUE);
|
||
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
}
|
||
|
||
Irp->IoStatus.Status = Status;
|
||
|
||
if (PowerFailed) {
|
||
|
||
Status = STATUS_PENDING;
|
||
|
||
} else {
|
||
|
||
DeviceExtension->CommandPhase = ScrIdle; // this is only necessary
|
||
// for KeSynchronize ioctls
|
||
KeSetEvent(&DeviceExtension->Event,0,FALSE);
|
||
|
||
KeRaiseIrql( DISPATCH_LEVEL, &OldIrql );
|
||
|
||
IoCompleteRequest( Irp, IO_VIDEO_INCREMENT );
|
||
|
||
KeLowerIrql( OldIrql );
|
||
|
||
}
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
BOOLEAN
|
||
ScreenResetDevice(
|
||
IN PDEVICE_EXTENSION DeviceExtension
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine resets the device after a powerfail. It sets the mode to
|
||
the current mode and the palette and color registers to what they were
|
||
before the powerfail.
|
||
|
||
Arguments:
|
||
|
||
DeviceObject - Pointer to the device object for this driver.
|
||
|
||
Return Value:
|
||
|
||
For now simply return TRUE.
|
||
|
||
--*/
|
||
|
||
{
|
||
KIRQL OldIrql;
|
||
|
||
KeRaiseIrql(POWER_LEVEL,
|
||
&OldIrql);
|
||
|
||
#ifdef SCREEN_POWER_RECOVERY
|
||
if (DeviceExtension->ScreenPowerFailed == TRUE) {
|
||
|
||
KeLowerIrql( OldIrql );
|
||
return TRUE;
|
||
|
||
}
|
||
#endif // POWER_RECOVERY
|
||
|
||
SetHWMode(DeviceExtension,
|
||
DeviceExtension->ModeIndex,
|
||
FALSE);
|
||
|
||
if (!( DeviceExtension->CurrentMode->fbType & SCREEN_MODE_GRAPHICS ) ) {
|
||
|
||
SetHWFontRegs(DeviceExtension,
|
||
Fonts[DeviceExtension->RomFontIndex].PelRows);
|
||
|
||
SetCursorPosition(DeviceExtension,
|
||
&DeviceExtension->CursorPosition);
|
||
|
||
SetCursorType(DeviceExtension,
|
||
&DeviceExtension->CursorType);
|
||
}
|
||
|
||
SetColorLookup(DeviceExtension,
|
||
(PSCREEN_CLUT) &DeviceExtension->Clut,
|
||
FALSE);
|
||
|
||
SetPaletteReg(DeviceExtension,
|
||
(PSCREEN_PALETTE_DATA) &DeviceExtension->Palette,
|
||
FALSE);
|
||
|
||
KeLowerIrql(OldIrql);
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
static
|
||
VOID
|
||
ScreenUnload (
|
||
IN PDRIVER_OBJECT DriverObject
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the unload routine for the screen disk device driver.
|
||
It performs no operation.
|
||
|
||
Arguments:
|
||
|
||
DriverObject - Supplies a pointer to the driver object that describes
|
||
this driver.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
DBG_UNREFERENCED_PARAMETER(DriverObject);
|
||
return;
|
||
}
|
||
|
||
|
||
#ifdef SCREEN_POWER_RECOVERY
|
||
|
||
VOID
|
||
ScreenPowerFail(
|
||
IN PKDPC Dpc,
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp,
|
||
IN PVOID Context
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called when the power fails. It calls the routine
|
||
to reset the device and restart any operations that write to the
|
||
device. It also completes any operations that were pending due to
|
||
a powerfail.
|
||
|
||
Arguments:
|
||
|
||
Dpc - Pointer to DPC object.
|
||
DeviceObject - Pointer to the device object.
|
||
Irp - Pointer to Irp.
|
||
Context - Action to take in DCP.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOLEAN PowerFailed;
|
||
PDEVICE_EXTENSION DeviceExtension;
|
||
KIRQL OldIrql;
|
||
|
||
DeviceExtension = DeviceObject->DeviceExtension;
|
||
|
||
//
|
||
// set ScreenPowerFailed to FALSE.
|
||
//
|
||
|
||
KeRaiseIrql(POWER_LEVEL,
|
||
&OldIrql);
|
||
|
||
DeviceExtension->ScreenPowerFailed = FALSE;
|
||
KeLowerIrql( OldIrql );
|
||
|
||
PowerFailed = KeSynchronizeExecution(
|
||
&DeviceExtension->ScreenInterruptObject,
|
||
ScreenPowerReset,
|
||
DeviceExtension);
|
||
|
||
if (PowerFailed == FALSE) {
|
||
|
||
DeviceExtension->CommandPhase = ScrIdle;
|
||
|
||
KeSetEvent(&DeviceExtension->Event,
|
||
0,
|
||
FALSE);
|
||
|
||
KeRaiseIrql(DISPATCH_LEVEL,
|
||
&OldIrql);
|
||
|
||
IoCompleteRequest(Irp,
|
||
IO_VIDEO_INCREMENT);
|
||
|
||
KeLowerIrql(OldIrql);
|
||
|
||
}
|
||
}
|
||
|
||
|
||
BOOLEAN
|
||
ScreenPowerReset(
|
||
IN PDEVICE_OBJECT DeviceObject
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine reinitializes the device after a powerfail and restarts
|
||
any operation that was writing to the device.
|
||
|
||
Arguments:
|
||
|
||
DeviceObject - Pointer to the device object for this driver.
|
||
|
||
Return Value:
|
||
|
||
Whether the power failed during the reset.
|
||
|
||
--*/
|
||
|
||
{
|
||
PDEVICE_EXTENSION DeviceExtension;
|
||
BOOLEAN PowerFailed;
|
||
|
||
DeviceExtension = DeviceObject->DeviceExtension;
|
||
|
||
//
|
||
// reset the device. this sets the mode, palette regs, and CLUT to what
|
||
// they were before the powerfail.
|
||
//
|
||
|
||
PowerFailed = ScreenResetDevice(DeviceExtension);
|
||
|
||
if (PowerFailed) {
|
||
|
||
return TRUE;
|
||
|
||
}
|
||
|
||
//
|
||
// restart operation
|
||
//
|
||
|
||
if (DeviceExtension->CommandPhase != ScrIdle) {
|
||
|
||
return WriteToDevice(DeviceObject);
|
||
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
#endif // POWER_RECOVERY
|