00076 {
00077
NTSTATUS status;
00078 OBJECT_ATTRIBUTES
ObjectAttributes;
00079 UNICODE_STRING
KeyName;
00080 UNICODE_STRING KeyName2;
00081 UNICODE_STRING ClassName;
00082 UNICODE_STRING ClassName2;
00083 UNICODE_STRING
ValueName;
00084 UNICODE_STRING ValueName2;
00085 HANDLE BaseHandle;
00086 HANDLE Testhand1;
00087 ULONG Disposition;
00088 LARGE_INTEGER CompTime;
00089 ULONG buffer[100];
00090 ULONG bufsize =
sizeof(ULONG) * 100;
00091 PKEY_NODE_INFORMATION NodeInformation;
00092 PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
00093 PKEY_VALUE_BASIC_INFORMATION KeyValueBasic;
00094 ULONG ResultLength;
00095 PUCHAR datastring =
"Some simple ascii data for use as a value";
00096 PUCHAR datastring2 =
"Some more not so simple data $#";
00097 ULONG expected;
00098 PVOID tp;
00099
00100
00101 printf(
"rtmisc1: starting\n");
00102
00103 NodeInformation = (PKEY_NODE_INFORMATION)&(buffer[0]);
00104 KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)&(buffer[0]);
00105 KeyValueBasic = (PKEY_VALUE_BASIC_INFORMATION)&(buffer[0]);
00106
00107
00108
00109
00110
00111
RtlInitUnicodeString(
00112 &KeyName,
00113 L
"\\REGISTRY\\MACHINE\\TEST"
00114 );
00115
00116 InitializeObjectAttributes(
00117 &ObjectAttributes,
00118 &KeyName,
00119 0,
00120 (HANDLE)NULL,
00121 NULL
00122 );
00123
ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
00124
00125 status =
NtOpenKey(
00126 &BaseHandle,
00127 MAXIMUM_ALLOWED,
00128 &ObjectAttributes
00129 );
00130
if (!
NT_SUCCESS(status)) {
00131 printf(
"rtmisc1: t0: %08lx\n", status);
00132
goto punt;
00133 }
00134
00135
00136
00137
00138
00139
00140
RtlInitUnicodeString(
00141 &ClassName,
00142 L
"t1 Class Name"
00143 );
00144
00145
RtlInitUnicodeString(
00146 &KeyName,
00147 L
"first_test_node"
00148 );
00149
00150 InitializeObjectAttributes(
00151 &ObjectAttributes,
00152 &KeyName,
00153 0,
00154 BaseHandle,
00155 NULL
00156 );
00157
ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
00158
00159 NtQuerySystemTime(&CompTime);
00160
00161
00162
00163
00164 status =
NtCreateKey(
00165 &Testhand1,
00166 MAXIMUM_ALLOWED,
00167 &ObjectAttributes,
00168 TITLE_INDEX_1,
00169 &ClassName,
00170 0,
00171 &Disposition
00172 );
00173
if (!
NT_SUCCESS(status)) {
00174 printf(
"rtmisc1: t1: %08lx\n", status);
00175
goto punt;
00176 }
00177
00178
if (Disposition != REG_CREATED_NEW_KEY) {
00179 printf(
"rtmisc1: t1a: got old key, expected to create new one\n");
00180
failure++;
00181 }
00182
00183
00184
00185
00186
00187 RtlZeroMemory(NodeInformation, bufsize);
00188 status =
NtQueryKey(
00189 Testhand1,
00190 KeyNodeInformation,
00191 NodeInformation,
00192 bufsize,
00193 &ResultLength
00194 );
00195
if (!
NT_SUCCESS(status)) {
00196 printf(
"rtmisc1: t2a: %08lx\n", status);
00197
goto punt;
00198 }
00199
if (ResultLength != 80) {
00200 printf(
"rtmisc1: t2i: expect 80, ResultLength = %d\n", ResultLength);
00201
failure++;
00202 }
00203
00204
00205
NameClassAndTitle(
00206 NodeInformation,
00207 ClassName,
00208 TITLE_INDEX_1,
00209 KeyName,
00210 CompTime,
00211 FALSE,
00212
"rtmisc1: t2b: "
00213 );
00214 CompTime = NodeInformation->LastWriteTime;
00215
00216 status =
NtClose(Testhand1);
00217
if (!
NT_SUCCESS(status)) {
00218 printf(
"rtmisc1: t2c: %08lx\n");
00219
goto punt;
00220 }
00221
00222
00223
00224
00225
00226
00227 status =
NtCreateKey(
00228 &Testhand1,
00229 MAXIMUM_ALLOWED,
00230 &ObjectAttributes,
00231 TITLE_INDEX_1,
00232 &ClassName,
00233 0,
00234 &Disposition
00235 );
00236
if (!
NT_SUCCESS(status)) {
00237 printf(
"rtmisc1: t3: %08lx\n", status);
00238
goto punt;
00239 }
00240
00241
if (Disposition != REG_OPENED_EXISTING_KEY) {
00242 printf(
"rtmisc1: t3a failure\n");
00243
failure++;
00244 }
00245
00246 RtlZeroMemory(NodeInformation, bufsize);
00247 status =
NtQueryKey(
00248 Testhand1,
00249 KeyNodeInformation,
00250 NodeInformation,
00251 bufsize,
00252 &ResultLength
00253 );
00254
if (!
NT_SUCCESS(status)) {
00255 printf(
"rtmisc1: t3b: %08lx\n", status);
00256
goto punt;
00257 }
00258
00259
NameClassAndTitle(
00260 NodeInformation,
00261 ClassName,
00262 TITLE_INDEX_1,
00263 KeyName,
00264 CompTime,
00265 FALSE,
00266
"rtmisc1: t3c: "
00267 );
00268
00269 status =
NtClose(Testhand1);
00270
if (!
NT_SUCCESS(status)) {
00271 printf(
"rtmisc1: t3d: %08lx\n");
00272
goto punt;
00273 }
00274
00275
00276
00277
00278
00279
00280 status =
NtOpenKey(
00281 &Testhand1,
00282 MAXIMUM_ALLOWED,
00283 &ObjectAttributes
00284 );
00285
if (!
NT_SUCCESS(status)) {
00286 printf(
"rtmisc1: t4: %08lx\n", status);
00287
goto punt;
00288 }
00289
00290 RtlZeroMemory(NodeInformation, bufsize);
00291 status =
NtQueryKey(
00292 Testhand1,
00293 KeyNodeInformation,
00294 NodeInformation,
00295 bufsize,
00296 &ResultLength
00297 );
00298
if (!
NT_SUCCESS(status)) {
00299 printf(
"rtmisc1: t4a: %08lx\n", status);
00300
goto punt;
00301 }
00302
00303
NameClassAndTitle(
00304 NodeInformation,
00305 ClassName,
00306 TITLE_INDEX_1,
00307 KeyName,
00308 CompTime,
00309 FALSE,
00310
"rtmisc1: t4b: "
00311 );
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
RtlInitUnicodeString(
00325 &ValueName,
00326 L
"the very first value stored in the registry"
00327 );
00328
00329
00330 status =
NtSetValueKey(
00331 Testhand1,
00332 &ValueName,
00333 TITLE_INDEX_2,
00334 TYPE_1,
00335 datastring,
00336
strlen(datastring)+1
00337 );
00338
if (!
NT_SUCCESS(status)) {
00339 printf(
"rtmisc1: t5: %08lx\n", status);
00340
failure++;
00341 }
00342
00343
00344
00345
00346
00347
00348 RtlZeroMemory(KeyValueInformation, bufsize);
00349 status =
NtQueryValueKey(
00350 Testhand1,
00351 &ValueName,
00352 KeyValueFullInformation,
00353 KeyValueInformation,
00354 bufsize,
00355 &ResultLength
00356 );
00357
if (!
NT_SUCCESS(status)) {
00358 printf(
"rtmisc1: t6: %08lx\n", status);
00359
goto punt;
00360 }
00361 expected = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name) +
00362
ValueName.Length +
strlen(datastring) + 1;
00363
if (ResultLength != expected) {
00364 printf(
"rtmisc1: t6a: expected = %08lx actual = %08lx",
00365 expected, ResultLength);
00366
failure++;
00367 }
00368
00369
if ( (KeyValueInformation->TitleIndex !=
TITLE_INDEX_2) ||
00370 (KeyValueInformation->Type !=
TYPE_1) ||
00371 (KeyValueInformation->NameLength !=
ValueName.Length) ||
00372 (KeyValueInformation->DataLength !=
strlen(datastring)+1))
00373 {
00374 printf(
"rtmisc1: t6b: wrong description data\n");
00375
failure++;
00376 }
00377
00378
00379 tp = (PWSTR)&(KeyValueInformation->Name[0]);
00380
if (wcsncmp(
ValueName.Buffer, tp, (
ValueName.Length/
sizeof(WCHAR))) != 0) {
00381 printf(
"rtmisc1: t6c: wrong name\n");
00382
expectstring(
00383
ValueName.Buffer,
00384 (
ValueName.Length/
sizeof(WCHAR)),
00385 (PWSTR)&(KeyValueInformation->Name[0]),
00386 (KeyValueInformation->NameLength/
sizeof(WCHAR))
00387 );
00388
failure++;
00389 }
00390
00391
00392 tp = (PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset;
00393
if (strcmp(tp, datastring) != 0) {
00394 printf(
"rtmisc1: t6d: wrong data\n");
00395 printf(
"expected '%s', got '%s'\n", datastring, tp);
00396
failure++;
00397 }
00398
00399
00400
00401
00402
00403
RtlInitUnicodeString(
00404 &ValueName2,
00405 L
"the second value stored in the registry"
00406 );
00407
00408
00409 status =
NtSetValueKey(
00410 Testhand1,
00411 &ValueName2,
00412 TITLE_INDEX_3,
00413 TYPE_2,
00414 datastring2,
00415
strlen(datastring2)+1
00416 );
00417
if (!
NT_SUCCESS(status)) {
00418 printf(
"rtmisc1: t7: %08lx\n", status);
00419
failure++;
00420 }
00421
00422
00423
00424
00425
00426 RtlZeroMemory(KeyValueBasic, bufsize);
00427 status =
NtQueryValueKey(
00428 Testhand1,
00429 &ValueName2,
00430 KeyValueBasicInformation,
00431 KeyValueBasic,
00432 bufsize,
00433 &ResultLength
00434 );
00435
if (!
NT_SUCCESS(status)) {
00436 printf(
"rtmisc1: t8: %08lx\n", status);
00437
goto punt;
00438 }
00439
00440 expected = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) +
00441 ValueName2.Length;
00442
if (ResultLength != expected) {
00443 printf(
"rtmisc1: t8a: expected = %08lx actual = %08lx",
00444 expected, ResultLength);
00445
failure++;
00446 }
00447
00448
if ( (KeyValueBasic->TitleIndex !=
TITLE_INDEX_3) ||
00449 (KeyValueBasic->Type !=
TYPE_2) ||
00450 (KeyValueBasic->NameLength != ValueName2.Length))
00451 {
00452 printf(
"rtmisc1: t8b: wrong description data\n");
00453
failure++;
00454 }
00455
00456
00457 tp = (PWSTR)&(KeyValueBasic->Name[0]);
00458
if (wcsncmp(ValueName2.Buffer, tp, (ValueName2.Length/
sizeof(WCHAR))) != 0) {
00459 printf(
"rtmisc1: t8c: wrong name\n");
00460
expectstring(
00461 ValueName2.Buffer,
00462 (ValueName2.Length/
sizeof(WCHAR)),
00463 (PWSTR)&(KeyValueBasic->Name[0]),
00464 (KeyValueBasic->NameLength/
sizeof(WCHAR))
00465 );
00466
failure++;
00467 }
00468
00469
00470
00471
00472
00473
00474 RtlZeroMemory(KeyValueBasic, bufsize);
00475 status =
NtEnumerateValueKey(
00476 Testhand1,
00477 0,
00478 KeyValueBasicInformation,
00479 KeyValueBasic,
00480 bufsize,
00481 &ResultLength
00482 );
00483
if (!
NT_SUCCESS(status)) {
00484 printf(
"rtmisc1: t9: %08lx\n", status);
00485
goto punt;
00486 }
00487
00488 expected = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) +
00489
ValueName.Length;
00490
if (ResultLength != expected) {
00491 printf(
"rtmisc1: t9a: expected = %08lx actual = %08lx",
00492 expected, ResultLength);
00493
failure++;
00494 }
00495
00496
if (KeyValueBasic->NameLength !=
ValueName.Length)
00497 {
00498 printf(
"rtmisc1: t9b: wrong description data\n");
00499
failure++;
00500 }
00501
00502
00503 tp = (PWSTR)&(KeyValueBasic->Name[0]);
00504
if (wcsncmp(
ValueName.Buffer, tp, (
ValueName.Length/
sizeof(WCHAR))) != 0) {
00505 printf(
"rtmisc1: t9c: wrong name\n");
00506
expectstring(
00507
ValueName.Buffer,
00508 (
ValueName.Length/
sizeof(WCHAR)),
00509 (PWSTR)&(KeyValueBasic->Name[0]),
00510 (KeyValueBasic->NameLength/
sizeof(WCHAR))
00511 );
00512
failure++;
00513 }
00514
00515 RtlZeroMemory(KeyValueBasic, bufsize);
00516 status =
NtEnumerateValueKey(
00517 Testhand1,
00518 1,
00519 KeyValueBasicInformation,
00520 KeyValueBasic,
00521 bufsize,
00522 &ResultLength
00523 );
00524
if (!
NT_SUCCESS(status)) {
00525 printf(
"rtmisc1: t9d: %08lx\n", status);
00526
goto punt;
00527 }
00528
00529 expected = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) +
00530 ValueName2.Length;
00531
if (ResultLength != expected) {
00532 printf(
"rtmisc1: t9e: expected = %08lx actual = %08lx",
00533 expected, ResultLength);
00534
failure++;
00535 }
00536
00537
if (KeyValueBasic->NameLength != ValueName2.Length)
00538 {
00539 printf(
"rtmisc1: t9f: wrong description data\n");
00540
failure++;
00541 }
00542
00543
00544 tp = (PWSTR)&(KeyValueBasic->Name[0]);
00545
if (wcsncmp(ValueName2.Buffer, tp, (ValueName2.Length/
sizeof(WCHAR))) != 0) {
00546 printf(
"rtmisc1: t9g: wrong name\n");
00547
expectstring(
00548 ValueName2.Buffer,
00549 (ValueName2.Length/
sizeof(WCHAR)),
00550 (PWSTR)&(KeyValueBasic->Name[0]),
00551 (KeyValueBasic->NameLength/
sizeof(WCHAR))
00552 );
00553
failure++;
00554 }
00555
00556 status =
NtEnumerateValueKey(
00557 Testhand1,
00558 2,
00559 KeyValueBasicInformation,
00560 KeyValueBasic,
00561 bufsize,
00562 &ResultLength
00563 );
00564
if (status != STATUS_NO_MORE_ENTRIES) {
00565 printf(
"rtmisc1: t9h: %08lx\n", status);
00566
goto punt;
00567 }
00568
00569
00570
00571
00572
00573 status =
NtClose(Testhand1);
00574
if (!
NT_SUCCESS(status)) {
00575 printf(
"rtmisc1: t10a: %08lx\n", status);
00576
failure++;
00577 }
00578
00579
RtlInitUnicodeString(
00580 &ClassName2,
00581 L
"t2 Class Name"
00582 );
00583
00584
RtlInitUnicodeString(
00585 &KeyName2,
00586 L
"second_test_node"
00587 );
00588
00589 InitializeObjectAttributes(
00590 &ObjectAttributes,
00591 &KeyName2,
00592 0,
00593 BaseHandle,
00594 NULL
00595 );
00596
ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
00597
00598 status =
NtCreateKey(
00599 &Testhand1,
00600 MAXIMUM_ALLOWED,
00601 &ObjectAttributes,
00602 TITLE_INDEX_2,
00603 &ClassName2,
00604 0,
00605 &Disposition
00606 );
00607
if (!
NT_SUCCESS(status)) {
00608 printf(
"rtmisc1: t10b: %08lx\n", status);
00609
goto punt;
00610 }
00611
00612
if (Disposition != REG_CREATED_NEW_KEY) {
00613 printf(
"rtmisc1: t10c: got old key, expected to create new one\n");
00614
failure++;
00615 }
00616
00617
00618
00619
00620
00621 RtlZeroMemory(NodeInformation, bufsize);
00622 status =
NtQueryKey(
00623 Testhand1,
00624 KeyNodeInformation,
00625 NodeInformation,
00626 bufsize,
00627 &ResultLength
00628 );
00629
if (!
NT_SUCCESS(status)) {
00630 printf(
"rtmisc1: t10d: %08lx\n", status);
00631
goto punt;
00632 }
00633 CompTime = NodeInformation->LastWriteTime;
00634
00635
00636
NameClassAndTitle(
00637 NodeInformation,
00638 ClassName2,
00639 TITLE_INDEX_2,
00640 KeyName2,
00641 CompTime,
00642 TRUE,
00643
"rtmisc1: t10e: "
00644 );
00645
00646 status =
NtClose(Testhand1);
00647
if (!
NT_SUCCESS(status)) {
00648 printf(
"rtmisc1: t10f: %08lx\n");
00649
goto punt;
00650 }
00651
00652
00653 RtlZeroMemory(NodeInformation, bufsize);
00654 status =
NtEnumerateKey(
00655 BaseHandle,
00656 0,
00657 KeyNodeInformation,
00658 NodeInformation,
00659 bufsize,
00660 &ResultLength
00661 );
00662
if (!
NT_SUCCESS(status)) {
00663 printf(
"rtmisc1: t10g: %08lx\n", status);
00664
failure++;
00665 }
00666 CompTime = NodeInformation->LastWriteTime;
00667
00668
NameClassAndTitle(
00669 NodeInformation,
00670 ClassName,
00671 TITLE_INDEX_1,
00672 KeyName,
00673 CompTime,
00674 TRUE,
00675
"rtmisc1: t10h: "
00676 );
00677
00678
00679 RtlZeroMemory(NodeInformation, bufsize);
00680 status =
NtEnumerateKey(
00681 BaseHandle,
00682 1,
00683 KeyNodeInformation,
00684 NodeInformation,
00685 bufsize,
00686 &ResultLength
00687 );
00688
if (!
NT_SUCCESS(status)) {
00689 printf(
"rtmisc1: t10i: %08lx\n", status);
00690
failure++;
00691 }
00692 CompTime = NodeInformation->LastWriteTime;
00693
00694
NameClassAndTitle(
00695 NodeInformation,
00696 ClassName2,
00697 TITLE_INDEX_2,
00698 KeyName2,
00699 CompTime,
00700 TRUE,
00701
"rtmisc1: t10j: "
00702 );
00703
00704
00705 status =
NtEnumerateKey(
00706 BaseHandle,
00707 2,
00708 KeyNodeInformation,
00709 NodeInformation,
00710 bufsize,
00711 &ResultLength
00712 );
00713
if (status != STATUS_NO_MORE_ENTRIES) {
00714 printf(
"rtmisc1: t10k: %08lx\n", status);
00715
failure++;
00716 }
00717
00718
00719
00720
00721
00722
if (!
failure) {
00723 printf(
"rtmisc1: success");
00724
exit(0);
00725 }
else {
00726 printf(
"rtmisc1: failed, %d failures\n", failure);
00727
exit(1);
00728 }
00729
00730 punt:
00731
failure++;
00732 printf(
"rtmisc1: failed, %d failures\n", failure);
00733
exit(1);
00734 }