|
|
/*++
Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
Module Name:
ptdrvcom.c
Abstract:
Code for the RDP remote port driver which is common to the mouse and keyboard
Environment:
Kernel mode only.
Revision History:
02/12/99 - Initial Revision based on pnpi8042 driver
--*/
#include <precomp.h>
#pragma hdrstop
#include <poclass.h>
#include "ptdrvcom.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, PtCreate)
#pragma alloc_text(PAGE, PtDeviceControl)
#pragma alloc_text(INIT, PtEntry)
#pragma alloc_text(PAGE, PtUnload)
#if PTDRV_VERBOSE
#pragma alloc_text(INIT, PtServiceParameters)
#endif
#endif // ALLOC_PRAGMA
GLOBALS Globals;
NTSTATUS PtCreate ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++
Routine Description:
This is the dispatch routine for create/open requests.
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
NT status code.
--*/ { NTSTATUS status = STATUS_SUCCESS; PCOMMON_DATA commonData = NULL;
Print(DBG_IOCTL_TRACE, ("Create enter\n"));
PAGED_CODE();
commonData = GET_COMMON_DATA(DeviceObject->DeviceExtension);
if (NULL == commonData->ConnectData.ClassService) { //
// No Connection yet. How can we be enabled?
//
Print(DBG_IOCTL_ERROR, ("ERROR: enable before connect!\n")); status = STATUS_INVALID_DEVICE_STATE; } else if (commonData->ManuallyRemoved) { status = STATUS_NO_SUCH_DEVICE; } else if (1 >= InterlockedIncrement(&commonData->EnableCount)) { Print(DBG_IOCTL_INFO, ("Enabling %s (%d)\n", commonData->IsKeyboard ? "Keyboard" : "Mouse", commonData->EnableCount )); }
//
// No need to call the lower driver (the root bus) because it only handles
// Power and PnP Irps
//
Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT);
Print(DBG_IOCTL_TRACE, ("Create (%x)\n", status));
return status; }
NTSTATUS PtClose ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++
Routine Description:
This is the dispatch routine for close requests. This request completes successfully.
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
NT status code.
--*/ { PCOMMON_DATA commonData;
PAGED_CODE();
Print(DBG_IOCTL_TRACE, ("Close\n"));
commonData = GET_COMMON_DATA(DeviceObject->DeviceExtension);
ASSERT(0 < commonData->EnableCount);
if (0 >= InterlockedDecrement(&commonData->EnableCount)) { Print(DBG_IOCTL_INFO, ("Disabling %s (%d)\n", commonData->IsKeyboard ? "Keyboard" : "Mouse", commonData->EnableCount )); }
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; }
NTSTATUS PtDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PPORT_KEYBOARD_EXTENSION kbExtension; PIO_STACK_LOCATION stack; NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
PAGED_CODE();
//
// Get a pointer to the device extension.
//
kbExtension = (PPORT_KEYBOARD_EXTENSION) DeviceObject->DeviceExtension;
if (!kbExtension->Started || !kbExtension->IsKeyboard || kbExtension->ManuallyRemoved) { status = STATUS_INVALID_DEVICE_REQUEST; } else { stack = IoGetCurrentIrpStackLocation(Irp); switch (stack->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_GET_SYS_BUTTON_CAPS: //
// We don't support any system buttons
//
if (stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) { Print(DBG_IOCTL_ERROR, ("get caps, buffer too small\n")); status = STATUS_INVALID_BUFFER_SIZE; } else { Print(DBG_IOCTL_INFO, ("Returned sys btn caps of 0x0\n")); *(PULONG) Irp->AssociatedIrp.SystemBuffer = 0x0; status = STATUS_SUCCESS; }
Irp->IoStatus.Information = sizeof(ULONG); break;
default: Print(DBG_IOCTL_ERROR, ("Invalid request 0x%x\n", stack->Parameters.DeviceIoControl.IoControlCode)); status = STATUS_INVALID_DEVICE_REQUEST; break; } }
Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status; }
NTSTATUS PtInternalDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++
Routine Description:
This routine is the dispatch routine for internal device control requests. This routine cannot be paged because the class drivers send down internal IOCTLs at DISPATCH_LEVEL.
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
Status is returned.
--*/ { PIO_STACK_LOCATION irpSp; PPORT_MOUSE_EXTENSION mouseExtension = DeviceObject->DeviceExtension; PPORT_KEYBOARD_EXTENSION kbExtension = DeviceObject->DeviceExtension; NTSTATUS status; ULONG sizeOfTranslation; PDEVICE_OBJECT topOfStack;
Print(DBG_IOCTL_TRACE, ("IOCTL: enter\n"));
Irp->IoStatus.Information = 0; irpSp = IoGetCurrentIrpStackLocation(Irp);
//
// Case on the device control subfunction that is being performed by the
// requestor.
//
switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
//
// Connect a keyboard class device driver to the port driver.
//
case IOCTL_INTERNAL_KEYBOARD_CONNECT: //
// This really isn't something to worry about overall, but it is worthy
// enough to be noted and recorded. The multiple starts will be handled in
// PtPnp and PtKeyboardStartDevice routines
//
if (KEYBOARD_PRESENT()) { Print(DBG_ALWAYS, ("Received 1+ kb connects!\n")); SET_HW_FLAGS(DUP_KEYBOARD_HARDWARE_PRESENT); }
InterlockedIncrement(&Globals.AddedKeyboards);
kbExtension->IsKeyboard = TRUE;
SET_HW_FLAGS(KEYBOARD_HARDWARE_PRESENT);
Print(DBG_IOCTL_INFO, ("IOCTL: keyboard connect\n"));
//
// Save away the keyboard device object - we'll need it later
//
KbdDeviceObject = DeviceObject;
//
// Only allow a connection if the keyboard hardware is present.
// Also, only allow one connection.
//
if (kbExtension->ConnectData.ClassService != NULL) {
Print(DBG_IOCTL_ERROR, ("IOCTL: error - already connected\n")); status = STATUS_SHARING_VIOLATION; break; } else if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) {
Print(DBG_IOCTL_ERROR, ("IOCTL: error - invalid buffer length\n")); status = STATUS_INVALID_PARAMETER; break; }
//
// Copy the connection parameters to the device extension.
//
kbExtension->ConnectData = *((PCONNECT_DATA) (irpSp->Parameters.DeviceIoControl.Type3InputBuffer));
status = STATUS_SUCCESS; break;
//
// Disconnect a keyboard class device driver from the port driver.
//
// NOTE: Not implemented.
//
case IOCTL_INTERNAL_KEYBOARD_DISCONNECT:
Print(DBG_IOCTL_INFO, ("IOCTL: keyboard disconnect\n"));
status = STATUS_NOT_IMPLEMENTED; break;
//
// Connect a mouse class device driver to the port driver.
//
case IOCTL_INTERNAL_MOUSE_CONNECT:
//
// This really isn't something to worry about overall, but it is worthy
// enough to be noted and recorded. The multiple starts will be handled in
// PtPnp and PtMouseStartDevice routines
//
if (MOUSE_PRESENT()) { Print(DBG_ALWAYS, ("Received 1+ mouse connects!\n")); SET_HW_FLAGS(DUP_MOUSE_HARDWARE_PRESENT); }
InterlockedIncrement(&Globals.AddedMice);
mouseExtension->IsKeyboard = FALSE;
SET_HW_FLAGS(MOUSE_HARDWARE_PRESENT);
Print(DBG_IOCTL_INFO, ("IOCTL: mouse connect\n"));
//
// Save away the mouse device object - we'll need it later
//
MouDeviceObject = DeviceObject;
//
// Only allow a connection if the mouse hardware is present.
// Also, only allow one connection.
//
if (mouseExtension->ConnectData.ClassService != NULL) {
Print(DBG_IOCTL_ERROR, ("IOCTL: error - already connected\n")); status = STATUS_SHARING_VIOLATION; break; } else if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) {
Print(DBG_IOCTL_ERROR, ("IOCTL: error - invalid buffer length\n")); status = STATUS_INVALID_PARAMETER; break; }
//
// Copy the connection parameters to the device extension.
//
mouseExtension->ConnectData = *((PCONNECT_DATA) (irpSp->Parameters.DeviceIoControl.Type3InputBuffer));
status = STATUS_SUCCESS; break;
//
// Disconnect a mouse class device driver from the port driver.
//
// NOTE: Not implemented.
//
case IOCTL_INTERNAL_MOUSE_DISCONNECT:
Print(DBG_IOCTL_INFO, ("IOCTL: mouse disconnect\n"));
status = STATUS_NOT_IMPLEMENTED; break;
//
// Query the keyboard attributes. First check for adequate buffer
// length. Then, copy the keyboard attributes from the device
// extension to the output buffer.
//
case IOCTL_KEYBOARD_QUERY_ATTRIBUTES:
Print(DBG_IOCTL_NOISE, ("IOCTL: keyboard query attributes\n"));
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_ATTRIBUTES)) { status = STATUS_BUFFER_TOO_SMALL; } else { //
// Copy the attributes from the DeviceExtension to the
// buffer.
//
PKEYBOARD_ATTRIBUTES pKBA = (PKEYBOARD_ATTRIBUTES)Irp->AssociatedIrp.SystemBuffer;
pKBA->KeyboardIdentifier.Type = 0x51; pKBA->KeyboardIdentifier.Subtype = 0;
pKBA->KeyboardMode = 1; pKBA->NumberOfFunctionKeys = KEYBOARD_NUM_FUNCTION_KEYS; pKBA->NumberOfIndicators = KEYBOARD_NUM_INDICATORS; pKBA->NumberOfKeysTotal = KEYBOARD_NUM_KEYS_TOTAL; pKBA->InputDataQueueLength = 100;
pKBA->KeyRepeatMinimum.UnitId = 0; pKBA->KeyRepeatMinimum.Rate = 2; pKBA->KeyRepeatMinimum.Delay = 250;
pKBA->KeyRepeatMaximum.UnitId = 0; pKBA->KeyRepeatMaximum.Rate = 30; pKBA->KeyRepeatMaximum.Delay = 1000;
Irp->IoStatus.Information = sizeof(KEYBOARD_ATTRIBUTES); status = STATUS_SUCCESS;
}
break;
//
// Query the scan code to indicator-light mapping. Validate the
// parameters, and copy the indicator mapping information from
// the port device extension to the SystemBuffer.
//
case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: {
PKEYBOARD_INDICATOR_TRANSLATION translation;
ASSERT(kbExtension->IsKeyboard);
Print(DBG_IOCTL_NOISE, ("IOCTL: keyboard query indicator translation\n"));
sizeOfTranslation = sizeof(KEYBOARD_INDICATOR_TRANSLATION) + (sizeof(INDICATOR_LIST) * (KEYBOARD_NUM_INDICATORS - 1));
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeOfTranslation) { status = STATUS_BUFFER_TOO_SMALL; } else { //
// Copy the indicator mapping information to the system
// buffer.
//
translation = (PKEYBOARD_INDICATOR_TRANSLATION) Irp->AssociatedIrp.SystemBuffer; translation->NumberOfIndicatorKeys = KEYBOARD_NUM_INDICATORS;
RtlMoveMemory( translation->IndicatorList, (PCHAR) IndicatorList, sizeof(INDICATOR_LIST) * translation->NumberOfIndicatorKeys );
Irp->IoStatus.Information = sizeOfTranslation; status = STATUS_SUCCESS; }
break; }
//
// Query the keyboard indicators. Validate the parameters, and
// copy the indicator information from the port device extension to
// the SystemBuffer.
//
case IOCTL_KEYBOARD_QUERY_INDICATORS:
ASSERT(kbExtension->IsKeyboard);
Print(DBG_IOCTL_NOISE, ("IOCTL: keyboard query indicators\n"));
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS)) { status = STATUS_BUFFER_TOO_SMALL; } else { //
// Just say they're all off
//
((PKEYBOARD_INDICATOR_PARAMETERS)Irp->AssociatedIrp.SystemBuffer)->LedFlags = 0; Irp->IoStatus.Information = sizeof(KEYBOARD_INDICATOR_PARAMETERS); status = STATUS_SUCCESS; }
break;
//
// Set the keyboard indicators
//
case IOCTL_KEYBOARD_SET_INDICATORS:
// Just return success
Print(DBG_IOCTL_NOISE, ("IOCTL: keyboard set indicators\n")); status = STATUS_SUCCESS;
break;
//
// Query the current keyboard typematic rate and delay. Validate
// the parameters, and copy the typematic information from the port
// device extension to the SystemBuffer.
//
case IOCTL_KEYBOARD_QUERY_TYPEMATIC:
Print(DBG_IOCTL_NOISE, ("IOCTL: keyboard query typematic\n"));
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) { status = STATUS_BUFFER_TOO_SMALL; } else { //
// just return our default info
//
PKEYBOARD_TYPEMATIC_PARAMETERS pKTP = (PKEYBOARD_TYPEMATIC_PARAMETERS) Irp->AssociatedIrp.SystemBuffer;
pKTP->Rate = KEYBOARD_TYPEMATIC_RATE_DEFAULT; pKTP->Delay = KEYBOARD_TYPEMATIC_DELAY_DEFAULT;
Irp->IoStatus.Information = sizeof(KEYBOARD_TYPEMATIC_PARAMETERS); status = STATUS_SUCCESS; }
break;
//
// Sets the keyboard typematic rate and delay
// We just say 'fine'
//
case IOCTL_KEYBOARD_SET_TYPEMATIC: { status = STATUS_SUCCESS; } break;
case IOCTL_KEYBOARD_SET_IME_STATUS:
Print(DBG_IOCTL_NOISE, ("IOCTL: keyboard set ime status\n")); status = STATUS_INVALID_DEVICE_REQUEST; break;
//
// Query the mouse attributes. First check for adequate buffer
// length. Then, copy the mouse attributes from the device
// extension to the output buffer.
//
case IOCTL_MOUSE_QUERY_ATTRIBUTES:
Print(DBG_IOCTL_NOISE, ("IOCTL: mouse query attributes\n"));
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUSE_ATTRIBUTES)) { status = STATUS_BUFFER_TOO_SMALL; } else { //
// Copy the attributes from the DeviceExtension to the
// buffer.
//
PMOUSE_ATTRIBUTES pMA = (PMOUSE_ATTRIBUTES) Irp->AssociatedIrp.SystemBuffer; pMA->MouseIdentifier = MOUSE_IDENTIFIER; pMA->NumberOfButtons = MOUSE_NUM_BUTTONS; pMA->SampleRate = MOUSE_SAMPLE_RATE; pMA->InputDataQueueLength = MOUSE_INPUT_QLEN;
Irp->IoStatus.Information = sizeof(MOUSE_ATTRIBUTES); status = STATUS_SUCCESS; }
break;
case IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER: case IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER: Print(DBG_IOCTL_NOISE, ("IOCTL: mouse send buffer\n")); status = STATUS_INVALID_DEVICE_REQUEST; break;
case IOCTL_INTERNAL_I8042_CONTROLLER_WRITE_BUFFER: status = STATUS_NOT_SUPPORTED; break;
default:
Print(DBG_IOCTL_ERROR, ("IOCTL: INVALID REQUEST\n"));
status = STATUS_INVALID_DEVICE_REQUEST; break; }
Irp->IoStatus.Status = status; if (status == STATUS_PENDING) { IoMarkIrpPending(Irp); IoStartPacket(DeviceObject, Irp, (PULONG) NULL, NULL ); } else { IoCompleteRequest(Irp, IO_NO_INCREMENT ); }
Print(DBG_IOCTL_TRACE, ("IOCTL: exit (0x%x)\n", status));
return status; }
VOID PtStartIo( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++
Routine Description:
This routine starts an I/O operation for the device which is further controlled by the controller object
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
None.
--*/ { KIRQL cancelIrql; PIO_STACK_LOCATION irpSp;
Print(DBG_IOCTL_TRACE, ("PtStartIo: enter\n"));
irpSp = IoGetCurrentIrpStackLocation(Irp); switch(irpSp->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_KEYBOARD_SET_INDICATORS: case IOCTL_KEYBOARD_SET_TYPEMATIC: case IOCTL_KEYBOARD_SET_IME_STATUS: case IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER: case IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER: case IOCTL_INTERNAL_MOUSE_RESET: default:
Print(DBG_IOCTL_ERROR, ("PtStartIo: INVALID REQUEST\n"));
IoAcquireCancelSpinLock(&cancelIrql); IoSetCancelRoutine(Irp, NULL); IoReleaseCancelSpinLock(cancelIrql);
Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoStartNextPacket(DeviceObject, FALSE); }
Print(DBG_IOCTL_TRACE, ("PtStartIo: exit\n")); }
NTSTATUS PtEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS status = STATUS_SUCCESS;
RtlZeroMemory(&Globals, sizeof(GLOBALS) );
Globals.ControllerData = (PCONTROLLER_DATA) ExAllocatePool( NonPagedPool, sizeof(CONTROLLER_DATA) );
if (!Globals.ControllerData) { status = STATUS_INSUFFICIENT_RESOURCES; goto DriverEntryError; }
RtlZeroMemory(Globals.ControllerData, sizeof(CONTROLLER_DATA) );
Globals.ControllerData->ControllerObject = IoCreateController(0);
if (!Globals.ControllerData->ControllerObject) { status = STATUS_INSUFFICIENT_RESOURCES; goto DriverEntryError; }
Globals.RegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL); Globals.RegistryPath.Length = RegistryPath->Length; Globals.RegistryPath.Buffer = ExAllocatePool( NonPagedPool, Globals.RegistryPath.MaximumLength );
if (!Globals.RegistryPath.Buffer) {
Print (DBG_SS_ERROR, ("Initialize: Couldn't allocate pool for registry path."));
status = STATUS_INSUFFICIENT_RESOURCES; goto DriverEntryError; }
RtlZeroMemory (Globals.RegistryPath.Buffer, Globals.RegistryPath.MaximumLength);
RtlMoveMemory (Globals.RegistryPath.Buffer, RegistryPath->Buffer, RegistryPath->Length);
#if PTDRV_VERBOSE
PtServiceParameters(RegistryPath); #endif
ExInitializeFastMutex(&Globals.DispatchMutex); KeInitializeSpinLock(&Globals.ControllerData->PowerUpSpinLock);
Print(DBG_SS_TRACE, ("PortDriverEntry (0x%x) \n", status));
return status;
DriverEntryError:
//
// Clean after something has gone wrong
// and set pointers to NULL for PtUnload
//
if (Globals.ControllerData) { if (Globals.ControllerData->ControllerObject) { IoDeleteController(Globals.ControllerData->ControllerObject); }
ExFreePool(Globals.ControllerData); Globals.ControllerData = NULL; }
if (Globals.RegistryPath.Buffer) { ExFreePool(Globals.RegistryPath.Buffer); Globals.RegistryPath.Buffer = NULL; Globals.RegistryPath.Length = 0; Globals.RegistryPath.MaximumLength = 0; }
Print(DBG_SS_ERROR, ("PortDriverEntry (0x%x) \n", status)); return status; }
VOID PtUnload( IN PDRIVER_OBJECT Driver ) /*++
Routine Description:
Free all the allocated resources associated with this driver.
Arguments:
DriverObject - Pointer to the driver object.
Return Value:
None.
--*/
{ ULONG i;
PAGED_CODE();
ASSERT(NULL == Driver->DeviceObject);
Print(DBG_SS_TRACE, ("Unload \n"));
//
// Free resources in Globals
//
// test for all pointers in case they were not allocated
if (Globals.ControllerData) { if (Globals.ControllerData->ControllerObject) { IoDeleteController(Globals.ControllerData->ControllerObject); } ExFreePool(Globals.ControllerData); Globals.ControllerData = NULL; }
if (Globals.RegistryPath.Buffer) { ExFreePool(Globals.RegistryPath.Buffer); Globals.RegistryPath.Buffer = NULL; Globals.RegistryPath.Length = 0; Globals.RegistryPath.MaximumLength = 0; }
return; }
#if PTDRV_VERBOSE
VOID PtServiceParameters( IN PUNICODE_STRING RegistryPath )
/*++
Routine Description:
This routine retrieves this driver's service parameters information from the registry.
Arguments:
RegistryPath - Pointer to the null-terminated Unicode name of the registry path for this driver.
Return Value:
None. As a side-effect, sets fields in DeviceExtension->Configuration.
--*/
{ NTSTATUS status = STATUS_SUCCESS; PI8042_CONFIGURATION_INFORMATION configuration; PRTL_QUERY_REGISTRY_TABLE parameters = NULL; PWSTR path = NULL; ULONG defaultDebugFlags = DEFAULT_DEBUG_FLAGS; ULONG i = 0; UNICODE_STRING parametersPath; USHORT queries = 2;
if (Globals.ControllerData == NULL) return;
configuration = &(Globals.ControllerData->Configuration); parametersPath.Buffer = NULL;
Globals.DebugFlags = DEFAULT_DEBUG_FLAGS; //
// Registry path is already null-terminated, so just use it.
//
path = RegistryPath->Buffer;
if (NT_SUCCESS(status)) {
//
// Allocate the Rtl query table.
//
parameters = ExAllocatePool( PagedPool, sizeof(RTL_QUERY_REGISTRY_TABLE) * (queries + 1) );
if (!parameters) {
Print(DBG_SS_ERROR, ("%s: couldn't allocate table for Rtl query to %ws for %ws\n", pFncServiceParameters, pwParameters, path )); status = STATUS_UNSUCCESSFUL;
} else {
RtlZeroMemory( parameters, sizeof(RTL_QUERY_REGISTRY_TABLE) * (queries + 1) );
//
// Form a path to this driver's Parameters subkey.
//
RtlInitUnicodeString( ¶metersPath, NULL ); parametersPath.MaximumLength = RegistryPath->Length + (wcslen(pwParameters) * sizeof(WCHAR) ) + sizeof(UNICODE_NULL);
parametersPath.Buffer = ExAllocatePool( PagedPool, parametersPath.MaximumLength );
if (!parametersPath.Buffer) {
Print(DBG_SS_ERROR, ("%s: Couldn't allocate string for path to %ws for %ws\n", pFncServiceParameters, pwParameters, path )); status = STATUS_UNSUCCESSFUL;
} } }
if (NT_SUCCESS(status)) {
//
// Form the parameters path.
//
RtlZeroMemory( parametersPath.Buffer, parametersPath.MaximumLength ); RtlAppendUnicodeToString( ¶metersPath, path ); RtlAppendUnicodeToString( ¶metersPath, pwParameters );
Print(DBG_SS_INFO, ("%s: %ws path is %ws\n", pFncServiceParameters, pwParameters, parametersPath.Buffer ));
parameters[i].Flags = RTL_QUERY_REGISTRY_DIRECT; parameters[i].Name = pwDebugFlags; parameters[i].EntryContext = &Globals.DebugFlags; parameters[i].DefaultType = REG_DWORD; parameters[i].DefaultData = &defaultDebugFlags; parameters[i].DefaultLength = sizeof(ULONG);
status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, parametersPath.Buffer, parameters, NULL, NULL );
if (!NT_SUCCESS(status)) {
Print(DBG_SS_INFO, ("%s: RtlQueryRegistryValues failed with 0x%x\n", pFncServiceParameters, status )); } }
Print(DBG_SS_NOISE, ("PtServiceParameters results..\n"));
Print(DBG_SS_NOISE, ("\tDebug flags are 0x%x\n", Globals.DebugFlags ));
//
// Free the allocated memory before returning.
//
if (parametersPath.Buffer) ExFreePool(parametersPath.Buffer); if (parameters) ExFreePool(parameters);
} #endif // PTDRV_VERBOSE
|