test: rtmisc1.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# rtmisc1.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1991  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     rtmisc1.c
    00008
    00009 Abstract:
    00010
    00011     NT level registry api test program #1, basic non-error paths.
    00012
    00013     Test open, create, setvalue, queryvalue, enumeratekey, enumeratevalue,
    00014     querykey.
    00015
    00016 Author:
    00017
    00018     Bryan Willman (bryanwi)  19-Nov-91
    00019
    00020 Revision History:
    00021
    00022 --*/
    00023
    00024 #include "cmp.h"
    00025 #include <stdio.h>
    00026 #include <stdlib.h>
    00027 #include <string.h>
    00028
    00029 //
    00030 //  NOTE:   This version of the test operations on \REGISTRY\MACHINE\TEST\*,
    00031 //          which is the TEST hive.  This hive will not exist in production
    00032 //          systems, so the test will have to change.
    00033 //
    00034
    00035
    00036 void __cdecl main(int, char *);
    00037
    00038 VOID
    00039 NameClassAndTitle(
    00040     KEY_NODE_INFORMATION    *NodeInformation,
    00041     UNICODE_STRING          ClassName,
    00042     ULONG                   TitleIndex,
    00043     UNICODE_STRING          KeyName,
    00044     LARGE_INTEGER           CompTime,
    00045     BOOLEAN                 Strong,         // time must be >= CompTime
    00046     PUCHAR                  TestName
    00047     );
    00048
    00049 VOID
    00050 expectstring(
    00051     PWSTR   expected,
    00052     ULONG   expectedlength,
    00053     PWSTR   actual,
    00054     ULONG   actuallength
    00055     );
    00056
    00057 VOID
    00058 expecttime(
    00059     LARGE_INTEGER   ExpectTime,
    00060     LARGE_INTEGER   ActualTime
    00061     );
    00062
    00063
    00064 #define TITLE_INDEX_1   122259
    00065 #define TITLE_INDEX_2   120858
    00066 #define TITLE_INDEX_3   120159
    00067 #define TYPE_1          666
    00068 #define TYPE_2          1066
    00069
    00070
    00071 ULONG           failure = 0;
    00072
    00073
    00074 void
    00075 __cdecl main(int, char *)
    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     // t0: Perform all operations against a base node, open it here.
    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     // t1: Create a key with class and title index
    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 //  printf("ClassName@%08lx  KeyName@%08lx\n",
    00162 //          ClassName.Buffer, KeyName.Buffer);
    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     // t2: See if we can get data back, and if it makes sense
    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,          // time must be >= CompTime
    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     // t3: Reopen the key with create, see if data still there.
    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,          // time must be >= CompTime
    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     // t4: Reopen the key with open, see if data still there.
    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,          // time must be >= CompTime
    00310         "rtmisc1: t4b: "
    00311         );
    00312
    00313 //  status = NtClose(Testhand1);
    00314 //  if (!NT_SUCCESS(status)) {
    00315 //      printf("rtmisc1: t4c: %08lx\n");
    00316 //      exit(1);
    00317 //  }
    00318
    00319
    00320     //
    00321     // t5: Create a value
    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     // t6: Read the value back
    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     // t7: Create a second value
    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     // t8: Read the second value back (short form)
    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     // t9: Enumerate the values (short form)
    00472     //
    00473
    00474     RtlZeroMemory(KeyValueBasic, bufsize);
    00475     status = NtEnumerateValueKey(
    00476                 Testhand1,
    00477                 0,              // Index
    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,              // Index
    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,              // Index
    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     // t10: create a second subkey and ennumerate the subkeys
    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     // See if we can get data back, and if it makes sense
    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     // Summary report
    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 }
    00735
    00736
    00737
    00738 VOID
    00739 NameClassAndTitle(
    00740     KEY_NODE_INFORMATION    *NodeInformation,
    00741     UNICODE_STRING          ClassName,
    00742     ULONG                   TitleIndex,
    00743     UNICODE_STRING          KeyName,
    00744     LARGE_INTEGER           CompTime,
    00745     BOOLEAN                 Strong,         // time must be >= CompTime
    00746     PUCHAR                  TestName
    00747     )
    00748 {
    00749     PWSTR   p;
    00750
    00751     if (Strong) {
    00752
    00753         //
    00754         // require exact match
    00755         //
    00756
    00757         if ((CompTime.HighPart != NodeInformation->LastWriteTime.HighPart) ||
    00758             (CompTime.LowPart != NodeInformation->LastWriteTime.LowPart))
    00759         {
    00760             printf("%s Wrong time (a)\n", TestName);
    00761             expecttime(CompTime, NodeInformation->LastWriteTime);
    00762             failure++;
    00763         }
    00764
    00765
    00766     } else {
    00767
    00768         //
    00769         // >= will do
    00770         //
    00771
    00772         if ( (CompTime.HighPart > NodeInformation->LastWriteTime.HighPart) ||
    00773              ((CompTime.HighPart == NodeInformation->LastWriteTime.HighPart) &&
    00774               (CompTime.LowPart > NodeInformation->LastWriteTime.LowPart)) )
    00775         {
    00776             printf("%s Wrong time (b)\n", TestName);
    00777             expecttime(CompTime, NodeInformation->LastWriteTime);
    00778             failure++;
    00779         }
    00780     }
    00781
    00782
    00783     p = (PWSTR)((PUCHAR)NodeInformation + NodeInformation->ClassOffset);
    00784     if ( (NodeInformation->ClassLength != ClassName.Length) ||
    00785          (wcsncmp(ClassName.Buffer, p, (ClassName.Length/sizeof(WCHAR))) != 0))
    00786     {
    00787         printf("%s wrong class name\n", TestName);
    00788         failure++;
    00789     }
    00790
    00791     if (NodeInformation->TitleIndex != TitleIndex) {
    00792         printf("%s wrong title index\n", TestName);
    00793         failure++;
    00794     }
    00795
    00796     p = (PWSTR)(&(NodeInformation->Name[0]));
    00797     if ( (NodeInformation->NameLength != KeyName.Length) ||
    00798          (wcsncmp(KeyName.Buffer, p, (KeyName.Length/sizeof(WCHAR))) != 0))
    00799     {
    00800         printf("%s wrong name\n", TestName);
    00801         expectstring(
    00802             KeyName.Buffer,
    00803             (KeyName.Length/sizeof(WCHAR)),
    00804             (PWSTR)&(NodeInformation->Name[0]),
    00805             (NodeInformation->NameLength/sizeof(WCHAR))
    00806             );
    00807         failure++;
    00808     }
    00809 }
    00810
    00811 VOID
    00812 expecttime(
    00813     LARGE_INTEGER   ExpectTime,
    00814     LARGE_INTEGER   ActualTime
    00815     )
    00816 {
    00817     printf("Expected %08lx%08lx\n", ExpectTime.HighPart, ExpectTime.LowPart);
    00818     printf("Got      %08lx%08lx\n", ActualTime.HighPart, ActualTime.LowPart);
    00819     return;
    00820 }
    00821
    00822 VOID
    00823 expectstring(
    00824     PWSTR   expected,
    00825     ULONG   expectedlength,
    00826     PWSTR   actual,
    00827     ULONG   actuallength
    00828     )
    00829 {
    00830     ULONG   i;
    00831
    00832     printf("Expected Len %d Str = '", expectedlength);
    00833     for (i = 0; i < expectedlength; i++) {
    00834         printf("%c", (UCHAR)(expected[i]));
    00835     }
    00836     printf("'\n");
    00837
    00838     printf("Got Len %d Str = '", actuallength);
    00839     for (i = 0; i < actuallength; i++) {
    00840         printf("%c", (UCHAR)(actual[i]));
    00841     }
    00842     printf("'\n");
    00843     return;
    00844 }