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.

746 lines
19 KiB

  1. /*--
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. neckbrep.c
  5. Abstract:
  6. Environment:
  7. Kernel mode only.
  8. Notes:
  9. Revision History:
  10. --*/
  11. #include "neckbrep.h"
  12. NTSTATUS DriverEntry (PDRIVER_OBJECT, PUNICODE_STRING);
  13. #ifdef ALLOC_PRAGMA
  14. #pragma alloc_text (INIT, DriverEntry)
  15. #pragma alloc_text (PAGE, KbRepeatCreateClose)
  16. #pragma alloc_text (PAGE, KbRepeatInternIoCtl)
  17. #pragma alloc_text (PAGE, KbRepeatUnload)
  18. #endif
  19. NTSTATUS
  20. DriverEntry (
  21. IN PDRIVER_OBJECT DriverObject,
  22. IN PUNICODE_STRING RegistryPath
  23. )
  24. /*++
  25. Routine Description:
  26. Initialize the entry points of the driver.
  27. --*/
  28. {
  29. NTSTATUS status = STATUS_SUCCESS;
  30. ULONG i;
  31. UNREFERENCED_PARAMETER (RegistryPath);
  32. //
  33. // Fill in all the dispatch entry points with the pass through function
  34. // and the explicitly fill in the functions we are going to intercept
  35. //
  36. for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) {
  37. DriverObject->MajorFunction[i] = KbRepeatDispatchPassThrough;
  38. }
  39. DriverObject->MajorFunction [IRP_MJ_CREATE] =
  40. DriverObject->MajorFunction [IRP_MJ_CLOSE] = KbRepeatCreateClose;
  41. DriverObject->MajorFunction [IRP_MJ_PNP] = KbRepeatPnP;
  42. DriverObject->MajorFunction [IRP_MJ_POWER] = KbRepeatPower;
  43. DriverObject->MajorFunction [IRP_MJ_INTERNAL_DEVICE_CONTROL] =
  44. KbRepeatInternIoCtl;
  45. DriverObject->DriverUnload = KbRepeatUnload;
  46. DriverObject->DriverExtension->AddDevice = KbRepeatAddDevice;
  47. return STATUS_SUCCESS;
  48. }
  49. NTSTATUS
  50. KbRepeatAddDevice(
  51. IN PDRIVER_OBJECT Driver,
  52. IN PDEVICE_OBJECT PDO
  53. )
  54. {
  55. PDEVICE_EXTENSION devExt;
  56. IO_ERROR_LOG_PACKET errorLogEntry;
  57. PDEVICE_OBJECT device;
  58. NTSTATUS status = STATUS_SUCCESS;
  59. PAGED_CODE();
  60. status = IoCreateDevice(Driver, // driver
  61. sizeof(DEVICE_EXTENSION), // size of extension
  62. NULL, // device name
  63. FILE_DEVICE_8042_PORT, // device type
  64. 0, // device characteristics
  65. FALSE, // exclusive
  66. &device // new device
  67. );
  68. if (!NT_SUCCESS(status)) {
  69. return (status);
  70. }
  71. RtlZeroMemory(device->DeviceExtension, sizeof(DEVICE_EXTENSION));
  72. devExt = (PDEVICE_EXTENSION) device->DeviceExtension;
  73. devExt->TopOfStack = IoAttachDeviceToDeviceStack(device, PDO);
  74. if (devExt->TopOfStack == NULL) {
  75. IoDeleteDevice(device);
  76. return STATUS_DEVICE_NOT_CONNECTED;
  77. }
  78. ASSERT(devExt->TopOfStack);
  79. devExt->Self = device;
  80. devExt->PDO = PDO;
  81. devExt->DeviceState = PowerDeviceD0;
  82. devExt->Removed = FALSE;
  83. devExt->Started = FALSE;
  84. device->Flags |= DO_BUFFERED_IO;
  85. device->Flags |= DO_POWER_PAGABLE;
  86. device->Flags &= ~DO_DEVICE_INITIALIZING;
  87. //
  88. // Initialize Timer DPC.
  89. //
  90. KeInitializeTimer (&(devExt->KbRepeatTimer));
  91. KeInitializeDpc (&(devExt->KbRepeatDPC),
  92. KbRepeatDpc,
  93. device);
  94. //
  95. // Initialize device extension.
  96. //
  97. RtlZeroMemory(&(devExt->KbRepeatInput), sizeof(KEYBOARD_INPUT_DATA));
  98. devExt->KbRepeatDelay.LowPart = -(KEYBOARD_TYPEMATIC_DELAY_DEFAULT * 10000);
  99. devExt->KbRepeatDelay.HighPart = -1;
  100. devExt->KbRepeatRate = 1000 / KEYBOARD_TYPEMATIC_RATE_DEFAULT;
  101. return status;
  102. }
  103. NTSTATUS
  104. KbRepeatComplete(
  105. IN PDEVICE_OBJECT DeviceObject,
  106. IN PIRP Irp,
  107. IN PVOID Context
  108. )
  109. {
  110. PKEVENT event;
  111. PIO_STACK_LOCATION irpStack;
  112. NTSTATUS status = STATUS_SUCCESS;
  113. event = (PKEVENT) Context;
  114. UNREFERENCED_PARAMETER(DeviceObject);
  115. if (Irp->PendingReturned) {
  116. IoMarkIrpPending(Irp);
  117. }
  118. //
  119. // We could switch on the major and minor functions of the IRP to perform
  120. // different functions, but we know that Context is an event that needs
  121. // to be set.
  122. //
  123. KeSetEvent(event, 0, FALSE);
  124. //
  125. // Allows the caller to use the IRP after it is completed
  126. //
  127. return STATUS_MORE_PROCESSING_REQUIRED;
  128. }
  129. NTSTATUS
  130. KbRepeatCreateClose (
  131. IN PDEVICE_OBJECT DeviceObject,
  132. IN PIRP Irp
  133. )
  134. /*++
  135. Routine Description:
  136. Maintain a simple count of the creates and closes sent against this device
  137. --*/
  138. {
  139. PIO_STACK_LOCATION irpStack;
  140. NTSTATUS status = STATUS_SUCCESS;
  141. PDEVICE_EXTENSION devExt;
  142. PKEYBOARD_INPUT_DATA CurrentRepeat;
  143. PAGED_CODE();
  144. irpStack = IoGetCurrentIrpStackLocation(Irp);
  145. devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  146. switch (irpStack->MajorFunction) {
  147. case IRP_MJ_CREATE:
  148. if (NULL == devExt->UpperConnectData.ClassService) {
  149. //
  150. // No Connection yet. How can we be enabled?
  151. //
  152. status = STATUS_INVALID_DEVICE_STATE;
  153. }
  154. break;
  155. case IRP_MJ_CLOSE:
  156. CurrentRepeat = &(devExt->KbRepeatInput);
  157. if (CurrentRepeat->MakeCode != 0) {
  158. Print(("NecKbRep-KbRepeatCreateClose : Stopping repeat\n"));
  159. KeCancelTimer(&(devExt->KbRepeatTimer));
  160. RtlZeroMemory(CurrentRepeat, sizeof(KEYBOARD_INPUT_DATA));
  161. }
  162. break;
  163. }
  164. Irp->IoStatus.Status = status;
  165. //
  166. // Pass on the create and the close
  167. //
  168. return KbRepeatDispatchPassThrough(DeviceObject, Irp);
  169. }
  170. NTSTATUS
  171. KbRepeatDispatchPassThrough(
  172. IN PDEVICE_OBJECT DeviceObject,
  173. IN PIRP Irp
  174. )
  175. /*++
  176. Routine Description:
  177. Passes a request on to the lower driver.
  178. --*/
  179. {
  180. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
  181. //
  182. // Pass the IRP to the target
  183. //
  184. IoSkipCurrentIrpStackLocation(Irp);
  185. return IoCallDriver(
  186. ((PDEVICE_EXTENSION) DeviceObject->DeviceExtension)->TopOfStack,
  187. Irp);
  188. }
  189. NTSTATUS
  190. KbRepeatInternIoCtl(
  191. IN PDEVICE_OBJECT DeviceObject,
  192. IN PIRP Irp
  193. )
  194. /*++
  195. Routine Description:
  196. This routine is the dispatch routine for internal device control requests.
  197. Arguments:
  198. DeviceObject - Pointer to the device object.
  199. Irp - Pointer to the request packet.
  200. Return Value:
  201. Status is returned.
  202. --*/
  203. {
  204. PIO_STACK_LOCATION irpStack;
  205. PDEVICE_EXTENSION devExt;
  206. KEVENT event;
  207. PCONNECT_DATA connectData;
  208. PKEYBOARD_TYPEMATIC_PARAMETERS TypematicParameters;
  209. NTSTATUS status = STATUS_SUCCESS;
  210. //
  211. // Get a pointer to the device extension.
  212. //
  213. devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  214. //
  215. // Initialize the returned Information field.
  216. //
  217. Irp->IoStatus.Information = 0;
  218. //
  219. // Get a pointer to the current parameters for this request. The
  220. // information is contained in the current stack location.
  221. //
  222. irpStack = IoGetCurrentIrpStackLocation(Irp);
  223. //
  224. // Case on the device control subfunction that is being performed by the
  225. // requestor.
  226. //
  227. switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {
  228. //
  229. // Connect a keyboard class device driver to the port driver.
  230. //
  231. case IOCTL_INTERNAL_KEYBOARD_CONNECT:
  232. //
  233. // Only allow a connection if the keyboard hardware is present.
  234. // Also, only allow one connection.
  235. //
  236. if (devExt->UpperConnectData.ClassService != NULL) {
  237. status = STATUS_SHARING_VIOLATION;
  238. break;
  239. }
  240. else if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
  241. sizeof(CONNECT_DATA)) {
  242. //
  243. // invalid buffer
  244. //
  245. status = STATUS_INVALID_PARAMETER;
  246. break;
  247. }
  248. //
  249. // Copy the connection parameters to the device extension.
  250. //
  251. connectData = ((PCONNECT_DATA)
  252. (irpStack->Parameters.DeviceIoControl.Type3InputBuffer));
  253. devExt->UpperConnectData = *connectData;
  254. connectData->ClassDeviceObject = devExt->Self;
  255. connectData->ClassService = KbRepeatServiceCallback;
  256. break;
  257. //
  258. // Disconnect a keyboard class device driver from the port driver.
  259. //
  260. case IOCTL_INTERNAL_KEYBOARD_DISCONNECT:
  261. //
  262. // Clear the connection parameters in the device extension.
  263. //
  264. // devExt->UpperConnectData.ClassDeviceObject = NULL;
  265. // devExt->UpperConnectData.ClassService = NULL;
  266. status = STATUS_NOT_IMPLEMENTED;
  267. break;
  268. case IOCTL_KEYBOARD_SET_TYPEMATIC:
  269. TypematicParameters = (PKEYBOARD_TYPEMATIC_PARAMETERS)(Irp->AssociatedIrp.SystemBuffer);
  270. if (TypematicParameters->Rate != 0) {
  271. devExt->KbRepeatDelay.LowPart = -TypematicParameters->Delay * 10000;
  272. devExt->KbRepeatDelay.HighPart = -1;
  273. devExt->KbRepeatRate = 1000 / TypematicParameters->Rate;
  274. Print((
  275. "NecKbRep-KbRepeatInternIoCtl : New Delay = %d, New Rate = %d\n",
  276. TypematicParameters->Delay,
  277. TypematicParameters->Rate
  278. ));
  279. } else {
  280. Print((
  281. "NecKbRep-KbRepeatInternIoCtl : Invalid Parameters. New Delay = %d, New Rate = %d\n",
  282. TypematicParameters->Delay,
  283. TypematicParameters->Rate
  284. ));
  285. }
  286. break;
  287. //
  288. // Might want to capture these in the future
  289. //
  290. case IOCTL_KEYBOARD_QUERY_ATTRIBUTES:
  291. case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION:
  292. case IOCTL_KEYBOARD_QUERY_INDICATORS:
  293. case IOCTL_KEYBOARD_SET_INDICATORS:
  294. case IOCTL_KEYBOARD_QUERY_TYPEMATIC:
  295. break;
  296. }
  297. if (!NT_SUCCESS(status)) {
  298. return status;
  299. }
  300. return KbRepeatDispatchPassThrough(DeviceObject, Irp);
  301. }
  302. NTSTATUS
  303. KbRepeatPnP(
  304. IN PDEVICE_OBJECT DeviceObject,
  305. IN PIRP Irp
  306. )
  307. /*++
  308. Routine Description:
  309. This routine is the dispatch routine for plug and play irps
  310. Arguments:
  311. DeviceObject - Pointer to the device object.
  312. Irp - Pointer to the request packet.
  313. Return Value:
  314. Status is returned.
  315. --*/
  316. {
  317. PDEVICE_EXTENSION devExt;
  318. PIO_STACK_LOCATION irpStack;
  319. NTSTATUS status = STATUS_SUCCESS;
  320. KIRQL oldIrql;
  321. KEVENT event;
  322. PAGED_CODE();
  323. devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  324. irpStack = IoGetCurrentIrpStackLocation(Irp);
  325. switch (irpStack->MinorFunction) {
  326. case IRP_MN_START_DEVICE: {
  327. //
  328. // The device is starting.
  329. //
  330. // We cannot touch the device (send it any non pnp irps) until a
  331. // start device has been passed down to the lower drivers.
  332. //
  333. IoCopyCurrentIrpStackLocationToNext(Irp);
  334. KeInitializeEvent(&event,
  335. NotificationEvent,
  336. FALSE
  337. );
  338. IoSetCompletionRoutine(Irp,
  339. (PIO_COMPLETION_ROUTINE) KbRepeatComplete,
  340. &event,
  341. TRUE,
  342. TRUE,
  343. TRUE); // No need for Cancel
  344. status = IoCallDriver(devExt->TopOfStack, Irp);
  345. if (STATUS_PENDING == status) {
  346. KeWaitForSingleObject(
  347. &event,
  348. Executive, // Waiting for reason of a driver
  349. KernelMode, // Waiting in kernel mode
  350. FALSE, // No allert
  351. NULL); // No timeout
  352. }
  353. if (NT_SUCCESS(status) && NT_SUCCESS(Irp->IoStatus.Status)) {
  354. //
  355. // As we are successfully now back from our start device
  356. // we can do work.
  357. //
  358. devExt->Started = TRUE;
  359. devExt->Removed = FALSE;
  360. }
  361. //
  362. // We must now complete the IRP, since we stopped it in the
  363. // completetion routine with MORE_PROCESSING_REQUIRED.
  364. //
  365. Irp->IoStatus.Status = status;
  366. Irp->IoStatus.Information = 0;
  367. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  368. break;
  369. }
  370. case IRP_MN_REMOVE_DEVICE:
  371. IoSkipCurrentIrpStackLocation(Irp);
  372. IoCallDriver(devExt->TopOfStack, Irp);
  373. devExt->Removed = TRUE;
  374. IoDetachDevice(devExt->TopOfStack);
  375. IoDeleteDevice(DeviceObject);
  376. status = STATUS_SUCCESS;
  377. break;
  378. case IRP_MN_QUERY_REMOVE_DEVICE:
  379. case IRP_MN_QUERY_STOP_DEVICE:
  380. case IRP_MN_CANCEL_REMOVE_DEVICE:
  381. case IRP_MN_CANCEL_STOP_DEVICE:
  382. case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
  383. case IRP_MN_STOP_DEVICE:
  384. case IRP_MN_QUERY_DEVICE_RELATIONS:
  385. case IRP_MN_QUERY_INTERFACE:
  386. case IRP_MN_QUERY_CAPABILITIES:
  387. case IRP_MN_QUERY_DEVICE_TEXT:
  388. case IRP_MN_QUERY_RESOURCES:
  389. case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
  390. case IRP_MN_READ_CONFIG:
  391. case IRP_MN_WRITE_CONFIG:
  392. case IRP_MN_EJECT:
  393. case IRP_MN_SET_LOCK:
  394. case IRP_MN_QUERY_ID:
  395. case IRP_MN_QUERY_PNP_DEVICE_STATE:
  396. default:
  397. //
  398. // Here the filter driver might modify the behavior of these IRPS
  399. // Please see PlugPlay documentation for use of these IRPs.
  400. //
  401. IoSkipCurrentIrpStackLocation(Irp);
  402. status = IoCallDriver(devExt->TopOfStack, Irp);
  403. break;
  404. }
  405. return status;
  406. }
  407. NTSTATUS
  408. KbRepeatPower(
  409. IN PDEVICE_OBJECT DeviceObject,
  410. IN PIRP Irp
  411. )
  412. /*++
  413. Routine Description:
  414. This routine is the dispatch routine for power irps Does nothing except
  415. record the state of the device.
  416. Arguments:
  417. DeviceObject - Pointer to the device object.
  418. Irp - Pointer to the request packet.
  419. Return Value:
  420. Status is returned.
  421. --*/
  422. {
  423. PIO_STACK_LOCATION irpStack;
  424. NTSTATUS status;
  425. PDEVICE_EXTENSION devExt;
  426. POWER_STATE powerState;
  427. POWER_STATE_TYPE powerType;
  428. devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  429. irpStack = IoGetCurrentIrpStackLocation(Irp);
  430. powerType = irpStack->Parameters.Power.Type;
  431. powerState = irpStack->Parameters.Power.State;
  432. switch (irpStack->MinorFunction) {
  433. case IRP_MN_SET_POWER:
  434. Print(("NecKbRep-KbRepeatPower : Power Setting %s state to %d\n",
  435. ((powerType == SystemPowerState) ? "System"
  436. : "Device"),
  437. powerState.SystemState - 1));
  438. if (powerType == DevicePowerState) {
  439. devExt->DeviceState = powerState.DeviceState;
  440. switch (powerState.DeviceState) {
  441. case PowerDeviceD0:
  442. //
  443. // if powering up, clear last repeat
  444. //
  445. RtlZeroMemory(&(devExt->KbRepeatInput), sizeof(KEYBOARD_INPUT_DATA));
  446. break;
  447. case PowerDeviceD1:
  448. case PowerDeviceD2:
  449. case PowerDeviceD3:
  450. //
  451. // if powering down, stop current repeat
  452. //
  453. Print(("NecKbRep-KbRepeatPower : Stopping repeat\n"));
  454. KeCancelTimer(&(devExt->KbRepeatTimer));
  455. RtlZeroMemory(&(devExt->KbRepeatInput), sizeof(KEYBOARD_INPUT_DATA));
  456. break;
  457. default:
  458. Print(("NecKbRep-KbRepeatPower : DeviceState (%d) no known\n",
  459. powerState.DeviceState - 1));
  460. break;
  461. }
  462. }
  463. break;
  464. case IRP_MN_QUERY_POWER:
  465. Print(("NecKbRep-KbRepeatPower : Power query %s status to %d\n",
  466. ((powerType == SystemPowerState) ? "System"
  467. : "Device"),
  468. powerState.SystemState - 1));
  469. break;
  470. default:
  471. Print(("NecKbRep-KbRepeatPower : Power minor (0x%x) no known\n",
  472. irpStack->MinorFunction));
  473. break;
  474. }
  475. PoStartNextPowerIrp(Irp);
  476. IoSkipCurrentIrpStackLocation(Irp);
  477. PoCallDriver(devExt->TopOfStack, Irp);
  478. return STATUS_SUCCESS;
  479. }
  480. VOID
  481. KbRepeatServiceCallback(
  482. IN PDEVICE_OBJECT DeviceObject,
  483. IN PKEYBOARD_INPUT_DATA InputDataStart,
  484. IN PKEYBOARD_INPUT_DATA InputDataEnd,
  485. IN OUT PULONG InputDataConsumed
  486. )
  487. {
  488. PDEVICE_EXTENSION devExt;
  489. PKEYBOARD_INPUT_DATA CurrentRepeat, NewInput;
  490. KEYBOARD_INPUT_DATA TempRepeat;
  491. devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  492. CurrentRepeat = &(devExt->KbRepeatInput);
  493. RtlMoveMemory(
  494. (PCHAR)&TempRepeat,
  495. (PCHAR)CurrentRepeat,
  496. sizeof(KEYBOARD_INPUT_DATA)
  497. );
  498. for (NewInput = InputDataStart; NewInput < InputDataEnd; NewInput++) {
  499. if ((TempRepeat.MakeCode == NewInput->MakeCode) &&
  500. ((TempRepeat.Flags & (KEY_E0 | KEY_E1)) == (NewInput->Flags & (KEY_E0 | KEY_E1)))) {
  501. if (!(NewInput->Flags & KEY_BREAK)) {
  502. // Do nothing(Inserted by this driver)
  503. ;
  504. } else {
  505. // Stop current repeat
  506. RtlZeroMemory(&TempRepeat, sizeof(KEYBOARD_INPUT_DATA));
  507. }
  508. } else {
  509. if (!(NewInput->Flags & KEY_BREAK)) {
  510. // Start new repeat
  511. RtlMoveMemory(
  512. (PCHAR)&TempRepeat,
  513. (PCHAR)NewInput,
  514. sizeof(KEYBOARD_INPUT_DATA)
  515. );
  516. } else {
  517. // Do nothing(Break code is inserted, but it's not repeated)
  518. ;
  519. }
  520. }
  521. }
  522. (*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(
  523. devExt->UpperConnectData.ClassDeviceObject,
  524. InputDataStart,
  525. InputDataEnd,
  526. InputDataConsumed);
  527. if ((TempRepeat.MakeCode != CurrentRepeat->MakeCode)||
  528. ((TempRepeat.Flags & (KEY_E0 | KEY_E1)) != (CurrentRepeat->Flags & (KEY_E0 | KEY_E1)))) {
  529. if (CurrentRepeat->MakeCode != 0) {
  530. // Stop Current Repeat.
  531. KeCancelTimer(&(devExt->KbRepeatTimer));
  532. }
  533. RtlMoveMemory(
  534. (PCHAR)CurrentRepeat,
  535. (PCHAR)&TempRepeat,
  536. sizeof(KEYBOARD_INPUT_DATA)
  537. );
  538. if ((TempRepeat.MakeCode != 0)&&(TempRepeat.MakeCode != 0xff)) {
  539. // Start new repeat.
  540. KeSetTimerEx(&(devExt->KbRepeatTimer),
  541. devExt->KbRepeatDelay,
  542. devExt->KbRepeatRate,
  543. &(devExt->KbRepeatDPC));
  544. }
  545. }
  546. }
  547. VOID
  548. KbRepeatUnload(
  549. IN PDRIVER_OBJECT Driver
  550. )
  551. /*++
  552. Routine Description:
  553. Free all the allocated resources associated with this driver.
  554. Arguments:
  555. DriverObject - Pointer to the driver object.
  556. Return Value:
  557. None.
  558. --*/
  559. {
  560. PAGED_CODE();
  561. ASSERT(NULL == Driver->DeviceObject);
  562. return;
  563. }
  564. VOID
  565. KbRepeatDpc(
  566. IN PKDPC DPC,
  567. IN PVOID DeferredContext,
  568. IN PVOID SystemArgument1,
  569. IN PVOID SystemArgument2
  570. )
  571. {
  572. PDEVICE_EXTENSION devExt;
  573. PKEYBOARD_INPUT_DATA InputDataStart;
  574. PKEYBOARD_INPUT_DATA InputDataEnd;
  575. LONG InputDataConsumed;
  576. devExt = ((PDEVICE_OBJECT)DeferredContext)->DeviceExtension;
  577. InputDataStart = &(devExt->KbRepeatInput);
  578. InputDataEnd = InputDataStart + 1;
  579. (*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(
  580. devExt->UpperConnectData.ClassDeviceObject,
  581. InputDataStart,
  582. InputDataEnd,
  583. &InputDataConsumed);
  584. return;
  585. }