bootvid.c
来自「一个类似windows」· C语言 代码 · 共 673 行 · 第 1/2 页
C
673 行
bminfo = (PBITMAPV5HEADER) &BootimageBitmap[0];
DPRINT("bV5Size = %d\n", bminfo->bV5Size);
DPRINT("bV5Width = %d\n", bminfo->bV5Width);
DPRINT("bV5Height = %d\n", bminfo->bV5Height);
DPRINT("bV5Planes = %d\n", bminfo->bV5Planes);
DPRINT("bV5BitCount = %d\n", bminfo->bV5BitCount);
DPRINT("bV5Compression = %d\n", bminfo->bV5Compression);
DPRINT("bV5SizeImage = %d\n", bminfo->bV5SizeImage);
DPRINT("bV5XPelsPerMeter = %d\n", bminfo->bV5XPelsPerMeter);
DPRINT("bV5YPelsPerMeter = %d\n", bminfo->bV5YPelsPerMeter);
DPRINT("bV5ClrUsed = %d\n", bminfo->bV5ClrUsed);
DPRINT("bV5ClrImportant = %d\n", bminfo->bV5ClrImportant);
if (bminfo->bV5ClrUsed)
ClrUsed = bminfo->bV5ClrUsed;
else
ClrUsed = 1 << bminfo->bV5BitCount;
bfOffBits = bminfo->bV5Size + ClrUsed * sizeof(RGBQUAD);
DPRINT("bfOffBits = %d\n", bfOffBits);
DPRINT("size of color indices = %d\n", ClrUsed * sizeof(RGBQUAD));
DPRINT("first byte of data = %d\n", BootimageBitmap[bfOffBits]);
InbvSetBlackPalette();
ImageData = ExAllocatePool(NonPagedPool, bminfo->bV5Width * bminfo->bV5Height);
RtlZeroMemory(ImageData, bminfo->bV5Width * bminfo->bV5Height);
/*
* ImageData has 1 pixel per byte.
* bootimage has 2 pixels per byte.
*/
if (bminfo->bV5Compression == 2)
{
k = 0;
j = 0;
while ((j < bminfo->bV5SizeImage) && (k < (ULONG) (bminfo->bV5Width * bminfo->bV5Height)))
{
unsigned char b;
clen = BootimageBitmap[bfOffBits + j];
j++;
if (clen > 0)
{
/* Encoded mode */
b = BootimageBitmap[bfOffBits + j];
j++;
for (i = 0; i < (clen / 2); i++)
{
ImageData[k] = (b & 0xf0) >> 4;
k++;
ImageData[k] = b & 0xf;
k++;
}
if ((clen & 1) > 0)
{
ImageData[k] = (b & 0xf0) >> 4;
k++;
}
}
else
{
/* Absolute mode */
b = BootimageBitmap[bfOffBits + j];
j++;
if (b == 0)
{
/* End of line */
if (k % bminfo->bV5Width)
{
cury = k / bminfo->bV5Width;
k = (cury + 1) * bminfo->bV5Width;
}
}
else if (b == 1)
{
/* End of image */
break;
}
else if (b == 2)
{
x = BootimageBitmap[bfOffBits + j];
j++;
y = BootimageBitmap[bfOffBits + j];
j++;
curx = k % bminfo->bV5Width;
cury = k / bminfo->bV5Width;
k = (cury + y) * bminfo->bV5Width + (curx + x);
}
else
{
if ((j & 1) > 0)
{
DPRINT("Unaligned copy!\n");
}
clen = b;
for (i = 0; i < (clen / 2); i++)
{
b = BootimageBitmap[bfOffBits + j];
j++;
ImageData[k] = (b & 0xf0) >> 4;
k++;
ImageData[k] = b & 0xf;
k++;
}
if ((clen & 1) > 0)
{
b = BootimageBitmap[bfOffBits + j];
j++;
ImageData[k] = (b & 0xf0) >> 4;
k++;
}
/* Word align */
j += (j & 1);
}
}
}
InbvDisplayBitmap(bminfo->bV5Width, bminfo->bV5Height, ImageData);
}
else
{
DbgPrint("Warning boot image need to be compressed using RLE4\n");
}
ExFreePool(ImageData);
}
static VOID FASTCALL
InbvFadeUpPalette()
{
PBITMAPV5HEADER bminfo;
PRGBQUAD Palette;
ULONG i;
unsigned char r, g, b;
register ULONG c;
LARGE_INTEGER Interval;
FADER_PALETTE_ENTRY FaderPalette[16];
FADER_PALETTE_ENTRY FaderPaletteDelta[16];
UCHAR ClrUsed;
RtlZeroMemory(&FaderPalette, sizeof(FaderPalette));
RtlZeroMemory(&FaderPaletteDelta, sizeof(FaderPaletteDelta));
bminfo = (PBITMAPV5HEADER)&BootimageBitmap[0];
Palette = (PRGBQUAD)&BootimageBitmap[bminfo->bV5Size];
if (bminfo->bV5ClrUsed)
ClrUsed = bminfo->bV5ClrUsed;
else
ClrUsed = 1 << bminfo->bV5BitCount;
for (i = 0; i < 16 && i < ClrUsed; i++)
{
FaderPaletteDelta[i].r = ((Palette[i].rgbRed << 8) / PALETTE_FADE_STEPS);
FaderPaletteDelta[i].g = ((Palette[i].rgbGreen << 8) / PALETTE_FADE_STEPS);
FaderPaletteDelta[i].b = ((Palette[i].rgbBlue << 8) / PALETTE_FADE_STEPS);
}
for (i = 0; i < PALETTE_FADE_STEPS && !ShutdownNotify; i++)
{
/* Disable screen and enable palette access. */
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x00);
for (c = 0; c < ClrUsed; c++)
{
/* Add the delta */
FaderPalette[c].r += FaderPaletteDelta[c].r;
FaderPalette[c].g += FaderPaletteDelta[c].g;
FaderPalette[c].b += FaderPaletteDelta[c].b;
/* Get the integer values */
r = FaderPalette[c].r >> 8;
g = FaderPalette[c].g >> 8;
b = FaderPalette[c].b >> 8;
/* Don't go too far */
if (r > Palette[c].rgbRed)
r = Palette[c].rgbRed;
if (g > Palette[c].rgbGreen)
g = Palette[c].rgbGreen;
if (b > Palette[c].rgbBlue)
b = Palette[c].rgbBlue;
/* Update the hardware */
InbvSetColor(c, r, g, b);
}
/* Enable screen and disable palette access. */
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x20);
/* Wait for a bit. */
Interval.QuadPart = -PALETTE_FADE_TIME;
KeDelayExecutionThread(KernelMode, FALSE, &Interval);
}
}
static VOID STDCALL
InbvBitmapThreadMain(PVOID Ignored)
{
if (InbvFindBootimage())
{
InbvDisplayCompressedBitmap();
InbvFadeUpPalette();
}
else
{
DbgPrint("Warning: Cannot find boot image\n");
}
KeSetEvent(&ShutdownCompleteEvent, 0, FALSE);
}
static BOOLEAN STDCALL
VidInitialize(VOID)
{
NTSTATUS Status;
HANDLE BitmapThreadHandle;
InbvMapVideoMemory();
InbvInitVGAMode();
Status = PsCreateSystemThread(
&BitmapThreadHandle,
THREAD_ALL_ACCESS,
NULL,
NULL,
&BitmapThreadId,
InbvBitmapThreadMain,
NULL);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
ZwClose(BitmapThreadHandle);
return TRUE;
}
static NTSTATUS STDCALL
VidDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
NTBOOTVID_FUNCTION_TABLE* FunctionTable;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
Status = STATUS_SUCCESS;
switch(IrpSp->MajorFunction)
{
/* Opening and closing handles to the device */
case IRP_MJ_CREATE:
case IRP_MJ_CLOSE:
break;
case IRP_MJ_DEVICE_CONTROL:
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_BOOTVID_INITIALIZE:
VidInitialize();
FunctionTable = (NTBOOTVID_FUNCTION_TABLE *)
Irp->AssociatedIrp.SystemBuffer;
FunctionTable->ResetDisplay = VidResetDisplay;
Irp->IoStatus.Information = sizeof(NTBOOTVID_FUNCTION_TABLE);
break;
case IOCTL_BOOTVID_CLEANUP:
VidCleanUp();
break;
default:
Status = STATUS_NOT_IMPLEMENTED;
break;
}
break;
/* Unsupported operations */
default:
Status = STATUS_NOT_IMPLEMENTED;
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS STDCALL
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT BootVidDevice;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\BootVid");
NTSTATUS Status;
BootVidDriverObject = DriverObject;
ShutdownNotify = 0;
KeInitializeEvent(&ShutdownCompleteEvent, NotificationEvent, FALSE);
/* Register driver routines */
DriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatch;
DriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VidDispatch;
DriverObject->DriverUnload = NULL;
DriverObject->Flags |= DO_BUFFERED_IO;
/* Create device */
Status = IoCreateDevice(
DriverObject,
0,
&DeviceName,
FILE_DEVICE_BOOTVID,
0,
FALSE,
&BootVidDevice);
return Status;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?