test: edithive.c Source File

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

# edithive.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1991  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     edithive.c
    00008
    00009 Abstract:
    00010
    00011     Provides functionality for dumping and editing registry hive files from
    00012     user-mode.
    00013
    00014 Author:
    00015
    00016     John Vert (jvert) 26-Mar-1992
    00017
    00018 Revision History:
    00019
    00020 --*/
    00021 #include "edithive.h"
    00022 #include "nturtl.h"
    00023
    00024 extern GENERIC_MAPPING CmpKeyMapping;
    00025 extern LIST_ENTRY CmpHiveListHead;            // List of CMHIVEs
    00026
    00027 #define SECURITY_CELL_LENGTH(pDescriptor) \
    00028     FIELD_OFFSET(CM_KEY_SECURITY,Descriptor) + \
    00029     RtlLengthSecurityDescriptor(pDescriptor)
    00030
    00031
    00032 NTSTATUS
    00033 EhpAttachSecurity(
    00034     IN PHHIVE Hive,
    00035     IN HCELL_INDEX Cell
    00036     );
    00037
    00038 PVOID
    00039 EhpAllocate(
    00040     ULONG   Size
    00041     );
    00042
    00043 VOID
    00044 EhpFree(
    00045     PVOID   MemoryBlock
    00046     );
    00047
    00048 BOOLEAN
    00049 EhpFileRead (
    00050     HANDLE      FileHandle,
    00051     PULONG      FileOffset,
    00052     PVOID       DataBuffer,
    00053     ULONG       DataLength
    00054     );
    00055
    00056 BOOLEAN
    00057 EhpFileWrite(
    00058     HANDLE      FileHandle,
    00059     PULONG      FileOffset,
    00060     PVOID       DataBuffer,
    00061     ULONG       DataLength
    00062     );
    00063
    00064 BOOLEAN
    00065 EhpFileFlush (
    00066     HANDLE      FileHandle
    00067     );
    00068
    00069 VOID
    00070 CmpGetObjectSecurity(
    00071     IN HCELL_INDEX Cell,
    00072     IN PHHIVE Hive,
    00073     OUT PCM_KEY_SECURITY *Security,
    00074     OUT PHCELL_INDEX SecurityCell OPTIONAL
    00075     )
    00076
    00077 /*++
    00078
    00079 Routine Description:
    00080
    00081     This routine maps in the security cell of a registry object.
    00082
    00083 Arguments:
    00084
    00085     Cell - Supplies the cell index of the object.
    00086
    00087     Hive - Supplies the hive the object's cell is in.
    00088
    00089     Security - Returns a pointer to the security cell of the object.
    00090
    00091     SecurityCell - Returns the index of the security cell
    00092
    00093 Return Value:
    00094
    00095     NONE.
    00096
    00097 --*/
    00098
    00099 {
    00100     HCELL_INDEX CellIndex;
    00101     PCM_KEY_NODE Node;
    00102
    00103     //
    00104     // Map the node we need to get the security descriptor for
    00105     //
    00106     Node = (PCM_KEY_NODE) HvGetCell(Hive, Cell);
    00107
    00108     CellIndex = Node->u1.s1.Security;
    00109
    00110     //
    00111     // Map in the security descriptor cell
    00112     //
    00113     *Security = (PCM_KEY_SECURITY) HvGetCell(Hive, CellIndex);
    00114
    00115     if (ARGUMENT_PRESENT(SecurityCell)) {
    00116         *SecurityCell = CellIndex;
    00117     }
    00118
    00119     return;
    00120 }
    00121
    00122
    00123 VOID
    00124 EhCloseHive(
    00125     IN HANDLE HiveHandle
    00126     )
    00127
    00128 /*++
    00129
    00130 Routine Description:
    00131
    00132     Closes a hive, including writing all the data out to disk and freeing
    00133     the relevant structures.
    00134
    00135 Arguments:
    00136
    00137     HiveHandle - Supplies a handle to the hive control structure
    00138
    00139 Return Value:
    00140
    00141     None.
    00142
    00143 --*/
    00144
    00145 {
    00146     HvSyncHive((PHHIVE)HiveHandle);
    00147     NtClose(((PCMHIVE)HiveHandle)->FileHandles[HFILE_TYPE_PRIMARY]);
    00148     NtClose(((PCMHIVE)HiveHandle)->FileHandles[HFILE_TYPE_ALTERNATE]);
    00149     NtClose(((PCMHIVE)HiveHandle)->FileHandles[HFILE_TYPE_LOG]);
    00150     CmpFree((PCMHIVE)HiveHandle, sizeof(CMHIVE));
    00151
    00152 }
    00153
    00154
    00155 HANDLE
    00156 EhOpenHive(
    00157     IN PUNICODE_STRING FileName,
    00158     OUT PHANDLE RootHandle,
    00159     IN PUNICODE_STRING RootName,
    00160     IN ULONG HiveType
    00161     )
    00162
    00163 /*++
    00164
    00165 Routine Description:
    00166
    00167     Opens an existing hive.  If the filename does not exist it will be
    00168     created.
    00169
    00170     WARNING:    Allocate FileName large enough to acomodate .log or
    00171                 .alt extension.
    00172
    00173 Arguments:
    00174
    00175     FileName - Supplies the NULL-terminated filename to open as a hive.
    00176
    00177     HiveType - TYPE_SIMPLE = no log or alternate
    00178                TYPE_LOG = log
    00179                TYPE_ALT = alternate
    00180
    00181 Return Value:
    00182
    00183     != NULL - Handle to the opened hive.
    00184     == NULL - Indicates file could not be opened.
    00185
    00186 --*/
    00187
    00188 {
    00189     NTSTATUS Status;
    00190     HANDLE File;
    00191     BOOLEAN Allocate;
    00192     PCMHIVE Hive;
    00193     IO_STATUS_BLOCK IoStatus;
    00194     ULONG CreateDisposition;
    00195     OBJECT_ATTRIBUTES ObjectAttributes;
    00196     PCM_KEY_NODE RootNode;
    00197     HANDLE Handle;
    00198     HANDLE  Primary;
    00199     HANDLE  Log;
    00200     HANDLE  Alt;
    00201     ULONG   FileType;
    00202     ULONG   Disposition;
    00203     ULONG   SecondaryDisposition;
    00204     ULONG   Operation;
    00205
    00206     Alt = NULL;
    00207     Log = NULL;
    00208     InitializeListHead(&CmpHiveListHead);
    00209
    00210     switch (HiveType) {
    00211     case TYPE_SIMPLE:
    00212         Status = CmpOpenHiveFiles(
    00213                     FileName,
    00214                     NULL,
    00215                     &Primary,
    00216                     NULL,
    00217                     &Disposition,
    00218                     &SecondaryDisposition,
    00219                     TRUE,
    00220                     NULL
    00221                     );
    00222         if (!NT_SUCCESS(Status))
    00223         {
    00224             return NULL;
    00225         }
    00226         FileType = HFILE_TYPE_PRIMARY;
    00227         break;
    00228
    00229     case TYPE_LOG:
    00230         Status = CmpOpenHiveFiles(
    00231                     FileName,
    00232                     L".log",
    00233                     &Primary,
    00234                     &Log,
    00235                     &Disposition,
    00236                     &SecondaryDisposition,
    00237                     TRUE,
    00238                     NULL
    00239                     );
    00240         if (!NT_SUCCESS(Status))
    00241         {
    00242             return NULL;
    00243         }
    00244         if (Log == NULL) {
    00245             return NULL;
    00246         }
    00247         FileType = HFILE_TYPE_LOG;
    00248         break;
    00249
    00250     case TYPE_ALT:
    00251         Status = CmpOpenHiveFiles(
    00252                     FileName,
    00253                     L".alt",
    00254                     &Primary,
    00255                     &Alt,
    00256                     &Disposition,
    00257                     &SecondaryDisposition,
    00258                     TRUE,
    00259                     NULL
    00260                     );
    00261         if (!NT_SUCCESS(Status))
    00262         {
    00263             return NULL;
    00264         }
    00265         if (Alt == NULL) {
    00266             return NULL;
    00267         }
    00268         FileType = HFILE_TYPE_ALTERNATE;
    00269         break;
    00270
    00271     default:
    00272         return NULL;
    00273     }
    00274
    00275     //
    00276     // Initialize hive
    00277     //
    00278     if (Disposition == FILE_CREATED) {
    00279         Operation = HINIT_CREATE;
    00280         Allocate = TRUE;
    00281     } else {
    00282         Operation = HINIT_FILE;
    00283         Allocate = FALSE;
    00284     }
    00285
    00286     if ( ! CmpInitializeHive(
    00287                     &Hive,
    00288                     Operation,
    00289                     FALSE,
    00290                     FileType,
    00291                     NULL,
    00292                     Primary,
    00293                     Alt,
    00294                     Log,
    00295                     NULL,
    00296                     NULL
    00297                     ))
    00298     {
    00299         return NULL;
    00300     }
    00301
    00302     if (!Allocate) {
    00303         *RootHandle = (HANDLE)(Hive->Hive.BaseBlock->RootCell);
    00304         RootNode = (PCM_KEY_NODE)HvGetCell(
    00305                                 (PHHIVE)Hive, Hive->Hive.BaseBlock->RootCell);
    00306         RootName->Length = RootName->MaximumLength = RootNode->NameLength;
    00307         RootName->Buffer = RootNode->Name;
    00308     } else {
    00309         RtlInitUnicodeString(RootName, L"HiveRoot");
    00310         *RootHandle = (HANDLE)HCELL_NIL;
    00311         HvSyncHive((PHHIVE)Hive);
    00312     }
    00313
    00314
    00315     return((HANDLE)Hive);
    00316 }
    00317
    00318
    00319 NTSTATUS
    00320 EhEnumerateKey(
    00321     IN HANDLE HiveHandle,
    00322     IN HANDLE CellHandle,
    00323     IN ULONG Index,
    00324     IN KEY_INFORMATION_CLASS KeyInformationClass,
    00325     IN PVOID KeyInformation,
    00326     IN ULONG Length,
    00327     IN PULONG ResultLength
    00328     )
    00329 /*++
    00330
    00331 Routine Description:
    00332
    00333     Enumerate sub keys, return data on Index'th entry.
    00334
    00335     CmEnumerateKey returns the name of the Index'th sub key of the open
    00336     key specified.  The value STATUS_NO_MORE_ENTRIES will be
    00337     returned if value of Index is larger than the number of sub keys.
    00338
    00339     Note that Index is simply a way to select among child keys.  Two calls
    00340     to CmEnumerateKey with the same Index are NOT guaranteed to return
    00341     the same results.
    00342
    00343     If KeyInformation is not long enough to hold all requested data,
    00344     STATUS_BUFFER_OVERFLOW will be returned, and ResultLength will be
    00345     set to the number of bytes actually required.
    00346
    00347 Arguments:
    00348
    00349     Hive - supplies a pointer to the hive control structure for the hive
    00350
    00351     Cell - supplies index of node to whose sub keys are to be found
    00352
    00353     Index - Specifies the (0-based) number of the sub key to be returned.
    00354
    00355     KeyInformationClass - Specifies the type of information returned in
    00356         Buffer.  One of the following types:
    00357
    00358         KeyBasicInformation - return last write time, title index, and name.
    00359             (see KEY_BASIC_INFORMATION structure)
    00360
    00361         KeyNodeInformation - return last write time, title index, name, class.
    00362             (see KEY_NODE_INFORMATION structure)
    00363
    00364     KeyInformation -Supplies pointer to buffer to receive the data.
    00365
    00366     Length - Length of KeyInformation in bytes.
    00367
    00368     ResultLength - Number of bytes actually written into KeyInformation.
    00369
    00370 Return Value:
    00371
    00372     NTSTATUS - Result code from call, among the following:
    00373
    00374         <TBS>
    00375
    00376 --*/
    00377 {
    00378     CM_KEY_CONTROL_BLOCK    kcb;
    00379
    00380     kcb.Signature = CM_KEY_CONTROL_BLOCK_SIGNATURE;
    00381     kcb.Delete = FALSE;
    00382     kcb.KeyHive = &((PCMHIVE)HiveHandle)->Hive;
    00383     kcb.KeyCell = (HCELL_INDEX)CellHandle;
    00384     kcb.RefCount = 1;
    00385
    00386     return(CmEnumerateKey(&kcb,
    00387                           Index,
    00388                           KeyInformationClass,
    00389                           KeyInformation,
    00390                           Length,
    00391                           ResultLength));
    00392 }
    00393
    00394
    00395 NTSTATUS
    00396 EhEnumerateValueKey(
    00397     IN HANDLE HiveHandle,
    00398     IN HANDLE CellHandle,
    00399     IN ULONG Index,
    00400     IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
    00401     IN PVOID KeyValueInformation,
    00402     IN ULONG Length,
    00403     IN PULONG ResultLength
    00404     )
    00405 /*++
    00406
    00407 Routine Description:
    00408
    00409     The value entries of an open key may be enumerated.
    00410
    00411     CmEnumerateValueKey returns the name of the Index'th value
    00412     entry of the open key specified by KeyHandle.  The value
    00413     STATUS_NO_MORE_ENTRIES will be returned if value of Index is
    00414     larger than the number of sub keys.
    00415
    00416     Note that Index is simply a way to select among value
    00417     entries.  Two calls to NtEnumerateValueKey with the same Index
    00418     are NOT guaranteed to return the same results.
    00419
    00420     If KeyValueInformation is not long enough to hold all requested data,
    00421     STATUS_BUFFER_OVERFLOW will be returned, and ResultLength will be
    00422     set to the number of bytes actually required.
    00423
    00424 Arguments:
    00425
    00426     Hive - supplies a handle to the hive
    00427
    00428     Cell - supplies handle to node whose sub keys are to be found
    00429
    00430     Index - Specifies the (0-based) number of the sub key to be returned.
    00431
    00432     KeyValueInformationClass - Specifies the type of information returned
    00433     in Buffer. One of the following types:
    00434
    00435         KeyValueBasicInformation - return time of last write,
    00436             title index, and name.  (See KEY_VALUE_BASIC_INFORMATION)
    00437
    00438         KeyValueFullInformation - return time of last write,
    00439             title index, name, class.  (See KEY_VALUE_FULL_INFORMATION)
    00440
    00441     KeyValueInformation -Supplies pointer to buffer to receive the data.
    00442
    00443     Length - Length of KeyValueInformation in bytes.
    00444
    00445     ResultLength - Number of bytes actually written into KeyValueInformation.
    00446
    00447 Return Value:
    00448
    00449     NTSTATUS - Result code from call, among the following:
    00450
    00451         <TBS>
    00452
    00453 --*/
    00454 {
    00455     CM_KEY_CONTROL_BLOCK    kcb;
    00456
    00457     kcb.Signature = CM_KEY_CONTROL_BLOCK_SIGNATURE;
    00458     kcb.Delete = FALSE;
    00459     kcb.KeyHive = (PHHIVE)&(((PCMHIVE)HiveHandle)->Hive);
    00460     kcb.KeyCell = (HCELL_INDEX)CellHandle;
    00461     kcb.RefCount = 1;
    00462
    00463     return(CmEnumerateValueKey(&kcb,
    00464                                Index,
    00465                                KeyValueInformationClass,
    00466                                KeyValueInformation,
    00467                                Length,
    00468                                ResultLength));
    00469 }
    00470
    00471
    00472 NTSTATUS
    00473 EhOpenChildByNumber(
    00474     IN HANDLE HiveHandle,
    00475     IN HANDLE CellHandle,
    00476     IN ULONG  Index,
    00477     IN NODE_TYPE   Type,
    00478     OUT PHANDLE ChildCell
    00479     )
    00480 /*++
    00481
    00482 Routine Description:
    00483
    00484     Return the cell index of the Nth child cell.
    00485
    00486 Arguments:
    00487
    00488     HiveHandle - handle of hive control structure for hive of interest
    00489
    00490     CellHandle - handle for parent cell
    00491
    00492     Index - number of desired child
    00493
    00494     Type - type of the child object
    00495
    00496     ChildCell - supplies a pointer to a variable to receive the
    00497                     HCELL_INDEX of the Index'th child.
    00498
    00499 Return Value:
    00500
    00501     status
    00502
    00503 --*/
    00504 {
    00505     return(CmpFindChildByNumber(&((PCMHIVE)HiveHandle)->Hive,
    00506                                 (HCELL_INDEX)CellHandle,
    00507                                 Index,
    00508                                 Type,
    00509                                 (PHCELL_INDEX)ChildCell));
    00510
    00511 }
    00512
    00513
    00514 NTSTATUS
    00515 EhSetValueKey(
    00516     IN HANDLE HiveHandle,
    00517     IN HANDLE CellHandle,
    00518     IN PUNICODE_STRING ValueName,
    00519     IN ULONG TitleIndex OPTIONAL,
    00520     IN ULONG Type,
    00521     IN PVOID Data,
    00522     IN ULONG DataSize
    00523     )
    00524 /*++
    00525
    00526 Routine Description:
    00527
    00528     A value entry may be created or replaced with EhSetValueKey.
    00529
    00530     If a value entry with a Value ID (i.e. name) matching the
    00531     one specified by ValueName exists, it is deleted and replaced
    00532     with the one specified.  If no such value entry exists, a new
    00533     one is created.  NULL is a legal Value ID.  While Value IDs must
    00534     be unique within any given key, the same Value ID may appear
    00535     in many different keys.
    00536
    00537 Arguments:
    00538
    00539     HiveHandle - handle of hive control structure for hive of interest
    00540
    00541     CellHandle - handle for parent cell
    00542
    00543     ValueName - The unique (relative to the containing key) name
    00544         of the value entry.  May be NULL.
    00545
    00546     TitleIndex - Supplies the title index for ValueName.  The title
    00547         index specifies the index of the localized alias for the ValueName.
    00548
    00549     Type - The integer type number of the value entry.
    00550
    00551     Data - Pointer to buffer with actual data for the value entry.
    00552
    00553     DataSize - Size of Data buffer.
    00554
    00555
    00556 Return Value:
    00557
    00558     NTSTATUS - Result code from call, among the following:
    00559
    00560         <TBS>
    00561
    00562 --*/
    00563 {
    00564     CM_KEY_CONTROL_BLOCK kcb;
    00565
    00566     kcb.Delete = FALSE;
    00567     kcb.Signature = CM_KEY_CONTROL_BLOCK_SIGNATURE;
    00568     kcb.KeyHive = (PHHIVE)&(((PCMHIVE)HiveHandle)->Hive);
    00569     kcb.KeyCell = (HCELL_INDEX)CellHandle;
    00570     kcb.FullName.Length = 0;
    00571     kcb.FullName.MaximumLength = 0;
    00572     kcb.FullName.Buffer = NULL;
    00573
    00574     return(CmSetValueKey(&kcb,
    00575                          *ValueName,
    00576                          TitleIndex,
    00577                          Type,
    00578                          Data,
    00579                          DataSize));
    00580
    00581 }
    00582
    00583
    00584 NTSTATUS
    00585 EhOpenChildByName(
    00586     HANDLE HiveHandle,
    00587     HANDLE CellHandle,
    00588     PUNICODE_STRING  Name,
    00589     PHANDLE ChildCell
    00590     )
    00591 /*++
    00592
    00593 Routine Description:
    00594
    00595     Find the child subkey cell specified by Name.
    00596
    00597 Arguments:
    00598
    00599     HiveHandle - handle of hive control structure for hive of interest
    00600
    00601     CellHandle - handle for parent cell
    00602
    00603     Name - name of child object to find
    00604
    00605     ChildCell - pointer to variable to receive cell index of child
    00606
    00607 Return Value:
    00608
    00609     status
    00610
    00611 --*/
    00612 {
    00613     PHCELL_INDEX    Index;
    00614
    00615     return(CmpFindChildByName(&((PCMHIVE)HiveHandle)->Hive,
    00616                               (HCELL_INDEX)CellHandle,
    00617                               *Name,
    00618                               KeyBodyNode,
    00619                               (PHCELL_INDEX)ChildCell,
    00620                               &Index));
    00621 }
    00622
    00623
    00624 NTSTATUS
    00625 EhCreateChild(
    00626     IN HANDLE HiveHandle,
    00627     IN HANDLE CellHandle,
    00628     IN PUNICODE_STRING  Name,
    00629     OUT PHANDLE ChildCell,
    00630     OUT PULONG Disposition OPTIONAL
    00631     )
    00632 /*++
    00633
    00634 Routine Description:
    00635
    00636     Attempts to open the given child subkey specified by name.  If the
    00637     child does not exist, it is created.
    00638
    00639 Arguments:
    00640
    00641     HiveHandle - handle of hive control structure for hive of interest
    00642
    00643     CellHandle - handle for parent cell
    00644
    00645
    00646     Name - name of child object to create
    00647
    00648     ChildCell - pointer to variable to receive cell index of child
    00649
    00650     Disposition - This optional parameter is a pointer to a variable
    00651         that will receive a value indicating whether a new Registry
    00652         key was created or an existing one opened:
    00653
    00654         REG_CREATED_NEW_KEY - A new Registry Key was created
    00655         REG_OPENED_EXISTING_KEY - An existing Registry Key was opened
    00656
    00657 Return Value:
    00658
    00659     status
    00660
    00661 --*/
    00662 {
    00663     PHCELL_INDEX Index;
    00664     NTSTATUS Status;
    00665     PHHIVE Hive;
    00666     HCELL_INDEX NewCell;
    00667     HCELL_INDEX NewListCell;
    00668     HCELL_INDEX OldListCell;
    00669     PHCELL_INDEX NewList;
    00670     PHCELL_INDEX OldList;
    00671     PCM_KEY_NODE Child;
    00672     PCM_KEY_NODE Parent;
    00673     PCM_KEY_SECURITY Security;
    00674     HANDLE Handle;
    00675     ULONG oldcount;
    00676
    00677     Hive = &((PCMHIVE)HiveHandle)->Hive;
    00678
    00679     if ((HCELL_INDEX)CellHandle == HCELL_NIL) {
    00680         if (Hive->BaseBlock->RootCell != HCELL_NIL) {
    00681             *ChildCell = (HANDLE)(Hive->BaseBlock->RootCell);
    00682             if (ARGUMENT_PRESENT(Disposition)) {
    00683                 *Disposition = REG_OPENED_EXISTING_KEY;
    00684             }
    00685             return(STATUS_SUCCESS);
    00686         } else {
    00687             Status = STATUS_OBJECT_NAME_NOT_FOUND;
    00688         }
    00689     } else {
    00690         Parent = (PCM_KEY_NODE)HvGetCell(Hive, (HCELL_INDEX)CellHandle);
    00691         Status = CmpFindChildByName(Hive,
    00692                                     (HCELL_INDEX)CellHandle,
    00693                                     *Name,
    00694                                     KeyBodyNode,
    00695                                     (PHCELL_INDEX)ChildCell,
    00696                                     &Index);
    00697     }
    00698     if (Status == STATUS_OBJECT_NAME_NOT_FOUND) {
    00699
    00700         NewCell = HvAllocateCell(Hive,
    00701                                  CmpHKeyNodeSize(Hive,Name->Length),
    00702                                  Stable);
    00703         if (NewCell != HCELL_NIL) {
    00704
    00705             *ChildCell = (HANDLE)NewCell;
    00706             Child = (PCM_KEY_NODE)HvGetCell(Hive, NewCell);
    00707
    00708             Child->Signature = CM_KEY_NODE_SIGNATURE;
    00709             Child->Flags = 0;
    00710
    00711             KeQuerySystemTime(&(Child->LastWriteTime));
    00712
    00713             Child->Spare = 0;
    00714             Child->Parent = (HCELL_INDEX)CellHandle;
    00715
    00716             Child->ValueList.Count = 0;
    00717             Child->ValueList.List = HCELL_NIL;
    00718             Child->u1.s1.Security = HCELL_NIL;
    00719             Child->u1.s1.Class = HCELL_NIL;
    00720             Child->NameLength = Name->Length;
    00721             Child->ClassLength = 0;
    00722
    00723             Child->SubKeyCounts[Stable] = 0;
    00724             Child->SubKeyCounts[Volatile] = 0;
    00725             Child->SubKeyLists[Stable] = HCELL_NIL;
    00726             Child->SubKeyLists[Volatile] = HCELL_NIL;
    00727
    00728             Child->MaxValueDataLen = 0;
    00729             Child->MaxNameLen = 0;
    00730             Child->MaxValueNameLen = 0;
    00731             Child->MaxClassLen = 0;
    00732
    00733             if((HCELL_INDEX)CellHandle == HCELL_NIL) {
    00734                 Hive->BaseBlock->RootCell = NewCell;
    00735                 Status = EhpAttachSecurity(Hive, NewCell);
    00736             } else {
    00737                 Child->u1.s1.Security = Parent->u1.s1.Security;
    00738                 Security = (PCM_KEY_SECURITY)HvGetCell(Hive, Child->u1.s1.Security);
    00739                 ++Security->ReferenceCount;
    00740             }
    00741
    00742             RtlMoveMemory(
    00743                 &(Child->Name[0]),
    00744                 Name->Buffer,
    00745                 Name->Length
    00746                 );
    00747
    00748             Status = STATUS_SUCCESS;
    00749         } else {
    00750             Status == STATUS_INSUFFICIENT_RESOURCES;
    00751             return(Status);
    00752         }
    00753         if (ARGUMENT_PRESENT(Disposition)) {
    00754             *Disposition = REG_CREATED_NEW_KEY;
    00755         }
    00756
    00757         if ((HCELL_INDEX)CellHandle != HCELL_NIL) {
    00758
    00759             //
    00760             // put newly created child into parent's sub key list
    00761             //
    00762             if (! CmpAddSubKey(Hive, (HCELL_INDEX)CellHandle, NewCell)) {
    00763                 CmpFreeKeyByCell(Hive, NewCell, FALSE);
    00764                 return STATUS_INSUFFICIENT_RESOURCES;
    00765             }
    00766
    00767             Parent = (PCM_KEY_NODE)HvGetCell(Hive, (HCELL_INDEX)CellHandle);
    00768
    00769             if (Parent->MaxNameLen < Name->Length) {
    00770                 Parent->MaxNameLen = Name->Length;
    00771             }
    00772             Parent->MaxClassLen = 0;
    00773         }
    00774     } else {
    00775         Status = STATUS_SUCCESS;
    00776         if (ARGUMENT_PRESENT(Disposition)) {
    00777             *Disposition = REG_OPENED_EXISTING_KEY;
    00778         }
    00779     }
    00780     return(Status);
    00781 }
    00782
    00783
    00784 NTSTATUS
    00785 EhQueryKey(
    00786     IN HANDLE HiveHandle,
    00787     IN HANDLE KeyHandle,
    00788     IN KEY_INFORMATION_CLASS KeyInformationClass,
    00789     IN PVOID KeyInformation,
    00790     IN ULONG Length,
    00791     IN PULONG ResultLength
    00792     )
    00793 /*++
    00794
    00795 Routine Description:
    00796
    00797     Data about the class of a key, and the numbers and sizes of its
    00798     children and value entries may be queried with CmQueryKey.
    00799
    00800     NOTE: The returned lengths are guaranteed to be at least as
    00801           long as the described values, but may be longer in
    00802           some circumstances.
    00803
    00804 Arguments:
    00805
    00806     Hive - supplies a handle to the hive control structure for the hive
    00807
    00808     Cell - supplies handle of node to whose sub keys are to be found
    00809
    00810     KeyInformationClass - Specifies the type of information
    00811         returned in Buffer.  One of the following types:
    00812
    00813         KeyBasicInformation - return last write time, title index, and name.
    00814             (See KEY_BASIC_INFORMATION)
    00815
    00816         KeyNodeInformation - return last write time, title index, name, class.
    00817             (See KEY_NODE_INFORMATION)
    00818
    00819         KeyFullInformation - return all data except for name and security.
    00820             (See KEY_FULL_INFORMATION)
    00821
    00822     KeyInformation -Supplies pointer to buffer to receive the data.
    00823
    00824     Length - Length of KeyInformation in bytes.
    00825
    00826     ResultLength - Number of bytes actually written into KeyInformation.
    00827
    00828 Return Value:
    00829
    00830     NTSTATUS - Result code from call, among the following:
    00831
    00832         <TBS>
    00833
    00834 --*/
    00835 {
    00836     CM_KEY_CONTROL_BLOCK Kcb;
    00837
    00838     Kcb.Delete = FALSE;
    00839     Kcb.Signature = CM_KEY_CONTROL_BLOCK_SIGNATURE;
    00840     Kcb.KeyHive = &((PCMHIVE)HiveHandle)->Hive;
    00841     Kcb.KeyCell = (HCELL_INDEX)KeyHandle;
    00842     Kcb.FullName.Length = 0;
    00843     Kcb.FullName.MaximumLength = 0;
    00844     Kcb.FullName.Buffer = NULL;
    00845
    00846     return(CmQueryKey(&Kcb,
    00847                       KeyInformationClass,
    00848                       KeyInformation,
    00849                       Length,
    00850                       ResultLength));
    00851 }
    00852
    00853 PSECURITY_DESCRIPTOR
    00854 EhGetKeySecurity(
    00855     IN HANDLE HiveHandle,
    00856     IN HANDLE KeyHandle
    00857     )
    00858 {
    00859     PCM_KEY_SECURITY Security;
    00860
    00861     CmpGetObjectSecurity((HCELL_INDEX)KeyHandle,
    00862                          &((PCMHIVE)HiveHandle)->Hive,
    00863                          &Security,
    00864                          NULL);
    00865
    00866     return(&Security->Descriptor);
    00867 }
    00868
    00869
    00870 NTSTATUS
    00871 EhQueryValueKey(
    00872     IN HANDLE HiveHandle,
    00873     IN HANDLE KeyHandle,
    00874     IN PUNICODE_STRING ValueName,
    00875     IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
    00876     IN PVOID KeyValueInformation,
    00877     IN ULONG Length,
    00878     IN PULONG ResultLength
    00879     )
    00880 /*++
    00881
    00882 Routine Description:
    00883
    00884     The ValueName, TitleIndex, Type, and Data for any one of a key's
    00885     value entries may be queried with CmQueryValueKey.
    00886
    00887     If KeyValueInformation is not long enough to hold all requested data,
    00888     STATUS_BUFFER_OVERFLOW will be returned, and ResultLength will be
    00889     set to the number of bytes actually required.
    00890
    00891 Arguments:
    00892
    00893     Hive - supplies a pointer to the hive control structure for the hive
    00894
    00895     Cell - supplies index of node to whose sub keys are to be found
    00896
    00897     ValueName  - The name of the value entry to return data for.
    00898
    00899     KeyValueInformationClass - Specifies the type of information
    00900         returned in KeyValueInformation.  One of the following types:
    00901
    00902         KeyValueBasicInformation - return time of last write, title
    00903             index, and name.  (See KEY_VALUE_BASIC_INFORMATION)
    00904
    00905         KeyValueFullInformation - return time of last write, title
    00906             index, name, class.  (See KEY_VALUE_FULL_INFORMATION)
    00907
    00908     KeyValueInformation -Supplies pointer to buffer to receive the data.
    00909
    00910     Length - Length of KeyValueInformation in bytes.
    00911
    00912     ResultLength - Number of bytes actually written into KeyValueInformation.
    00913
    00914 Return Value:
    00915
    00916     NTSTATUS - Result code from call, among the following:
    00917
    00918         <TBS>
    00919
    00920 --*/
    00921 {
    00922     CM_KEY_CONTROL_BLOCK kcb;
    00923
    00924     kcb.Delete = FALSE;
    00925     kcb.Signature = CM_KEY_CONTROL_BLOCK_SIGNATURE;
    00926     kcb.KeyHive = &((PCMHIVE)HiveHandle)->Hive;
    00927     kcb.KeyCell = (HCELL_INDEX)KeyHandle;
    00928     kcb.FullName.Length = 0;
    00929     kcb.FullName.MaximumLength = 0;
    00930     kcb.FullName.Buffer = NULL;
    00931
    00932     return(CmQueryValueKey(&kcb,
    00933                            *ValueName,
    00934                            KeyValueInformationClass,
    00935                            KeyValueInformation,
    00936                            Length,
    00937                            ResultLength));
    00938
    00939 }
    00940
    00941
    00942 NTSTATUS
    00943 EhDeleteValueKey(
    00944     IN HANDLE HiveHandle,
    00945     IN HANDLE CellHandle,
    00946     IN PUNICODE_STRING ValueName         // RAW
    00947     )
    00948 /*++
    00949
    00950 Routine Description:
    00951
    00952     One of the value entries of a registry key may be removed with this call.
    00953
    00954     The value entry with ValueName matching ValueName is removed from the key.
    00955     If no such entry exists, an error is returned.
    00956
    00957 Arguments:
    00958
    00959     Hive - Supplies a handle to the hive control structure
    00960
    00961     Cell - Supplies a handle to the registry key to be operated on
    00962
    00963     ValueName - The name of the value to be deleted.  NULL is a legal name.
    00964
    00965 Return Value:
    00966
    00967     NTSTATUS - Result code from call, among the following:
    00968
    00969         <TBS>
    00970
    00971 --*/
    00972 {
    00973     CM_KEY_CONTROL_BLOCK kcb;
    00974
    00975     kcb.Delete = FALSE;
    00976     kcb.Signature = CM_KEY_CONTROL_BLOCK_SIGNATURE;
    00977     kcb.KeyHive = &((PCMHIVE)HiveHandle)->Hive;
    00978     kcb.KeyCell = (HCELL_INDEX)CellHandle;
    00979     kcb.FullName.Length = 0;
    00980     kcb.FullName.MaximumLength = 0;
    00981     kcb.FullName.Buffer = NULL;
    00982
    00983     return(CmDeleteValueKey(&kcb, *ValueName));
    00984 }
    00985
    00986
    00987 NTSTATUS
    00988 EhpAttachSecurity(
    00989     IN PHHIVE Hive,
    00990     IN HCELL_INDEX Cell
    00991     )
    00992
    00993 /*++
    00994
    00995 Routine Description:
    00996
    00997     Creates a security descriptor cell and attaches it to the given
    00998     node.
    00999
    01000 Arguments:
    01001
    01002     Hive - Supplies a pointer to the hive control structure.
    01003
    01004     Cell - Supplies the cell index of the node to attach the security
    01005            descriptor to.
    01006
    01007 Return Value:
    01008
    01009     None.
    01010
    01011 --*/
    01012
    01013 {
    01014     NTSTATUS Status;
    01015     HANDLE Token;
    01016     HCELL_INDEX SecurityCell;
    01017     PCM_KEY_NODE Node;
    01018     PCM_KEY_SECURITY Security;
    01019     PSECURITY_DESCRIPTOR Descriptor;
    01020     ULONG DescriptorLength;
    01021     HANDLE Handle;
    01022
    01023     Status = NtOpenProcessToken( NtCurrentProcess(),
    01024                                  TOKEN_QUERY,
    01025                                  &Token );
    01026     if (!NT_SUCCESS(Status)) {
    01027         return(Status);
    01028     }
    01029
    01030     Status = RtlNewSecurityObject( NULL,
    01031                                    NULL,
    01032                                    &Descriptor,
    01033                                    FALSE,
    01034                                    Token,
    01035                                    &CmpKeyMapping );
    01036     if (!NT_SUCCESS(Status)) {
    01037         return(Status);
    01038     }
    01039
    01040     Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
    01041     SecurityCell = HvAllocateCell(Hive,
    01042                                   SECURITY_CELL_LENGTH(Descriptor),
    01043                                   Stable);
    01044     if (SecurityCell == HCELL_NIL) {
    01045         return STATUS_INSUFFICIENT_RESOURCES;
    01046     }
    01047     Node->u1.s1.Security = SecurityCell;
    01048     Security = (PCM_KEY_SECURITY)HvGetCell(Hive, SecurityCell);
    01049     DescriptorLength = RtlLengthSecurityDescriptor(Descriptor);
    01050     Security->Signature = CM_KEY_SECURITY_SIGNATURE;
    01051     Security->ReferenceCount = 1;
    01052     Security->DescriptorLength = DescriptorLength;
    01053     RtlMoveMemory( &Security->Descriptor,
    01054                    Descriptor,
    01055                    DescriptorLength );
    01056     Security->Flink = Security->Blink = SecurityCell;
    01057     return(STATUS_SUCCESS);
    01058
    01059 }
    01060