Source code of Windows XP (NT5)
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
21 KiB

  1. /*++
  2. Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved
  3. Copyright (c) 1993 Logitech Inc.
  4. Module Name:
  5. sermdep.c
  6. Abstract:
  7. The initialization and hardware-dependent portions of
  8. the Microsoft serial (i8250) mouse port driver. Modifications
  9. to support new mice similar to the serial mouse should be
  10. localized to this file.
  11. Environment:
  12. Kernel mode only.
  13. Notes:
  14. NOTES: (Future/outstanding issues)
  15. - Powerfail not implemented.
  16. - Consolidate duplicate code, where possible and appropriate.
  17. - The serial ballpoint is supported. However, Windows USER does not
  18. intend (right now) to use the ballpoint in anything except mouse
  19. emulation mode. In ballpoint mode, there is extra functionality that
  20. would need to be supported. E.g., the driver would need to pass
  21. back extra button information from the 4th byte of the ballpoint
  22. data packet. Windows USER would need/want to allow the user to select
  23. which buttons are used, what the orientation of the ball is (esp.
  24. important for lefthanders), sensitivity, and acceleration profile.
  25. Revision History:
  26. --*/
  27. #include "stdarg.h"
  28. #include "stdio.h"
  29. #include "string.h"
  30. #include "ntddk.h"
  31. #include "mouser.h"
  32. #include "sermlog.h"
  33. #include "cseries.h"
  34. #include "mseries.h"
  35. #include "debug.h"
  36. //
  37. // Use the alloc_text pragma to specify the driver initialization routines
  38. // (they can be paged out).
  39. //
  40. #ifdef ALLOC_PRAGMA
  41. #pragma alloc_text(INIT, DriverEntry)
  42. #pragma alloc_text(PAGE, SerialMouseServiceParameters)
  43. #pragma alloc_text(PAGE, SerialMouseClosePort)
  44. #pragma alloc_text(PAGE, SerialMouseInitializeHardware)
  45. #pragma alloc_text(PAGE, SerialMouseInitializeDevice)
  46. #pragma alloc_text(PAGE, SerialMouseSpinUpRead)
  47. #pragma alloc_text(PAGE, SerialMouseStartDevice)
  48. #pragma alloc_text(PAGE, SerialMouseUnload)
  49. #if DBG
  50. #pragma alloc_text(INIT,SerialMouseGetDebugFlags)
  51. #endif
  52. #endif
  53. #if DBG
  54. ULONG GlobalDebugFlags;
  55. #endif
  56. NTSTATUS
  57. DriverEntry(
  58. IN PDRIVER_OBJECT DriverObject,
  59. IN PUNICODE_STRING RegistryPath
  60. )
  61. /*++
  62. Routine Description:
  63. This routine initializes the serial (i8250) mouse port driver.
  64. Arguments:
  65. DriverObject - Pointer to driver object created by system.
  66. RegistryPath - Pointer to the Unicode name of the registry path
  67. for this driver.
  68. Return Value:
  69. The function value is the final status from the initialization operation.
  70. --*/
  71. {
  72. PUNICODE_STRING regPath;
  73. NTSTATUS status;
  74. status = IoAllocateDriverObjectExtension(DriverObject,
  75. (PVOID) 1,
  76. sizeof(UNICODE_STRING),
  77. (PVOID *) &regPath);
  78. ASSERT(NT_SUCCESS(status));
  79. if (regPath) {
  80. regPath->MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL);
  81. regPath->Length = RegistryPath->Length;
  82. regPath->Buffer = ExAllocatePool(NonPagedPool,
  83. regPath->MaximumLength);
  84. if (regPath->Buffer) {
  85. RtlZeroMemory(regPath->Buffer,
  86. regPath->MaximumLength);
  87. RtlMoveMemory(regPath->Buffer,
  88. RegistryPath->Buffer,
  89. RegistryPath->Length);
  90. }
  91. else {
  92. regPath->MaximumLength = regPath->Length = 0;
  93. }
  94. }
  95. #if DBG
  96. SerialMouseGetDebugFlags(regPath);
  97. #endif
  98. //
  99. // Set up the device driver entry points and leave
  100. //
  101. DriverObject->MajorFunction[IRP_MJ_CREATE] = SerialMouseCreate;
  102. DriverObject->MajorFunction[IRP_MJ_CLOSE] = SerialMouseClose;
  103. DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] =
  104. SerialMouseFlush;
  105. DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
  106. SerialMouseInternalDeviceControl;
  107. DriverObject->MajorFunction[IRP_MJ_PNP] = SerialMousePnP;
  108. DriverObject->MajorFunction[IRP_MJ_POWER] = SerialMousePower;
  109. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
  110. SerialMouseSystemControl;
  111. DriverObject->DriverUnload = SerialMouseUnload;
  112. DriverObject->DriverExtension->AddDevice = SerialMouseAddDevice;
  113. return STATUS_SUCCESS;
  114. }
  115. VOID
  116. SerialMouseClosePort(
  117. PDEVICE_EXTENSION DeviceExtension,
  118. PIRP Irp
  119. )
  120. {
  121. PIO_STACK_LOCATION next;
  122. SerialMouseRestorePort(DeviceExtension);
  123. next = IoGetNextIrpStackLocation (Irp);
  124. RtlZeroMemory(next, sizeof(IO_STACK_LOCATION));
  125. next->MajorFunction = IRP_MJ_CLEANUP;
  126. SerialMouseSendIrpSynchronously(DeviceExtension->TopOfStack,
  127. Irp,
  128. FALSE);
  129. next = IoGetNextIrpStackLocation (Irp);
  130. RtlZeroMemory(next, sizeof(IO_STACK_LOCATION));
  131. next->MajorFunction = IRP_MJ_CLOSE;
  132. SerialMouseSendIrpSynchronously(DeviceExtension->TopOfStack,
  133. Irp,
  134. FALSE);
  135. }
  136. NTSTATUS
  137. SerialMouseSpinUpRead(
  138. PDEVICE_EXTENSION DeviceExtension
  139. )
  140. {
  141. NTSTATUS status;
  142. PAGED_CODE();
  143. IoAcquireRemoveLock(&DeviceExtension->RemoveLock,
  144. DeviceExtension->ReadIrp);
  145. ASSERT(DeviceExtension->Started);
  146. //
  147. // SerialMouseStartRead needs started to be set to true
  148. //
  149. DeviceExtension->ReadInterlock = SERIAL_MOUSE_END_READ;
  150. status = SerialMouseStartRead(DeviceExtension);
  151. if (status == STATUS_PENDING || status == STATUS_SUCCESS) {
  152. Print(DeviceExtension, DBG_PNP_INFO,
  153. ("Start read succeeded, 0x%x\n", status));
  154. status = STATUS_SUCCESS;
  155. }
  156. else {
  157. Print(DeviceExtension, DBG_PNP_ERROR,
  158. ("Start read failed, 0x%x\n", status));
  159. ASSERT(!NT_SUCCESS(status));
  160. //
  161. // No need to release the remove lock here. If SerialMouseStartRead
  162. // fails, then it will release the lock on its own.
  163. //
  164. // IoReleaseRemoveLock(&DeviceExtension->RemoveLock,
  165. // DeviceExtension->ReadIrp);
  166. DeviceExtension->Started = FALSE;
  167. }
  168. return status;
  169. }
  170. NTSTATUS
  171. SerialMouseStartDevice(
  172. PDEVICE_EXTENSION DeviceExtension,
  173. PIRP Irp,
  174. BOOLEAN CloseOnFailure
  175. )
  176. {
  177. PIO_STACK_LOCATION next;
  178. NTSTATUS status;
  179. PAGED_CODE();
  180. status = SerialMouseInitializeDevice(DeviceExtension);
  181. Print(DeviceExtension, DBG_PNP_INFO, ("InitializeDevice 0x%x\n", status));
  182. if (NT_SUCCESS(status)) {
  183. status = SerialMouseSpinUpRead(DeviceExtension);
  184. }
  185. if (!NT_SUCCESS(status) && CloseOnFailure) {
  186. Print(DeviceExtension, DBG_PNP_ERROR,
  187. ("sending close due to failure, 0x%x\n", status));
  188. //
  189. // The start failed and we sent the create as part of the start
  190. // Send the matching cleanup/close so the port is accessible again.
  191. //
  192. SerialMouseClosePort(DeviceExtension, Irp);
  193. InterlockedDecrement(&DeviceExtension->EnableCount);
  194. }
  195. return status;
  196. }
  197. NTSTATUS
  198. SerialMouseInitializeDevice (
  199. IN PDEVICE_EXTENSION DeviceExtension
  200. )
  201. /*++
  202. Routine Description:
  203. This routine initializes the device for the given device
  204. extension.
  205. Arguments:
  206. DriverObject - Supplies the driver object.
  207. TmpDeviceExtension - Supplies a temporary device extension for the
  208. device to initialize.
  209. RegistryPath - Supplies the registry path.
  210. BaseDeviceName - Supplies the base device name to the device
  211. to create.
  212. Return Value:
  213. None.
  214. --*/
  215. {
  216. #define DUMP_COUNT 4
  217. NTSTATUS status = STATUS_SUCCESS;
  218. PIO_ERROR_LOG_PACKET errorLogEntry;
  219. ULONG uniqueErrorValue,
  220. dumpCount = 0,
  221. i,
  222. dumpData[DUMP_COUNT];
  223. UNICODE_STRING keyName;
  224. KEVENT event;
  225. IO_STATUS_BLOCK iosb;
  226. ULONG waitMask;
  227. for (i = 0; i < DUMP_COUNT; i++) {
  228. dumpData[i] = 0;
  229. }
  230. Print(DeviceExtension, DBG_SS_TRACE, ("StartDevice, enter\n"));
  231. PAGED_CODE();
  232. DeviceExtension->Started = TRUE;
  233. //
  234. // Set the wait mask to zero so that when we send the
  235. // wait request it won't get completed due to init flipping lines
  236. //
  237. // (the wait mask could have been set by a previous app or by this driver
  238. // and we are coming out of a > D0 state)
  239. //
  240. waitMask = 0x0;
  241. KeInitializeEvent(&event, NotificationEvent, FALSE);
  242. SerialMouseIoSyncIoctlEx(IOCTL_SERIAL_SET_WAIT_MASK,
  243. DeviceExtension->TopOfStack,
  244. &event,
  245. &iosb,
  246. &waitMask,
  247. sizeof(ULONG),
  248. NULL,
  249. 0);
  250. //
  251. // Initialize the h/w and figure out what type of mouse is on the port
  252. //
  253. status = SerialMouseInitializeHardware(DeviceExtension);
  254. if (!NT_SUCCESS(status)) {
  255. Print(DeviceExtension, DBG_SS_ERROR,
  256. ("Could not initialize hardware\n"));
  257. goto SerialMouseInitializeExit;
  258. }
  259. if (!DeviceExtension->MouseAttributes.MouseIdentifier) {
  260. DeviceExtension->MouseAttributes.MouseIdentifier =
  261. MOUSE_SERIAL_HARDWARE;
  262. }
  263. DeviceExtension->DetectionSupported = TRUE;
  264. SerialMouseStartDetection(DeviceExtension);
  265. SerialMouseInitializeExit:
  266. //
  267. // Log an error, if necessary.
  268. //
  269. if (status != STATUS_SUCCESS) {
  270. DeviceExtension->Started = FALSE;
  271. errorLogEntry = (PIO_ERROR_LOG_PACKET)
  272. IoAllocateErrorLogEntry(
  273. DeviceExtension->Self,
  274. (UCHAR) (sizeof(IO_ERROR_LOG_PACKET)
  275. + (dumpCount * sizeof(ULONG)))
  276. );
  277. if (errorLogEntry != NULL) {
  278. errorLogEntry->ErrorCode = status;
  279. errorLogEntry->DumpDataSize = (USHORT) dumpCount * sizeof(ULONG);
  280. errorLogEntry->SequenceNumber = 0;
  281. errorLogEntry->MajorFunctionCode = 0;
  282. errorLogEntry->IoControlCode = 0;
  283. errorLogEntry->RetryCount = 0;
  284. // errorLogEntry->UniqueErrorValue = uniqueErrorValue;
  285. errorLogEntry->FinalStatus = status;
  286. for (i = 0; i < dumpCount; i++)
  287. errorLogEntry->DumpData[i] = dumpData[i];
  288. IoWriteErrorLogEntry(errorLogEntry);
  289. }
  290. }
  291. Print(DeviceExtension, DBG_SS_TRACE, ("IntializeDevice 0x%x\n", status));
  292. return status;
  293. }
  294. VOID
  295. SerialMouseUnload(
  296. IN PDRIVER_OBJECT DriverObject
  297. )
  298. {
  299. PUNICODE_STRING regPath;
  300. PAGED_CODE();
  301. ASSERT(NULL == DriverObject->DeviceObject);
  302. regPath = SerialMouseGetRegistryPath(DriverObject);
  303. if (regPath && regPath->Buffer) {
  304. ExFreePool(regPath->Buffer);
  305. }
  306. }
  307. NTSTATUS
  308. SerialMouseInitializeHardware(
  309. IN PDEVICE_EXTENSION DeviceExtension
  310. )
  311. /*++
  312. Routine Description:
  313. This routine initializes the serial mouse/ballpoint. Note that this
  314. routine is only called at initialization time, so synchronization is
  315. not required.
  316. Arguments:
  317. DeviceObject - Pointer to the device object.
  318. Return Value:
  319. STATUS_SUCCESS if a pointing device is detected, otherwise STATUS_UNSUCCESSFUL
  320. --*/
  321. {
  322. MOUSETYPE mouseType;
  323. ULONG hardwareButtons;
  324. NTSTATUS status = STATUS_UNSUCCESSFUL;
  325. Print(DeviceExtension, DBG_SS_TRACE, ("SerialMouseInitializeHardware: enter\n"));
  326. //
  327. // Zero out the handler data in case we have previous state from a
  328. // previous start
  329. //
  330. RtlZeroMemory(&DeviceExtension->HandlerData, sizeof(HANDLER_DATA));
  331. if ((mouseType = MSerDetect(DeviceExtension)) != NO_MOUSE) {
  332. status = STATUS_SUCCESS;
  333. switch (mouseType) {
  334. case MOUSE_2B:
  335. DeviceExtension->ProtocolHandler =
  336. MSerSetProtocol(DeviceExtension, MSER_PROTOCOL_MP);
  337. DeviceExtension->MouseAttributes.MouseIdentifier =
  338. MOUSE_SERIAL_HARDWARE;
  339. hardwareButtons = 2;
  340. break;
  341. case MOUSE_3B:
  342. DeviceExtension->ProtocolHandler =
  343. MSerSetProtocol(DeviceExtension, MSER_PROTOCOL_MP);
  344. DeviceExtension->MouseAttributes.MouseIdentifier =
  345. MOUSE_SERIAL_HARDWARE;
  346. hardwareButtons = 3;
  347. break;
  348. case BALLPOINT:
  349. DeviceExtension->ProtocolHandler =
  350. MSerSetProtocol(DeviceExtension, MSER_PROTOCOL_BP);
  351. DeviceExtension->MouseAttributes.MouseIdentifier =
  352. BALLPOINT_SERIAL_HARDWARE;
  353. hardwareButtons = 2;
  354. break;
  355. case MOUSE_Z:
  356. DeviceExtension->ProtocolHandler =
  357. MSerSetProtocol(DeviceExtension, MSER_PROTOCOL_Z);
  358. hardwareButtons = 3;
  359. DeviceExtension->MouseAttributes.MouseIdentifier =
  360. WHEELMOUSE_SERIAL_HARDWARE;
  361. break;
  362. }
  363. }
  364. else if (CSerDetect(DeviceExtension, &hardwareButtons)) {
  365. status = STATUS_SUCCESS;
  366. DeviceExtension->ProtocolHandler =
  367. CSerSetProtocol(DeviceExtension, CSER_PROTOCOL_MM);
  368. #if DBG
  369. DeviceExtension->DebugFlags |= (DBG_HANDLER_INFO | DBG_HANDLER_ERROR);
  370. #endif
  371. }
  372. else {
  373. DeviceExtension->ProtocolHandler = NULL;
  374. hardwareButtons = MOUSE_NUMBER_OF_BUTTONS;
  375. }
  376. //
  377. // If the hardware wasn't overridden, set the number of buttons
  378. // according to the protocol.
  379. //
  380. DeviceExtension->MouseAttributes.NumberOfButtons =
  381. (USHORT) hardwareButtons;
  382. if (NT_SUCCESS(status)) {
  383. //
  384. // Make sure the FIFO is turned off.
  385. //
  386. SerialMouseSetFifo(DeviceExtension, 0);
  387. //
  388. // Clean up anything left in the receive buffer.
  389. //
  390. SerialMouseFlushReadBuffer(DeviceExtension);
  391. }
  392. Print(DeviceExtension, DBG_SS_TRACE,
  393. ("SerialMouseInitializeHardware exit (0x%x)\n", status));
  394. return status;
  395. }
  396. #if DBG
  397. VOID
  398. SerialMouseGetDebugFlags(
  399. IN PUNICODE_STRING RegPath
  400. )
  401. {
  402. }
  403. #endif
  404. VOID
  405. SerialMouseServiceParameters(
  406. IN PDEVICE_EXTENSION DeviceExtension,
  407. IN HANDLE Handle
  408. )
  409. /*++
  410. Routine Description:
  411. This routine retrieves this driver's service parameters information
  412. from the registry.
  413. Arguments:
  414. DeviceExtension - Pointer to the device extension.
  415. RegistryPath - Pointer to the null-terminated Unicode name of the
  416. registry path for this driver.
  417. DeviceName - Pointer to the Unicode string that will receive
  418. the port device name.
  419. Return Value:
  420. None. As a side-effect, sets fields in DeviceExtension->Configuration.
  421. --*/
  422. {
  423. PRTL_QUERY_REGISTRY_TABLE parameters = NULL;
  424. NTSTATUS status = STATUS_SUCCESS;
  425. LONG defaultWaitEventMask = 0x0,
  426. numberOfButtons = MOUSE_NUMBER_OF_BUTTONS,
  427. defaultNumberOfButtons = MOUSE_NUMBER_OF_BUTTONS,
  428. sampleRate = MOUSE_SAMPLE_RATE,
  429. defaultSampleRate = MOUSE_SAMPLE_RATE,
  430. i;
  431. USHORT queriesPlusOne = 4;
  432. WCHAR strParameters[] = L"Parameters";
  433. PUNICODE_STRING regPath;
  434. UNICODE_STRING parametersPath;
  435. #if DBG
  436. ULONG defaultDebugFlags = DEFAULT_DEBUG_FLAGS;
  437. queriesPlusOne++;
  438. #endif
  439. RtlInitUnicodeString(&parametersPath, NULL);
  440. //
  441. // Allocate the Rtl query table.
  442. //
  443. parameters = ExAllocatePool(
  444. PagedPool,
  445. sizeof(RTL_QUERY_REGISTRY_TABLE) * queriesPlusOne
  446. );
  447. if (!parameters) {
  448. status = STATUS_UNSUCCESSFUL;
  449. goto SetParameters;
  450. }
  451. else {
  452. RtlZeroMemory(
  453. parameters,
  454. sizeof(RTL_QUERY_REGISTRY_TABLE) * queriesPlusOne
  455. );
  456. regPath = SerialMouseGetRegistryPath(DeviceExtension->Self->DriverObject);
  457. if (!regPath || !regPath->Buffer) {
  458. goto GetServiceParametersByHandle;
  459. }
  460. parametersPath.MaximumLength = regPath->Length +
  461. (wcslen(strParameters) * sizeof(WCHAR) ) + sizeof(UNICODE_NULL);
  462. parametersPath.Buffer = ExAllocatePool(PagedPool,
  463. parametersPath.MaximumLength);
  464. if (!parametersPath.Buffer) {
  465. status = STATUS_UNSUCCESSFUL;
  466. goto GetServiceParametersByHandle;
  467. }
  468. }
  469. RtlZeroMemory(parametersPath.Buffer,
  470. parametersPath.MaximumLength);
  471. RtlAppendUnicodeToString(&parametersPath,
  472. regPath->Buffer);
  473. RtlAppendUnicodeToString(&parametersPath,
  474. strParameters);
  475. //
  476. // Gather all of the "user specified" information from
  477. // the registry.
  478. //
  479. i = 0;
  480. parameters[i].Flags = RTL_QUERY_REGISTRY_DIRECT;
  481. parameters[i].Name = L"NumberOfButtons";
  482. parameters[i].EntryContext = &numberOfButtons;
  483. parameters[i].DefaultType = REG_DWORD;
  484. parameters[i].DefaultData = &defaultNumberOfButtons;
  485. parameters[i].DefaultLength = sizeof(LONG);
  486. parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
  487. parameters[i].Name = L"SampleRate";
  488. parameters[i].EntryContext = &sampleRate;
  489. parameters[i].DefaultType = REG_DWORD;
  490. parameters[i].DefaultData = &defaultSampleRate;
  491. parameters[i].DefaultLength = sizeof(LONG);
  492. #if DBG
  493. parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
  494. parameters[i].Name = L"DebugFlags";
  495. parameters[i].EntryContext = &DeviceExtension->DebugFlags;
  496. parameters[i].DefaultType = REG_DWORD;
  497. parameters[i].DefaultData = &defaultDebugFlags;
  498. parameters[i].DefaultLength = sizeof(ULONG);
  499. #endif
  500. status = RtlQueryRegistryValues(
  501. RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
  502. parametersPath.Buffer,
  503. parameters,
  504. NULL,
  505. NULL
  506. );
  507. if (!NT_SUCCESS(status)) {
  508. Print(DeviceExtension, DBG_SS_ERROR,
  509. ("RtlQueryRegistryValues failed with 0x%x\n", status));
  510. DeviceExtension->DebugFlags = DEFAULT_DEBUG_FLAGS;
  511. }
  512. GetServiceParametersByHandle:
  513. if (Handle) {
  514. LONG prevNumberOfButtons = numberOfButtons,
  515. prevSampleRate = sampleRate;
  516. i = 0;
  517. parameters[i].Flags = RTL_QUERY_REGISTRY_DIRECT;
  518. parameters[i].Name = L"NumberOfButtons";
  519. parameters[i].EntryContext = &numberOfButtons;
  520. parameters[i].DefaultType = REG_DWORD;
  521. parameters[i].DefaultData = &prevNumberOfButtons;
  522. parameters[i].DefaultLength = sizeof(LONG);
  523. parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
  524. parameters[i].Name = L"SampleRate";
  525. parameters[i].EntryContext = &sampleRate;
  526. parameters[i].DefaultType = REG_DWORD;
  527. parameters[i].DefaultData = &prevSampleRate;
  528. parameters[i].DefaultLength = sizeof(LONG);
  529. parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
  530. parameters[i].Name = L"WaitEventMask";
  531. parameters[i].EntryContext = &DeviceExtension->WaitEventMask;
  532. parameters[i].DefaultType = REG_DWORD;
  533. parameters[i].DefaultData = &defaultWaitEventMask;
  534. parameters[i].DefaultLength = sizeof(LONG);
  535. #if DBG
  536. parameters[++i].Flags = RTL_QUERY_REGISTRY_DIRECT;
  537. parameters[i].Name = L"DebugFlags";
  538. parameters[i].EntryContext = &DeviceExtension->DebugFlags;
  539. parameters[i].DefaultType = REG_DWORD;
  540. parameters[i].DefaultData = &defaultDebugFlags;
  541. parameters[i].DefaultLength = sizeof(ULONG);
  542. #endif
  543. status = RtlQueryRegistryValues(
  544. RTL_REGISTRY_HANDLE,
  545. (PWSTR) Handle,
  546. parameters,
  547. NULL,
  548. NULL
  549. );
  550. }
  551. SetParameters:
  552. if (!NT_SUCCESS(status)) {
  553. DeviceExtension->WaitEventMask = defaultWaitEventMask;
  554. #if DBG
  555. DeviceExtension->DebugFlags = defaultDebugFlags;
  556. #endif
  557. }
  558. #if DBG
  559. if (defaultDebugFlags == DeviceExtension->DebugFlags &&
  560. GlobalDebugFlags != 0x0) {
  561. DeviceExtension->DebugFlags = GlobalDebugFlags;
  562. }
  563. #endif
  564. DeviceExtension->MouseAttributes.NumberOfButtons = (USHORT) numberOfButtons;
  565. DeviceExtension->MouseAttributes.SampleRate = (USHORT) sampleRate;
  566. Print(DeviceExtension, DBG_SS_NOISE, ("NumberOfButtons = %d\n",
  567. DeviceExtension->MouseAttributes.NumberOfButtons));
  568. Print(DeviceExtension, DBG_SS_NOISE, ("SampleRate = %d\n",
  569. DeviceExtension->MouseAttributes.SampleRate));
  570. Print(DeviceExtension, DBG_SS_NOISE, ("WaitEventMask = 0x%x\n",
  571. DeviceExtension->WaitEventMask));
  572. Print(DeviceExtension, DBG_SS_NOISE, ("DebugFlags 0x%x\n",
  573. DeviceExtension->DebugFlags));
  574. if (parametersPath.Buffer)
  575. ExFreePool(parametersPath.Buffer);
  576. if (parameters)
  577. ExFreePool(parameters);
  578. }