00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "iop.h"
00021
#undef ExAllocatePool
00022
#undef ExAllocatePoolWithQuota
00023
#include "..\config\cmp.h"
00024
#include <string.h>
00025
#include <profiles.h>
00026
#include <wdmguid.h>
00027
00028
#if DBG
00029
00030
#define ASSERT_SEMA_NOT_SIGNALLED(SemaphoreObject) \
00031
ASSERT(KeReadStateSemaphore(SemaphoreObject) == 0) ;
00032
00033
#else // DBG
00034
00035 #define ASSERT_SEMA_NOT_SIGNALLED(SemaphoreObject)
00036
00037
#endif // DBG
00038
00039
00040
00041
00042
00043
NTSTATUS
00044
IopExecuteHardwareProfileChange(
00045 IN
HARDWARE_PROFILE_BUS_TYPE Bus,
00046 IN PWCHAR * ProfileSerialNumbers,
00047 IN ULONG SerialNumbersCount,
00048 OUT PHANDLE NewProfile,
00049 OUT PBOOLEAN ProfileChanged
00050 );
00051
00052
NTSTATUS
00053
IopUpdateHardwareProfile (
00054 OUT PBOOLEAN ProfileChanged
00055 );
00056
00057
VOID
00058
IopHardwareProfileSendCommit(
00059 VOID
00060 );
00061
00062
VOID
00063
IopHardwareProfileSendCancel(
00064 VOID
00065 );
00066
00067
00068
00069
00070
00071 LIST_ENTRY
IopDockDeviceListHead;
00072 ULONG
IopDockDeviceCount;
00073 FAST_MUTEX IopDockDeviceListLock;
00074 KSEMAPHORE IopProfileChangeSemaphore;
00075 BOOLEAN
IopProfileChangeCancelRequired;
00076 LONG
IopDocksInTransition;
00077
00078 typedef struct {
00079
00080 WORK_QUEUE_ITEM WorkItem;
00081 KEVENT NotificationCompleted ;
00082 LPGUID NotificationGuid ;
00083 NTSTATUS FinalStatus ;
00084 PPNP_VETO_TYPE VetoType ;
00085 PUNICODE_STRING VetoName ;
00086
00087 }
PROFILE_WORK_ITEM, *
PPROFILE_WORK_ITEM ;
00088
00089
#ifdef ALLOC_PRAGMA
00090
#pragma alloc_text(PAGE, IopHardwareProfileBeginTransition)
00091
#pragma alloc_text(PAGE, IopHardwareProfileMarkDock)
00092
#pragma alloc_text(PAGE, IopHardwareProfileQueryChange)
00093
#pragma alloc_text(PAGE, IopHardwareProfileCommitStartedDock)
00094
#pragma alloc_text(PAGE, IopHardwareProfileCommitRemovedDock)
00095
#pragma alloc_text(PAGE, IopHardwareProfileCancelRemovedDock)
00096
#pragma alloc_text(PAGE, IopHardwareProfileCancelTransition)
00097
#define alloc_text(PAGE, IopHardwareProfileSendCommit)
00098
#pragma alloc_text(PAGE, IopHardwareProfileSendCancel)
00099
#endif // ALLOC_PRAGMA
00100
00101
00102
VOID
00103 IopHardwareProfileBeginTransition(
00104 IN BOOLEAN SubsumeExistingDeparture
00105 )
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 {
00130
NTSTATUS status ;
00131
00132
if (SubsumeExistingDeparture) {
00133
00134
00135
00136
00137
00138
00139
ASSERT_SEMA_NOT_SIGNALLED(&
IopProfileChangeSemaphore) ;
00140
ASSERT(
IopDocksInTransition != 0) ;
00141
return ;
00142 }
00143
00144
00145
00146
00147
00148 status =
KeWaitForSingleObject(
00149 &
IopProfileChangeSemaphore,
00150
Executive,
00151
KernelMode,
00152
FALSE,
00153
NULL
00154 );
00155
00156
ASSERT(status == STATUS_SUCCESS) ;
00157 }
00158
00159
VOID
00160 IopHardwareProfileMarkDock(
00161
PDEVICE_NODE DeviceNode,
00162 PROFILE_STATUS ChangeInPresence
00163 )
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 {
00184 PWCHAR deviceSerialNumber;
00185
PDEVICE_OBJECT deviceObject;
00186
NTSTATUS status;
00187
00188
00189
00190
00191
00192
ASSERT_SEMA_NOT_SIGNALLED(&
IopProfileChangeSemaphore) ;
00193
ASSERT(DeviceNode->
DockInfo.DockStatus ==
DOCK_QUIESCENT) ;
00194
ASSERT((ChangeInPresence ==
DOCK_DEPARTING)||
00195 (ChangeInPresence ==
DOCK_ARRIVING)) ;
00196
00197
if (ChangeInPresence ==
DOCK_ARRIVING) {
00198
00199
00200
00201
00202
00203
00204
if (IsListEmpty(&DeviceNode->
DockInfo.ListEntry)) {
00205
00206
00207
00208
00209 ExAcquireFastMutex(&
IopDockDeviceListLock);
00210
00211
00212
00213
00214 InsertHeadList(&
IopDockDeviceListHead,
00215 &DeviceNode->
DockInfo.ListEntry);
00216
IopDockDeviceCount++;
00217
00218
00219
00220
00221 ExReleaseFastMutex(&
IopDockDeviceListLock);
00222 }
00223
00224
00225
00226
00227
00228
00229 deviceObject = DeviceNode->
PhysicalDeviceObject;
00230 status =
IopQueryDeviceSerialNumber(deviceObject,
00231 &deviceSerialNumber);
00232
00233
if (
NT_SUCCESS(status) && (deviceSerialNumber !=
NULL)) {
00234
00235
ExFreePool(deviceSerialNumber) ;
00236 }
00237
00238 }
else {
00239
00240
00241
00242
00243
ASSERT(!IsListEmpty(&DeviceNode->
DockInfo.ListEntry)) ;
00244 }
00245
00246 InterlockedIncrement(&
IopDocksInTransition) ;
00247 DeviceNode->
DockInfo.DockStatus = ChangeInPresence ;
00248 }
00249
00250
NTSTATUS
00251 IopHardwareProfileQueryChange(
00252 IN BOOLEAN SubsumingExistingDeparture,
00253 IN PROFILE_NOTIFICATION_TIME InPnpEvent,
00254 OUT PPNP_VETO_TYPE VetoType,
00255 OUT PUNICODE_STRING VetoName OPTIONAL
00256 )
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 {
00292
PROFILE_WORK_ITEM profileWorkItem;
00293
NTSTATUS status;
00294 BOOLEAN arrivingDockFound;
00295 PLIST_ENTRY listEntry ;
00296
PDEVICE_NODE devNode ;
00297
00298
ASSERT_SEMA_NOT_SIGNALLED(&
IopProfileChangeSemaphore) ;
00299
00300
00301
00302
00303
00304 ExAcquireFastMutex(&
IopDockDeviceListLock);
00305
00306
ASSERT(
IopDocksInTransition) ;
00307
00308 arrivingDockFound =
FALSE ;
00309
for (listEntry =
IopDockDeviceListHead.Flink;
00310 listEntry != &(
IopDockDeviceListHead);
00311 listEntry = listEntry->Flink ) {
00312
00313 devNode = CONTAINING_RECORD(listEntry,
00314
DEVICE_NODE,
00315 DockInfo.ListEntry);
00316
00317
ASSERT((devNode->
DockInfo.DockStatus !=
DOCK_NOTDOCKDEVICE)&&
00318 (devNode->
DockInfo.DockStatus !=
DOCK_EJECTIRP_COMPLETED)) ;
00319
00320
if (devNode->
DockInfo.DockStatus ==
DOCK_ARRIVING) {
00321
00322 arrivingDockFound =
TRUE ;
00323 }
00324 }
00325
00326
00327
00328
00329 ExReleaseFastMutex(&
IopDockDeviceListLock);
00330
00331
if (SubsumingExistingDeparture) {
00332
00333
ASSERT(
IopProfileChangeCancelRequired) ;
00334
00335
00336
00337
return STATUS_SUCCESS ;
00338 }
00339
00340
if (arrivingDockFound) {
00341
00342
00343
00344
00345
00346
00347
00348
IopProfileChangeCancelRequired =
FALSE ;
00349
return STATUS_SUCCESS ;
00350 }
00351
00352 PIDBGMSG(PIDBG_HWPROFILE, (
"NTOSKRNL: Sending HW profile change [query]\n")) ;
00353
00354 status =
IopRequestHwProfileChangeNotification(
00355 (LPGUID) &GUID_HWPROFILE_QUERY_CHANGE,
00356 InPnpEvent,
00357 VetoType,
00358 VetoName
00359 );
00360
00361
if (
NT_SUCCESS(status)) {
00362
IopProfileChangeCancelRequired =
TRUE ;
00363 }
else {
00364
IopProfileChangeCancelRequired =
FALSE ;
00365 }
00366
return status ;
00367 }
00368
00369
VOID
00370 IopHardwareProfileCommitStartedDock(
00371 IN
PDEVICE_NODE DeviceNode
00372 )
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 {
00391
NTSTATUS status;
00392
PDEVICE_OBJECT deviceObject;
00393 PWCHAR deviceSerialNumber;
00394 BOOLEAN profileChanged =
FALSE ;
00395
00396
ASSERT_SEMA_NOT_SIGNALLED(&
IopProfileChangeSemaphore) ;
00397
ASSERT(DeviceNode->DockInfo.DockStatus ==
DOCK_ARRIVING) ;
00398
ASSERT(!IsListEmpty(&DeviceNode->DockInfo.ListEntry)) ;
00399
00400 DeviceNode->DockInfo.DockStatus =
DOCK_QUIESCENT ;
00401 InterlockedDecrement(&
IopDocksInTransition) ;
00402
00403
00404
00405
00406
ASSERT(!
IopDocksInTransition) ;
00407
00408
00409
00410
00411
if (DeviceNode->DockInfo.SerialNumber ==
NULL) {
00412
00413 deviceObject = DeviceNode->PhysicalDeviceObject;
00414
00415 status =
IopQueryDeviceSerialNumber(deviceObject,
00416 &deviceSerialNumber);
00417
00418 DeviceNode->DockInfo.SerialNumber = deviceSerialNumber;
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 status =
IopUpdateHardwareProfile(&profileChanged);
00429
if (!
NT_SUCCESS(status)) {
00430
00431 PIDBGMSG(
00432 PIDBG_HWPROFILE,
00433 (
"IopUpdateHardwareProfile failed with status == %lx\n", status)
00434 ) ;
00435 }
00436
00437 }
else {
00438
00439
00440
00441 status = STATUS_UNSUCCESSFUL;
00442 }
00443
00444
if (
NT_SUCCESS(status) && profileChanged) {
00445
00446
IopHardwareProfileSendCommit() ;
00447
IopProcessNewProfile();
00448
00449 }
else if (
IopProfileChangeCancelRequired) {
00450
00451
IopHardwareProfileSendCancel() ;
00452 }
00453
00454
KeReleaseSemaphore(
00455 &
IopProfileChangeSemaphore,
00456
IO_NO_INCREMENT,
00457 1,
00458
FALSE
00459 );
00460
00461
return ;
00462 }
00463
00464
VOID
00465 IopHardwareProfileCommitRemovedDock(
00466 IN
PDEVICE_NODE DeviceNode
00467 )
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 {
00487
NTSTATUS status;
00488 BOOLEAN profileChanged ;
00489 LONG remainingDockCount ;
00490
00491
00492
00493
00494 ExAcquireFastMutex(&
IopDockDeviceListLock);
00495
00496
00497
00498
00499
00500
ASSERT_SEMA_NOT_SIGNALLED(&
IopProfileChangeSemaphore) ;
00501
ASSERT((DeviceNode->DockInfo.DockStatus ==
DOCK_DEPARTING)||
00502 (DeviceNode->DockInfo.DockStatus ==
DOCK_EJECTIRP_COMPLETED)) ;
00503
ASSERT(!IsListEmpty(&DeviceNode->DockInfo.ListEntry)) ;
00504
00505
00506
00507
00508 RemoveEntryList(&DeviceNode->DockInfo.ListEntry);
00509 InitializeListHead(&DeviceNode->DockInfo.ListEntry);
00510
if (DeviceNode->DockInfo.SerialNumber) {
00511
00512
ExFreePool(DeviceNode->DockInfo.SerialNumber);
00513 DeviceNode->DockInfo.SerialNumber =
NULL;
00514 }
00515
IopDockDeviceCount--;
00516
00517 DeviceNode->DockInfo.DockStatus =
DOCK_QUIESCENT ;
00518 remainingDockCount = InterlockedDecrement(&
IopDocksInTransition) ;
00519
ASSERT(remainingDockCount >= 0) ;
00520
00521
00522
00523
00524 ExReleaseFastMutex(&
IopDockDeviceListLock);
00525
00526
if (remainingDockCount) {
00527
00528
return ;
00529 }
00530
00531
00532
00533
00534 status =
IopUpdateHardwareProfile(&profileChanged);
00535
00536
if (!
NT_SUCCESS(status)) {
00537
00538
00539
00540
00541
00542 PIDBGMSG(
00543 PIDBG_HWPROFILE,
00544 (
"IopUpdateHardwareProfile failed with status == %lx\n", status)
00545 ) ;
00546
00547
ASSERT(
NT_SUCCESS(status)) ;
00548 }
00549
00550
if (
NT_SUCCESS(status) && profileChanged) {
00551
00552
IopHardwareProfileSendCommit() ;
00553
IopProcessNewProfile();
00554
00555 }
else {
00556
00557
ASSERT(
IopProfileChangeCancelRequired) ;
00558
IopHardwareProfileSendCancel() ;
00559 }
00560
00561
KeReleaseSemaphore(
00562 &
IopProfileChangeSemaphore,
00563
IO_NO_INCREMENT,
00564 1,
00565
FALSE
00566 );
00567
00568
return ;
00569 }
00570
00571
VOID
00572 IopHardwareProfileCancelRemovedDock(
00573 IN
PDEVICE_NODE DeviceNode
00574 )
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594 {
00595
NTSTATUS status;
00596 BOOLEAN profileChanged ;
00597 LONG remainingDockCount ;
00598
00599
00600
00601
00602 ExAcquireFastMutex(&
IopDockDeviceListLock);
00603
00604
00605
00606
00607
00608
ASSERT_SEMA_NOT_SIGNALLED(&
IopProfileChangeSemaphore) ;
00609
ASSERT(DeviceNode->DockInfo.DockStatus ==
DOCK_EJECTIRP_COMPLETED) ;
00610
ASSERT(!IsListEmpty(&DeviceNode->DockInfo.ListEntry)) ;
00611
00612 DeviceNode->DockInfo.DockStatus =
DOCK_QUIESCENT ;
00613 remainingDockCount = InterlockedDecrement(&
IopDocksInTransition) ;
00614
ASSERT(remainingDockCount >= 0) ;
00615
00616
00617
00618
00619 ExReleaseFastMutex(&
IopDockDeviceListLock);
00620
00621
if (remainingDockCount) {
00622
00623
return ;
00624 }
00625
00626
00627
00628
00629 status =
IopUpdateHardwareProfile(&profileChanged);
00630
00631
if (!
NT_SUCCESS(status)) {
00632
00633
00634
00635
00636
00637 PIDBGMSG(
00638 PIDBG_HWPROFILE,
00639 (
"IopUpdateHardwareProfile failed with status == %lx\n", status)
00640 ) ;
00641
ASSERT(
NT_SUCCESS(status)) ;
00642 }
00643
00644
if (
NT_SUCCESS(status) && profileChanged) {
00645
00646
IopHardwareProfileSendCommit() ;
00647
IopProcessNewProfile();
00648
00649 }
else {
00650
00651
ASSERT(
IopProfileChangeCancelRequired) ;
00652
IopHardwareProfileSendCancel() ;
00653 }
00654
00655
KeReleaseSemaphore(
00656 &
IopProfileChangeSemaphore,
00657
IO_NO_INCREMENT,
00658 1,
00659
FALSE
00660 );
00661
00662
return ;
00663 }
00664
00665
VOID
00666 IopHardwareProfileCancelTransition(
00667 VOID
00668 )
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686 {
00687 PLIST_ENTRY listEntry;
00688
PDEVICE_NODE devNode;
00689
00690
ASSERT_SEMA_NOT_SIGNALLED(&
IopProfileChangeSemaphore) ;
00691
00692
00693
00694
00695 ExAcquireFastMutex(&
IopDockDeviceListLock);
00696
00697
for (listEntry =
IopDockDeviceListHead.Flink;
00698 listEntry != &(
IopDockDeviceListHead);
00699 listEntry = listEntry->Flink ) {
00700
00701 devNode = CONTAINING_RECORD(listEntry,
00702
DEVICE_NODE,
00703 DockInfo.ListEntry);
00704
00705
ASSERT((devNode->
DockInfo.DockStatus !=
DOCK_NOTDOCKDEVICE)&&
00706 (devNode->
DockInfo.DockStatus !=
DOCK_EJECTIRP_COMPLETED)) ;
00707
if (devNode->
DockInfo.DockStatus !=
DOCK_QUIESCENT) {
00708
00709 InterlockedDecrement(&
IopDocksInTransition) ;
00710 devNode->
DockInfo.DockStatus =
DOCK_QUIESCENT ;
00711 }
00712 }
00713
00714
ASSERT(!
IopDocksInTransition) ;
00715
00716
00717
00718
00719 ExReleaseFastMutex(&
IopDockDeviceListLock);
00720
00721
if (
IopProfileChangeCancelRequired) {
00722
00723
IopHardwareProfileSendCancel() ;
00724 }
00725
00726
00727
00728
00729
00730
KeReleaseSemaphore(
00731 &
IopProfileChangeSemaphore,
00732
IO_NO_INCREMENT,
00733 1,
00734
FALSE
00735 );
00736 }
00737
00738
VOID
00739 IopHardwareProfileSetMarkedDocksEjected(
00740 VOID
00741 )
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761 {
00762 PLIST_ENTRY listEntry;
00763
PDEVICE_NODE devNode;
00764
00765
ASSERT_SEMA_NOT_SIGNALLED(&
IopProfileChangeSemaphore) ;
00766
00767
00768
00769
00770 ExAcquireFastMutex(&
IopDockDeviceListLock);
00771
00772
for (listEntry =
IopDockDeviceListHead.Flink;
00773 listEntry != &(
IopDockDeviceListHead);
00774 listEntry = listEntry->Flink ) {
00775
00776 devNode = CONTAINING_RECORD(listEntry,
00777
DEVICE_NODE,
00778 DockInfo.ListEntry);
00779
00780
ASSERT((devNode->
DockInfo.DockStatus ==
DOCK_QUIESCENT)||
00781 (devNode->
DockInfo.DockStatus ==
DOCK_DEPARTING)) ;
00782
if (devNode->
DockInfo.DockStatus !=
DOCK_QUIESCENT) {
00783
00784 devNode->
DockInfo.DockStatus =
DOCK_EJECTIRP_COMPLETED ;
00785 }
00786 }
00787
00788
00789
00790
00791 ExReleaseFastMutex(&
IopDockDeviceListLock);
00792 }
00793
00794
VOID
00795 IopHardwareProfileSendCommit(
00796 VOID
00797 )
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814 {
00815
ASSERT_SEMA_NOT_SIGNALLED(&
IopProfileChangeSemaphore) ;
00816 PIDBGMSG(PIDBG_HWPROFILE, (
"NTOSKRNL: Sending HW profile change [commit]\n")) ;
00817
00818
IopRequestHwProfileChangeNotification(
00819 (LPGUID) &GUID_HWPROFILE_CHANGE_COMPLETE,
00820
PROFILE_PERHAPS_IN_PNPEVENT,
00821
NULL,
00822
NULL
00823 );
00824 }
00825
00826
VOID
00827 IopHardwareProfileSendCancel(
00828 VOID
00829 )
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845 {
00846
PROFILE_WORK_ITEM profileWorkItem;
00847 PNP_VETO_TYPE vetoType;
00848
NTSTATUS status;
00849
00850
ASSERT_SEMA_NOT_SIGNALLED(&
IopProfileChangeSemaphore) ;
00851 PIDBGMSG(PIDBG_HWPROFILE, (
"NTOSKRNL: Sending HW profile change [cancel]\n")) ;
00852
00853
IopRequestHwProfileChangeNotification(
00854 (LPGUID) &GUID_HWPROFILE_CHANGE_CANCELLED,
00855
PROFILE_PERHAPS_IN_PNPEVENT,
00856
NULL,
00857
NULL
00858 ) ;
00859 }
00860
00861
NTSTATUS
00862 IopUpdateHardwareProfile (
00863 OUT PBOOLEAN ProfileChanged
00864 )
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882 {
00883
NTSTATUS status = STATUS_SUCCESS;
00884 PLIST_ENTRY listEntry;
00885
PDEVICE_NODE devNode;
00886 PWCHAR *profileSerialNumbers, *p;
00887 HANDLE hProfileKey=
NULL;
00888 ULONG len, numProfiles;
00889 HANDLE hCurrent, hIDConfigDB;
00890 UNICODE_STRING unicodeName;
00891
00892
00893
00894
00895 ExAcquireFastMutex(&
IopDockDeviceListLock);
00896
00897
00898
00899
00900
RtlInitUnicodeString(&unicodeName,
CM_HARDWARE_PROFILE_STR_DATABASE);
00901
if(
NT_SUCCESS(
IopOpenRegistryKey(&hIDConfigDB,
00902
NULL,
00903 &unicodeName,
00904 KEY_READ,
00905
FALSE) )) {
00906
00907
RtlInitUnicodeString(&unicodeName,
CM_HARDWARE_PROFILE_STR_CURRENT_DOCK_INFO);
00908
if(
NT_SUCCESS(
IopOpenRegistryKey(&hCurrent,
00909 hIDConfigDB,
00910 &unicodeName,
00911 KEY_READ | KEY_WRITE,
00912
FALSE) )) {
00913
00914
RtlInitUnicodeString(&unicodeName, REGSTR_VAL_EJECTABLE_DOCKS);
00915 ZwSetValueKey(hCurrent,
00916 &unicodeName,
00917 0,
00918 REG_DWORD,
00919 &
IopDockDeviceCount,
00920
sizeof(
IopDockDeviceCount));
00921 ZwClose(hCurrent);
00922 }
00923 ZwClose(hIDConfigDB);
00924 }
00925
00926
if (
IopDockDeviceCount == 0) {
00927
00928
00929
00930
00931
00932 numProfiles = 1;
00933
ASSERT(IsListEmpty(&
IopDockDeviceListHead));
00934 }
else {
00935 numProfiles =
IopDockDeviceCount;
00936
ASSERT(!IsListEmpty(&
IopDockDeviceListHead));
00937 }
00938
00939
00940
00941
00942 len = (numProfiles+1)*
sizeof(PWCHAR);
00943 profileSerialNumbers =
ExAllocatePool(
NonPagedPool, len);
00944
00945
if (profileSerialNumbers) {
00946
00947 p = profileSerialNumbers;
00948
00949
00950
00951
00952
for (listEntry =
IopDockDeviceListHead.Flink;
00953 listEntry != &(
IopDockDeviceListHead);
00954 listEntry = listEntry->Flink ) {
00955
00956 devNode = CONTAINING_RECORD(listEntry,
00957
DEVICE_NODE,
00958 DockInfo.ListEntry);
00959
00960
00961
00962
00963
00964
ASSERT(devNode->
DockInfo.DockStatus !=
DOCK_NOTDOCKDEVICE) ;
00965
if (devNode->
DockInfo.SerialNumber) {
00966 *p = devNode->
DockInfo.SerialNumber;
00967 p++;
00968 }
00969 }
00970
00971 ExReleaseFastMutex(&
IopDockDeviceListLock);
00972
00973
if (p == profileSerialNumbers) {
00974
00975
00976
00977
00978 *p =
NULL;
00979 p++;
00980 }
00981
00982
00983
00984
00985 *p =
NULL;
00986
00987 numProfiles = (ULONG)(p - profileSerialNumbers);
00988
00989
00990
00991
00992
00993 status =
IopExecuteHardwareProfileChange(
HardwareProfileBusTypeACPI,
00994 profileSerialNumbers,
00995 numProfiles,
00996 &hProfileKey,
00997 ProfileChanged);
00998
if (hProfileKey) {
00999 ZwClose(hProfileKey);
01000 }
01001
ExFreePool (profileSerialNumbers);
01002
01003 }
else {
01004
01005 ExReleaseFastMutex(&
IopDockDeviceListLock);
01006
01007 status = STATUS_INSUFFICIENT_RESOURCES;
01008 }
01009
01010
return status;
01011 }
01012
01013
NTSTATUS
01014 IopExecuteHwpDefaultSelect (
01015 IN
PCM_HARDWARE_PROFILE_LIST ProfileList,
01016 OUT PULONG ProfileIndexToUse,
01017 IN PVOID Context
01018 )
01019 {
01020 UNREFERENCED_PARAMETER (Context);
01021
01022 * ProfileIndexToUse = 0;
01023
01024
return STATUS_SUCCESS;
01025 }
01026
01027
NTSTATUS
01028 IopExecuteHardwareProfileChange(
01029 IN HARDWARE_PROFILE_BUS_TYPE Bus,
01030 IN PWCHAR * ProfileSerialNumbers,
01031 IN ULONG SerialNumbersCount,
01032 OUT PHANDLE NewProfile,
01033 OUT PBOOLEAN ProfileChanged
01034 )
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066 {
01067
NTSTATUS status = STATUS_SUCCESS;
01068 ULONG len;
01069 ULONG tmplen;
01070 ULONG i, j;
01071 PWCHAR tmpStr;
01072 UNICODE_STRING tmpUStr;
01073 PUNICODE_STRING sortedSerials =
NULL;
01074
01075
PPROFILE_ACPI_DOCKING_STATE dockState =
NULL;
01076
01077 PIDBGMSG(
01078 PIDBG_HWPROFILE,
01079 (
"Execute Profile (BusType %x), (SerialNumCount %x)\n", Bus, SerialNumbersCount)
01080 ) ;
01081
01082
01083
01084
01085 len =
sizeof (UNICODE_STRING) * SerialNumbersCount;
01086 sortedSerials =
ExAllocatePool (
NonPagedPool, len);
01087
if (
NULL == sortedSerials) {
01088 status = STATUS_INSUFFICIENT_RESOURCES;
01089
goto Clean;
01090 }
01091
for (i = 0; i < SerialNumbersCount; i++) {
01092
RtlInitUnicodeString (&sortedSerials[i], ProfileSerialNumbers[i]);
01093 }
01094
01095
01096
01097
01098
for (i = 0; i < SerialNumbersCount; i++) {
01099
for (j = 0; j < SerialNumbersCount - 1; j++) {
01100
if (0 <
RtlCompareUnicodeString (&sortedSerials[j],
01101 &sortedSerials[j+1],
01102
FALSE)) {
01103 tmpUStr = sortedSerials[j];
01104 sortedSerials[j] = sortedSerials[j+1];
01105 sortedSerials[j+1] = tmpUStr;
01106 }
01107 }
01108 }
01109
01110
01111
01112
01113 len = 0;
01114
for (i = 0; i < SerialNumbersCount; i++) {
01115 len += sortedSerials[i].Length;
01116 }
01117 len +=
sizeof (WCHAR);
01118
01119 dockState = (
PPROFILE_ACPI_DOCKING_STATE)
01120
ExAllocatePool (
NonPagedPool,
01121 len +
sizeof (
PROFILE_ACPI_DOCKING_STATE));
01122
01123
01124
if (
NULL == dockState) {
01125 status = STATUS_INSUFFICIENT_RESOURCES;
01126
goto Clean;
01127 }
01128
for (i = 0, tmpStr = dockState->
SerialNumber, tmplen = 0;
01129 i < SerialNumbersCount;
01130 i++) {
01131
01132 tmplen = sortedSerials[i].Length;
01133
ASSERT (tmplen <= len - ((PCHAR)tmpStr - (PCHAR)dockState->SerialNumber));
01134
01135 RtlCopyMemory (tmpStr, sortedSerials[i].
Buffer, tmplen);
01136 (PCHAR) tmpStr += tmplen;
01137 }
01138
01139 *(tmpStr++) =
L'\0';
01140
01141
ASSERT (len == (ULONG) ((PCHAR) tmpStr - (PCHAR) dockState->
SerialNumber));
01142 dockState->
SerialLength = (
USHORT) len;
01143
01144
if ((SerialNumbersCount > 1) || (
L'\0' != dockState->
SerialNumber[0])) {
01145 dockState->
DockingState =
HW_PROFILE_DOCKSTATE_DOCKED;
01146 }
else {
01147 dockState->
DockingState =
HW_PROFILE_DOCKSTATE_UNDOCKED;
01148 }
01149
01150
01151
01152
01153
01154
switch (Bus) {
01155
case HardwareProfileBusTypeACPI:
01156
01157 status =
CmSetAcpiHwProfile (dockState,
01158
IopExecuteHwpDefaultSelect,
01159
NULL,
01160 NewProfile,
01161 ProfileChanged);
01162
01163
ASSERT(
NT_SUCCESS(status) || (!(*ProfileChanged))) ;
01164
break;
01165
01166
default:
01167 *ProfileChanged =
FALSE ;
01168 status = STATUS_NOT_SUPPORTED;
01169
goto Clean;
01170 }
01171
01172 Clean:
01173
if (
NULL != sortedSerials) {
01174
ExFreePool (sortedSerials);
01175 }
01176
if (
NULL != dockState) {
01177
ExFreePool (dockState);
01178 }
01179
01180
return status;
01181 }
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
#if 0
01194
01195
struct _IOP_NEW_ACPI_STATE {
01196 ULONG Blah;
01197
PCM_HARDWARE_PROFILE_LIST ProfileList;
01198
01199 } IOP_NEW_ACPI_STATE, *PIOP_NEW_ACPI_STATE;
01200
01201
01202
NTSTATUS
01203 IopProfileAcquisition (
01204 IN
PCM_HARDWARE_PROFILE_LIST ProfileList,
01205 OUT PULONG ProfileIndexToUse,
01206 IN PIOP_PROFILE_LIST NewAcpiState
01207 )
01208
01209
01210
01211
01212 {
01213
PCM_HARDWARE_PROFILE_LIST tmpList;
01214
NTSTATUS status = STATUS_SUCCESS;
01215 ULONG i;
01216 ULONG k;
01217 ULONG oldSize;
01218 ULONG newSize;
01219 BOOLEAN found;
01220
01221
01222
01223
01224
01225
01226
01227
ASSERT (ProfileList->CurrentProfileCount <= ProfileList->MaxProfileCount);
01228
for (i = 0; i < ProfileList->CurrentProfileCount; i++) {
01229 found =
FALSE;
01230
01231
for (k = 0; k < NewAcpiState->ProfileList->CurrentProfileCount; k++) {
01232
if (ProfileList->Profile[i].Id ==
01233 NewAcpiState->ProfileList->Profile[k]) {
01234 found =
TRUE;
01235
break;
01236 }
01237 }
01238
01239
if (!found) {
01240
01241
01242
01243
if (NewAcpiState->MaxProfileCount <= NewAcpiState->CurrentProfileCount) {
01244 tmpList = NewAcpiState->ProfileList;
01245
01246 oldSize =
sizeof (
CM_HARDWARE_PROFILE_LIST)
01247 + (
sizeof (
CM_HARDWARE_PROFILE) *
01248 (tmpList->
MaxProfileCount - 1));
01249
01250 newSize = tmpList->
MaxProfileCount * 2;
01251 newSize =
sizeof (
CM_HARDWARE_PROFILE_LIST)
01252 + (
sizeof (CM_HAREWARE_PROFILE) * (newSize - 1));
01253
01254 tmpList =
ExAllocatePool (PagedPool, newSize);
01255
if (
NULL == tmpList) {
01256
return STATUS_INSUFFICIENT_RESOURCES;
01257 }
01258 RtlCopyMemory (tmpList, NewAcpiState->ProfileList, oldSize);
01259
01260 tmpList->
MaxProfileCount *= 2;
01261
01262
ExFreePool (NewAcpiState->ProfileList);
01263 NewAcpiState->ProfileList = tmpList;
01264 }
01265
01266 k = NewAcpiState->ProfileList->
CurrentProfileCount++;
01267 NewAcpiState->ProfileList->Profile[k] = ProfileList->Profile[i].
01268 }
01269
01270 }
01271
01272
01273
01274 *ProfileIndexToUse = -1;
01275
return status;
01276 }
01277
01278
01279
NTSTATUS
01280 IopFindPossibleProfiles (
01281 IN
PPROFILE_ACPI_DOCKING_STATE * AcpiProfiles,
01282 IN ULONG PossibleDockingStates,
01283 OUT
PCM_HARDWARE_PROFILE_LIST * ProfileList
01284 )
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300 {
01301
NTSTATUS status = STATUS_SUCCESS;
01302 ULONG i;
01303 IOP_PROFILE_CONTEXT context;
01304
PROFILE_ACPI_DOCKING_STATE acpiDockState;
01305
01306 context->ProfileList =
ExAllocatePool (NonPagedPool,
01307
sizeof (
PCM_HARDWARE_PROFILE_LIST));
01308
if (
NULL == context->ProfileList) {
01309 status = STATUS_INSUFICIENT_RESOURCES;
01310
goto Clean;
01311 }
01312 context->ProfileList->MaxProfileCount = 1;
01313 context->ProfileList->CurrentProfileCount = 0;
01314
01315
for (i = 0; i < PossibleDockingStates; i++) {
01316
01317 status =
CmSetAcpiHwProfile (AcpiProfiles[i],
01318 IopProfileAcquisition,
01319 &context);
01320
01321
if (STATUS_MORE_PROCESSING_REQUIRED == status) {
01322 status = STATUS_SUCCESS;
01323 }
01324
if (!
NT_SUCCESS (status)) {
01325
goto Clean;
01326 }
01327 }
01328 status = STATUS_SUCCESS
01329
01330 *ProfileList = context->ProfileList;
01331
01332 Clean:
01333
01334
if (
NULL != context->ProfileList) {
01335
ExFreePool (context->ProfileList);
01336 }
01337
01338
if (!
NT_SUCCESS(status)) {
01339
if (possibleProfileList) {
01340
ExFreePool (possibleProfileList);
01341 }
01342 }
01343
01344
return status;
01345 }
01346
01347
typedef struct _IOP_ACPI_DOCKING_PROFILE_INFO {
01348 ULONG Blah;
01349 } IOP_ACPI_DOCKING_PROFILE_INFO, * PIOP_ACPI_DOCKING_PROFILE_INFO;
01350
01351
NTSTATUS
01352 IopAcpiQueryDockingProfileEvent (
01353 IN PUCHAR * AcpiDockSerialNumbers,
01354 IN ULONG PossibleSerialNumbers,
01355 IN PFOOBAR DockRelations,
01356 OUT PIOP_ACPI_DOCKING_PROFILE_INFO * AcpiDockInfo,
01357 )
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388 {
01389
NTSTATUS status = STATUS_SUCCESS;
01390
01391
return status;
01392 }
01393
01394
#endif
01395
01396