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.
755 lines
22 KiB
755 lines
22 KiB
/*++
|
|
|
|
Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved
|
|
Copyright (c) 1993 Logitech Inc.
|
|
|
|
Module Name:
|
|
|
|
sermdep.c
|
|
|
|
Abstract:
|
|
|
|
The initialization and hardware-dependent portions of
|
|
the Microsoft serial (i8250) mouse port driver. Modifications
|
|
to support new mice similar to the serial mouse should be
|
|
localized to this file.
|
|
|
|
Environment:
|
|
|
|
Kernel mode only.
|
|
|
|
Notes:
|
|
|
|
NOTES: (Future/outstanding issues)
|
|
|
|
- Powerfail not implemented.
|
|
|
|
- Consolidate duplicate code, where possible and appropriate.
|
|
|
|
- The serial ballpoint is supported. However, Windows USER does not
|
|
intend (right now) to use the ballpoint in anything except mouse
|
|
emulation mode. In ballpoint mode, there is extra functionality that
|
|
would need to be supported. E.g., the driver would need to pass
|
|
back extra button information from the 4th byte of the ballpoint
|
|
data packet. Windows USER would need/want to allow the user to select
|
|
which buttons are used, what the orientation of the ball is (esp.
|
|
important for lefthanders), sensitivity, and acceleration profile.
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#include "stdarg.h"
|
|
#include "stdio.h"
|
|
#include "string.h"
|
|
#include "ntddk.h"
|
|
#include "mouser.h"
|
|
#include "sermlog.h"
|
|
#include "cseries.h"
|
|
#include "mseries.h"
|
|
#include "debug.h"
|
|
|
|
//
|
|
// Use the alloc_text pragma to specify the driver initialization routines
|
|
// (they can be paged out).
|
|
//
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(INIT, DriverEntry)
|
|
#pragma alloc_text(PAGE, SerialMouseServiceParameters)
|
|
#pragma alloc_text(PAGE, SerialMouseClosePort)
|
|
#pragma alloc_text(PAGE, SerialMouseInitializeHardware)
|
|
#pragma alloc_text(PAGE, SerialMouseInitializeDevice)
|
|
#pragma alloc_text(PAGE, SerialMouseSpinUpRead)
|
|
#pragma alloc_text(PAGE, SerialMouseStartDevice)
|
|
#pragma alloc_text(PAGE, SerialMouseUnload)
|
|
|
|
#if DBG
|
|
#pragma alloc_text(INIT,SerialMouseGetDebugFlags)
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#if DBG
|
|
ULONG GlobalDebugFlags;
|
|
#endif
|
|
|
|
NTSTATUS
|
|
DriverEntry(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING RegistryPath
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine initializes the serial (i8250) mouse port driver.
|
|
|
|
Arguments:
|
|
|
|
DriverObject - Pointer to driver object created by system.
|
|
|
|
RegistryPath - Pointer to the Unicode name of the registry path
|
|
for this driver.
|
|
|
|
Return Value:
|
|
|
|
The function value is the final status from the initialization operation.
|
|
|
|
--*/
|
|
|
|
{
|
|
PUNICODE_STRING regPath;
|
|
NTSTATUS status;
|
|
|
|
status = IoAllocateDriverObjectExtension(DriverObject,
|
|
(PVOID) 1,
|
|
sizeof(UNICODE_STRING),
|
|
(PVOID *) ®Path);
|
|
|
|
ASSERT(NT_SUCCESS(status));
|
|
|
|
if (regPath) {
|
|
regPath->MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL);
|
|
regPath->Length = RegistryPath->Length;
|
|
regPath->Buffer = ExAllocatePool(NonPagedPool,
|
|
regPath->MaximumLength);
|
|
|
|
if (regPath->Buffer) {
|
|
RtlZeroMemory(regPath->Buffer,
|
|
regPath->MaximumLength);
|
|
|
|
RtlMoveMemory(regPath->Buffer,
|
|
RegistryPath->Buffer,
|
|
RegistryPath->Length);
|
|
}
|
|
else {
|
|
regPath->MaximumLength = regPath->Length = 0;
|
|
}
|
|
}
|
|
|
|
#if DBG
|
|
SerialMouseGetDebugFlags(regPath);
|
|
#endif
|
|
|
|
//
|
|
// Set up the device driver entry points and leave
|
|
//
|
|
|
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = SerialMouseCreate;
|
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = SerialMouseClose;
|
|
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] =
|
|
SerialMouseFlush;
|
|
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
|
|
SerialMouseInternalDeviceControl;
|
|
|
|
DriverObject->MajorFunction[IRP_MJ_PNP] = SerialMousePnP;
|
|
DriverObject->MajorFunction[IRP_MJ_POWER] = SerialMousePower;
|
|
|
|
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
|
|
SerialMouseSystemControl;
|
|
|
|
DriverObject->DriverUnload = SerialMouseUnload;
|
|
DriverObject->DriverExtension->AddDevice = SerialMouseAddDevice;
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
VOID
|
|
SerialMouseClosePort(
|
|
PDEVICE_EXTENSION DeviceExtension,
|
|
PIRP Irp
|
|
)
|
|
{
|
|
PIO_STACK_LOCATION next;
|
|
|
|
SerialMouseRestorePort(DeviceExtension);
|
|
|
|
next = IoGetNextIrpStackLocation (Irp);
|
|
RtlZeroMemory(next, sizeof(IO_STACK_LOCATION));
|
|
next->MajorFunction = IRP_MJ_CLEANUP;
|
|
|
|
SerialMouseSendIrpSynchronously(DeviceExtension->TopOfStack,
|
|
Irp,
|
|
FALSE);
|
|
|
|
next = IoGetNextIrpStackLocation (Irp);
|
|
RtlZeroMemory(next, sizeof(IO_STACK_LOCATION));
|
|
next->MajorFunction = IRP_MJ_CLOSE;
|
|
|
|
SerialMouseSendIrpSynchronously(DeviceExtension->TopOfStack,
|
|
Irp,
|
|
FALSE);
|
|
|
|
}
|
|
NTSTATUS
|
|
SerialMouseSpinUpRead(
|
|
PDEVICE_EXTENSION DeviceExtension
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
|
|
PAGED_CODE();
|
|
|
|
IoAcquireRemoveLock(&DeviceExtension->RemoveLock,
|
|
DeviceExtension->ReadIrp);
|
|
|
|
ASSERT(DeviceExtension->Started);
|
|
|
|
//
|
|
// SerialMouseStartRead needs started to be set to true
|
|
//
|
|
DeviceExtension->ReadInterlock = SERIAL_MOUSE_END_READ;
|
|
|
|
status = SerialMouseStartRead(DeviceExtension);
|
|
|
|
if (status == STATUS_PENDING || status == STATUS_SUCCESS) {
|
|
Print(DeviceExtension, DBG_PNP_INFO,
|
|
("Start read succeeded, 0x%x\n", status));
|
|
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
else {
|
|
Print(DeviceExtension, DBG_PNP_ERROR,
|
|
("Start read failed, 0x%x\n", status));
|
|
|
|
ASSERT(!NT_SUCCESS(status));
|
|
|
|
//
|
|
// No need to release the remove lock here. If SerialMouseStartRead
|
|
// fails, then it will release the lock on its own.
|
|
//
|
|
// IoReleaseRemoveLock(&DeviceExtension->RemoveLock,
|
|
// DeviceExtension->ReadIrp);
|
|
|
|
DeviceExtension->Started = FALSE;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS
|
|
SerialMouseStartDevice(
|
|
PDEVICE_EXTENSION DeviceExtension,
|
|
PIRP Irp,
|
|
BOOLEAN CloseOnFailure
|
|
)
|
|
{
|
|
PIO_STACK_LOCATION next;
|
|
NTSTATUS status;
|
|
|
|
PAGED_CODE();
|
|
|
|
status = SerialMouseInitializeDevice(DeviceExtension);
|
|
|
|
Print(DeviceExtension, DBG_PNP_INFO, ("InitializeDevice 0x%x\n", status));
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
status = SerialMouseSpinUpRead(DeviceExtension);
|
|
}
|
|
|
|
if (!NT_SUCCESS(status) && CloseOnFailure) {
|
|
|
|
Print(DeviceExtension, DBG_PNP_ERROR,
|
|
("sending close due to failure, 0x%x\n", status));
|
|
|
|
//
|
|
// The start failed and we sent the create as part of the start
|
|
// Send the matching cleanup/close so the port is accessible again.
|
|
//
|
|
SerialMouseClosePort(DeviceExtension, Irp);
|
|
|
|
InterlockedDecrement(&DeviceExtension->EnableCount);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS
|
|
SerialMouseInitializeDevice (
|
|
IN PDEVICE_EXTENSION DeviceExtension
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine initializes the device for the given device
|
|
extension.
|
|
|
|
Arguments:
|
|
|
|
DriverObject - Supplies the driver object.
|
|
|
|
TmpDeviceExtension - Supplies a temporary device extension for the
|
|
device to initialize.
|
|
|
|
RegistryPath - Supplies the registry path.
|
|
|
|
BaseDeviceName - Supplies the base device name to the device
|
|
to create.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
#define DUMP_COUNT 4
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
PIO_ERROR_LOG_PACKET errorLogEntry;
|
|
ULONG uniqueErrorValue,
|
|
dumpCount = 0,
|
|
i,
|
|
dumpData[DUMP_COUNT];
|
|
UNICODE_STRING keyName;
|
|
KEVENT event;
|
|
IO_STATUS_BLOCK iosb;
|
|
ULONG waitMask;
|
|
|
|
for (i = 0; i < DUMP_COUNT; i++) {
|
|
dumpData[i] = 0;
|
|
}
|
|
|
|
Print(DeviceExtension, DBG_SS_TRACE, ("StartDevice, enter\n"));
|
|
|
|
PAGED_CODE();
|
|
|
|
DeviceExtension->Started = TRUE;
|
|
|
|
//
|
|
// Set the wait mask to zero so that when we send the
|
|
// wait request it won't get completed due to init flipping lines
|
|
//
|
|
// (the wait mask could have been set by a previous app or by this driver
|
|
// and we are coming out of a > D0 state)
|
|
//
|
|
waitMask = 0x0;
|
|
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
|
|
|
SerialMouseIoSyncIoctlEx(IOCTL_SERIAL_SET_WAIT_MASK,
|
|
DeviceExtension->TopOfStack,
|
|
&event,
|
|
&iosb,
|
|
&waitMask,
|
|
sizeof(ULONG),
|
|
NULL,
|
|
0);
|
|
|
|
//
|
|
// Initialize the h/w and figure out what type of mouse is on the port
|
|
//
|
|
status = SerialMouseInitializeHardware(DeviceExtension);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
Print(DeviceExtension, DBG_SS_ERROR,
|
|
("Could not initialize hardware\n"));
|
|
goto SerialMouseInitializeExit;
|
|
}
|
|
|
|
if (!DeviceExtension->MouseAttributes.MouseIdentifier) {
|
|
DeviceExtension->MouseAttributes.MouseIdentifier =
|
|
MOUSE_SERIAL_HARDWARE;
|
|
}
|
|
|
|
DeviceExtension->DetectionSupported = TRUE;
|
|
SerialMouseStartDetection(DeviceExtension);
|
|
|
|
SerialMouseInitializeExit:
|
|
|
|
//
|
|
// Log an error, if necessary.
|
|
//
|
|
|
|
if (status != STATUS_SUCCESS) {
|
|
DeviceExtension->Started = FALSE;
|
|
|
|
errorLogEntry = (PIO_ERROR_LOG_PACKET)
|
|
IoAllocateErrorLogEntry(
|
|
DeviceExtension->Self,
|
|
(UCHAR) (sizeof(IO_ERROR_LOG_PACKET)
|
|
+ (dumpCount * sizeof(ULONG)))
|
|
);
|
|
|
|
if (errorLogEntry != NULL) {
|
|
|
|
errorLogEntry->ErrorCode = status;
|
|
errorLogEntry->DumpDataSize = (USHORT) dumpCount * sizeof(ULONG);
|
|
errorLogEntry->SequenceNumber = 0;
|
|
errorLogEntry->MajorFunctionCode = 0;
|
|
errorLogEntry->IoControlCode = 0;
|
|
errorLogEntry->RetryCount = 0;
|
|
// errorLogEntry->UniqueErrorValue = uniqueErrorValue;
|
|
errorLogEntry->FinalStatus = status;
|
|
for (i = 0; i < dumpCount; i++)
|
|
errorLogEntry->DumpData[i] = dumpData[i];
|
|
|
|
IoWriteErrorLogEntry(errorLogEntry);
|
|
}
|
|
}
|
|
|
|
Print(DeviceExtension, DBG_SS_TRACE, ("IntializeDevice 0x%x\n", status));
|
|
|
|
return status;
|
|
}
|
|
|
|
VOID
|
|
SerialMouseUnload(
|
|
IN PDRIVER_OBJECT DriverObject
|
|
)
|
|
{
|
|
PUNICODE_STRING regPath;
|
|
|
|
PAGED_CODE();
|
|
|
|
ASSERT(NULL == DriverObject->DeviceObject);
|
|
|
|
regPath = SerialMouseGetRegistryPath(DriverObject);
|
|
if (regPath && regPath->Buffer) {
|
|
ExFreePool(regPath->Buffer);
|
|
}
|
|
}
|
|
|
|
NTSTATUS
|
|
SerialMouseInitializeHardware(
|
|
IN PDEVICE_EXTENSION DeviceExtension
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine initializes the serial mouse/ballpoint. Note that this
|
|
routine is only called at initialization time, so synchronization is
|
|
not required.
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - Pointer to the device object.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS if a pointing device is detected, otherwise STATUS_UNSUCCESSFUL
|
|
|
|
--*/
|
|
|
|
{
|
|
MOUSETYPE mouseType;
|
|
ULONG hardwareButtons;
|
|
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
|
|
|
Print(DeviceExtension, DBG_SS_TRACE, ("SerialMouseInitializeHardware: enter\n"));
|
|
|
|
//
|
|
// Zero out the handler data in case we have previous state from a
|
|
// previous start
|
|
//
|
|
RtlZeroMemory(&DeviceExtension->HandlerData, sizeof(HANDLER_DATA));
|
|
|
|
if ((mouseType = MSerDetect(DeviceExtension)) != NO_MOUSE) {
|
|
status = STATUS_SUCCESS;
|
|
switch (mouseType) {
|
|
case MOUSE_2B:
|
|
DeviceExtension->ProtocolHandler =
|
|
MSerSetProtocol(DeviceExtension, MSER_PROTOCOL_MP);
|
|
DeviceExtension->MouseAttributes.MouseIdentifier =
|
|
MOUSE_SERIAL_HARDWARE;
|
|
hardwareButtons = 2;
|
|
break;
|
|
case MOUSE_3B:
|
|
DeviceExtension->ProtocolHandler =
|
|
MSerSetProtocol(DeviceExtension, MSER_PROTOCOL_MP);
|
|
DeviceExtension->MouseAttributes.MouseIdentifier =
|
|
MOUSE_SERIAL_HARDWARE;
|
|
hardwareButtons = 3;
|
|
break;
|
|
case BALLPOINT:
|
|
DeviceExtension->ProtocolHandler =
|
|
MSerSetProtocol(DeviceExtension, MSER_PROTOCOL_BP);
|
|
DeviceExtension->MouseAttributes.MouseIdentifier =
|
|
BALLPOINT_SERIAL_HARDWARE;
|
|
hardwareButtons = 2;
|
|
break;
|
|
case MOUSE_Z:
|
|
DeviceExtension->ProtocolHandler =
|
|
MSerSetProtocol(DeviceExtension, MSER_PROTOCOL_Z);
|
|
hardwareButtons = 3;
|
|
DeviceExtension->MouseAttributes.MouseIdentifier =
|
|
WHEELMOUSE_SERIAL_HARDWARE;
|
|
break;
|
|
}
|
|
}
|
|
else if (CSerDetect(DeviceExtension, &hardwareButtons)) {
|
|
status = STATUS_SUCCESS;
|
|
DeviceExtension->ProtocolHandler =
|
|
CSerSetProtocol(DeviceExtension, CSER_PROTOCOL_MM);
|
|
#if DBG
|
|
DeviceExtension->DebugFlags |= (DBG_HANDLER_INFO | DBG_HANDLER_ERROR);
|
|
#endif
|
|
}
|
|
else {
|
|
DeviceExtension->ProtocolHandler = NULL;
|
|
hardwareButtons = MOUSE_NUMBER_OF_BUTTONS;
|
|
}
|
|
|
|
|
|
//
|
|
// If the hardware wasn't overridden, set the number of buttons
|
|
// according to the protocol.
|
|
//
|
|
|
|
DeviceExtension->MouseAttributes.NumberOfButtons =
|
|
(USHORT) hardwareButtons;
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
//
|
|
// Make sure the FIFO is turned off.
|
|
//
|
|
|
|
SerialMouseSetFifo(DeviceExtension, 0);
|
|
|
|
//
|
|
// Clean up anything left in the receive buffer.
|
|
//
|
|
SerialMouseFlushReadBuffer(DeviceExtension);
|
|
|
|
}
|
|
|
|
Print(DeviceExtension, DBG_SS_TRACE,
|
|
("SerialMouseInitializeHardware exit (0x%x)\n", status));
|
|
|
|
return status;
|
|
}
|
|
|
|
#if DBG
|
|
VOID
|
|
SerialMouseGetDebugFlags(
|
|
IN PUNICODE_STRING RegPath
|
|
)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
VOID
|
|
SerialMouseServiceParameters(
|
|
IN PDEVICE_EXTENSION DeviceExtension,
|
|
IN HANDLE Handle
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine retrieves this driver's service parameters information
|
|
from the registry.
|
|
|
|
Arguments:
|
|
|
|
DeviceExtension - Pointer to the device extension.
|
|
|
|
RegistryPath - Pointer to the null-terminated Unicode name of the
|
|
registry path for this driver.
|
|
|
|
DeviceName - Pointer to the Unicode string that will receive
|
|
the port device name.
|
|
|
|
Return Value:
|
|
|
|
None. As a side-effect, sets fields in DeviceExtension->Configuration.
|
|
|
|
--*/
|
|
|
|
{
|
|
PRTL_QUERY_REGISTRY_TABLE parameters = NULL;
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
LONG defaultWaitEventMask = 0x0,
|
|
numberOfButtons = MOUSE_NUMBER_OF_BUTTONS,
|
|
defaultNumberOfButtons = MOUSE_NUMBER_OF_BUTTONS,
|
|
sampleRate = MOUSE_SAMPLE_RATE,
|
|
defaultSampleRate = MOUSE_SAMPLE_RATE,
|
|
i;
|
|
USHORT queriesPlusOne = 4;
|
|
|
|
WCHAR strParameters[] = L"Parameters";
|
|
PUNICODE_STRING regPath;
|
|
UNICODE_STRING parametersPath;
|
|
|
|
#if DBG
|
|
ULONG defaultDebugFlags = DEFAULT_DEBUG_FLAGS;
|
|
|
|
queriesPlusOne++;
|
|
#endif
|
|
|
|
RtlInitUnicodeString(¶metersPath, NULL);
|
|
|
|
//
|
|
// Allocate the Rtl query table.
|
|
//
|
|
parameters = ExAllocatePool(
|
|
PagedPool,
|
|
sizeof(RTL_QUERY_REGISTRY_TABLE) * queriesPlusOne
|
|
);
|
|
|
|
if (!parameters) {
|
|
status = STATUS_UNSUCCESSFUL;
|
|
goto SetParameters;
|
|
}
|
|
else {
|
|
RtlZeroMemory(
|
|
parameters,
|
|
sizeof(RTL_QUERY_REGISTRY_TABLE) * queriesPlusOne
|
|
);
|
|
|
|
regPath = SerialMouseGetRegistryPath(DeviceExtension->Self->DriverObject);
|
|
if (!regPath || !regPath->Buffer) {
|
|
goto GetServiceParametersByHandle;
|
|
}
|
|
parametersPath.MaximumLength = regPath->Length +
|
|
(wcslen(strParameters) * sizeof(WCHAR) ) + sizeof(UNICODE_NULL);
|
|
|
|
parametersPath.Buffer = ExAllocatePool(PagedPool,
|
|
parametersPath.MaximumLength);
|
|
|
|
if (!parametersPath.Buffer) {
|
|
status = STATUS_UNSUCCESSFUL;
|
|
goto GetServiceParametersByHandle;
|
|
}
|
|
|
|
}
|
|
|
|
RtlZeroMemory(parametersPath.Buffer,
|
|
parametersPath.MaximumLength);
|
|
RtlAppendUnicodeToString(¶metersPath,
|
|
regPath->Buffer);
|
|
RtlAppendUnicodeToString(¶metersPath,
|
|
strParameters);
|
|
|
|
//
|
|
// Gather all of the "user specified" information from
|
|
// the registry.
|
|
//
|
|
|
|
i = 0;
|
|
parameters[i].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
parameters[i].Name = L"NumberOfButtons";
|
|
parameters[i].EntryContext = &numberOfButtons;
|
|
parameters[i].DefaultType = REG_DWORD;
|
|
parameters[i].DefaultData = &defaultNumberOfButtons;
|
|
parameters[i].DefaultLength = sizeof(LONG);
|
|
|
|
parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
parameters[i].Name = L"SampleRate";
|
|
parameters[i].EntryContext = &sampleRate;
|
|
parameters[i].DefaultType = REG_DWORD;
|
|
parameters[i].DefaultData = &defaultSampleRate;
|
|
parameters[i].DefaultLength = sizeof(LONG);
|
|
|
|
#if DBG
|
|
parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
parameters[i].Name = L"DebugFlags";
|
|
parameters[i].EntryContext = &DeviceExtension->DebugFlags;
|
|
parameters[i].DefaultType = REG_DWORD;
|
|
parameters[i].DefaultData = &defaultDebugFlags;
|
|
parameters[i].DefaultLength = sizeof(ULONG);
|
|
#endif
|
|
|
|
status = RtlQueryRegistryValues(
|
|
RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
|
|
parametersPath.Buffer,
|
|
parameters,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
Print(DeviceExtension, DBG_SS_ERROR,
|
|
("RtlQueryRegistryValues failed with 0x%x\n", status));
|
|
|
|
DeviceExtension->DebugFlags = DEFAULT_DEBUG_FLAGS;
|
|
}
|
|
|
|
GetServiceParametersByHandle:
|
|
if (Handle) {
|
|
LONG prevNumberOfButtons = numberOfButtons,
|
|
prevSampleRate = sampleRate;
|
|
|
|
i = 0;
|
|
parameters[i].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
parameters[i].Name = L"NumberOfButtons";
|
|
parameters[i].EntryContext = &numberOfButtons;
|
|
parameters[i].DefaultType = REG_DWORD;
|
|
parameters[i].DefaultData = &prevNumberOfButtons;
|
|
parameters[i].DefaultLength = sizeof(LONG);
|
|
|
|
parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
parameters[i].Name = L"SampleRate";
|
|
parameters[i].EntryContext = &sampleRate;
|
|
parameters[i].DefaultType = REG_DWORD;
|
|
parameters[i].DefaultData = &prevSampleRate;
|
|
parameters[i].DefaultLength = sizeof(LONG);
|
|
|
|
parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
parameters[i].Name = L"WaitEventMask";
|
|
parameters[i].EntryContext = &DeviceExtension->WaitEventMask;
|
|
parameters[i].DefaultType = REG_DWORD;
|
|
parameters[i].DefaultData = &defaultWaitEventMask;
|
|
parameters[i].DefaultLength = sizeof(LONG);
|
|
|
|
#if DBG
|
|
parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
parameters[i].Name = L"DebugFlags";
|
|
parameters[i].EntryContext = &DeviceExtension->DebugFlags;
|
|
parameters[i].DefaultType = REG_DWORD;
|
|
parameters[i].DefaultData = &defaultDebugFlags;
|
|
parameters[i].DefaultLength = sizeof(ULONG);
|
|
#endif
|
|
|
|
status = RtlQueryRegistryValues(
|
|
RTL_REGISTRY_HANDLE,
|
|
(PWSTR) Handle,
|
|
parameters,
|
|
NULL,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
SetParameters:
|
|
if (!NT_SUCCESS(status)) {
|
|
DeviceExtension->WaitEventMask = defaultWaitEventMask;
|
|
#if DBG
|
|
DeviceExtension->DebugFlags = defaultDebugFlags;
|
|
#endif
|
|
}
|
|
|
|
#if DBG
|
|
if (defaultDebugFlags == DeviceExtension->DebugFlags &&
|
|
GlobalDebugFlags != 0x0) {
|
|
DeviceExtension->DebugFlags = GlobalDebugFlags;
|
|
}
|
|
#endif
|
|
|
|
DeviceExtension->MouseAttributes.NumberOfButtons = (USHORT) numberOfButtons;
|
|
DeviceExtension->MouseAttributes.SampleRate = (USHORT) sampleRate;
|
|
|
|
Print(DeviceExtension, DBG_SS_NOISE, ("NumberOfButtons = %d\n",
|
|
DeviceExtension->MouseAttributes.NumberOfButtons));
|
|
|
|
Print(DeviceExtension, DBG_SS_NOISE, ("SampleRate = %d\n",
|
|
DeviceExtension->MouseAttributes.SampleRate));
|
|
|
|
Print(DeviceExtension, DBG_SS_NOISE, ("WaitEventMask = 0x%x\n",
|
|
DeviceExtension->WaitEventMask));
|
|
|
|
Print(DeviceExtension, DBG_SS_NOISE, ("DebugFlags 0x%x\n",
|
|
DeviceExtension->DebugFlags));
|
|
|
|
if (parametersPath.Buffer)
|
|
ExFreePool(parametersPath.Buffer);
|
|
if (parameters)
|
|
ExFreePool(parameters);
|
|
}
|