00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#include "precomp.h"
00015
#pragma hdrstop
00016
00017 DEVICE_TEMPLATE aDeviceTemplate[
DEVICE_TYPE_MAX + 1] = {
00018
00019 {
00020
sizeof(
GENERIC_DEVICE_INFO)+
sizeof(
MOUSE_DEVICE_INFO),
00021 &GUID_CLASS_MOUSE,
00022
PMAP_MOUCLASS_PARAMS,
00023
L"mouclass",
00024 DD_MOUSE_DEVICE_NAME_U
L"0",
00025 DD_MOUSE_DEVICE_NAME_U
L"Legacy0",
00026 IOCTL_MOUSE_QUERY_ATTRIBUTES,
00027 FIELD_OFFSET(
DEVICEINFO, mouse.Attr),
00028
sizeof((
PDEVICEINFO)
NULL)->mouse.Attr,
00029 FIELD_OFFSET(
DEVICEINFO, mouse.Data),
00030
sizeof((
PDEVICEINFO)
NULL)->mouse.Data,
00031
ProcessMouseInput,
00032
NULL
00033 },
00034
00035 {
00036
sizeof(
GENERIC_DEVICE_INFO)+
sizeof(
KEYBOARD_DEVICE_INFO),
00037 &GUID_CLASS_KEYBOARD,
00038
PMAP_KBDCLASS_PARAMS,
00039
L"kbdclass",
00040 DD_KEYBOARD_DEVICE_NAME_U
L"0",
00041 DD_KEYBOARD_DEVICE_NAME_U
L"Legacy0",
00042 IOCTL_KEYBOARD_QUERY_ATTRIBUTES,
00043 FIELD_OFFSET(
DEVICEINFO, keyboard.Attr),
00044
sizeof((
PDEVICEINFO)
NULL)->keyboard.Attr,
00045 FIELD_OFFSET(
DEVICEINFO, keyboard.Data),
00046
sizeof((
PDEVICEINFO)
NULL)->keyboard.Data,
00047
ProcessKeyboardInput,
00048
NULL
00049 },
00050
00051 };
00052
00053
#ifdef DIAGNOSE_IO
00054 NTSTATUS gKbdIoctlLEDSStatus = -1;
00055
#endif
00056
00057 typedef struct _CDROM_NOTIFY {
00058 LIST_ENTRY
Entry;
00059 ULONG
Size;
00060 PVOID
RegistrationHandle;
00061 ULONG
Event;
00062
00063 MOUNTMGR_DRIVE_LETTER_TARGET
DeviceName;
00064 }
CDROM_NOTIFY, *
PCDROM_NOTIFY;
00065
00066 LIST_ENTRY
gMediaChangeList;
00067 PFAST_MUTEX gMediaChangeMutex;
00068 HANDLE
gpEventMediaChange =
NULL;
00069 UCHAR
DriveLetterChange[26];
00070 #define EVENT_CDROM_MEDIA_ARRIVAL 1
00071 #define EVENT_CDROM_MEDIA_REMOVAL 2
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
NTSTATUS
00090 Win32kPnPDriverEntry(
00091 IN
PDRIVER_OBJECT DriverObject,
00092 IN PUNICODE_STRING pustrRegistryPath
00093 )
00094
00095 {
00096 TAGMSG2(DBGTAG_PNP,
00097
"Win32kPnPDriverEntry(DriverObject = %lx, pustrRegistryPath = %#p)",
00098 DriverObject, pustrRegistryPath);
00099
00100
00101
00102
00103
gpWin32kDriverObject = DriverObject;
00104
return STATUS_SUCCESS;
00105
00106 UNREFERENCED_PARAMETER(pustrRegistryPath);
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
VOID
00119 InitializeMediaChange(HANDLE hMediaRequestEvent)
00120 {
00121
if (!
gbRemoteSession) {
00122
00123 InitializeListHead(&
gMediaChangeList);
00124
00125
ObReferenceObjectByHandle(hMediaRequestEvent,
00126 EVENT_ALL_ACCESS,
00127 *
ExEventObjectType,
00128
KernelMode,
00129 &
gpEventMediaChange,
00130
NULL);
00131
00132
gMediaChangeMutex = UserAllocPoolNonPaged(
sizeof(
FAST_MUTEX), TAG_PNP);
00133
00134
if (
gMediaChangeMutex) {
00135
ExInitializeFastMutex(
gMediaChangeMutex);
00136 }
00137 }
00138
00139
return;
00140 }
00141
00142 __inline
VOID EnterMediaCrit() {
00143
KeEnterCriticalRegion();
00144
ExAcquireFastMutexUnsafe(
gMediaChangeMutex);
00145 }
00146
00147 __inline
VOID LeaveMediaCrit() {
00148
ExReleaseFastMutexUnsafe(
gMediaChangeMutex);
00149
KeLeaveCriticalRegion();
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 ULONG
GetDeviceChangeInfo()
00163 {
00164 UNICODE_STRING name;
00165
PFILE_OBJECT FileObject;
00166
PDEVICE_OBJECT DeviceObject;
00167
KEVENT event;
00168
PIRP irp;
00169 MOUNTMGR_DRIVE_LETTER_INFORMATION output;
00170 IO_STATUS_BLOCK ioStatus;
00171
NTSTATUS status;
00172
PCDROM_NOTIFY pContext = 0;
00173
00174 ULONG retval = 0;
00175
00176
if (!(
ISCSRSS())) {
00177
return 0;
00178 }
00179
00180
EnterMediaCrit();
00181
if (!IsListEmpty(&
gMediaChangeList)) {
00182 pContext = (
PCDROM_NOTIFY) RemoveTailList(&
gMediaChangeList);
00183 }
00184
LeaveMediaCrit();
00185
00186
if (pContext ==
NULL) {
00187
return 0;
00188 }
00189
00190
RtlInitUnicodeString(&name, MOUNTMGR_DEVICE_NAME);
00191 status =
IoGetDeviceObjectPointer(&name,
00192 FILE_READ_ATTRIBUTES,
00193 &FileObject,
00194 &DeviceObject);
00195
00196
if (
NT_SUCCESS(status)) {
00197
00198
KeInitializeEvent(&event, NotificationEvent,
FALSE);
00199 irp =
IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER,
00200 DeviceObject,
00201 &pContext->
DeviceName,
00202
sizeof(MOUNTMGR_DRIVE_LETTER_TARGET) +
00203 pContext->
DeviceName.DeviceNameLength,
00204 &output,
00205
sizeof(output),
00206
FALSE,
00207 &event,
00208 &ioStatus);
00209
if (irp) {
00210
00211 status =
IoCallDriver(DeviceObject, irp);
00212
if (status == STATUS_PENDING) {
00213
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
00214 status = ioStatus.Status;
00215 }
00216
if ((status == STATUS_SUCCESS) &&
00217 (output.CurrentDriveLetter)) {
00218
00219 UserAssert((output.CurrentDriveLetter -
'A') < 30);
00220
00221 retval = 1 << (output.CurrentDriveLetter -
'A');
00222
00223
if (pContext->
Event &
EVENT_CDROM_MEDIA_ARRIVAL) {
00224 retval |= 0x80000000;
00225 }
00226 }
00227 }
00228
00229
ObDereferenceObject(FileObject);
00230 }
00231
00232
00233
00234
00235
00236 UserFreePool(pContext);
00237
00238
return retval;
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248 NTSTATUS DeviceCDROMNotify(
00249 IN
PTARGET_DEVICE_CUSTOM_NOTIFICATION Notification,
00250 IN PCDROM_NOTIFY pContext)
00251 {
00252
PCDROM_NOTIFY pNew;
00253
00254
CheckCritOut();
00255
00256 UserAssert(!
gbRemoteSession);
00257 UserAssert(pContext);
00258
00259
if (IsEqualGUID(&Notification->Event, &GUID_IO_MEDIA_ARRIVAL))
00260 {
00261 pContext->Event =
EVENT_CDROM_MEDIA_ARRIVAL;
00262 }
00263
else if (IsEqualGUID(&Notification->Event, &GUID_IO_MEDIA_REMOVAL))
00264 {
00265 pContext->Event =
EVENT_CDROM_MEDIA_REMOVAL;
00266 }
00267
else if (IsEqualGUID(&Notification->Event, &GUID_TARGET_DEVICE_REMOVE_COMPLETE))
00268 {
00269
IoUnregisterPlugPlayNotification(pContext->RegistrationHandle);
00270 UserFreePool(pContext);
00271
return STATUS_SUCCESS;
00272 }
00273
else
00274 {
00275
return STATUS_SUCCESS;
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 pNew = UserAllocPoolNonPaged(pContext->Size, TAG_PNP);
00287
if (pNew)
00288 {
00289 RtlCopyMemory(pNew, pContext, pContext->
Size);
00290
00291
EnterMediaCrit();
00292 InsertHeadList(&
gMediaChangeList, &pNew->
Entry);
00293
LeaveMediaCrit();
00294
00295
KeSetEvent(
gpEventMediaChange,
EVENT_INCREMENT,
FALSE);
00296 }
00297
00298
return STATUS_SUCCESS;
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
NTSTATUS
00310 DeviceClassCDROMNotify (
00311 IN
PDEVICE_INTERFACE_CHANGE_NOTIFICATION classChange,
00312 IN PVOID Unused
00313 )
00314 {
00315
NTSTATUS Status = STATUS_SUCCESS;
00316
PFILE_OBJECT FileObject;
00317
PDEVICE_OBJECT DeviceObject;
00318
PCDROM_NOTIFY pContext;
00319 ULONG
Size;
00320
00321 UNREFERENCED_PARAMETER(Unused);
00322
00323
CheckCritOut();
00324
00325
00326
00327
00328 UserAssert(IsEqualGUID(&classChange->InterfaceClassGuid, &CdRomClassGuid));
00329
00330
if (IsEqualGUID(&classChange->Event, &GUID_DEVICE_INTERFACE_ARRIVAL)) {
00331
00332
Status =
IoGetDeviceObjectPointer(classChange->SymbolicLinkName,
00333 FILE_READ_ATTRIBUTES,
00334 &FileObject,
00335 &DeviceObject);
00336
00337
if (
NT_SUCCESS(
Status)) {
00338
00339
Size =
sizeof(
CDROM_NOTIFY) + classChange->SymbolicLinkName->Length;
00340
00341 pContext = (
PCDROM_NOTIFY) UserAllocPool(
Size, TAG_PNP);
00342
00343
00344
00345
00346
00347
if (pContext) {
00348
00349 pContext->
Size =
Size;
00350 pContext->
DeviceName.DeviceNameLength = classChange->SymbolicLinkName->Length;
00351 RtlCopyMemory(pContext->
DeviceName.DeviceName,
00352 classChange->SymbolicLinkName->Buffer,
00353 pContext->
DeviceName.DeviceNameLength);
00354
00355
IoRegisterPlugPlayNotification (
00356
EventCategoryTargetDeviceChange,
00357 0,
00358 FileObject,
00359
gpWin32kDriverObject,
00360
DeviceCDROMNotify,
00361 pContext,
00362 &(pContext->
RegistrationHandle));
00363 }
00364
00365
ObDereferenceObject(FileObject);
00366 }
00367
00368 }
else if (IsEqualGUID(&classChange->Event, &GUID_DEVICE_INTERFACE_REMOVAL)) {
00369
00370
00371
00372
00373
00374 }
else {
00375 RIPMSG0(RIP_ERROR,
"unrecognized Event GUID");
00376 }
00377
00378
00379
return STATUS_SUCCESS;
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 PDEVICEINFO CreateDeviceInfo(DWORD DeviceType, PUNICODE_STRING pustrName, BYTE bFlags)
00407 {
00408
PDEVICEINFO pDeviceInfo =
NULL;
00409
00410
CheckCritIn();
00411
BEGINATOMICCHECK();
00412
00413 UserAssert(pustrName !=
NULL);
00414
00415 TAGMSG3(DBGTAG_PNP,
"CreateDeviceInfo(%d, %S, %x)", DeviceType, pustrName->Buffer, bFlags);
00416
00417
if (DeviceType >
DEVICE_TYPE_MAX) {
00418 RIPMSG1(RIP_ERROR,
"Unknown DeviceType %lx", DeviceType);
00419 }
00420
00421 pDeviceInfo = UserAllocPoolZInit(
aDeviceTemplate[DeviceType].cbDeviceInfo, TAG_PNP);
00422
if (pDeviceInfo ==
NULL) {
00423 RIPMSG0(RIP_WARNING,
"CreateDeviceInfo() out of memory allocating DEVICEINFO");
00424
EXITATOMICCHECK();
00425
return NULL;
00426 }
00427
00428
if (pustrName->Buffer !=
NULL) {
00429 pDeviceInfo->ustrName.Buffer = UserAllocPool(pustrName->Length, TAG_PNP);
00430
00431
if (pDeviceInfo->ustrName.Buffer ==
NULL) {
00432 RIPMSG1(RIP_WARNING,
"CreateDeviceInfo: Can't duplicate string %ws",
00433 pustrName->Buffer);
00434
goto CreateFailed;
00435 }
00436
00437 pDeviceInfo->ustrName.MaximumLength = pustrName->Length;
00438
RtlCopyUnicodeString(&pDeviceInfo->ustrName, pustrName);
00439 }
00440
00441 pDeviceInfo->type = (
BYTE)DeviceType;
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452 pDeviceInfo->pkeHidChangeCompleted =
CreateKernelEvent(SynchronizationEvent,
FALSE);
00453
if (pDeviceInfo->pkeHidChangeCompleted ==
NULL) {
00454 RIPMSG0(RIP_WARNING,
00455
"CreateDeviceInfo: failed to create pkeHidChangeCompleted");
00456
goto CreateFailed;
00457 }
00458
00459
00460
00461
00462
EnterDeviceInfoListCrit();
00463 pDeviceInfo->pNext =
gpDeviceInfoList;
00464
gpDeviceInfoList = pDeviceInfo;
00465 pDeviceInfo->bFlags |= bFlags;
00466
00467
00468
00469
00470
00471
RequestDeviceChange(pDeviceInfo,
GDIAF_ARRIVED,
TRUE);
00472
LeaveDeviceInfoListCrit();
00473
00474
EXITATOMICCHECK();
00475
return pDeviceInfo;
00476
00477 CreateFailed:
00478
00479
if (pDeviceInfo) {
00480
if (pDeviceInfo->ustrName.Buffer) {
00481 UserFreePool(pDeviceInfo->ustrName.Buffer);
00482 }
00483 UserFreePool(pDeviceInfo);
00484 }
00485
00486
ENDATOMICCHECK();
00487
return NULL;
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
NTSTATUS
00503 DeviceClassNotify (
00504 IN
PDEVICE_INTERFACE_CHANGE_NOTIFICATION classChange,
00505 IN PVOID DeviceType
00506 )
00507 {
00508
DWORD dwDeviceType;
00509
00510
CheckCritOut();
00511 dwDeviceType = PtrToUlong( DeviceType );
00512 TAGMSG2(DBGTAG_PNP,
"enter DeviceClassNotify(%lx, %lx)", classChange, dwDeviceType);
00513
00514
00515
00516
00517 UserAssert((dwDeviceType ==
DEVICE_TYPE_MOUSE) || (dwDeviceType ==
DEVICE_TYPE_KEYBOARD));
00518 UserAssert(IsEqualGUID(&classChange->InterfaceClassGuid,
aDeviceTemplate[dwDeviceType].
pClassGUID));
00519
00520
00521 TAGMSG3(DBGTAG_PNP | RIP_THERESMORE,
" Event GUID %lx, %x, %x",
00522 classChange->Event.Data1,
00523 classChange->Event.Data2,
00524 classChange->Event.Data3);
00525 TAGMSG8(DBGTAG_PNP | RIP_THERESMORE,
" %2x%2x%2x%2x%2x%2x%2x%2x",
00526 classChange->Event.Data4[0], classChange->Event.Data4[1],
00527 classChange->Event.Data4[2], classChange->Event.Data4[3],
00528 classChange->Event.Data4[4], classChange->Event.Data4[5],
00529 classChange->Event.Data4[6], classChange->Event.Data4[7]);
00530 TAGMSG4(DBGTAG_PNP | RIP_THERESMORE,
" InterfaceClassGuid %lx, %lx, %lx, %lx",
00531 ((
DWORD *)&(classChange->InterfaceClassGuid))[0],
00532 ((
DWORD *)&(classChange->InterfaceClassGuid))[1],
00533 ((
DWORD *)&(classChange->InterfaceClassGuid))[2],
00534 ((
DWORD *)&(classChange->InterfaceClassGuid))[3]);
00535 TAGMSG1(DBGTAG_PNP | RIP_THERESMORE,
" SymbolicLinkName %ws", classChange->SymbolicLinkName->Buffer);
00536
00537
if (IsEqualGUID(&classChange->Event, &GUID_DEVICE_INTERFACE_ARRIVAL)) {
00538
00539
00540
EnterCrit();
00541
CreateDeviceInfo(dwDeviceType, classChange->SymbolicLinkName, 0);
00542
LeaveCrit();
00543 TAGMSG0(DBGTAG_PNP,
"=== CREATED ===");
00544 }
00545
00546
return STATUS_SUCCESS;
00547 }
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
BOOL
00565 OpenMultiplePortDevice(DWORD DeviceType)
00566 {
00567 WCHAR awchDeviceName[
MAX_PATH];
00568 UNICODE_STRING DeviceName;
00569
PDEVICE_TEMPLATE pDevTpl;
00570
PDEVICEINFO pDeviceInfo;
00571 PWCHAR pwchNameIndex;
00572
00573
UINT uiConnectMultiplePorts = 0;
00574
00575
CheckCritIn();
00576
00577
if (DeviceType <=
DEVICE_TYPE_MAX) {
00578 pDevTpl = &
aDeviceTemplate[DeviceType];
00579 }
else {
00580 RIPMSG1(RIP_ERROR,
"OpenMultiplePortDevice(%d) - unknown type", DeviceType);
00581
return FALSE;
00582 }
00583
00584
00585
00586
00587
00588
00589 uiConnectMultiplePorts =
FastGetProfileDwordW(
NULL,
00590 pDevTpl->
uiRegistrySection,
L"ConnectMultiplePorts", 0);
00591
00592
00593
00594
00595
if (uiConnectMultiplePorts || (
gpWin32kDriverObject ==
NULL)) {
00596
00597
00598
00599
00600
00601
FastGetProfileStringW(
NULL,
00602
PMAP_INPUT,
00603 pDevTpl->
pwszClassName,
00604 pDevTpl->
pwszDefDevName,
00605 awchDeviceName,
00606
sizeof(awchDeviceName)/
sizeof(WCHAR));
00607
00608
RtlInitUnicodeString(&DeviceName, awchDeviceName);
00609
00610 pDeviceInfo =
CreateDeviceInfo(DeviceType, &DeviceName,
GDIF_NOTPNP);
00611
if (pDeviceInfo) {
00612
return TRUE;
00613 }
00614 }
else {
00615 DeviceName.Length = 0;
00616 DeviceName.MaximumLength =
sizeof(awchDeviceName);
00617 DeviceName.Buffer = awchDeviceName;
00618
00619
RtlAppendUnicodeToString(&DeviceName, pDevTpl->
pwszLegacyDevName);
00620 pwchNameIndex = &DeviceName.Buffer[(DeviceName.Length /
sizeof(WCHAR)) - 1];
00621
for (*pwchNameIndex =
L'0'; *pwchNameIndex <=
L'9'; (*pwchNameIndex)++) {
00622
CreateDeviceInfo(DeviceType, &DeviceName,
GDIF_NOTPNP);
00623 }
00624 }
00625
00626
return FALSE;
00627 }
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
NTSTATUS
00639 xxxRegisterForDeviceClassNotifications()
00640 {
00641
IO_NOTIFICATION_EVENT_CATEGORY eventCategory;
00642 ULONG eventFlags;
00643 PVOID RegistrationEntry;
00644
NTSTATUS Status;
00645 UNICODE_STRING ustrDriverName;
00646
DWORD DeviceType;
00647
00648
00649
00650
CheckCritIn();
00651
00652 TAGMSG0(DBGTAG_PNP,
"enter xxxRegisterForDeviceClassNotifications()");
00653
00654
00655
00656
00657 UserAssert(!
gbRemoteSession);
00658
00659
00660
00661
00662
00663
RtlInitUnicodeString(&ustrDriverName,
L"\\Driver\\Win32k");
00664
Status =
IoCreateDriver(&ustrDriverName,
Win32kPnPDriverEntry);
00665
00666 TAGMSG1(DBGTAG_PNP | RIP_THERESMORE,
"IoCreateDriver returned status = %lx",
Status);
00667 TAGMSG1(DBGTAG_PNP,
"gpWin32kDriverObject = %lx",
gpWin32kDriverObject);
00668
00669
if (!
NT_SUCCESS(
Status)) {
00670 RIPMSG1(RIP_ERROR,
"IoCreateDriver failed, status %lx",
Status);
00671
Status = STATUS_SUCCESS;
00672 }
00673
00674 UserAssert(
gpWin32kDriverObject);
00675
00676
00677
00678
00679 eventCategory =
EventCategoryDeviceInterfaceChange;
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689 eventFlags =
PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES;
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
for (DeviceType = 0; DeviceType <=
DEVICE_TYPE_MAX; DeviceType++) {
00701
if (!
OpenMultiplePortDevice(DeviceType)) {
00702
00703
00704
00705
00706 TAGMSG1(DBGTAG_PNP,
"Registering device type %d", DeviceType);
00707
LeaveCrit();
00708
Status =
IoRegisterPlugPlayNotification (
00709 eventCategory,
00710 eventFlags,
00711 (PVOID)
aDeviceTemplate[DeviceType].pClassGUID,
00712
gpWin32kDriverObject,
00713 (
PDRIVER_NOTIFICATION_CALLBACK_ROUTINE)
DeviceClassNotify,
00714 LongToPtr( DeviceType ),
00715 &RegistrationEntry);
00716
EnterCrit();
00717 TAGMSG1(DBGTAG_PNP,
"Registration returned status %lx",
Status);
00718
if (!
NT_SUCCESS(
Status)) {
00719 RIPMSG2(RIP_ERROR,
"IoRegisterPlugPlayNotification(%d) failed, status %lx",
00720 DeviceType,
Status);
00721 }
00722 }
00723 }
00724
00725
00726
LeaveCrit();
00727
00728
Status =
IoRegisterPlugPlayNotification (
00729 eventCategory,
00730 eventFlags,
00731 (PVOID) &CdRomClassGuid,
00732
gpWin32kDriverObject,
00733 (
PDRIVER_NOTIFICATION_CALLBACK_ROUTINE)
DeviceClassCDROMNotify,
00734
NULL,
00735 &RegistrationEntry);
00736
EnterCrit();
00737
00738
00739
00740
return Status;
00741 }
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
NTSTATUS
00761 QueryDeviceInfo(
00762
PDEVICEINFO pDeviceInfo)
00763 {
00764
NTSTATUS Status;
00765
PDEVICE_TEMPLATE pDevTpl = &
aDeviceTemplate[pDeviceInfo->type];
00766
00767
#ifdef DIAGNOSE_IO
00768
pDeviceInfo->AttrStatus =
00769
#endif
00770
Status = ZwDeviceIoControlFile(pDeviceInfo->handle,
NULL,
NULL,
NULL,
00771 &pDeviceInfo->iosb,
00772 pDevTpl->
IOCTL_Attr,
00773
NULL, 0,
00774 (PVOID)((
PBYTE)pDeviceInfo + pDevTpl->
offAttr),
00775 pDevTpl->
cbAttr);
00776
00777
if (!
NT_SUCCESS(
Status)) {
00778 RIPMSG2(RIP_WARNING,
"QueryDeviceInfo(%p): IOCTL failed - Status %lx",
00779 pDeviceInfo,
Status);
00780 }
00781 TAGMSG1(DBGTAG_PNP,
"IOCTL_*_QUERY_ATTRIBUTES returns Status %lx",
Status);
00782
return Status;
00783 }
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807 BOOL OpenDevice(
PDEVICEINFO pDeviceInfo)
00808 {
00809 OBJECT_ATTRIBUTES
ObjectAttributes;
00810
NTSTATUS Status;
00811
00812
CheckCritIn();
00813 UserAssert((
PtiCurrentShared() ==
gptiRit) || (
PtiCurrentShared() ==
gTermIO.
ptiDesktop));
00814
00815 TAGMSG3(DBGTAG_PNP,
"OpenDevice(): Opening type %d (%lx %ws)",
00816 pDeviceInfo->type, pDeviceInfo->handle, pDeviceInfo->ustrName.Buffer);
00817
00818
#ifdef DIAGNOSE_IO
00819
pDeviceInfo->OpenerProcess =
PsGetCurrentThread()->Cid.UniqueProcess;
00820
#endif
00821
00822
if (
gbRemoteSession) {
00823
00824
00825
00826
00827
00828 UserAssert(pDeviceInfo->ustrName.Buffer ==
NULL);
00829
00830 pDeviceInfo->bFlags |=
GDIF_NOTPNP;
00831
00832
switch (pDeviceInfo->type) {
00833
case DEVICE_TYPE_MOUSE:
00834 pDeviceInfo->handle =
ghRemoteMouseChannel;
00835
if (
ghRemoteMouseChannel ==
NULL) {
00836
return FALSE;
00837 }
00838
break;
00839
case DEVICE_TYPE_KEYBOARD:
00840 pDeviceInfo->handle =
ghRemoteKeyboardChannel;
00841
if (
ghRemoteKeyboardChannel ==
NULL) {
00842
return FALSE;
00843 }
00844
break;
00845
default:
00846 RIPMSG2(RIP_ERROR,
"Unknown device type %d DeviceInfo %#p",
00847 pDeviceInfo->type, pDeviceInfo);
00848
return FALSE;
00849 }
00850 }
else {
00851 InitializeObjectAttributes(&
ObjectAttributes, &(pDeviceInfo->ustrName), 0,
NULL,
NULL);
00852
00853
#ifdef DIAGNOSE_IO
00854
pDeviceInfo->OpenStatus =
00855
#endif
00856
Status =
ZwCreateFile(&pDeviceInfo->handle, FILE_READ_DATA | SYNCHRONIZE,
00857 &
ObjectAttributes, &pDeviceInfo->iosb,
NULL, 0, FILE_SHARE_WRITE, FILE_OPEN_IF, 0,
NULL, 0);
00858
00859 TAGMSG2(DBGTAG_PNP,
"ZwCreateFile returns handle %lx, Status %lx",
00860 pDeviceInfo->handle,
Status);
00861
00862
if (!
NT_SUCCESS(
Status)) {
00863
if ((pDeviceInfo->bFlags &
GDIF_NOTPNP) == 0) {
00864
00865
00866
00867
00868 RIPMSG1(RIP_WARNING,
"OpenDevice: ZwCreateFile failed with Status %lx",
Status);
00869 }
00870
00871
00872
00873
00874
00875
return FALSE;
00876 }
00877 }
00878
00879
Status =
QueryDeviceInfo(pDeviceInfo);
00880
00881
00882
return NT_SUCCESS(
Status);
00883 }
00884
00885 VOID CloseDevice(
PDEVICEINFO pDeviceInfo)
00886 {
00887
NTSTATUS Status;
00888 IO_STATUS_BLOCK IoStatusBlock;
00889
CheckCritIn();
00890
00891
00892 TAGMSG3(DBGTAG_PNP,
"CloseDevice(): closing type %d (%lx %ws)",
00893 pDeviceInfo->type, pDeviceInfo->handle, pDeviceInfo->ustrName.Buffer);
00894
if (pDeviceInfo->handle) {
00895 UserAssert(pDeviceInfo->OpenerProcess ==
PsGetCurrentThread()->Cid.UniqueProcess);
00896 ZwCancelIoFile(pDeviceInfo->handle, &IoStatusBlock);
00897 UserAssertMsg2(
NT_SUCCESS(IoStatusBlock.Status),
"NtCancelIoFile handle %x failed status %#x",
00898 pDeviceInfo->handle, IoStatusBlock.Status);
00899
Status = ZwClose(pDeviceInfo->handle);
00900 UserAssertMsg2(
NT_SUCCESS(
Status),
"ZwClose handle %x failed status %#x",
00901 pDeviceInfo->handle,
Status);
00902 pDeviceInfo->handle = 0;
00903 }
else {
00904
00905
00906
00907
00908 UserAssert((pDeviceInfo->iosb.Status == STATUS_CANCELLED) ||
00909 (pDeviceInfo->ReadStatus == STATUS_INVALID_HANDLE));
00910 }
00911 }
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 BOOL RegisterForDeviceChangeNotifications(
PDEVICEINFO pDeviceInfo)
00930 {
00931
PFILE_OBJECT pFileObject;
00932
NTSTATUS Status;
00933
00934
00935
00936
00937
00938
00939
CheckCritIn();
00940 UserAssert((
PtiCurrentShared() ==
gptiRit) || (
PtiCurrentShared() ==
gTermIO.
ptiDesktop));
00941 UserAssert(pDeviceInfo->handle);
00942 UserAssert(pDeviceInfo->OpenerProcess ==
PsGetCurrentThread()->Cid.UniqueProcess);
00943
00944
if (pDeviceInfo->bFlags &
GDIF_NOTPNP) {
00945
return TRUE;
00946 }
00947
Status =
ObReferenceObjectByHandle(pDeviceInfo->handle,
00948 0,
00949
NULL,
00950
KernelMode,
00951 (PVOID)&pFileObject,
00952
NULL);
00953
if (
NT_SUCCESS(
Status)) {
00954
Status =
IoRegisterPlugPlayNotification (
00955
EventCategoryTargetDeviceChange,
00956 0,
00957 (PVOID)pFileObject,
00958
gpWin32kDriverObject,
00959
00960
DeviceNotify,
00961 (PVOID)pDeviceInfo,
00962 &pDeviceInfo->NotificationEntry);
00963
ObDereferenceObject(pFileObject);
00964
if (!
NT_SUCCESS(
Status)) {
00965
00966 RIPMSG3(RIP_ERROR,
00967
"IoRegisterPlugPlayNotification failed on device %.*ws, status %lx, email DoronH : #333453",
00968 pDeviceInfo->ustrName.Length /
sizeof(WCHAR),
00969 pDeviceInfo->ustrName.Buffer,
Status);
00970 }
00971 }
else {
00972
00973 RIPMSG2(RIP_ERROR,
"Can't get pFileObject from handle %lx, status %lx",
00974 pDeviceInfo->handle,
Status);
00975 }
00976
00977
return NT_SUCCESS(
Status);
00978 }
00979
00980
00981 BOOL UnregisterForDeviceChangeNotifications(
PDEVICEINFO pDeviceInfo)
00982 {
00983
NTSTATUS Status;
00984
00985
CheckCritIn();
00986 UserAssert((
PtiCurrentShared() ==
gptiRit) || (
PtiCurrentShared() ==
gTermIO.
ptiDesktop));
00987 UserAssert(pDeviceInfo->NotificationEntry);
00988 UserAssert(pDeviceInfo->OpenerProcess ==
PsGetCurrentThread()->Cid.UniqueProcess);
00989
00990
if (pDeviceInfo->NotificationEntry ==
NULL) {
00991
00992
00993
00994
00995
00996
return TRUE;
00997 }
00998
00999
01000 UserAssert((pDeviceInfo->bFlags &
GDIF_NOTPNP) == 0);
01001
01002 TAGMSG3(DBGTAG_PNP,
"UnregisterForDeviceChangeNotifications(): type %d (%lx %ws)",
01003 pDeviceInfo->type, pDeviceInfo, pDeviceInfo->ustrName.Buffer);
01004
Status =
IoUnregisterPlugPlayNotification(pDeviceInfo->NotificationEntry);
01005
if (!
NT_SUCCESS(
Status)) {
01006 RIPMSG2(RIP_ERROR,
01007
"IoUnregisterPlugPlayNotification failed Status = %lx, DEVICEINFO %lx",
01008
Status, pDeviceInfo);
01009
return FALSE;
01010 }
01011 pDeviceInfo->NotificationEntry = 0;
01012
return TRUE;
01013 }
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025 NTSTATUS DeviceNotify(
01026 IN PPLUGPLAY_NOTIFY_HDR pNotification,
01027 IN
PDEVICEINFO pDeviceInfo)
01028 {
01029
USHORT usAction;
01030
01031
#if DBG
01032
{
01033
PDEVICEINFO pDeviceInfoDbg;
01034
for (pDeviceInfoDbg =
gpDeviceInfoList; pDeviceInfoDbg; pDeviceInfoDbg = pDeviceInfoDbg->pNext) {
01035
if (pDeviceInfoDbg == pDeviceInfo) {
01036
break;
01037 }
01038 }
01039 UserAssertMsg1(pDeviceInfoDbg !=
NULL,
"Notification for unlisted DEVICEINFO %lx", pDeviceInfo);
01040 }
01041
#endif
01042
01043
CheckCritOut();
01044
01045 UserAssert(!
gbRemoteSession);
01046
01047 TAGMSG1(DBGTAG_PNP | RIP_THERESMORE,
"DeviceNotify >>> %lx", pDeviceInfo);
01048
01049 UserAssert(pDeviceInfo->OpenerProcess !=
PsGetCurrentThread()->Cid.UniqueProcess);
01050 UserAssert(pDeviceInfo->usActions == 0);
01051
01052
if (IsEqualGUID(&pNotification->Event, &GUID_TARGET_DEVICE_QUERY_REMOVE)) {
01053 TAGMSG0(DBGTAG_PNP | RIP_NONAME,
"QueryRemove");
01054 usAction =
GDIAF_QUERYREMOVE;
01055
01056 }
else if (IsEqualGUID(&pNotification->Event, &GUID_TARGET_DEVICE_REMOVE_CANCELLED)) {
01057 TAGMSG0(DBGTAG_PNP | RIP_NONAME,
"RemoveCancelled");
01058 usAction =
GDIAF_REMOVECANCELLED;
01059
01060 }
else if (IsEqualGUID(&pNotification->Event, &GUID_TARGET_DEVICE_REMOVE_COMPLETE)) {
01061 TAGMSG1(DBGTAG_PNP | RIP_NONAME,
"RemoveComplete (process %#x)",
PsGetCurrentThread()->Cid.UniqueProcess);
01062 usAction =
GDIAF_DEPARTED;
01063
01064 }
else {
01065 TAGMSG4(DBGTAG_PNP | RIP_NONAME,
"GUID Unknown: %lx:%lx:%lx:%x...",
01066 pNotification->Event.Data1, pNotification->Event.Data2,
01067 pNotification->Event.Data3, pNotification->Event.Data4[0]);
01068
return STATUS_UNSUCCESSFUL;
01069 }
01070
01071
01072
01073
01074
01075
CheckCritOut();
01076
CheckDeviceInfoListCritOut();
01077
RequestDeviceChange(pDeviceInfo, (
USHORT)(usAction |
GDIAF_PNPWAITING),
FALSE);
01078
01079
return STATUS_SUCCESS;
01080 }
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099 PDEVICEINFO StartDeviceRead(
01100
PDEVICEINFO pDeviceInfo)
01101 {
01102
PDEVICE_TEMPLATE pDevTpl;
01103
01104 pDeviceInfo->bFlags |=
GDIF_READING;
01105
01106
01107
01108
01109
if (pDeviceInfo->usActions &
GDIAF_FREEME) {
01110
BOOL fPreviouslyAcquired =
ExIsResourceAcquiredExclusiveLite(
gpresDeviceInfoList);
01111
if (!fPreviouslyAcquired) {
01112
EnterDeviceInfoListCrit();
01113 }
01114 pDeviceInfo->bFlags &= ~
GDIF_READING;
01115 pDeviceInfo =
FreeDeviceInfo(pDeviceInfo);
01116
if (!fPreviouslyAcquired) {
01117
LeaveDeviceInfoListCrit();
01118 }
01119
return pDeviceInfo;
01120 }
01121
01122
01123
01124
01125 pDeviceInfo->iosb.Status = STATUS_UNSUCCESSFUL;
01126 pDeviceInfo->iosb.Information = 0;
01127
01128 pDevTpl = &
aDeviceTemplate[pDeviceInfo->type];
01129
01130 UserAssert(pDeviceInfo->OpenerProcess ==
PsGetCurrentThread()->Cid.UniqueProcess);
01131
LOGTIME(pDeviceInfo->timeStartRead);
01132
#ifdef DIAGNOSE_IO
01133
pDeviceInfo->nReadsOutstanding++;
01134
#endif
01135
pDeviceInfo->ReadStatus = ZwReadFile(
01136 pDeviceInfo->handle,
01137
NULL,
01138
InputApc,
01139 pDeviceInfo,
01140 &pDeviceInfo->iosb,
01141 (PVOID)((
PBYTE)pDeviceInfo + pDevTpl->
offData),
01142 pDevTpl->
cbData,
01143
PZERO(LARGE_INTEGER),
NULL);
01144
LOGTIME(pDeviceInfo->timeEndRead);
01145
01146
#if DBG
01147
if (pDeviceInfo->bFlags &
GDIF_DBGREAD) {
01148 TAGMSG2(DBGTAG_PNP,
"ZwReadFile of Device handle %lx returned status %lx",
01149 pDeviceInfo->handle, pDeviceInfo->ReadStatus);
01150 }
01151
#endif
01152
01153
if (!
NT_SUCCESS(pDeviceInfo->ReadStatus)) {
01154
BOOL fPreviouslyAcquired =
ExIsResourceAcquiredExclusiveLite(
gpresDeviceInfoList);
01155
if (!fPreviouslyAcquired) {
01156
EnterDeviceInfoListCrit();
01157 }
01158
01159
01160
01161
01162
01163
01164
01165
if (pDeviceInfo->ReadStatus == STATUS_INSUFFICIENT_RESOURCES) {
01166
if (pDeviceInfo->nRetryRead++ <
MAXIMUM_READ_RETRIES) {
01167 pDeviceInfo->usActions |=
GDIAF_RETRYREAD;
01168
gnRetryReadInput++;
01169 }
01170 }
else {
01171 pDeviceInfo->bFlags &= ~
GDIF_READING;
01172 }
01173
01174
#ifdef DIAGNOSE_IO
01175
pDeviceInfo->nReadsOutstanding--;
01176
#endif
01177
if (!fPreviouslyAcquired) {
01178
LeaveDeviceInfoListCrit();
01179 }
01180 }
else {
01181 pDeviceInfo->nRetryRead = 0;
01182 }
01183
01184
if (!
ISTS() && !
NT_SUCCESS(pDeviceInfo->ReadStatus))
01185 RIPMSG2(RIP_WARNING,
"StartDeviceRead %#p failed Status %#x",
01186 pDeviceInfo, pDeviceInfo->ReadStatus);
01187
01188
return NULL;
01189 }
01190
01191 VOID ProcessDeviceChanges(DWORD DeviceType)
01192 {
01193
PDEVICEINFO pDeviceInfo;
01194
USHORT usOriginalActions;
01195
#if DBG
01196
int nChanges = 0;
01197 ULONG timeStartReadPrev;
01198
#endif
01199
01200
01201
01202
01203
DWORD nMice = 0;
01204
DWORD nWheels = 0;
01205
DWORD nMaxButtons = 0;
01206
int nKeyboards = 0;
01207
01208
CheckCritIn();
01209
BEGINATOMICCHECK();
01210 UserAssert((
PtiCurrentShared() ==
gptiRit) || (
PtiCurrentShared() ==
gTermIO.
ptiDesktop));
01211
01212
EnterDeviceInfoListCrit();
01213
BEGINATOMICDEVICEINFOLISTCHECK();
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225 pDeviceInfo =
gpDeviceInfoList;
01226
while (pDeviceInfo) {
01227
if (pDeviceInfo->type != DeviceType) {
01228 pDeviceInfo = pDeviceInfo->pNext;
01229
continue;
01230 }
01231
01232 usOriginalActions = pDeviceInfo->usActions;
01233 UserAssert((usOriginalActions == 0) || (usOriginalActions & ~
GDIAF_PNPWAITING));
01234
01235
01236
01237
01238
01239
01240
if (pDeviceInfo->usActions &
GDIAF_REFRESH_MOUSE) {
01241 pDeviceInfo->usActions &= ~
GDIAF_REFRESH_MOUSE;
01242
01243 UserAssert(pDeviceInfo->type ==
DEVICE_TYPE_MOUSE);
01244
#if DBG
01245
nChanges++;
01246
#endif
01247
TAGMSG1(DBGTAG_PNP,
"QueryDeviceInfo: %lx", pDeviceInfo);
01248
QueryDeviceInfo(pDeviceInfo);
01249 }
01250
01251
01252
01253
01254
01255
01256
if (pDeviceInfo->usActions &
GDIAF_QUERYREMOVE) {
01257 pDeviceInfo->usActions &= ~
GDIAF_QUERYREMOVE;
01258
#if DBG
01259
nChanges++;
01260
#endif
01261
TAGMSG1(DBGTAG_PNP,
"QueryRemove: %lx", pDeviceInfo);
01262
CloseDevice(pDeviceInfo);
01263 }
01264
01265
01266
01267
01268
01269
01270
if (pDeviceInfo->usActions & (
GDIAF_ARRIVED |
GDIAF_REMOVECANCELLED)) {
01271
01272
01273
if (pDeviceInfo->usActions &
GDIAF_REMOVECANCELLED) {
01274 pDeviceInfo->usActions &= ~
GDIAF_REMOVECANCELLED;
01275
#if DBG
01276
nChanges++;
01277
#endif
01278
TAGMSG1(DBGTAG_PNP,
"RemoveCancelled: %lx", pDeviceInfo);
01279
UnregisterForDeviceChangeNotifications(pDeviceInfo);
01280 }
01281
01282
#if DBG
01283
if (pDeviceInfo->usActions &
GDIAF_ARRIVED) {
01284 nChanges++;
01285 }
01286
#endif
01287
01288 pDeviceInfo->usActions &= ~
GDIAF_ARRIVED;
01289
if (
OpenDevice(pDeviceInfo)) {
01290
PDEVICEINFO pDeviceInfoNext;
01291
RegisterForDeviceChangeNotifications(pDeviceInfo);
01292
01293
if (!(
gbRemoteSession && (pDeviceInfo->usActions &
GDIAF_RECONNECT))) {
01294
01295 pDeviceInfoNext =
StartDeviceRead(pDeviceInfo);
01296
if (pDeviceInfoNext) {
01297
01298
01299
01300 pDeviceInfo = pDeviceInfoNext;
01301
continue;
01302 }
01303 }
01304 pDeviceInfo->usActions &= ~
GDIAF_RECONNECT;
01305
01306 }
else {
01307
01308
01309
01310
01311
01312
#if DBG
01313
if ((usOriginalActions &
GDIAF_ARRIVED) == 0) {
01314 RIPMSG2(RIP_WARNING,
"Re-Open %#p failed status %x during RemoveCancelled",
01315 pDeviceInfo, pDeviceInfo->OpenStatus);
01316 }
01317
#endif
01318
pDeviceInfo =
FreeDeviceInfo(pDeviceInfo);
01319
continue;
01320 }
01321 }
01322
01323
01324
01325
01326
01327
01328
01329
if (pDeviceInfo->usActions &
GDIAF_DEPARTED) {
01330 pDeviceInfo->usActions &= ~
GDIAF_DEPARTED;
01331
#if DBG
01332
nChanges++;
01333
#endif
01334
TAGMSG1(DBGTAG_PNP,
"RemoveComplete: %lx (process %#x)", pDeviceInfo);
01335
CloseDevice(pDeviceInfo);
01336
UnregisterForDeviceChangeNotifications(pDeviceInfo);
01337 pDeviceInfo =
FreeDeviceInfo(pDeviceInfo);
01338
continue;
01339 }
01340
01341
if (pDeviceInfo->usActions &
GDIAF_IME_STATUS) {
01342 pDeviceInfo->usActions &= ~
GDIAF_IME_STATUS;
01343
#if DBG
01344
nChanges++;
01345
#endif
01346
if ((pDeviceInfo->type ==
DEVICE_TYPE_KEYBOARD) && (pDeviceInfo->handle)) {
01347
if (FUJITSU_KBD_CONSOLE(pDeviceInfo->
keyboard.
Attr.KeyboardIdentifier) ||
01348 (
gbRemoteSession &&
01349 FUJITSU_KBD_REMOTE(
gRemoteClientKeyboardType))
01350 ) {
01351
01352
01353
01354 ZwDeviceIoControlFile(pDeviceInfo->handle,
NULL,
NULL,
NULL,
01355 &
giosbKbdControl, IOCTL_KEYBOARD_SET_IME_STATUS,
01356 (PVOID)&
gKbdImeStatus,
sizeof(
gKbdImeStatus),
NULL, 0);
01357 }
01358 }
01359 }
01360
01361
if (pDeviceInfo->usActions &
GDIAF_RETRYREAD) {
01362
PDEVICEINFO pDeviceInfoNext;
01363 pDeviceInfo->usActions &= ~
GDIAF_RETRYREAD;
01364 UserAssert(pDeviceInfo->ReadStatus == STATUS_INSUFFICIENT_RESOURCES);
01365
#if DBG
01366
timeStartReadPrev = pDeviceInfo->timeStartRead;
01367
#endif
01368
TAGMSG2(DBGTAG_PNP,
"Retry Read %#p after %lx ticks",
01369 pDeviceInfo, pDeviceInfo->timeStartRead - timeStartReadPrev);
01370 pDeviceInfoNext =
StartDeviceRead(pDeviceInfo);
01371
if (pDeviceInfoNext) {
01372
01373
01374
01375 pDeviceInfo = pDeviceInfoNext;
01376
continue;
01377 }
01378 }
01379
01380
01381
01382
01383
if (pDeviceInfo->handle) {
01384
switch (pDeviceInfo->type) {
01385
case DEVICE_TYPE_MOUSE:
01386 UserAssert(
PtiCurrentShared() ==
gTermIO.
ptiDesktop);
01387
if (pDeviceInfo->usActions &
GDIAF_REFRESH_MOUSE) {
01388 pDeviceInfo->usActions &= ~
GDIAF_REFRESH_MOUSE;
01389
#if DBG
01390
nChanges++;
01391
#endif
01392
}
01393 nMice++;
01394 nMaxButtons =
max(nMaxButtons, pDeviceInfo->
mouse.
Attr.NumberOfButtons);
01395
switch(pDeviceInfo->
mouse.
Attr.MouseIdentifier) {
01396
case WHEELMOUSE_I8042_HARDWARE:
01397
case WHEELMOUSE_SERIAL_HARDWARE:
01398
case WHEELMOUSE_HID_HARDWARE:
01399 nWheels++;
01400 }
01401
break;
01402
01403
case DEVICE_TYPE_KEYBOARD:
01404 UserAssert(
PtiCurrentShared() ==
gptiRit);
01405 {
01406
NTSTATUS Status;
01407
01408
01409
#ifdef DIAGNOSE_IO
01410
gKbdIoctlLEDSStatus =
01411
#endif
01412
Status = ZwDeviceIoControlFile(pDeviceInfo->handle,
NULL,
NULL,
NULL,
01413 &
giosbKbdControl, IOCTL_KEYBOARD_QUERY_INDICATORS,
01414
NULL, 0,
01415 (PVOID)&
gklpBootTime,
sizeof(
gklpBootTime));
01416 UserAssertMsg2(
NT_SUCCESS(
Status),
01417
"IOCTL_KEYBOARD_QUERY_INDICATORS failed: DeviceInfo %#x, Status %#x",
01418 pDeviceInfo,
Status);
01419
01420
01421
gKeyboardInfo = pDeviceInfo->
keyboard.
Attr;
01422 }
01423 nKeyboards++;
01424
break;
01425
01426
default:
01427
01428 RIPMSG2(RIP_ERROR,
"pDeviceInfo %#p has strange type %d",
01429 pDeviceInfo, pDeviceInfo->type);
01430
break;
01431 }
01432 }
01433
01434
01435
01436
01437
if (usOriginalActions &
GDIAF_PNPWAITING) {
01438
KeSetEvent(pDeviceInfo->pkeHidChangeCompleted,
EVENT_INCREMENT,
FALSE);
01439 }
01440
01441 pDeviceInfo = pDeviceInfo->pNext;
01442 }
01443
01444
ENDATOMICDEVICEINFOLISTCHECK();
01445
LeaveDeviceInfoListCrit();
01446
01447
01448
switch (DeviceType) {
01449
case DEVICE_TYPE_MOUSE:
01450
01451
01452
01453
if (nMice) {
01454
if (
gnMice == 0) {
01455
01456
01457
01458
SET_GTERMF(
GTERMF_MOUSE);
01459
SYSMET(MOUSEPRESENT) =
TRUE;
01460
SetGlobalCursorLevel(0);
01461 UserAssert(
PpiFromProcess(
gpepCSRSS)->ptiList->iCursorLevel == 0);
01462 UserAssert(
PpiFromProcess(
gpepCSRSS)->ptiList->pq->iCursorLevel == 0);
01463 GreMovePointer(
gpDispInfo->
hDev,
gpsi->ptCursor.x,
gpsi->ptCursor.y);
01464 }
01465 }
else {
01466
if (
gnMice != 0) {
01467
01468
01469
01470
CLEAR_GTERMF(
GTERMF_MOUSE);
01471
SYSMET(MOUSEPRESENT) =
FALSE;
01472
SetGlobalCursorLevel(-1);
01473
01474
01475
01476
01477
01478
#if DBG
01479
if (
gwMouseOwnerButton)
01480 RIPMSG1(RIP_WARNING,
01481
"gwMouseOwnerButton=%x, being cleared forcibly\n",
01482
gwMouseOwnerButton);
01483
#endif
01484
gwMouseOwnerButton = 0;
01485 }
01486 }
01487
01488
01489
01490
01491
SYSMET(CMOUSEBUTTONS) = nMaxButtons;
01492
SYSMET(MOUSEWHEELPRESENT) = (nWheels > 0);
01493
gnMice = nMice;
01494
break;
01495
01496
case DEVICE_TYPE_KEYBOARD:
01497
01498
01499
01500
01501
if (nKeyboards >
gnKeyboards) {
01502
01503
01504
01505
UpdateKeyLights(
FALSE);
01506 }
01507
01508
if ((nKeyboards != 0) && (
gnKeyboards == 0)) {
01509
01510
01511
01512
SetDebugHotKeys();
01513 }
01514
gnKeyboards = nKeyboards;
01515
break;
01516
01517
default:
01518
break;
01519 }
01520
01521
ENDATOMICCHECK();
01522 }
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535 VOID RequestDeviceChange(
01536
PDEVICEINFO pDeviceInfo,
01537 USHORT usAction,
01538 BOOL fInDeviceInfoListCrit)
01539 {
01540
PDEVICE_TEMPLATE pDevTpl = &
aDeviceTemplate[pDeviceInfo->type];
01541 UserAssert(pDevTpl->
pkeHidChange !=
NULL);
01542 UserAssert((usAction &
GDIAF_FREEME) == 0);
01543 UserAssert((pDeviceInfo->usActions &
GDIAF_PNPWAITING) == 0);
01544
01545
#if DBG
01546
if (pDeviceInfo->usActions != 0) {
01547 TAGMSG3(DBGTAG_PNP,
"RequestDeviceChange(%#p, %x), but action %x pending",
01548 pDeviceInfo, usAction, pDeviceInfo->usActions);
01549 }
01550
01551
01552
01553
01554
01555
01556
if (usAction &
GDIAF_PNPWAITING) {
01557
CheckDeviceInfoListCritOut();
01558
CheckCritOut();
01559 }
01560
#endif
01561
01562 TAGMSG2(DBGTAG_PNP,
"RequestDeviceChange(%p, %x)", pDeviceInfo, usAction);
01563
01564
01565
01566
01567 UserAssert(!fInDeviceInfoListCrit == !
ExIsResourceAcquiredExclusiveLite(
gpresDeviceInfoList));
01568
if (fInDeviceInfoListCrit) {
01569
CheckDeviceInfoListCritIn();
01570 pDeviceInfo->usActions |= usAction;
01571 }
else {
01572
EnterDeviceInfoListCrit();
01573 pDeviceInfo->usActions |= usAction;
01574
LeaveDeviceInfoListCrit();
01575 }
01576
01577
if (usAction &
GDIAF_PNPWAITING) {
01578
CheckDeviceInfoListCritOut();
01579
KeSetEvent(pDevTpl->
pkeHidChange,
EVENT_INCREMENT,
FALSE);
01580
KeWaitForSingleObject(pDeviceInfo->pkeHidChangeCompleted,
WrUserRequest,
KernelMode,
FALSE,
NULL);
01581
01582
EnterDeviceInfoListCrit();
01583
01584
01585
01586
01587 UserAssert(pDeviceInfo->usActions &
GDIAF_PNPWAITING);
01588 pDeviceInfo->usActions &= ~
GDIAF_PNPWAITING;
01589 UserAssert((pDeviceInfo->usActions & usAction) == 0);
01590
if (pDeviceInfo->usActions &
GDIAF_FREEME) {
01591
FreeDeviceInfo(pDeviceInfo);
01592 }
01593
LeaveDeviceInfoListCrit();
01594 }
else {
01595
KeSetEvent(pDevTpl->
pkeHidChange,
EVENT_INCREMENT,
FALSE);
01596 }
01597 }