00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include "cmp.h"
00024
00025
NTSTATUS
00026
CmDeleteKeyRecursive(
00027 HANDLE hKeyRoot,
00028 PWSTR Key,
00029 PVOID TemporaryBuffer,
00030 ULONG LengthTemporaryBuffer,
00031 BOOLEAN ThisKeyToo
00032 );
00033
00034
NTSTATUS
00035
CmpGetAcpiProfileInformation (
00036 IN HANDLE IDConfigDB,
00037 OUT
PCM_HARDWARE_PROFILE_LIST * ProfileList,
00038 OUT
PCM_HARDWARE_PROFILE_ACPI_ALIAS_LIST * AliasList,
00039 IN PWCHAR NameBuffer,
00040 IN PUCHAR ValueBuffer,
00041 IN ULONG Len
00042 );
00043
00044
NTSTATUS
00045
CmpFilterAcpiDockingState (
00046 IN
PPROFILE_ACPI_DOCKING_STATE NewDockState,
00047 IN ULONG CurrentDockingState,
00048 IN PWCHAR CurrentAcpiSN,
00049 IN ULONG CurrentProfileNumber,
00050 IN OUT
PCM_HARDWARE_PROFILE_LIST ProfileList,
00051 IN OUT
PCM_HARDWARE_PROFILE_ACPI_ALIAS_LIST AliasList
00052 );
00053
00054
NTSTATUS
00055
CmpMoveBiosAliasTable (
00056 IN HANDLE IDConfigDB,
00057 IN HANDLE CurrentInfo,
00058 IN ULONG CurrentProfileNumber,
00059 IN ULONG NewProfileNumber,
00060 IN PWCHAR nameBuffer,
00061 IN PCHAR valueBuffer,
00062 IN ULONG bufferLen
00063 );
00064
00065
#pragma alloc_text(PAGE,CmpCloneHwProfile)
00066
#pragma alloc_text(PAGE,CmSetAcpiHwProfile)
00067
#pragma alloc_text(PAGE,CmpFilterAcpiDockingState)
00068
#pragma alloc_text(PAGE,CmpGetAcpiProfileInformation)
00069
#pragma alloc_text(PAGE,CmpAddAcpiAliasEntry)
00070
#pragma alloc_text(PAGE,CmpMoveBiosAliasTable)
00071
#pragma alloc_text(PAGE,CmpCreateHwProfileFriendlyName)
00072
00073 extern UNICODE_STRING
CmSymbolicLinkValueName;
00074
00075
NTSTATUS
00076 CmpGetAcpiProfileInformation (
00077 IN HANDLE IDConfigDB,
00078 OUT
PCM_HARDWARE_PROFILE_LIST * ProfileList,
00079 OUT
PCM_HARDWARE_PROFILE_ACPI_ALIAS_LIST * AliasList,
00080 IN PWCHAR nameBuffer,
00081 IN PUCHAR valueBuffer,
00082 IN ULONG bufferLen
00083 )
00084
00085
00086
00087
00088
00089
00090 {
00091
NTSTATUS status = STATUS_SUCCESS;
00092 HANDLE acpiAlias =
NULL;
00093 HANDLE profiles =
NULL;
00094 HANDLE entry =
NULL;
00095 ULONG len = 0;
00096 ULONG i, j;
00097 OBJECT_ATTRIBUTES attributes;
00098 UNICODE_STRING name;
00099 KEY_FULL_INFORMATION keyInfo;
00100 PKEY_VALUE_FULL_INFORMATION value;
00101 PKEY_BASIC_INFORMATION basicInfo;
00102
00103
PAGED_CODE ();
00104
00105 *ProfileList =
NULL;
00106 *AliasList =
NULL;
00107
00108 value = (PKEY_VALUE_FULL_INFORMATION) valueBuffer;
00109 basicInfo = (PKEY_BASIC_INFORMATION) valueBuffer;
00110
00111
00112
00113
00114
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_HARDWARE_PROFILES);
00115 InitializeObjectAttributes (&attributes,
00116 &name,
00117 OBJ_CASE_INSENSITIVE,
00118 IDConfigDB,
00119
NULL);
00120 status = ZwOpenKey (&profiles,
00121 KEY_READ,
00122 &attributes);
00123
00124
if (!
NT_SUCCESS (status)) {
00125 profiles =
NULL;
00126
goto Clean;
00127 }
00128
00129
00130
00131
00132 status = ZwQueryKey (profiles,
00133 KeyFullInformation,
00134 &keyInfo,
00135
sizeof (keyInfo),
00136 &len);
00137
00138
if (!
NT_SUCCESS (status)) {
00139
goto Clean;
00140 }
00141
00142
ASSERT (0 < keyInfo.SubKeys);
00143
00144 len =
sizeof (
CM_HARDWARE_PROFILE_LIST)
00145 + (
sizeof (
CM_HARDWARE_PROFILE) * (keyInfo.SubKeys - 1));
00146
00147 * ProfileList =
ExAllocatePool (
PagedPool, len);
00148
if (
NULL == *ProfileList) {
00149 status = STATUS_INSUFFICIENT_RESOURCES;
00150
goto Clean;
00151 }
00152 RtlZeroMemory (*ProfileList, len);
00153
00154 (*ProfileList)->MaxProfileCount = keyInfo.SubKeys;
00155 (*ProfileList)->CurrentProfileCount = 0;
00156
00157
00158
00159
00160
for (i = 0; i < keyInfo.SubKeys; i++) {
00161
CM_HARDWARE_PROFILE TempProfile;
00162 UNICODE_STRING
KeyName;
00163 ULONG realsize;
00164
00165
00166
00167
00168 status = ZwEnumerateKey (profiles,
00169 i,
00170 KeyBasicInformation,
00171 basicInfo,
00172 bufferLen -
sizeof (UNICODE_NULL),
00173 &len);
00174
00175
if (!
NT_SUCCESS (status)) {
00176
00177
00178
00179
break;
00180 }
00181
00182 basicInfo->Name [basicInfo->NameLength/
sizeof(WCHAR)] = 0;
00183 name.Length = (
USHORT) basicInfo->NameLength;
00184 name.MaximumLength = (
USHORT) basicInfo->NameLength +
sizeof (UNICODE_NULL);
00185 name.Buffer = basicInfo->Name;
00186
00187 InitializeObjectAttributes (&attributes,
00188 &name,
00189 OBJ_CASE_INSENSITIVE,
00190 profiles,
00191
NULL);
00192 status = ZwOpenKey (&entry,
00193 KEY_READ,
00194 &attributes);
00195
if (!
NT_SUCCESS (status)) {
00196
break;
00197 }
00198
00199
00200
00201
00202
00203
RtlUnicodeStringToInteger(&name, 0, &TempProfile.
Id);
00204
00205
00206
00207
00208
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_PREFERENCE_ORDER);
00209 status =
NtQueryValueKey(entry,
00210 &name,
00211 KeyValueFullInformation,
00212 valueBuffer,
00213 bufferLen,
00214 &len);
00215
00216
if ((!
NT_SUCCESS (status)) || (value->Type != REG_DWORD)) {
00217 TempProfile.
PreferenceOrder = -1;
00218
00219 }
else {
00220 TempProfile.
PreferenceOrder
00221 = * (PULONG) ((PUCHAR) value + value->DataOffset);
00222 }
00223
00224
00225
00226
00227
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_FRIENDLY_NAME);
00228 status =
NtQueryValueKey(entry,
00229 &name,
00230 KeyValueFullInformation,
00231 valueBuffer,
00232 bufferLen,
00233 &len);
00234
00235
if (!
NT_SUCCESS (status) || (value->Type != REG_SZ)) {
00236 WCHAR tmpname[] =
L"------";
00237 ULONG len;
00238 PVOID buffer;
00239
00240 len =
sizeof (tmpname);
00241 buffer =
ExAllocatePool (
PagedPool, len);
00242
00243 TempProfile.
NameLength = len;
00244 TempProfile.
FriendlyName = buffer;
00245
if (
NULL == buffer) {
00246 status = STATUS_INSUFFICIENT_RESOURCES;
00247 ZwClose (entry);
00248
goto Clean;
00249 }
00250 RtlCopyMemory (buffer, tmpname, value->DataLength);
00251
00252 }
else {
00253 PVOID buffer;
00254
00255 buffer =
ExAllocatePool (
PagedPool, value->DataLength);
00256 TempProfile.
NameLength = value->DataLength;
00257 TempProfile.
FriendlyName = buffer;
00258
if (
NULL == buffer) {
00259 status = STATUS_INSUFFICIENT_RESOURCES;
00260 ZwClose (entry);
00261
goto Clean;
00262 }
00263 RtlCopyMemory (buffer,
00264 (PUCHAR) value + value->DataOffset,
00265 value->DataLength);
00266 }
00267
00268 TempProfile.
Flags = 0;
00269
00270
00271
00272
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_ALIASABLE);
00273 status =
NtQueryValueKey(entry,
00274 &name,
00275 KeyValueFullInformation,
00276 valueBuffer,
00277 bufferLen,
00278 &len);
00279
00280
if (
NT_SUCCESS (status) && (value->Type == REG_DWORD)) {
00281
if (* (PULONG) ((PUCHAR) value + value->DataOffset)) {
00282 TempProfile.
Flags |=
CM_HP_FLAGS_ALIASABLE;
00283 }
00284
00285 }
else {
00286 TempProfile.
Flags |=
CM_HP_FLAGS_ALIASABLE;
00287 }
00288
00289
00290
00291
00292
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_PRISTINE);
00293 status =
NtQueryValueKey(entry,
00294 &name,
00295 KeyValueFullInformation,
00296 valueBuffer,
00297 bufferLen,
00298 &len);
00299
00300
if (
NT_SUCCESS (status) && (value->Type == REG_DWORD)) {
00301
if (* (PULONG) ((PUCHAR) value + value->DataOffset)) {
00302 TempProfile.
Flags =
CM_HP_FLAGS_PRISTINE;
00303
00304 }
00305 }
00306
00307
00308
00309
00310
00311
00312
if (0 == TempProfile.
Id) {
00313 TempProfile.
Flags =
CM_HP_FLAGS_PRISTINE;
00314
00315
00316 TempProfile.
PreferenceOrder = -1;
00317 }
00318
00319
00320
00321
00322
00323
00324
for (j=0; j < (*ProfileList)->CurrentProfileCount; j++) {
00325
if ((*ProfileList)->Profile[j].PreferenceOrder >=
00326 TempProfile.
PreferenceOrder) {
00327
00328
00329
00330
00331 RtlMoveMemory(&(*ProfileList)->Profile[j+1],
00332 &(*ProfileList)->Profile[j],
00333
sizeof(
CM_HARDWARE_PROFILE) *
00334 ((*ProfileList)->MaxProfileCount-j-1));
00335
break;
00336 }
00337 }
00338 (*ProfileList)->Profile[j] = TempProfile;
00339 ++(*ProfileList)->CurrentProfileCount;
00340
00341 ZwClose (entry);
00342 }
00343
00344
00345
00346
00347
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_ACPI_ALIAS);
00348 InitializeObjectAttributes (&attributes,
00349 &name,
00350 OBJ_CASE_INSENSITIVE,
00351 IDConfigDB,
00352
NULL);
00353 status = ZwOpenKey (&acpiAlias,
00354 KEY_READ,
00355 &attributes);
00356
00357
if (!
NT_SUCCESS (status)) {
00358
00359
00360
00361 status = STATUS_SUCCESS;
00362 acpiAlias =
NULL;
00363
goto Clean;
00364 }
00365
00366
00367
00368
00369 status = ZwQueryKey (acpiAlias,
00370 KeyFullInformation,
00371 &keyInfo,
00372
sizeof (keyInfo),
00373 &len);
00374
00375
if (!
NT_SUCCESS (status)) {
00376
goto Clean;
00377 }
00378
00379
00380
ASSERT (0 < keyInfo.SubKeys);
00381
00382 * AliasList =
ExAllocatePool (
00383
PagedPool,
00384
sizeof (
CM_HARDWARE_PROFILE_LIST) +
00385 (
sizeof (
CM_HARDWARE_PROFILE) * (keyInfo.SubKeys - 1)));
00386
00387
if (
NULL == *AliasList) {
00388 status = STATUS_INSUFFICIENT_RESOURCES;
00389
goto Clean;
00390 }
00391
00392 (*AliasList)->MaxAliasCount =
00393 (*AliasList)->CurrentAliasCount = keyInfo.SubKeys;
00394
00395
00396
00397
00398
for (i = 0; i < keyInfo.SubKeys; i++) {
00399
00400
00401
00402
00403 status = ZwEnumerateKey (acpiAlias,
00404 i,
00405 KeyBasicInformation,
00406 basicInfo,
00407 bufferLen -
sizeof (UNICODE_NULL),
00408 &len);
00409
00410
if (!
NT_SUCCESS (status)) {
00411
00412
00413
00414
break;
00415 }
00416
00417 basicInfo->Name [basicInfo->NameLength/
sizeof(WCHAR)] = 0;
00418 name.Length = (
USHORT) basicInfo->NameLength;
00419 name.MaximumLength = (
USHORT) basicInfo->NameLength +
sizeof (UNICODE_NULL);
00420 name.Buffer = basicInfo->Name;
00421
00422 InitializeObjectAttributes (&attributes,
00423 &name,
00424 OBJ_CASE_INSENSITIVE,
00425 acpiAlias,
00426
NULL);
00427 status = ZwOpenKey (&entry,
00428 KEY_READ,
00429 &attributes);
00430
if (!
NT_SUCCESS (status)) {
00431
break;
00432 }
00433
00434
00435
00436
00437
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_PROFILE_NUMBER);
00438 status =
NtQueryValueKey(entry,
00439 &name,
00440 KeyValueFullInformation,
00441 valueBuffer,
00442 bufferLen,
00443 &len);
00444
00445
if (!
NT_SUCCESS (status) || (value->Type != REG_DWORD)) {
00446 status = STATUS_REGISTRY_CORRUPT;
00447 ZwClose (entry);
00448
goto Clean;
00449 }
00450 (*AliasList)->Alias[i].ProfileNumber =
00451 * (PULONG) ((PUCHAR) value + value->DataOffset);
00452
00453
00454
00455
00456
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_DOCKING_STATE);
00457 status =
NtQueryValueKey(entry,
00458 &name,
00459 KeyValueFullInformation,
00460 valueBuffer,
00461 bufferLen,
00462 &len);
00463
00464
if (!
NT_SUCCESS (status) || (value->Type != REG_DWORD)) {
00465 status = STATUS_REGISTRY_CORRUPT;
00466 ZwClose (entry);
00467
goto Clean;
00468 }
00469 (*AliasList)->Alias[i].DockState =
00470 * (PULONG) ((PUCHAR) value + value->DataOffset);
00471
00472
00473
00474
00475
00476
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_ACPI_SERIAL_NUMBER);
00477 status =
NtQueryValueKey(entry,
00478 &name,
00479 KeyValueFullInformation,
00480 valueBuffer,
00481 bufferLen,
00482 &len);
00483
00484
if (!
NT_SUCCESS (status) || (value->Type != REG_BINARY)) {
00485 status = STATUS_REGISTRY_CORRUPT;
00486 ZwClose (entry);
00487
goto Clean;
00488 }
00489
00490 (*AliasList)->Alias[i].SerialLength = value->DataLength;
00491 (*AliasList)->Alias[i].SerialNumber =
00492 (value->DataLength) ?
00493
ExAllocatePool (
PagedPool, value->DataLength) :
00494 0;
00495
00496
if (value->DataLength && (
NULL == (*AliasList)->Alias[i].SerialNumber)) {
00497
00498 status = STATUS_INSUFFICIENT_RESOURCES;
00499 ZwClose (entry);
00500
goto Clean;
00501 }
00502
00503
if (value->DataLength) {
00504 RtlCopyMemory ((*AliasList)->Alias[i].SerialNumber,
00505 (PUCHAR) value + value->DataOffset,
00506 value->DataLength);
00507 }
00508
00509 ZwClose (entry);
00510 }
00511
00512 Clean:
00513
if (
NULL != acpiAlias) {
00514
NtClose (acpiAlias);
00515 }
00516
if (
NULL != profiles) {
00517
NtClose (profiles);
00518 }
00519
00520
if (!
NT_SUCCESS (status)) {
00521
if (
NULL != *ProfileList) {
00522
for (i = 0; i < (*ProfileList)->CurrentProfileCount; i++) {
00523
if ((*ProfileList)->Profile[i].FriendlyName) {
00524
ExFreePool ((*ProfileList)->Profile[i].FriendlyName);
00525 }
00526 }
00527
ExFreePool (*ProfileList);
00528 *ProfileList = 0;
00529 }
00530
if (
NULL != *AliasList) {
00531
for (i = 0; i < (*AliasList)->CurrentAliasCount; i++) {
00532
if ((*AliasList)->Alias[i].SerialNumber) {
00533
ExFreePool ((*AliasList)->Alias[i].SerialNumber);
00534 }
00535 }
00536
ExFreePool (*AliasList);
00537 *AliasList = 0;
00538 }
00539 }
00540
return status;
00541 }
00542
00543
NTSTATUS
00544 CmpAddAcpiAliasEntry (
00545 IN HANDLE IDConfigDB,
00546 IN
PPROFILE_ACPI_DOCKING_STATE NewDockState,
00547 IN ULONG ProfileNumber,
00548 IN PWCHAR nameBuffer,
00549 IN PVOID valueBuffer,
00550 IN ULONG valueBufferLength,
00551 IN BOOLEAN PreventDuplication
00552 )
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 {
00577 OBJECT_ATTRIBUTES attributes;
00578
NTSTATUS status = STATUS_SUCCESS;
00579 ANSI_STRING ansiString;
00580 UNICODE_STRING name;
00581 HANDLE aliasKey =
NULL;
00582 HANDLE aliasEntry =
NULL;
00583 ULONG value;
00584 ULONG disposition;
00585 ULONG aliasNumber = 0;
00586 ULONG len;
00587 PKEY_VALUE_FULL_INFORMATION keyInfo;
00588
00589
PAGED_CODE ();
00590
00591 keyInfo = (PKEY_VALUE_FULL_INFORMATION) valueBuffer;
00592
00593
00594
00595
00596
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_ACPI_ALIAS);
00597
00598 InitializeObjectAttributes (&attributes,
00599 &name,
00600 OBJ_CASE_INSENSITIVE,
00601 IDConfigDB,
00602
NULL);
00603
00604 status =
NtOpenKey (&aliasKey,
00605 KEY_READ | KEY_WRITE,
00606 &attributes);
00607
00608
if (STATUS_OBJECT_NAME_NOT_FOUND == status) {
00609 status =
NtCreateKey (&aliasKey,
00610 KEY_READ | KEY_WRITE,
00611 &attributes,
00612 0,
00613
NULL,
00614 0,
00615 &disposition);
00616 }
00617
00618
if (!
NT_SUCCESS (status)) {
00619 aliasKey =
NULL;
00620
goto Exit;
00621 }
00622
00623
00624
00625
00626
00627
while (aliasNumber < 200) {
00628 aliasNumber++;
00629
00630 swprintf (nameBuffer,
L"%04d", aliasNumber);
00631
RtlInitUnicodeString (&name, nameBuffer);
00632
00633 InitializeObjectAttributes(&attributes,
00634 &name,
00635 OBJ_CASE_INSENSITIVE,
00636 aliasKey,
00637
NULL);
00638
00639 status =
NtOpenKey (&aliasEntry,
00640 KEY_READ | KEY_WRITE,
00641 &attributes);
00642
00643
if (
NT_SUCCESS (status)) {
00644
00645
if (PreventDuplication) {
00646
00647
00648
00649
00650
00651
00652
00653
00654
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_DOCKING_STATE);
00655 status =
NtQueryValueKey(aliasEntry,
00656 &name,
00657 KeyValueFullInformation,
00658 valueBuffer,
00659 valueBufferLength,
00660 &len);
00661
00662
if (!
NT_SUCCESS (status) || (keyInfo->Type != REG_DWORD)) {
00663 status = STATUS_REGISTRY_CORRUPT;
00664
goto Exit;
00665 }
00666
00667
if (NewDockState->DockingState !=
00668 * (PULONG) ((PUCHAR) keyInfo + keyInfo->DataOffset)) {
00669
00670
00671
00672
00673
NtClose (aliasEntry);
00674 aliasEntry =
NULL;
00675
continue;
00676 }
00677
00678
00679
00680
00681
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_ACPI_SERIAL_NUMBER);
00682 status =
NtQueryValueKey(aliasEntry,
00683 &name,
00684 KeyValueFullInformation,
00685 valueBuffer,
00686 valueBufferLength,
00687 &len);
00688
00689
if (!
NT_SUCCESS (status) || (keyInfo->Type != REG_BINARY)) {
00690 status = STATUS_REGISTRY_CORRUPT;
00691
goto Exit;
00692 }
00693
00694
if (NewDockState->SerialLength != keyInfo->DataLength) {
00695
00696
00697
00698
00699
NtClose (aliasEntry);
00700 aliasEntry =
NULL;
00701
continue;
00702 }
00703
00704
if (!RtlEqualMemory (NewDockState->SerialNumber,
00705 ((PUCHAR) keyInfo + keyInfo->DataOffset),
00706 NewDockState->SerialLength)) {
00707
00708
00709
00710
00711
NtClose (aliasEntry);
00712 aliasEntry =
NULL;
00713
continue;
00714 }
00715
00716 status = STATUS_SUCCESS;
00717
goto Exit;
00718
00719 }
00720
00721 }
else if (STATUS_OBJECT_NAME_NOT_FOUND == status) {
00722 status = STATUS_SUCCESS;
00723
break;
00724
00725 }
else {
00726
break;
00727 }
00728
00729 }
00730
if (!
NT_SUCCESS (status)) {
00731
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
00732 KdPrint((
"CM: cmpCreateAcpiAliasEntry error finding new set %08lx\n",
00733 status));
00734 }
00735 aliasEntry = 0;
00736
goto Exit;
00737 }
00738
00739 status =
NtCreateKey (&aliasEntry,
00740 KEY_READ | KEY_WRITE,
00741 &attributes,
00742 0,
00743
NULL,
00744 0,
00745 &disposition);
00746
00747
if (!
NT_SUCCESS (status)) {
00748
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
00749 KdPrint((
"CM: cmpCreateAcpiAliasEntry error creating new set %08lx\n",
00750 status));
00751 }
00752 aliasEntry = 0;
00753
goto Exit;
00754 }
00755
00756
00757
00758
00759 value = NewDockState->DockingState;
00760
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_DOCKING_STATE);
00761 status =
NtSetValueKey (aliasEntry,
00762 &name,
00763 0,
00764 REG_DWORD,
00765 &value,
00766
sizeof (value));
00767
00768
00769
00770
00771
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_ACPI_SERIAL_NUMBER);
00772 status =
NtSetValueKey (aliasEntry,
00773 &name,
00774 0,
00775 REG_BINARY,
00776 NewDockState->SerialNumber,
00777 NewDockState->SerialLength);
00778
00779
00780
00781
00782 value = ProfileNumber;
00783
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_PROFILE_NUMBER);
00784 status =
NtSetValueKey (aliasEntry,
00785 &name,
00786 0,
00787 REG_DWORD,
00788 &value,
00789
sizeof (value));
00790
00791 Exit:
00792
00793
if (aliasKey) {
00794
NtClose (aliasKey);
00795 }
00796
00797
if (aliasEntry) {
00798
NtClose (aliasEntry);
00799 }
00800
00801
return status;
00802 }
00803
00804
NTSTATUS
00805 CmSetAcpiHwProfile (
00806 IN
PPROFILE_ACPI_DOCKING_STATE NewDockState,
00807 IN PCM_ACPI_SELECTION_ROUTINE Select,
00808 IN PVOID Context,
00809 OUT PHANDLE NewProfile,
00810 OUT PBOOLEAN ProfileChanged
00811 )
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835 {
00836
NTSTATUS status = STATUS_SUCCESS;
00837 HANDLE IDConfigDB =
NULL;
00838 HANDLE HardwareProfile =
NULL;
00839 HANDLE currentInfo =
NULL;
00840 HANDLE currentSymLink =
NULL;
00841 HANDLE parent =
NULL;
00842 WCHAR nameBuffer[128];
00843 UNICODE_STRING name;
00844 UCHAR valueBuffer[256];
00845 ULONG len;
00846 ULONG i;
00847 ULONG selectedElement;
00848 ULONG profileNum;
00849 ULONG currentDockingState;
00850 ULONG currentProfileNumber;
00851 ULONG disposition;
00852 ULONG flags;
00853 PWCHAR currentAcpiSN =
NULL;
00854
PCM_HARDWARE_PROFILE_ACPI_ALIAS_LIST AliasList =
NULL;
00855
PCM_HARDWARE_PROFILE_LIST ProfileList =
NULL;
00856 PKEY_VALUE_FULL_INFORMATION value;
00857 OBJECT_ATTRIBUTES attributes;
00858
00859
PAGED_CODE ();
00860
00861 *ProfileChanged =
FALSE;
00862
00863 value = (PKEY_VALUE_FULL_INFORMATION) valueBuffer;
00864
00865
00866
00867
00868
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_DATABASE);
00869 InitializeObjectAttributes (&attributes,
00870 &name,
00871 OBJ_CASE_INSENSITIVE,
00872
NULL,
00873
NULL);
00874
00875 status = ZwOpenKey (&IDConfigDB,
00876 KEY_READ,
00877 &attributes);
00878
00879
if (!
NT_SUCCESS (status)) {
00880 IDConfigDB =
NULL;
00881
goto Clean;
00882 }
00883
00884
00885
00886
00887 status =
CmpGetAcpiProfileInformation (IDConfigDB,
00888 &ProfileList,
00889 &AliasList,
00890 nameBuffer,
00891 valueBuffer,
00892
sizeof (valueBuffer));
00893
00894
if (!
NT_SUCCESS (status)) {
00895
goto Clean;
00896 }
00897
00898
00899
00900
00901
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_CCS_CURRENT);
00902 InitializeObjectAttributes (&attributes,
00903 &name,
00904 OBJ_CASE_INSENSITIVE,
00905
NULL,
00906
NULL);
00907
00908 status = ZwOpenKey (&HardwareProfile,
00909 KEY_READ,
00910 &attributes);
00911
if (!
NT_SUCCESS (status)) {
00912 HardwareProfile =
NULL;
00913
goto Clean;
00914 }
00915
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_CURRENT_DOCK_INFO);
00916 InitializeObjectAttributes (&attributes,
00917 &name,
00918 OBJ_CASE_INSENSITIVE,
00919 IDConfigDB,
00920
NULL);
00921
00922 status = ZwOpenKey (¤tInfo,
00923 KEY_READ,
00924 &attributes);
00925
if (!
NT_SUCCESS (status)) {
00926 currentInfo =
NULL;
00927
goto Clean;
00928 }
00929
00930
00931
00932
00933
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_DOCKING_STATE);
00934 status =
NtQueryValueKey (currentInfo,
00935 &name,
00936 KeyValueFullInformation,
00937 valueBuffer,
00938
sizeof (valueBuffer),
00939 &len);
00940
00941
if (!
NT_SUCCESS (status) || (value->Type != REG_DWORD)) {
00942 status = STATUS_REGISTRY_CORRUPT;
00943
goto Clean;
00944 }
00945 currentDockingState = * (PULONG) ((PUCHAR) value + value->DataOffset);
00946
00947
00948
00949
00950
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_ACPI_SERIAL_NUMBER);
00951 status =
NtQueryValueKey(currentInfo,
00952 &name,
00953 KeyValueFullInformation,
00954 valueBuffer,
00955
sizeof (valueBuffer),
00956 &len);
00957
00958
if (
NT_SUCCESS (status) && (value->Type == REG_BINARY)) {
00959
00960 currentAcpiSN =
ExAllocatePool (
PagedPool, value->DataLength);
00961
00962
if (
NULL == currentAcpiSN) {
00963 status = STATUS_INSUFFICIENT_RESOURCES;
00964
goto Clean;
00965 }
00966 RtlCopyMemory (currentAcpiSN,
00967 (PUCHAR) value + value->DataOffset,
00968 value->DataLength);
00969 }
else {
00970 currentAcpiSN = 0;
00971 }
00972
00973
00974
00975
00976
RtlInitUnicodeString(&name,
L"CurrentConfig");
00977 status =
NtQueryValueKey(IDConfigDB,
00978 &name,
00979 KeyValueFullInformation,
00980 valueBuffer,
00981
sizeof (valueBuffer),
00982 &len);
00983
00984
if (!
NT_SUCCESS(status) || (value->Type != REG_DWORD)) {
00985 status = STATUS_REGISTRY_CORRUPT;
00986
goto Clean;
00987 }
00988 currentProfileNumber = *(PULONG)((PUCHAR)value + value->DataOffset);
00989
00990
00991
00992
00993
00994 status =
CmpFilterAcpiDockingState (NewDockState,
00995 currentDockingState,
00996 currentAcpiSN,
00997 currentProfileNumber,
00998 ProfileList,
00999 AliasList);
01000
01001
if (!
NT_SUCCESS (status)) {
01002
goto Clean;
01003 }
01004
01005
01006
01007
01008 status = Select (ProfileList, &selectedElement, Context);
01009
01010
01011
01012
01013
01014
if (-1 == selectedElement) {
01015
ASSERT (STATUS_MORE_PROCESSING_REQUIRED == status);
01016
goto Clean;
01017 }
01018
01019
if (!
NT_SUCCESS (status)) {
01020
goto Clean;
01021 }
01022
01023
01024
01025
01026
01027
01028
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_CCS_HWPROFILE);
01029 InitializeObjectAttributes (&attributes,
01030 &name,
01031 OBJ_CASE_INSENSITIVE,
01032
NULL,
01033
NULL);
01034 status = ZwOpenKey (&parent, KEY_READ, &attributes);
01035
if (!
NT_SUCCESS (status)) {
01036 parent =
NULL;
01037
goto Clean;
01038 }
01039
01040
01041
01042
01043 flags = ProfileList->
Profile[selectedElement].
Flags;
01044 profileNum = ProfileList->
Profile[selectedElement].
Id;
01045
01046
01047
01048
01049
if (flags &
CM_HP_FLAGS_DUPLICATE) {
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
ASSERT (flags &
CM_HP_FLAGS_TRUE_MATCH);
01064
ASSERT (!(flags &
CM_HP_FLAGS_PRISTINE));
01065
01066 status =
CmpMoveBiosAliasTable (IDConfigDB,
01067 currentInfo,
01068 currentProfileNumber,
01069 profileNum,
01070 nameBuffer,
01071 valueBuffer,
01072
sizeof (valueBuffer));
01073
01074
if (!
NT_SUCCESS (status)) {
01075
goto Clean;
01076 }
01077 }
01078
01079
if ((flags &
CM_HP_FLAGS_PRISTINE) || (profileNum != currentProfileNumber)){
01080
01081
01082
01083 *ProfileChanged =
TRUE;
01084
01085
ASSERT (currentInfo);
01086 ZwClose (currentInfo);
01087 currentInfo =
NULL;
01088
01089
if (flags &
CM_HP_FLAGS_PRISTINE) {
01090
01091
01092
01093
ASSERT (!(flags &
CM_HP_FLAGS_TRUE_MATCH));
01094 status =
CmpCloneHwProfile (IDConfigDB,
01095 parent,
01096 HardwareProfile,
01097 profileNum,
01098 NewDockState->DockingState,
01099 &HardwareProfile,
01100 &profileNum);
01101
if (!
NT_SUCCESS (status)) {
01102 HardwareProfile = 0;
01103
goto Clean;
01104 }
01105 }
else {
01106
ASSERT (HardwareProfile);
01107 ZwClose (HardwareProfile);
01108
01109
01110
01111
01112 swprintf (nameBuffer,
L"%04d\0", profileNum);
01113
RtlInitUnicodeString (&name, nameBuffer);
01114 InitializeObjectAttributes (&attributes,
01115 &name,
01116 OBJ_CASE_INSENSITIVE,
01117 parent,
01118
NULL);
01119 status = ZwOpenKey (&HardwareProfile, KEY_READ, &attributes);
01120
if (!
NT_SUCCESS (status)) {
01121 HardwareProfile =
NULL;
01122
goto Clean;
01123 }
01124 }
01125
01126
ASSERT (currentProfileNumber != profileNum);
01127
01128
01129
01130
01131
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_CURRENT_DOCK_INFO);
01132 InitializeObjectAttributes (&attributes,
01133 &name,
01134 OBJ_CASE_INSENSITIVE,
01135 IDConfigDB,
01136
NULL);
01137
01138 status =
NtCreateKey (¤tInfo,
01139 KEY_READ | KEY_WRITE,
01140 &attributes,
01141 0,
01142
NULL,
01143 REG_OPTION_VOLATILE,
01144 &disposition);
01145
01146
if (!
NT_SUCCESS (status)) {
01147 currentInfo =
NULL;
01148
goto Clean;
01149 }
01150
01151
01152
01153
01154
RtlInitUnicodeString(&name,
L"CurrentConfig");
01155 status =
NtSetValueKey(IDConfigDB,
01156 &name,
01157 0,
01158 REG_DWORD,
01159 &profileNum,
01160
sizeof (profileNum));
01161
01162
if (!
NT_SUCCESS(status)) {
01163 status = STATUS_REGISTRY_CORRUPT;
01164
goto Clean;
01165 }
01166 }
01167
01168
01169
01170
01171 i = NewDockState->DockingState;
01172
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_DOCKING_STATE);
01173 status = ZwSetValueKey (currentInfo,
01174 &name,
01175 0,
01176 REG_DWORD,
01177 &i,
01178
sizeof (ULONG));
01179
01180
01181
01182
01183
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_ACPI_SERIAL_NUMBER);
01184 status = ZwSetValueKey (currentInfo,
01185 &name,
01186 0,
01187 REG_BINARY,
01188 NewDockState->SerialNumber,
01189 NewDockState->SerialLength);
01190
01191
if (!(flags &
CM_HP_FLAGS_TRUE_MATCH)) {
01192
01193
01194
01195 status =
CmpAddAcpiAliasEntry (IDConfigDB,
01196 NewDockState,
01197 profileNum,
01198 nameBuffer,
01199 valueBuffer,
01200
sizeof (valueBuffer),
01201
FALSE);
01202 }
01203
01204
if (profileNum != currentProfileNumber) {
01205
01206
01207
01208
RtlInitUnicodeString(&name,
CM_HARDWARE_PROFILE_STR_CCS_CURRENT);
01209 InitializeObjectAttributes(&attributes,
01210 &name,
01211 OBJ_CASE_INSENSITIVE | OBJ_OPENLINK,
01212
NULL,
01213
NULL);
01214
01215 status =
NtCreateKey(¤tSymLink,
01216 KEY_CREATE_LINK,
01217 &attributes,
01218 0,
01219
NULL,
01220 REG_OPTION_OPEN_LINK,
01221 &disposition);
01222
01223
ASSERT (STATUS_SUCCESS == status);
01224
ASSERT (REG_OPENED_EXISTING_KEY == disposition);
01225
01226 swprintf (nameBuffer,
01227
L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\%04d",
01228 profileNum);
01229
RtlInitUnicodeString (&name, nameBuffer);
01230 status =
NtSetValueKey (currentSymLink,
01231 &
CmSymbolicLinkValueName,
01232 0,
01233 REG_LINK,
01234 name.Buffer,
01235 name.Length);
01236
01237
ASSERT (STATUS_SUCCESS == status);
01238 }
01239
01240
01241 Clean:
01242
if (
NT_SUCCESS (status)) {
01243
01244 *NewProfile = HardwareProfile;
01245 }
else if (
NULL != HardwareProfile) {
01246 ZwClose (HardwareProfile);
01247 }
01248
01249
if (
NULL != IDConfigDB) {
01250 ZwClose (IDConfigDB);
01251 }
01252
if (
NULL != currentInfo) {
01253 ZwClose (currentInfo);
01254 }
01255
if (
NULL != parent) {
01256 ZwClose (parent);
01257 }
01258
if (
NULL != currentAcpiSN) {
01259
ExFreePool (currentAcpiSN);
01260 }
01261
if (
NULL != ProfileList) {
01262
for (i = 0; i < ProfileList->
CurrentProfileCount; i++) {
01263
if (ProfileList->
Profile[i].
FriendlyName) {
01264
ExFreePool (ProfileList->
Profile[i].
FriendlyName);
01265 }
01266 }
01267
ExFreePool (ProfileList);
01268 }
01269
if (
NULL != AliasList) {
01270
for (i = 0; i < AliasList->
CurrentAliasCount; i++) {
01271
if (AliasList->
Alias[i].
SerialNumber) {
01272
ExFreePool (AliasList->
Alias[i].
SerialNumber);
01273 }
01274 }
01275
ExFreePool (AliasList);
01276 }
01277
01278
return status;
01279 }
01280
01281
NTSTATUS
01282 CmpFilterAcpiDockingState (
01283 IN
PPROFILE_ACPI_DOCKING_STATE NewDockingState,
01284 IN ULONG CurrentDockState,
01285 IN PWCHAR CurrentAcpiSN,
01286 IN ULONG CurrentProfileNumber,
01287 IN OUT
PCM_HARDWARE_PROFILE_LIST ProfileList,
01288 IN OUT
PCM_HARDWARE_PROFILE_ACPI_ALIAS_LIST AliasList
01289 )
01290
01291
01292
01293
01294
01295
01296 {
01297
NTSTATUS status = STATUS_SUCCESS;
01298 ULONG i = 0;
01299 ULONG j;
01300 ULONG len;
01301 ULONG mask =
HW_PROFILE_DOCKSTATE_UNDOCKED |
HW_PROFILE_DOCKSTATE_DOCKED;
01302 ULONG flags;
01303
PCM_HARDWARE_PROFILE_ACPI_ALIAS alias;
01304 BOOLEAN trueMatch =
FALSE;
01305 BOOLEAN dupDetect =
FALSE;
01306 BOOLEAN currentListed =
FALSE;
01307 BOOLEAN keepCurrent =
FALSE;
01308
01309
PAGED_CODE ();
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
if (AliasList) {
01334
while (i < AliasList->CurrentAliasCount) {
01335 alias = &AliasList->Alias[i];
01336
01337
if (((alias->
DockState & mask) != 0) &&
01338 ((alias->
DockState & mask) !=
01339 (NewDockingState->DockingState & mask))) {
01340
01341
01342
01343
01344
01345 ;
01346
01347 }
else if (alias->
SerialLength != NewDockingState->SerialLength) {
01348
01349
01350
01351 ;
01352
01353 }
else if (alias->
SerialLength ==
01354 RtlCompareMemory (NewDockingState->SerialNumber,
01355 alias->
SerialNumber,
01356 alias->
SerialLength)) {
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
for (j = 0; j < ProfileList->CurrentProfileCount; j++) {
01368
if (ProfileList->Profile[j].Id == alias->
ProfileNumber) {
01369
01370
01371
01372
01373
ASSERT (!(ProfileList->Profile[j].Flags &
01374
CM_HP_FLAGS_PRISTINE));
01375
01376 ProfileList->Profile[j].Flags |=
CM_HP_FLAGS_TRUE_MATCH;
01377 trueMatch =
TRUE;
01378 }
01379
if ((CurrentDockState == NewDockingState->DockingState) &&
01380 (
NULL == CurrentAcpiSN)) {
01381
01382
01383
01384
01385
01386 dupDetect =
TRUE;
01387 }
01388
if (alias->
ProfileNumber == CurrentProfileNumber) {
01389
01390
01391
01392
01393
01394
01395 currentListed =
TRUE;
01396 }
01397 }
01398 }
01399 i++;
01400 }
01401 }
01402
01403
if ((!dupDetect) &&
01404 (
NULL == CurrentAcpiSN) &&
01405 (!trueMatch) &&
01406 (CurrentDockState == NewDockingState->DockingState)) {
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418 keepCurrent =
TRUE;
01419 trueMatch =
TRUE;
01420 }
01421
01422 i = 0;
01423
while (i < ProfileList->CurrentProfileCount) {
01424
01425 flags = ProfileList->Profile[i].Flags;
01426
01427
if (dupDetect) {
01428
if (flags &
CM_HP_FLAGS_TRUE_MATCH) {
01429
if (currentListed) {
01430
if (ProfileList->Profile[i].Id == CurrentProfileNumber) {
01431
01432
01433
01434
01435 i++;
01436
continue;
01437 }
01438
01439
01440
01441
01442 ;
01443
01444 }
else {
01445
01446
01447
01448
01449
01450
01451 ProfileList->Profile[i].Flags |=
CM_HP_FLAGS_DUPLICATE;
01452 i++;
01453
continue;
01454 }
01455 }
01456
01457
01458
01459 ;
01460
01461 }
else if ((flags &
CM_HP_FLAGS_PRISTINE) && !trueMatch) {
01462
01463
01464
01465 i++;
01466
continue;
01467
01468 }
else if (flags &
CM_HP_FLAGS_ALIASABLE) {
01469
01470
01471
01472
ASSERT (! (flags &
CM_HP_FLAGS_PRISTINE));
01473 i++;
01474
continue;
01475
01476 }
else if (flags &
CM_HP_FLAGS_TRUE_MATCH) {
01477
01478
01479
01480 i++;
01481
continue;
01482
01483 }
else if (keepCurrent &&
01484 (ProfileList->Profile[i].Id == CurrentProfileNumber)) {
01485
01486
01487
01488 i++;
01489
continue;
01490 }
01491
01492
01493
01494
01495
01496
01497 len = ProfileList->CurrentProfileCount - i - 1;
01498
if (0 < len) {
01499 RtlMoveMemory(&ProfileList->Profile[i],
01500 &ProfileList->Profile[i+1],
01501
sizeof(
CM_HARDWARE_PROFILE) * len);
01502 }
01503
01504 --ProfileList->CurrentProfileCount;
01505 }
01506
01507
return status;
01508 }
01509
01510
01511
01512
NTSTATUS
01513 CmpMoveBiosAliasTable (
01514 IN HANDLE IDConfigDB,
01515 IN HANDLE CurrentInfo,
01516 IN ULONG CurrentProfileNumber,
01517 IN ULONG NewProfileNumber,
01518 IN PWCHAR nameBuffer,
01519 IN PCHAR valueBuffer,
01520 IN ULONG bufferLen
01521 )
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536 {
01537
NTSTATUS status = STATUS_SUCCESS;
01538 HANDLE alias =
NULL;
01539 HANDLE entry =
NULL;
01540 HANDLE hwprofile =
NULL;
01541 UNICODE_STRING name;
01542 ULONG currentDockId;
01543 ULONG currentSerialNumber;
01544 ULONG len;
01545 ULONG i;
01546 OBJECT_ATTRIBUTES attributes;
01547 KEY_FULL_INFORMATION keyInfo;
01548 PKEY_BASIC_INFORMATION basicInfo;
01549 PKEY_VALUE_FULL_INFORMATION value;
01550
01551
PAGED_CODE ();
01552
01553 value = (PKEY_VALUE_FULL_INFORMATION) valueBuffer;
01554 basicInfo = (PKEY_BASIC_INFORMATION) valueBuffer;
01555
01556
01557
01558
01559
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_SERIAL_NUMBER);
01560 status =
NtQueryValueKey(CurrentInfo,
01561 &name,
01562 KeyValueFullInformation,
01563 valueBuffer,
01564 bufferLen,
01565 &len);
01566
if (!
NT_SUCCESS (status) || (value->Type != REG_DWORD)) {
01567 status = STATUS_REGISTRY_CORRUPT;
01568
goto Clean;
01569 }
01570 currentSerialNumber = * (PULONG) ((PUCHAR) value + value->DataOffset);
01571
01572
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_DOCKID);
01573 status =
NtQueryValueKey(CurrentInfo,
01574 &name,
01575 KeyValueFullInformation,
01576 valueBuffer,
01577 bufferLen,
01578 &len);
01579
if (!
NT_SUCCESS (status) || (value->Type != REG_DWORD)) {
01580 status = STATUS_REGISTRY_CORRUPT;
01581
goto Clean;
01582 }
01583 currentDockId = * (PULONG) ((PUCHAR) value + value->DataOffset);
01584
01585
01586
01587
01588
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_ALIAS);
01589 InitializeObjectAttributes (&attributes,
01590 &name,
01591 OBJ_CASE_INSENSITIVE,
01592 IDConfigDB,
01593
NULL);
01594 status = ZwOpenKey (&alias,
01595 KEY_READ,
01596 &attributes);
01597
01598
if (!
NT_SUCCESS (status)) {
01599
01600
01601
01602 status = STATUS_SUCCESS;
01603 alias =
NULL;
01604
goto Clean;
01605 }
01606
01607
01608 status = ZwQueryKey (alias,
01609 KeyFullInformation,
01610 &keyInfo,
01611
sizeof (keyInfo),
01612 &len);
01613
01614
if (!
NT_SUCCESS (status)) {
01615
goto Clean;
01616 }
01617
ASSERT (0 < keyInfo.SubKeys);
01618
01619
01620
01621
01622
for (i = 0; i < keyInfo.SubKeys; i++) {
01623
01624
01625
01626
01627 status = ZwEnumerateKey (alias,
01628 i,
01629 KeyBasicInformation,
01630 basicInfo,
01631 bufferLen -
sizeof (UNICODE_NULL),
01632 &len);
01633
01634
if (!
NT_SUCCESS (status)) {
01635
01636
01637
01638
break;
01639 }
01640
01641 basicInfo->Name [basicInfo->NameLength/
sizeof(WCHAR)] = 0;
01642 name.Length = (
USHORT) basicInfo->NameLength;
01643 name.MaximumLength = (
USHORT) basicInfo->NameLength +
sizeof (UNICODE_NULL);
01644 name.Buffer = basicInfo->Name;
01645
01646 InitializeObjectAttributes (&attributes,
01647 &name,
01648 OBJ_CASE_INSENSITIVE,
01649 alias,
01650
NULL);
01651 status = ZwOpenKey (&entry,
01652 KEY_READ | KEY_WRITE,
01653 &attributes);
01654
if (!
NT_SUCCESS (status)) {
01655
break;
01656 }
01657
01658
01659
01660
01661
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_PROFILE_NUMBER);
01662 status =
NtQueryValueKey(entry,
01663 &name,
01664 KeyValueFullInformation,
01665 valueBuffer,
01666 bufferLen,
01667 &len);
01668
01669
if (!
NT_SUCCESS (status) || (value->Type != REG_DWORD)) {
01670 status = STATUS_REGISTRY_CORRUPT;
01671
goto Clean;
01672 }
01673
01674
if (CurrentProfileNumber != *(PULONG)((PUCHAR)value + value->DataOffset)) {
01675
01676
01677
01678
01679 ZwClose (entry);
01680 entry =
NULL;
01681
continue;
01682 }
01683
01684
01685
01686
01687
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_DOCKID);
01688 status =
NtQueryValueKey(entry,
01689 &name,
01690 KeyValueFullInformation,
01691 valueBuffer,
01692 bufferLen,
01693 &len);
01694
if (!
NT_SUCCESS (status) || (value->Type != REG_DWORD)) {
01695 status = STATUS_REGISTRY_CORRUPT;
01696
goto Clean;
01697 }
01698
if (currentDockId != * (PULONG) ((PUCHAR) value + value->DataOffset)) {
01699
01700
01701
01702 ZwClose (entry);
01703 entry =
NULL;
01704
continue;
01705 }
01706
01707
01708
01709
01710
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_SERIAL_NUMBER);
01711 status =
NtQueryValueKey(entry,
01712 &name,
01713 KeyValueFullInformation,
01714 valueBuffer,
01715 bufferLen,
01716 &len);
01717
if (!
NT_SUCCESS (status) || (value->Type != REG_DWORD)) {
01718 status = STATUS_REGISTRY_CORRUPT;
01719
goto Clean;
01720 }
01721
if (currentSerialNumber != *(PULONG)((PUCHAR)value + value->DataOffset)) {
01722
01723
01724
01725 ZwClose (entry);
01726 entry =
NULL;
01727
continue;
01728 }
01729
01730
01731
01732
01733
01734
01735
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_PROFILE_NUMBER);
01736 status =
NtSetValueKey (entry,
01737 &name,
01738 0,
01739 REG_DWORD,
01740 &NewProfileNumber,
01741
sizeof (NewProfileNumber));
01742
01743
ASSERT (STATUS_SUCCESS == status);
01744
01745 ZwClose (entry);
01746 entry =
NULL;
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_HARDWARE_PROFILES);
01757 InitializeObjectAttributes (&attributes,
01758 &name,
01759 OBJ_CASE_INSENSITIVE,
01760 IDConfigDB,
01761
NULL);
01762 status = ZwOpenKey (&hwprofile, KEY_READ | KEY_WRITE, &attributes);
01763
if (!
NT_SUCCESS (status)) {
01764 hwprofile =
NULL;
01765 status = STATUS_REGISTRY_CORRUPT;
01766
goto Clean;
01767 }
01768
01769 swprintf (nameBuffer,
L"%04d\0", CurrentProfileNumber);
01770
RtlInitUnicodeString (&name, nameBuffer);
01771 InitializeObjectAttributes (&attributes,
01772 &name,
01773 OBJ_CASE_INSENSITIVE,
01774 hwprofile,
01775
NULL);
01776 status = ZwOpenKey (&entry, KEY_ALL_ACCESS, &attributes);
01777
if (!
NT_SUCCESS (status)) {
01778 entry =
NULL;
01779 status = STATUS_REGISTRY_CORRUPT;
01780
goto Clean;
01781 }
01782
01783
01784
01785
01786
01787
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_CLONED);
01788 status =
NtQueryValueKey(entry,
01789 &name,
01790 KeyValueFullInformation,
01791 valueBuffer,
01792 bufferLen,
01793 &len);
01794
01795
if (!
NT_SUCCESS (status) || (value->Type != REG_DWORD)) {
01796 status = STATUS_REGISTRY_CORRUPT;
01797
goto Clean;
01798 }
01799
01800
if (*(PULONG)((PUCHAR)value + value->DataOffset)) {
01801
01802
01803
01804 status = ZwDeleteKey (entry);
01805
ASSERT (
NT_SUCCESS (status));
01806
01807 ZwClose (entry);
01808 ZwClose (hwprofile);
01809 entry = hwprofile =
NULL;
01810
01811
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_CCS_HWPROFILE);
01812 InitializeObjectAttributes (&attributes,
01813 &name,
01814 OBJ_CASE_INSENSITIVE,
01815
NULL,
01816
NULL);
01817 status = ZwOpenKey (&hwprofile, KEY_READ | KEY_WRITE, &attributes);
01818
if (!
NT_SUCCESS (status)) {
01819 hwprofile =
NULL;
01820 status = STATUS_REGISTRY_CORRUPT;
01821
goto Clean;
01822 }
01823
01824 swprintf (nameBuffer,
L"%04d\0", CurrentProfileNumber);
01825
01826 status =
CmDeleteKeyRecursive (hwprofile,
01827 nameBuffer,
01828 valueBuffer,
01829 bufferLen,
01830
TRUE);
01831
01832
ASSERT (
NT_SUCCESS (status));
01833 ZwClose (hwprofile);
01834 hwprofile =
NULL;
01835
01836 }
else {
01837
01838
01839
01840
01841 ZwClose (entry);
01842 ZwClose (hwprofile);
01843 entry = hwprofile =
NULL;
01844 }
01845
01846
CM_HARDWARE_PROFILE_STR_CCS_HWPROFILE;
01847
01848
01849
01850 }
01851
01852 Clean:
01853
01854
if (alias) {
01855 ZwClose (alias);
01856 }
01857
if (entry) {
01858 ZwClose (entry);
01859 }
01860
if (hwprofile) {
01861 ZwClose (hwprofile);
01862 }
01863
01864
return status;
01865 }
01866
01867
01868
NTSTATUS
01869 CmpCloneHwProfile (
01870 IN HANDLE IDConfigDB,
01871 IN HANDLE Parent,
01872 IN HANDLE OldProfile,
01873 IN ULONG OldProfileNumber,
01874 IN USHORT DockingState,
01875 OUT PHANDLE NewProfile,
01876 OUT PULONG NewProfileNumber
01877 )
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898 {
01899
NTSTATUS status = STATUS_SUCCESS;
01900 UNICODE_STRING newProfileName;
01901 UNICODE_STRING name;
01902 UNICODE_STRING friendlyName;
01903 UNICODE_STRING guidStr;
01904
PCM_KEY_BODY oldProfileKey;
01905
PCM_KEY_BODY newProfileKey;
01906 OBJECT_ATTRIBUTES attributes;
01907 PSECURITY_DESCRIPTOR security;
01908 ULONG securityLength;
01909 WCHAR nameBuffer [64];
01910 HANDLE IDConfigDBEntry =
NULL;
01911 ULONG disposition;
01912 ULONG value;
01913
UUID uuid;
01914 PKEY_BASIC_INFORMATION keyBasicInfo;
01915 PKEY_FULL_INFORMATION keyFullInfo;
01916 PKEY_VALUE_FULL_INFORMATION keyValueInfo;
01917 ULONG length, profileSubKeys, i;
01918 UCHAR valueBuffer[256];
01919 HANDLE hardwareProfiles=
NULL;
01920 HANDLE profileEntry=
NULL;
01921
01922
PAGED_CODE ();
01923
01924 keyFullInfo = (PKEY_FULL_INFORMATION) valueBuffer;
01925 keyBasicInfo = (PKEY_BASIC_INFORMATION) valueBuffer;
01926 keyValueInfo = (PKEY_VALUE_FULL_INFORMATION) valueBuffer;
01927
01928 *NewProfile = 0;
01929 *NewProfileNumber = OldProfileNumber;
01930
01931
01932
01933
01934
01935
while (*NewProfileNumber < 200) {
01936 (*NewProfileNumber)++;
01937
01938 swprintf (nameBuffer,
L"%04d", *NewProfileNumber);
01939
RtlInitUnicodeString (&newProfileName, nameBuffer);
01940
01941 InitializeObjectAttributes(&attributes,
01942 &newProfileName,
01943 OBJ_CASE_INSENSITIVE,
01944 Parent,
01945
NULL);
01946
01947 status =
NtOpenKey (NewProfile,
01948 KEY_READ | KEY_WRITE,
01949 &attributes);
01950
01951
if (
NT_SUCCESS (status)) {
01952
NtClose (*NewProfile);
01953
01954 }
else if (STATUS_OBJECT_NAME_NOT_FOUND == status) {
01955 status = STATUS_SUCCESS;
01956
break;
01957
01958 }
else {
01959
break;
01960 }
01961
01962 }
01963
if (!
NT_SUCCESS (status)) {
01964
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
01965 KdPrint((
"CM: CmpCloneHwProfile error finding new profile key %08lx\n", status));
01966 }
01967
goto Exit;
01968 }
01969
01970
01971
01972
01973
01974 status =
NtQuerySecurityObject (OldProfile,
01975 DACL_SECURITY_INFORMATION,
01976
NULL,
01977 0,
01978 &securityLength);
01979
01980
if (STATUS_BUFFER_TOO_SMALL == status) {
01981
01982 security =
ExAllocatePool (
PagedPool, securityLength);
01983
01984
if (security !=
NULL) {
01985 status =
NtQuerySecurityObject(OldProfile,
01986 DACL_SECURITY_INFORMATION,
01987 security,
01988 securityLength,
01989 &securityLength);
01990
if (!
NT_SUCCESS (status)) {
01991
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
01992 KdPrint((
"CM: CmpCloneHwProfile"
01993
" - NtQuerySecurityObject failed %08lx\n", status));
01994 }
01995
ExFreePool(security);
01996 security=
NULL;
01997 }
01998 }
01999 }
else {
02000
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
02001 KdPrint((
"CM: CmpCloneHwProfile"
02002
" - NtQuerySecurityObject returned %08lx\n", status));
02003 }
02004 security=
NULL;
02005 }
02006
02007
02008
02009
02010 InitializeObjectAttributes (&attributes,
02011 &newProfileName,
02012 OBJ_CASE_INSENSITIVE,
02013 Parent,
02014 security);
02015
02016 status =
NtCreateKey (NewProfile,
02017 KEY_READ | KEY_WRITE,
02018 &attributes,
02019 0,
02020
NULL,
02021 0,
02022 &disposition);
02023
02024
if (
NULL != security) {
02025
ExFreePool (security);
02026 }
02027
if (!
NT_SUCCESS (status)) {
02028
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
02029 KdPrint((
"CM: CmpCloneHwProfile couldn't create Clone %08lx\n",status));
02030 }
02031
goto Exit;
02032 }
02033
02034
02035
02036
02037
02038
if (disposition != REG_CREATED_NEW_KEY) {
02039
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
02040
02041 }
02042
02043
02044
02045
02046
02047
02048
02049 status = STATUS_SUCCESS;
02050
goto Exit;
02051 }
02052
02053
02054
02055
02056 swprintf (nameBuffer,
L"Hardware Profiles\\%04d", *NewProfileNumber);
02057
RtlInitUnicodeString (&name, nameBuffer);
02058
02059 InitializeObjectAttributes (&attributes,
02060 &name,
02061 OBJ_CASE_INSENSITIVE,
02062 IDConfigDB,
02063
NULL);
02064
02065 status =
NtCreateKey (&IDConfigDBEntry,
02066 KEY_READ | KEY_WRITE,
02067 &attributes,
02068 0,
02069
NULL,
02070 0,
02071 &disposition);
02072
02073
if (!
NT_SUCCESS (status)) {
02074
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
02075 KdPrint((
"CM: CmpCloneHwProfile couldn't create Clone %08lx\n",status));
02076 }
02077 IDConfigDBEntry =
NULL;
02078
goto Exit;
02079 }
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_HARDWARE_PROFILES);
02092
02093 InitializeObjectAttributes (&attributes,
02094 &name,
02095 OBJ_CASE_INSENSITIVE,
02096 IDConfigDB,
02097
NULL);
02098 status = ZwOpenKey (&hardwareProfiles,
02099 KEY_READ,
02100 &attributes);
02101
02102
if (!
NT_SUCCESS (status)) {
02103 hardwareProfiles =
NULL;
02104
goto Exit;
02105 }
02106
02107
02108
02109
02110 status = ZwQueryKey (hardwareProfiles,
02111 KeyFullInformation,
02112 valueBuffer,
02113
sizeof (valueBuffer),
02114 &length);
02115
02116
if (!
NT_SUCCESS (status)) {
02117
goto Exit;
02118 }
02119
02120
02121
02122
02123
02124 profileSubKeys = keyFullInfo->SubKeys;
02125
ASSERT (1 < profileSubKeys);
02126
02127
02128
02129
02130 value = -1;
02131
02132
02133
02134
02135
for (i = 0; i < profileSubKeys; i++) {
02136
02137
02138
02139
02140 status = ZwEnumerateKey (hardwareProfiles,
02141 i,
02142 KeyBasicInformation,
02143 valueBuffer,
02144
sizeof(valueBuffer) -
sizeof (UNICODE_NULL),
02145 &length);
02146
if(!
NT_SUCCESS(status)) {
02147
break;
02148 }
02149
02150
02151
02152
02153 keyBasicInfo->Name[keyBasicInfo->NameLength/
sizeof(WCHAR)] = 0;
02154
02155
02156
02157
02158
if ((!_wtoi(keyBasicInfo->Name)) ||
02159 ((ULONG)(_wtoi(keyBasicInfo->Name)) == *NewProfileNumber)) {
02160
continue;
02161 }
02162
02163
02164
02165
02166 name.Length = (
USHORT) keyBasicInfo->NameLength;
02167 name.MaximumLength = (
USHORT) keyBasicInfo->NameLength +
sizeof (UNICODE_NULL);
02168 name.Buffer = keyBasicInfo->Name;
02169
02170 InitializeObjectAttributes (&attributes,
02171 &name,
02172 OBJ_CASE_INSENSITIVE,
02173 hardwareProfiles,
02174
NULL);
02175 status = ZwOpenKey (&profileEntry,
02176 KEY_READ,
02177 &attributes);
02178
if (!
NT_SUCCESS (status)) {
02179 profileEntry =
NULL;
02180
continue;
02181 }
02182
02183
02184
02185
02186
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_PREFERENCE_ORDER);
02187 status =
NtQueryValueKey(profileEntry,
02188 &name,
02189 KeyValueFullInformation,
02190 valueBuffer,
02191
sizeof(valueBuffer),
02192 &length);
02193
02194
if (!
NT_SUCCESS (status) || (keyValueInfo->Type != REG_DWORD)) {
02195
02196
02197
02198 ZwClose(profileEntry);
02199 profileEntry=
NULL;
02200
continue;
02201 }
02202
02203
02204
02205
02206
02207
02208
if (((*(PULONG) ((PUCHAR)keyValueInfo + keyValueInfo->DataOffset)) > value) ||
02209 (value == -1)) {
02210 value = (* (PULONG) ((PUCHAR)keyValueInfo + keyValueInfo->DataOffset));
02211 }
02212
02213 ZwClose(profileEntry);
02214 profileEntry=
NULL;
02215 }
02216
02217
02218
02219
02220
02221
02222 value += 1;
02223
02224
02225
02226
02227
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_PREFERENCE_ORDER);
02228 status =
NtSetValueKey (IDConfigDBEntry,
02229 &name,
02230 0,
02231 REG_DWORD,
02232 &value,
02233
sizeof (value));
02234
02235
02236
02237
02238 status =
CmpCreateHwProfileFriendlyName(IDConfigDB,
02239 DockingState,
02240 *NewProfileNumber,
02241 &friendlyName);
02242
02243
if (
NT_SUCCESS(status)) {
02244
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_FRIENDLY_NAME);
02245 status =
NtSetValueKey (IDConfigDBEntry,
02246 &name,
02247 0,
02248 REG_SZ,
02249 friendlyName.Buffer,
02250 friendlyName.Length +
sizeof(UNICODE_NULL));
02251
RtlFreeUnicodeString(&friendlyName);
02252 }
02253
02254
02255
02256
02257 value =
FALSE;
02258
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_ALIASABLE);
02259 status =
NtSetValueKey (IDConfigDBEntry,
02260 &name,
02261 0,
02262 REG_DWORD,
02263 &value,
02264
sizeof (value));
02265
02266
02267
02268
02269 value =
TRUE;
02270
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_CLONED);
02271 status =
NtSetValueKey (IDConfigDBEntry,
02272 &name,
02273 0,
02274 REG_DWORD,
02275 &value,
02276
sizeof (value));
02277
02278
02279
02280
02281
02282 status =
ExUuidCreate (&uuid);
02283
if (
NT_SUCCESS (status)) {
02284
02285 status =
RtlStringFromGUID (&uuid, &guidStr);
02286
if (
NT_SUCCESS (status)) {
02287
RtlInitUnicodeString (&name,
CM_HARDWARE_PROFILE_STR_HW_PROFILE_GUID);
02288
02289 status =
NtSetValueKey (IDConfigDBEntry,
02290 &name,
02291 0,
02292 REG_SZ,
02293 guidStr.Buffer,
02294 guidStr.MaximumLength);
02295
02296
RtlFreeUnicodeString(&guidStr);
02297 }
else {
02298
02299
02300
02301
02302 status = STATUS_SUCCESS;
02303 }
02304
02305 }
else {
02306
02307
02308
02309 status = STATUS_SUCCESS;
02310 }
02311
02312
02313
02314
02315
02316
02317
02318
02319 status =
ObReferenceObjectByHandle (OldProfile,
02320 KEY_READ,
02321
CmpKeyObjectType,
02322
KernelMode,
02323 (PVOID *)(&oldProfileKey),
02324
NULL);
02325
02326
if (!
NT_SUCCESS(status)) {
02327
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
02328 KdPrint((
"CM: CmpCloneHWProfile: couldn't reference CurrentHandle %08lx\n",
02329 status));
02330 }
02331
goto Exit;
02332 }
02333
02334
ObReferenceObjectByHandle (*NewProfile,
02335 KEY_WRITE,
02336
CmpKeyObjectType,
02337
KernelMode,
02338 (PVOID *)(&newProfileKey),
02339
NULL);
02340
02341
if (!
NT_SUCCESS(status)) {
02342
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
02343 KdPrint((
"CM: CmpCloneHWProfile: couldn't reference CurrentHandle %08lx\n",
02344 status));
02345 }
02346
goto Exit;
02347 }
02348
02349
CmpLockRegistryExclusive();
02350
02351
02352
02353
02354
02355
02356
02357
if (
CmpCopyTree(oldProfileKey->KeyControlBlock->KeyHive,
02358 oldProfileKey->KeyControlBlock->KeyCell,
02359 newProfileKey->KeyControlBlock->KeyHive,
02360 newProfileKey->KeyControlBlock->KeyCell)) {
02361
02362
02363
02364 newProfileKey->KeyControlBlock->KeyNode->MaxNameLen =
02365 oldProfileKey->KeyControlBlock->KeyNode->MaxNameLen;
02366 status = STATUS_SUCCESS;
02367 }
else {
02368
CMLOG(
CML_BUGCHECK,
CMS_INIT) {
02369 KdPrint((
"CM: CmpCloneHwProfile: tree copy failed.\n"));
02370 }
02371 status = STATUS_REGISTRY_CORRUPT;
02372 }
02373
CmpUnlockRegistry();
02374
02375
02376 Exit:
02377
NtClose (OldProfile);
02378
if (IDConfigDBEntry) {
02379
NtClose (IDConfigDBEntry);
02380 }
02381
if (hardwareProfiles) {
02382
NtClose (hardwareProfiles);
02383 }
02384
if (!
NT_SUCCESS (status)) {
02385
if (*NewProfile) {
02386
NtClose (*NewProfile);
02387 }
02388 }
02389
02390
return status;
02391 }
02392
02393
NTSTATUS
02394 CmDeleteKeyRecursive(
02395 HANDLE hKeyRoot,
02396 PWSTR Key,
02397 PVOID TemporaryBuffer,
02398 ULONG LengthTemporaryBuffer,
02399 BOOLEAN ThisKeyToo
02400 )
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423 {
02424 ULONG ResultLength;
02425 PKEY_BASIC_INFORMATION KeyInfo;
02426
NTSTATUS Status;
02427 UNICODE_STRING UnicodeString;
02428 OBJECT_ATTRIBUTES Obja;
02429 PWSTR SubkeyName;
02430 HANDLE hKey;
02431
02432
02433
02434
02435
02436 KeyInfo = (PKEY_BASIC_INFORMATION)TemporaryBuffer;
02437
02438
02439
02440
02441
02442
RtlInitUnicodeString (&UnicodeString,
Key);
02443
02444 InitializeObjectAttributes(&Obja,
02445 &UnicodeString,
02446 OBJ_CASE_INSENSITIVE,
02447 hKeyRoot,
02448
NULL);
02449
02450
Status = ZwOpenKey(&hKey,KEY_ALL_ACCESS,&Obja);
02451
if( !
NT_SUCCESS(
Status) ) {
02452
return(
Status);
02453 }
02454
02455
02456
02457
02458
02459
02460
while(1) {
02461
Status = ZwEnumerateKey(
02462 hKey,
02463 0,
02464 KeyBasicInformation,
02465 TemporaryBuffer,
02466 LengthTemporaryBuffer,
02467 &ResultLength
02468 );
02469
if(!
NT_SUCCESS(
Status)) {
02470
break;
02471 }
02472
02473
02474
02475
02476 KeyInfo->Name[KeyInfo->NameLength/
sizeof(WCHAR)] = 0;
02477
02478
02479
02480
02481
02482
02483 SubkeyName =
ExAllocatePool (
PagedPool,
02484 ((wcslen (KeyInfo->Name) + 1) *
02485 sizeof (WCHAR)));
02486
if (!SubkeyName) {
02487
Status = STATUS_INSUFFICIENT_RESOURCES;
02488
break;
02489 }
02490 wcscpy(SubkeyName, KeyInfo->Name);
02491
Status =
CmDeleteKeyRecursive( hKey,
02492 SubkeyName,
02493 TemporaryBuffer,
02494 LengthTemporaryBuffer,
02495
TRUE);
02496
ExFreePool(SubkeyName);
02497
if(!
NT_SUCCESS(
Status)) {
02498
break;
02499 }
02500 }
02501
02502
02503
02504
02505
02506
02507
02508
if(
Status == STATUS_NO_MORE_ENTRIES) {
02509
Status = STATUS_SUCCESS;
02510 }
02511
02512
if (!
NT_SUCCESS (
Status)) {
02513 ZwClose(hKey);
02514
return (
Status);
02515 }
02516
02517
02518
02519
02520
if( ThisKeyToo ) {
02521
Status = ZwDeleteKey (hKey);
02522 }
02523
02524 ZwClose(hKey);
02525
return(
Status);
02526 }
02527
02528
NTSTATUS
02529 CmpCreateHwProfileFriendlyName (
02530 IN HANDLE IDConfigDB,
02531 IN ULONG DockingState,
02532 IN ULONG NewProfileNumber,
02533 OUT PUNICODE_STRING FriendlyName
02534 )
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579 {
02580
NTSTATUS status = STATUS_SUCCESS;
02581 ANSI_STRING ansiString;
02582 UNICODE_STRING unicodeString;
02583 UNICODE_STRING labelName, keyName;
02584 PMESSAGE_RESOURCE_ENTRY messageEntry;
02585 PLDR_DATA_TABLE_ENTRY dataTableEntry;
02586 ULONG messageId;
02587 UCHAR valueBuffer[256];
02588 WCHAR friendlyNameBuffer[
MAX_FRIENDLY_NAME_LENGTH/
sizeof(WCHAR)];
02589 PKEY_VALUE_FULL_INFORMATION keyValueInfo;
02590 ULONG length, index;
02591 HANDLE hardwareProfiles=
NULL;
02592 OBJECT_ATTRIBUTES attributes;
02593
02594
PAGED_CODE ();
02595
02596
02597
02598
02599
if (!FriendlyName) {
02600
return STATUS_INVALID_PARAMETER;
02601 }
02602
02603
02604
02605
02606
02607
if (!IDConfigDB) {
02608 status = STATUS_INVALID_PARAMETER;
02609
goto Exit;
02610 }
02611
02612
02613
02614
02615
if ((DockingState &
HW_PROFILE_DOCKSTATE_UNKNOWN) ==
HW_PROFILE_DOCKSTATE_UNKNOWN){
02616 messageId = HARDWARE_PROFILE_UNKNOWN_STRING;
02617
RtlInitUnicodeString(&labelName,
CM_HARDWARE_PROFILE_STR_UNKNOWN);
02618 }
else if (DockingState &
HW_PROFILE_DOCKSTATE_DOCKED) {
02619 messageId = HARDWARE_PROFILE_DOCKED_STRING;
02620
RtlInitUnicodeString(&labelName,
CM_HARDWARE_PROFILE_STR_DOCKED);
02621 }
else if (DockingState &
HW_PROFILE_DOCKSTATE_UNDOCKED) {
02622 messageId = HARDWARE_PROFILE_UNDOCKED_STRING;
02623
RtlInitUnicodeString(&labelName,
CM_HARDWARE_PROFILE_STR_UNDOCKED);
02624 }
else {
02625 messageId = HARDWARE_PROFILE_UNKNOWN_STRING;
02626
RtlInitUnicodeString(&labelName,
CM_HARDWARE_PROFILE_STR_UNKNOWN);
02627 }
02628
02629
02630
02631
02632
02633
02634
02635
if (
KeLoaderBlock) {
02636 dataTableEntry = CONTAINING_RECORD(
KeLoaderBlock->
LoadOrderListHead.Flink,
02637 LDR_DATA_TABLE_ENTRY,
02638 InLoadOrderLinks);
02639 }
else if (
PsLoadedModuleList.Flink) {
02640 dataTableEntry = CONTAINING_RECORD(
PsLoadedModuleList.Flink,
02641 LDR_DATA_TABLE_ENTRY,
02642 InLoadOrderLinks);
02643 }
else {
02644 status = STATUS_UNSUCCESSFUL;
02645
goto Exit;
02646 }
02647
02648 status =
RtlFindMessage(dataTableEntry->DllBase,
02649 (ULONG_PTR)11,
02650 MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT),
02651 messageId,
02652 &messageEntry);
02653
02654
if (!
NT_SUCCESS(status)) {
02655
goto Exit;
02656 }
02657
02658
if(!(messageEntry->Flags & MESSAGE_RESOURCE_UNICODE)) {
02659
02660
02661
02662
02663
RtlInitAnsiString(&ansiString,messageEntry->Text);
02664 status =
RtlAnsiStringToUnicodeString(&unicodeString,&ansiString,
TRUE);
02665 }
else {
02666
02667
02668
02669 status =
RtlCreateUnicodeString(&unicodeString,(PWSTR)messageEntry->Text);
02670 }
02671
02672
if(!
NT_SUCCESS(status)) {
02673
goto Exit;
02674 }
02675
02676
02677
02678
02679
if (unicodeString.Length > 2 *
sizeof(WCHAR)) {
02680 unicodeString.Length -= 2 *
sizeof(WCHAR);
02681 unicodeString.Buffer[unicodeString.Length /
sizeof(WCHAR)] = UNICODE_NULL;
02682 }
02683
02684
02685
02686
02687
02688
02689
if ((unicodeString.Length + 5*
sizeof(WCHAR) +
sizeof(UNICODE_NULL)) >
02690
MAX_FRIENDLY_NAME_LENGTH) {
02691 status = STATUS_UNSUCCESSFUL;
02692
goto Clean;
02693 }
02694
02695
02696
02697
02698
RtlInitUnicodeString(&keyName,
CM_HARDWARE_PROFILE_STR_HARDWARE_PROFILES);
02699 InitializeObjectAttributes(&attributes,
02700 &keyName,
02701 OBJ_CASE_INSENSITIVE,
02702 IDConfigDB,
02703
NULL);
02704 status = ZwOpenKey(&hardwareProfiles,
02705 KEY_READ,
02706 &attributes);
02707
if (!
NT_SUCCESS(status)) {
02708 hardwareProfiles =
NULL;
02709
goto Clean;
02710 }
02711
02712
02713
02714
02715
02716 keyValueInfo = (PKEY_VALUE_FULL_INFORMATION) valueBuffer;
02717 status = ZwQueryValueKey(hardwareProfiles,
02718 &labelName,
02719 KeyValueFullInformation,
02720 valueBuffer,
02721
sizeof(valueBuffer),
02722 &length);
02723
02724
if (
NT_SUCCESS(status) && (keyValueInfo->Type == REG_DWORD)) {
02725
02726
02727
02728 index = (* (PULONG) ((PUCHAR)keyValueInfo + keyValueInfo->DataOffset));
02729 index++;
02730 }
else {
02731
02732
02733
02734 index = 1;
02735 }
02736
02737
02738
02739
02740 status = ZwSetValueKey(hardwareProfiles,
02741 &labelName,
02742 0,
02743 REG_DWORD,
02744 &index,
02745
sizeof(index));
02746
if (!
NT_SUCCESS(status)) {
02747
goto Clean;
02748 }
02749
02750
02751
02752
02753
if ((messageId == HARDWARE_PROFILE_UNKNOWN_STRING) || (index > 1)) {
02754 swprintf(friendlyNameBuffer,
L"%s %u",
02755 unicodeString.Buffer, index);
02756 }
else {
02757 wcscpy(friendlyNameBuffer, unicodeString.Buffer);
02758 }
02759
02760 Clean:
02761
02762
RtlFreeUnicodeString(&unicodeString);
02763
02764
if (hardwareProfiles!=
NULL) {
02765 ZwClose(hardwareProfiles);
02766 }
02767
02768 Exit:
02769
02770
if (!
NT_SUCCESS(status)) {
02771
02772
02773
02774
02775
02776 swprintf (friendlyNameBuffer,
L"%04d", NewProfileNumber);
02777 status = STATUS_SUCCESS;
02778 }
02779
02780
02781
02782
02783
if (!
RtlCreateUnicodeString(FriendlyName, (PWSTR)friendlyNameBuffer)) {
02784 status = STATUS_UNSUCCESSFUL;
02785 }
02786
02787
return status;
02788
02789 }