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.
1013 lines
27 KiB
1013 lines
27 KiB
/*++
|
|
|
|
Copyright (c) 1991 - 2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
##### #### ### ##### ## ### ## ## #### ##### #####
|
|
## ## ## ## # ## ## ## ### ## ## ## # ## ## ## ##
|
|
## ## ## ### ## ## ## ## ## #### ## ## ## ## ##
|
|
## ## ## ### ## ## ## ## ## #### ## ## ## ## ##
|
|
## ## ## ### ##### ## ####### ## ## ##### #####
|
|
## ## ## # ## ## ## ## ## ## ## ## # ## ##
|
|
##### #### ### ## ##### ## ## ## ## #### ## ##
|
|
|
|
Abstract:
|
|
|
|
This module contains functions specfic to the
|
|
display device. The logic in this module is not
|
|
hardware specific, but is logic that is common
|
|
to all hardware implementations.
|
|
|
|
Author:
|
|
|
|
Wesley Witt (wesw) 1-Oct-2001
|
|
|
|
Environment:
|
|
|
|
Kernel mode only.
|
|
|
|
Notes:
|
|
|
|
|
|
--*/
|
|
|
|
#include "internal.h"
|
|
|
|
PDISPLAY_DEVICE_EXTENSION g_DeviceExtension = NULL;
|
|
|
|
NTSTATUS
|
|
DoBitmapDisplay(
|
|
IN PDISPLAY_DEVICE_EXTENSION DeviceExtension,
|
|
IN PVOID BitmapBits,
|
|
IN ULONG MsgCode
|
|
);
|
|
|
|
VOID
|
|
SaDisplayProcessNotifyRoutine(
|
|
IN HANDLE ParentId,
|
|
IN HANDLE ProcessId,
|
|
IN BOOLEAN Create
|
|
);
|
|
|
|
|
|
NTSTATUS
|
|
SaDisplayLoadBitmapFromRegistry(
|
|
IN PDISPLAY_DEVICE_EXTENSION DeviceExtension,
|
|
IN PUNICODE_STRING RegistryPath,
|
|
IN PWSTR ValueName,
|
|
IN OUT PVOID *DataBuffer
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine loads a bitmap resource from the registry.
|
|
The bitmaps are loaded from the driver's parameters key.
|
|
|
|
Arguments:
|
|
|
|
RegistryPath - Full path to the driver's registry key
|
|
ValueName - Name of the value in the registry (also the bitmap name)
|
|
DataBuffer - Pointer to a pointer that is allocated by this function.
|
|
The allocated memory holds the bitmap's bits.
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS status;
|
|
PKEY_VALUE_FULL_INFORMATION KeyInformation = NULL;
|
|
|
|
|
|
__try {
|
|
|
|
status = ReadRegistryValue(
|
|
DeviceExtension->DriverExtension,
|
|
RegistryPath,
|
|
ValueName,
|
|
&KeyInformation
|
|
);
|
|
if (!NT_SUCCESS(status)) {
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "SaDisplayLoadBitmapFromRegistry could not read bitmap", status );
|
|
}
|
|
|
|
if (KeyInformation->Type != REG_BINARY) {
|
|
status = STATUS_OBJECT_TYPE_MISMATCH;
|
|
__leave;
|
|
}
|
|
|
|
*DataBuffer = ExAllocatePool( NonPagedPool, KeyInformation->DataLength );
|
|
if (*DataBuffer == NULL) {
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "Could not allocate pool", status );
|
|
}
|
|
|
|
RtlCopyMemory( *DataBuffer, (PUCHAR)KeyInformation + KeyInformation->DataOffset, KeyInformation->DataLength );
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
} __finally {
|
|
|
|
if (KeyInformation) {
|
|
ExFreePool( KeyInformation );
|
|
}
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
if (*DataBuffer) {
|
|
ExFreePool( *DataBuffer );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaDisplayLoadAllBitmaps(
|
|
IN PDISPLAY_DEVICE_EXTENSION DeviceExtension,
|
|
IN PUNICODE_STRING RegistryPath
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine loads all bitmap resources from the registry.
|
|
|
|
Arguments:
|
|
|
|
DeviceExtension - Display device extension
|
|
RegistryPath - Full path to the driver's registry key
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
PVOID StartingBitmap = NULL;
|
|
PVOID CheckDiskBitmap = NULL;
|
|
PVOID ReadyBitmap = NULL;
|
|
PVOID ShutdownBitmap = NULL;
|
|
PVOID UpdateBitmap = NULL;
|
|
|
|
|
|
__try {
|
|
|
|
ExAcquireFastMutex( &DeviceExtension->DisplayMutex );
|
|
|
|
Status = SaDisplayLoadBitmapFromRegistry( DeviceExtension, RegistryPath, DISPLAY_STARTING_PARAM, &StartingBitmap );
|
|
if (!NT_SUCCESS(Status)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Could not load starting bitmap", Status );
|
|
}
|
|
|
|
Status = SaDisplayLoadBitmapFromRegistry( DeviceExtension, RegistryPath, DISPLAY_CHECKDISK_PARAM, &CheckDiskBitmap );
|
|
if (!NT_SUCCESS(Status)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Could not load check disk bitmap", Status );
|
|
}
|
|
|
|
Status = SaDisplayLoadBitmapFromRegistry( DeviceExtension, RegistryPath, DISPLAY_READY_PARAM, &ReadyBitmap );
|
|
if (!NT_SUCCESS(Status)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Could not load ready bitmap", Status );
|
|
}
|
|
|
|
Status = SaDisplayLoadBitmapFromRegistry( DeviceExtension, RegistryPath, DISPLAY_SHUTDOWN_PARAM, &ShutdownBitmap );
|
|
if (!NT_SUCCESS(Status)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Could not load shutdown bitmap", Status );
|
|
}
|
|
|
|
Status = SaDisplayLoadBitmapFromRegistry( DeviceExtension, RegistryPath, DISPLAY_UPDATE_PARAM, &UpdateBitmap );
|
|
if (!NT_SUCCESS(Status)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Could not load update bitmap", Status );
|
|
}
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
DeviceExtension->StartingBitmap = StartingBitmap;
|
|
DeviceExtension->CheckDiskBitmap = CheckDiskBitmap;
|
|
DeviceExtension->ReadyBitmap = ReadyBitmap;
|
|
DeviceExtension->ShutdownBitmap = ShutdownBitmap;
|
|
DeviceExtension->UpdateBitmap = UpdateBitmap;
|
|
|
|
} __finally {
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
if (StartingBitmap) {
|
|
ExFreePool( StartingBitmap );
|
|
}
|
|
|
|
if (CheckDiskBitmap) {
|
|
ExFreePool( CheckDiskBitmap );
|
|
}
|
|
|
|
if (ReadyBitmap) {
|
|
ExFreePool( ReadyBitmap );
|
|
}
|
|
|
|
if (ShutdownBitmap) {
|
|
ExFreePool( ShutdownBitmap );
|
|
}
|
|
|
|
if (UpdateBitmap) {
|
|
ExFreePool( UpdateBitmap );
|
|
}
|
|
}
|
|
|
|
ExReleaseFastMutex( &DeviceExtension->DisplayMutex );
|
|
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
SaDisplayDisplayBitmap(
|
|
IN PDISPLAY_DEVICE_EXTENSION DeviceExtension,
|
|
IN PSA_DISPLAY_SHOW_MESSAGE Bitmap
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine calls the local display miniport to display a bitmap.
|
|
|
|
Arguments:
|
|
|
|
DeviceExtension - Display device extension
|
|
Bitmap - Pointer to a SA_DISPLAY_SHOW_MESSAGE structure
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
|
|
__try {
|
|
|
|
if (DeviceExtension->DisplayType != SA_DISPLAY_TYPE_BIT_MAPPED_LCD) {
|
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "The display does not support bitmapped LCD", Status );
|
|
}
|
|
|
|
Status = CallMiniPortDriverReadWrite(
|
|
DeviceExtension,
|
|
DeviceExtension->DeviceObject,
|
|
TRUE,
|
|
Bitmap,
|
|
sizeof(SA_DISPLAY_SHOW_MESSAGE),
|
|
0
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "Could not display the bitmap", Status );
|
|
}
|
|
|
|
} __finally {
|
|
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaDisplayClearDisplay(
|
|
PDISPLAY_DEVICE_EXTENSION DeviceExtension
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine causes the local display to be cleared of any bitmap image.
|
|
|
|
Arguments:
|
|
|
|
DeviceExtension - Display device extension
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
PSA_DISPLAY_SHOW_MESSAGE Bitmap = NULL;
|
|
|
|
|
|
__try {
|
|
|
|
if (DeviceExtension->DisplayType != SA_DISPLAY_TYPE_BIT_MAPPED_LCD) {
|
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "The display does not support bitmapped LCD", Status );
|
|
}
|
|
|
|
Bitmap = (PSA_DISPLAY_SHOW_MESSAGE) ExAllocatePool( PagedPool, sizeof(SA_DISPLAY_SHOW_MESSAGE) );
|
|
if (Bitmap == NULL) {
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "Could not allocate pool", Status );
|
|
}
|
|
|
|
Bitmap->SizeOfStruct = sizeof(SA_DISPLAY_SHOW_MESSAGE);
|
|
Bitmap->Width = DeviceExtension->DisplayWidth;
|
|
Bitmap->Height = DeviceExtension->DisplayHeight;
|
|
Bitmap->MsgCode = SA_DISPLAY_STARTING;
|
|
|
|
RtlZeroMemory( Bitmap->Bits, SA_DISPLAY_MAX_BITMAP_SIZE );
|
|
|
|
Status = SaDisplayDisplayBitmap( DeviceExtension, Bitmap );
|
|
if (!NT_SUCCESS(Status)) {
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "Could not display bitmap", Status );
|
|
}
|
|
|
|
} __finally {
|
|
|
|
if (Bitmap) {
|
|
ExFreePool( Bitmap );
|
|
}
|
|
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaDisplayStartDevice(
|
|
IN PDISPLAY_DEVICE_EXTENSION DeviceExtension
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is the local display specific code for processing
|
|
the PNP start device request. The local display's
|
|
capabilities are queried and then all the bitmap
|
|
resources are loaded.
|
|
|
|
Arguments:
|
|
|
|
DeviceExtension - Display device extension
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
SA_DISPLAY_CAPS DisplayCaps;
|
|
|
|
|
|
Status = CallMiniPortDriverDeviceControl(
|
|
DeviceExtension,
|
|
DeviceExtension->DeviceObject,
|
|
IOCTL_SA_GET_CAPABILITIES,
|
|
NULL,
|
|
0,
|
|
&DisplayCaps,
|
|
sizeof(SA_DISPLAY_CAPS)
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Could not query miniport's capabilities", Status );
|
|
return Status;
|
|
}
|
|
|
|
if (DisplayCaps.SizeOfStruct != sizeof(SA_DISPLAY_CAPS)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "SA_DISPLAY_CAPS is the wrong size", STATUS_INVALID_BUFFER_SIZE );
|
|
return STATUS_INVALID_BUFFER_SIZE;
|
|
}
|
|
|
|
DeviceExtension->DisplayType = DisplayCaps.DisplayType;
|
|
DeviceExtension->DisplayHeight = DisplayCaps.DisplayHeight;
|
|
DeviceExtension->DisplayWidth = DisplayCaps.DisplayWidth;
|
|
|
|
|
|
Status = SaDisplayLoadAllBitmaps( DeviceExtension, &DeviceExtension->DriverExtension->RegistryPath );
|
|
if (!NT_SUCCESS(Status)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Could not load all the bitmaps", Status );
|
|
return Status;
|
|
}
|
|
|
|
Status = DoBitmapDisplay(
|
|
(PDISPLAY_DEVICE_EXTENSION)DeviceExtension,
|
|
((PDISPLAY_DEVICE_EXTENSION)DeviceExtension)->StartingBitmap,
|
|
SA_DISPLAY_STARTING
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Could not display starting bitmap", Status );
|
|
}
|
|
|
|
g_DeviceExtension = DeviceExtension;
|
|
|
|
Status = PsSetCreateProcessNotifyRoutine(SaDisplayProcessNotifyRoutine,0);
|
|
if (!NT_SUCCESS(Status)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Could not display starting bitmap", Status );
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is the local display specific code for processing
|
|
notification of process creation and termination.
|
|
Process name is retrieved and checkdisk bitmap is
|
|
displayed if "autochk.exe" is running.
|
|
|
|
Arguments:
|
|
|
|
HANDLE - Handle to parent process
|
|
HANDLE - Handle to process
|
|
BOOLEAN - Flag(Creation or Termination)
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
VOID
|
|
SaDisplayProcessNotifyRoutine(
|
|
IN HANDLE ParentId,
|
|
IN HANDLE ProcessId,
|
|
IN BOOLEAN Create
|
|
)
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
PSTR ImageName;
|
|
PEPROCESS Process;
|
|
|
|
if (!g_DeviceExtension)
|
|
return;
|
|
|
|
Status = PsLookupProcessByProcessId(
|
|
ProcessId,
|
|
&Process
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
return;
|
|
}
|
|
|
|
ImageName = (PSTR)PsGetProcessImageFileName(Process);
|
|
|
|
_strlwr(ImageName);
|
|
|
|
if (strcmp(ImageName,"autochk.exe") == 0) {
|
|
|
|
if (Create) {
|
|
if (g_DeviceExtension->CheckDiskBitmap) {
|
|
Status = DoBitmapDisplay(
|
|
g_DeviceExtension,
|
|
g_DeviceExtension->CheckDiskBitmap,
|
|
SA_DISPLAY_ADD_START_TASKS
|
|
);
|
|
}
|
|
} else {
|
|
if (g_DeviceExtension->StartingBitmap) {
|
|
Status = DoBitmapDisplay(
|
|
g_DeviceExtension,
|
|
g_DeviceExtension->StartingBitmap,
|
|
SA_DISPLAY_ADD_START_TASKS
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaDisplayDeviceInitialization(
|
|
IN PSAPORT_DRIVER_EXTENSION DriverExtension
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is the local display specific code for driver initialization.
|
|
This function is called by SaPortInitialize, which is called by
|
|
the local display's DriverEntry function.
|
|
|
|
Arguments:
|
|
|
|
DriverExtension - Driver extension structure
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
UNREFERENCED_PARAMETER(DriverExtension);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaDisplayIoValidation(
|
|
IN PDISPLAY_DEVICE_EXTENSION DeviceExtension,
|
|
IN PIRP Irp,
|
|
PIO_STACK_LOCATION IrpSp
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is the local display specific code for processing
|
|
all I/O validation for reads and writes.
|
|
|
|
Arguments:
|
|
|
|
DeviceExtension - Display device extension
|
|
Irp - Pointer to an IRP structure that describes the requested I/O operation.
|
|
IrpSp - Irp stack pointer
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG Length;
|
|
|
|
|
|
if (IrpSp->MajorFunction == IRP_MJ_READ) {
|
|
Length = (ULONG)IrpSp->Parameters.Read.Length;
|
|
} else if (IrpSp->MajorFunction == IRP_MJ_WRITE) {
|
|
Length = (ULONG)IrpSp->Parameters.Write.Length;
|
|
} else {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Invalid I/O request", STATUS_INVALID_PARAMETER_1 );
|
|
return STATUS_INVALID_PARAMETER_1;
|
|
}
|
|
|
|
if (Length < sizeof(SA_DISPLAY_SHOW_MESSAGE)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "I/O length != sizeof(SA_DISPLAY_SHOW_MESSAGE)", STATUS_INVALID_PARAMETER_2 );
|
|
return STATUS_INVALID_PARAMETER_2;
|
|
}
|
|
|
|
//
|
|
// For the display device we support the concept of
|
|
// the user mode layer obtaining exclusive access
|
|
// to the device.
|
|
//
|
|
|
|
ExAcquireFastMutex( &DeviceExtension->DisplayMutex );
|
|
if (!DeviceExtension->AllowWrites) {
|
|
ExReleaseFastMutex( &DeviceExtension->DisplayMutex );
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Cannot write bitmap because the display is locked", STATUS_MEDIA_WRITE_PROTECTED );
|
|
return STATUS_MEDIA_WRITE_PROTECTED;
|
|
}
|
|
ExReleaseFastMutex( &DeviceExtension->DisplayMutex );
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaDisplayShutdownNotification(
|
|
IN PDISPLAY_DEVICE_EXTENSION DeviceExtension,
|
|
IN PIRP Irp,
|
|
PIO_STACK_LOCATION IrpSp
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is the local display specific code for processing
|
|
the system shutdown notification.
|
|
|
|
Arguments:
|
|
|
|
DeviceExtension - Display device extension
|
|
Irp - Pointer to an IRP structure that describes the requested I/O operation.
|
|
IrpSp - Irp stack pointer
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
UNREFERENCED_PARAMETER(DeviceExtension);
|
|
UNREFERENCED_PARAMETER(Irp);
|
|
UNREFERENCED_PARAMETER(IrpSp);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
DECLARE_IOCTL_HANDLER( HandleDisplayLock )
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine processes the private IOCTL_SADISPLAY_LOCK request. This
|
|
IOCTL allows an applicatgion to lock out display writes for a period
|
|
of time.
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - The device object for the target device.
|
|
Irp - Pointer to an IRP structure that describes the requested I/O operation.
|
|
DeviceExtension - Pointer to the main port driver device extension.
|
|
InputBuffer - Pointer to the user's input buffer
|
|
InputBufferLength - Length in bytes of the input buffer
|
|
OutputBuffer - Pointer to the user's output buffer
|
|
OutputBufferLength - Length in bytes of the output buffer
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
ExAcquireFastMutex( &((PDISPLAY_DEVICE_EXTENSION)DeviceExtension)->DisplayMutex );
|
|
((PDISPLAY_DEVICE_EXTENSION)DeviceExtension)->AllowWrites = FALSE;
|
|
ExReleaseFastMutex( &((PDISPLAY_DEVICE_EXTENSION)DeviceExtension)->DisplayMutex );
|
|
|
|
return CompleteRequest( Irp, STATUS_SUCCESS, 0 );
|
|
}
|
|
|
|
|
|
DECLARE_IOCTL_HANDLER( HandleDisplayUnlock )
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine processes the private IOCTL_SADISPLAY_UNLOCK request. This
|
|
IOCTL allows an applicatgion to unlock a previous lock.
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - The device object for the target device.
|
|
Irp - Pointer to an IRP structure that describes the requested I/O operation.
|
|
DeviceExtension - Pointer to the main port driver device extension.
|
|
InputBuffer - Pointer to the user's input buffer
|
|
InputBufferLength - Length in bytes of the input buffer
|
|
OutputBuffer - Pointer to the user's output buffer
|
|
OutputBufferLength - Length in bytes of the output buffer
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
ExAcquireFastMutex( &((PDISPLAY_DEVICE_EXTENSION)DeviceExtension)->DisplayMutex );
|
|
((PDISPLAY_DEVICE_EXTENSION)DeviceExtension)->AllowWrites = TRUE;
|
|
ExReleaseFastMutex( &((PDISPLAY_DEVICE_EXTENSION)DeviceExtension)->DisplayMutex );
|
|
|
|
return CompleteRequest( Irp, STATUS_SUCCESS, 0 );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
DoBitmapDisplay(
|
|
IN PDISPLAY_DEVICE_EXTENSION DeviceExtension,
|
|
IN PVOID BitmapBits,
|
|
IN ULONG MsgCode
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is an internal support function that displays a bitmap on the local display.
|
|
|
|
Arguments:
|
|
|
|
DeviceExtension - Pointer to the display specific device extension
|
|
BitmapBits - Pointer to the bitmap bits to display
|
|
MsgCode - Server appliance message code
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
PSA_DISPLAY_SHOW_MESSAGE Bitmap = NULL;
|
|
|
|
|
|
Status = SaDisplayClearDisplay( DeviceExtension );
|
|
if (!NT_SUCCESS(Status)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Could not clear the local display", Status );
|
|
return Status;
|
|
}
|
|
|
|
__try {
|
|
|
|
|
|
if (BitmapBits == NULL) {
|
|
Status = STATUS_DATA_ERROR;
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "Bitmap bits cannot be NULL", Status );
|
|
}
|
|
|
|
Bitmap = (PSA_DISPLAY_SHOW_MESSAGE) ExAllocatePool( PagedPool, sizeof(SA_DISPLAY_SHOW_MESSAGE) );
|
|
if (Bitmap == NULL) {
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "Could not allocate pool", Status );
|
|
}
|
|
|
|
Bitmap->SizeOfStruct = sizeof(SA_DISPLAY_SHOW_MESSAGE);
|
|
Bitmap->Width = DeviceExtension->DisplayWidth;
|
|
Bitmap->Height = DeviceExtension->DisplayHeight;
|
|
Bitmap->MsgCode = MsgCode;
|
|
|
|
RtlCopyMemory( Bitmap->Bits, BitmapBits, Bitmap->Height * (Bitmap->Width >> 3) );
|
|
|
|
Status = SaDisplayDisplayBitmap( DeviceExtension, Bitmap );
|
|
if (!NT_SUCCESS(Status)) {
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "Could not display bitmap", Status );
|
|
}
|
|
|
|
} __finally {
|
|
|
|
if (Bitmap) {
|
|
ExFreePool( Bitmap );
|
|
}
|
|
|
|
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
DECLARE_IOCTL_HANDLER( HandleDisplayBusyMessage )
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine displays the busy message bitmap on the local display.
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - The device object for the target device.
|
|
Irp - Pointer to an IRP structure that describes the requested I/O operation.
|
|
DeviceExtension - Pointer to the main port driver device extension.
|
|
InputBuffer - Pointer to the user's input buffer
|
|
InputBufferLength - Length in bytes of the input buffer
|
|
OutputBuffer - Pointer to the user's output buffer
|
|
OutputBufferLength - Length in bytes of the output buffer
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
|
|
Status = DoBitmapDisplay(
|
|
(PDISPLAY_DEVICE_EXTENSION)DeviceExtension,
|
|
((PDISPLAY_DEVICE_EXTENSION)DeviceExtension)->CheckDiskBitmap,
|
|
SA_DISPLAY_ADD_START_TASKS
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Could not display busy bitmap", Status );
|
|
return CompleteRequest( Irp, Status, 0 );
|
|
}
|
|
|
|
return CompleteRequest( Irp, STATUS_SUCCESS, 0 );
|
|
}
|
|
|
|
|
|
DECLARE_IOCTL_HANDLER( HandleDisplayShutdownMessage )
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine displays the shutdown message bitmap on the local display.
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - The device object for the target device.
|
|
Irp - Pointer to an IRP structure that describes the requested I/O operation.
|
|
DeviceExtension - Pointer to the main port driver device extension.
|
|
InputBuffer - Pointer to the user's input buffer
|
|
InputBufferLength - Length in bytes of the input buffer
|
|
OutputBuffer - Pointer to the user's output buffer
|
|
OutputBufferLength - Length in bytes of the output buffer
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
|
|
Status = DoBitmapDisplay(
|
|
(PDISPLAY_DEVICE_EXTENSION)DeviceExtension,
|
|
((PDISPLAY_DEVICE_EXTENSION)DeviceExtension)->ShutdownBitmap,
|
|
SA_DISPLAY_SHUTTING_DOWN
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Could not display shutdown bitmap", Status );
|
|
return CompleteRequest( Irp, Status, 0 );
|
|
}
|
|
|
|
return CompleteRequest( Irp, STATUS_SUCCESS, 0 );
|
|
}
|
|
|
|
|
|
DECLARE_IOCTL_HANDLER( HandleDisplayChangeLanguage )
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine causes all internal butmaps to be reloaded from the registry.
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - The device object for the target device.
|
|
Irp - Pointer to an IRP structure that describes the requested I/O operation.
|
|
DeviceExtension - Pointer to the main port driver device extension.
|
|
InputBuffer - Pointer to the user's input buffer
|
|
InputBufferLength - Length in bytes of the input buffer
|
|
OutputBuffer - Pointer to the user's output buffer
|
|
OutputBufferLength - Length in bytes of the output buffer
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
Status = SaDisplayLoadAllBitmaps( (PDISPLAY_DEVICE_EXTENSION)DeviceExtension, &DeviceExtension->DriverExtension->RegistryPath );
|
|
if (!NT_SUCCESS(Status)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Could not load all bitmaps", Status );
|
|
}
|
|
|
|
return CompleteRequest( Irp, Status, 0 );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaDisplayStoreBitmapInRegistry(
|
|
IN PDISPLAY_DEVICE_EXTENSION DeviceExtension,
|
|
IN PWSTR ValueName,
|
|
IN PSA_DISPLAY_SHOW_MESSAGE SaDisplay
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine stores a bitmap in the registry.
|
|
|
|
Arguments:
|
|
|
|
RegistryPath - Full path to the driver's registry key
|
|
ValueName - Name of the value in the registry (also the bitmap name)
|
|
SaDisplay - Pointer to the bitmap to be stored
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
|
|
Status = WriteRegistryValue(
|
|
DeviceExtension->DriverExtension,
|
|
&DeviceExtension->DriverExtension->RegistryPath,
|
|
ValueName,
|
|
REG_BINARY,
|
|
SaDisplay->Bits,
|
|
SaDisplay->Height * (SaDisplay->Width >> 3)
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "WriteRegistryValue failed", Status );
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
DECLARE_IOCTL_HANDLER( HandleDisplayStoreBitmap )
|
|
{
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine stores a bitmap in the registry for the display driver.
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - The device object for the target device.
|
|
Irp - Pointer to an IRP structure that describes the requested I/O operation.
|
|
DeviceExtension - Pointer to the main port driver device extension.
|
|
InputBuffer - Pointer to the user's input buffer
|
|
InputBufferLength - Length in bytes of the input buffer
|
|
OutputBuffer - Pointer to the user's output buffer
|
|
OutputBufferLength - Length in bytes of the output buffer
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
NTSTATUS Status;
|
|
PSA_DISPLAY_SHOW_MESSAGE SaDisplay = (PSA_DISPLAY_SHOW_MESSAGE) InputBuffer;
|
|
|
|
|
|
__try {
|
|
|
|
if (InputBuffer == NULL || InputBufferLength != sizeof(SA_DISPLAY_SHOW_MESSAGE)) {
|
|
Status = STATUS_INVALID_PARAMETER_1;
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "Input buffer is invalid", Status );
|
|
}
|
|
|
|
if (SaDisplay->SizeOfStruct != sizeof(SA_DISPLAY_SHOW_MESSAGE)) {
|
|
Status = STATUS_INVALID_PARAMETER_2;
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "SaDisplay->SizeOfStruct != sizeof(SA_DISPLAY_SHOW_MESSAGE)", Status );
|
|
}
|
|
|
|
if (SaDisplay->Width > ((PDISPLAY_DEVICE_EXTENSION)DeviceExtension)->DisplayWidth || SaDisplay->Height > ((PDISPLAY_DEVICE_EXTENSION)DeviceExtension)->DisplayHeight) {
|
|
Status = STATUS_INVALID_PARAMETER_3;
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "SaDisplay->SizeOfStruct != sizeof(SA_DISPLAY_SHOW_MESSAGE)", Status );
|
|
}
|
|
|
|
switch (SaDisplay->MsgCode) {
|
|
case SA_DISPLAY_STARTING:
|
|
Status = SaDisplayStoreBitmapInRegistry( (PDISPLAY_DEVICE_EXTENSION)DeviceExtension, DISPLAY_STARTING_PARAM, SaDisplay );
|
|
break;
|
|
|
|
case SA_DISPLAY_ADD_START_TASKS:
|
|
Status = SaDisplayStoreBitmapInRegistry( (PDISPLAY_DEVICE_EXTENSION)DeviceExtension, DISPLAY_UPDATE_PARAM, SaDisplay );
|
|
break;
|
|
|
|
case SA_DISPLAY_READY:
|
|
Status = SaDisplayStoreBitmapInRegistry( (PDISPLAY_DEVICE_EXTENSION)DeviceExtension, DISPLAY_READY_PARAM, SaDisplay );
|
|
break;
|
|
|
|
case SA_DISPLAY_SHUTTING_DOWN:
|
|
Status = SaDisplayStoreBitmapInRegistry( (PDISPLAY_DEVICE_EXTENSION)DeviceExtension, DISPLAY_SHUTDOWN_PARAM, SaDisplay );
|
|
break;
|
|
|
|
case SA_DISPLAY_CHECK_DISK:
|
|
Status = SaDisplayStoreBitmapInRegistry( (PDISPLAY_DEVICE_EXTENSION)DeviceExtension, DISPLAY_CHECKDISK_PARAM, SaDisplay );
|
|
break;
|
|
|
|
default:
|
|
Status = STATUS_INVALID_PARAMETER_4;
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "Invalid display message id", Status );
|
|
break;
|
|
}
|
|
|
|
} __finally {
|
|
|
|
|
|
}
|
|
|
|
return CompleteRequest( Irp, Status, 0 );
|
|
}
|