Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencmi.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2006 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* COPYRIGHT: See COPYING in the top level directory 00020 * PROJECT: ReactOS hive maker 00021 * FILE: tools/mkhive/cmi.c 00022 * PURPOSE: Registry file manipulation routines 00023 * PROGRAMMER: Hervé Poussineau 00024 */ 00025 00026 #define NDEBUG 00027 #include "mkhive.h" 00028 00029 static PVOID 00030 NTAPI 00031 CmpAllocate( 00032 IN SIZE_T Size, 00033 IN BOOLEAN Paged, 00034 IN ULONG Tag) 00035 { 00036 return (PVOID) malloc((size_t)Size); 00037 } 00038 00039 static VOID 00040 NTAPI 00041 CmpFree( 00042 IN PVOID Ptr, 00043 IN ULONG Quota) 00044 { 00045 free(Ptr); 00046 } 00047 00048 static BOOLEAN 00049 NTAPI 00050 CmpFileRead( 00051 IN PHHIVE RegistryHive, 00052 IN ULONG FileType, 00053 IN PULONG FileOffset, 00054 OUT PVOID Buffer, 00055 IN SIZE_T BufferLength) 00056 { 00057 DPRINT1("CmpFileRead() unimplemented\n"); 00058 return FALSE; 00059 } 00060 00061 static BOOLEAN 00062 NTAPI 00063 CmpFileWrite( 00064 IN PHHIVE RegistryHive, 00065 IN ULONG FileType, 00066 IN PULONG FileOffset, 00067 IN PVOID Buffer, 00068 IN SIZE_T BufferLength) 00069 { 00070 PCMHIVE CmHive = (PCMHIVE)RegistryHive; 00071 FILE *File = CmHive->FileHandles[HFILE_TYPE_PRIMARY]; 00072 if (0 != fseek (File, *FileOffset, SEEK_SET)) 00073 return FALSE; 00074 return BufferLength == fwrite (Buffer, 1, BufferLength, File); 00075 } 00076 00077 static BOOLEAN 00078 NTAPI 00079 CmpFileSetSize( 00080 IN PHHIVE RegistryHive, 00081 IN ULONG FileType, 00082 IN ULONG FileSize, 00083 IN ULONG OldFileSize) 00084 { 00085 DPRINT1("CmpFileSetSize() unimplemented\n"); 00086 return FALSE; 00087 } 00088 00089 static BOOLEAN 00090 NTAPI 00091 CmpFileFlush( 00092 IN PHHIVE RegistryHive, 00093 IN ULONG FileType, 00094 PLARGE_INTEGER FileOffset, 00095 ULONG Length) 00096 { 00097 PCMHIVE CmHive = (PCMHIVE)RegistryHive; 00098 FILE *File = CmHive->FileHandles[HFILE_TYPE_PRIMARY]; 00099 return 0 == fflush (File); 00100 } 00101 00102 NTSTATUS 00103 CmiInitializeTempHive( 00104 IN OUT PCMHIVE Hive) 00105 { 00106 NTSTATUS Status; 00107 00108 RtlZeroMemory ( 00109 Hive, 00110 sizeof(CMHIVE)); 00111 00112 DPRINT("Hive 0x%p\n", Hive); 00113 00114 Status = HvInitialize(&Hive->Hive, 00115 HINIT_CREATE, 00116 0, 00117 0, 00118 0, 00119 CmpAllocate, 00120 CmpFree, 00121 CmpFileSetSize, 00122 CmpFileWrite, 00123 CmpFileRead, 00124 CmpFileFlush, 00125 1, 00126 NULL); 00127 if (!NT_SUCCESS(Status)) 00128 { 00129 return Status; 00130 } 00131 00132 if (!CmCreateRootNode (&Hive->Hive, L"")) 00133 { 00134 HvFree (&Hive->Hive); 00135 return STATUS_INSUFFICIENT_RESOURCES; 00136 } 00137 00138 Hive->Flags = HIVE_NO_FILE; 00139 00140 /* Add the new hive to the hive list */ 00141 InsertTailList ( 00142 &CmiHiveListHead, 00143 &Hive->HiveList); 00144 00145 VERIFY_REGISTRY_HIVE (Hive); 00146 00147 return STATUS_SUCCESS; 00148 } 00149 00150 static NTSTATUS 00151 CmiAddKeyToHashTable( 00152 IN PCMHIVE RegistryHive, 00153 IN OUT PCM_KEY_FAST_INDEX HashCell, 00154 IN HCELL_INDEX HashCellIndex, 00155 IN PCM_KEY_NODE NewKeyCell, 00156 IN HCELL_INDEX NKBOffset) 00157 { 00158 ULONG i; 00159 ULONG HashKey = 0; 00160 00161 if (NewKeyCell->Flags & KEY_COMP_NAME) 00162 { 00163 RtlCopyMemory( 00164 &HashKey, 00165 NewKeyCell->Name, 00166 min(NewKeyCell->NameLength, sizeof(ULONG))); 00167 } 00168 00169 for (i = 0; i < HashCell->Count; i++) 00170 { 00171 if (HashCell->List[i].HashKey > HashKey) 00172 break; 00173 } 00174 00175 if (i < HashCell->Count) 00176 { 00177 RtlMoveMemory(HashCell->List + i + 1, 00178 HashCell->List + i, 00179 (HashCell->Count - i) * 00180 sizeof(HashCell->List[0])); 00181 } 00182 00183 HashCell->List[i].Cell = NKBOffset; 00184 HashCell->List[i].HashKey = HashKey; 00185 HashCell->Count++; 00186 HvMarkCellDirty(&RegistryHive->Hive, HashCellIndex, FALSE); 00187 return STATUS_SUCCESS; 00188 } 00189 00190 static NTSTATUS 00191 CmiAllocateHashTableCell ( 00192 IN PCMHIVE RegistryHive, 00193 OUT PCM_KEY_FAST_INDEX *HashBlock, 00194 OUT HCELL_INDEX *HBOffset, 00195 IN USHORT SubKeyCount, 00196 IN HSTORAGE_TYPE Storage) 00197 { 00198 PCM_KEY_FAST_INDEX NewHashBlock; 00199 ULONG NewHashSize; 00200 NTSTATUS Status; 00201 00202 Status = STATUS_SUCCESS; 00203 *HashBlock = NULL; 00204 NewHashSize = FIELD_OFFSET(CM_KEY_FAST_INDEX, List) + 00205 (SubKeyCount * sizeof(CM_INDEX)); 00206 *HBOffset = HvAllocateCell(&RegistryHive->Hive, NewHashSize, Storage, HCELL_NIL); 00207 00208 if (*HBOffset == HCELL_NIL) 00209 { 00210 Status = STATUS_INSUFFICIENT_RESOURCES; 00211 } 00212 else 00213 { 00214 NewHashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (&RegistryHive->Hive, *HBOffset); 00215 NewHashBlock->Signature = CM_KEY_FAST_LEAF; 00216 NewHashBlock->Count = 0; 00217 *HashBlock = NewHashBlock; 00218 } 00219 00220 return Status; 00221 } 00222 00223 NTSTATUS 00224 CmiAddSubKey( 00225 IN PCMHIVE RegistryHive, 00226 IN PCM_KEY_NODE ParentKeyCell, 00227 IN HCELL_INDEX ParentKeyCellOffset, 00228 IN PCUNICODE_STRING SubKeyName, 00229 IN ULONG CreateOptions, 00230 OUT PCM_KEY_NODE *pSubKeyCell, 00231 OUT HCELL_INDEX *pBlockOffset) 00232 { 00233 PCM_KEY_FAST_INDEX HashBlock; 00234 HCELL_INDEX NKBOffset; 00235 PCM_KEY_NODE NewKeyCell; 00236 ULONG NewBlockSize; 00237 NTSTATUS Status; 00238 USHORT NameLength; 00239 PWSTR NamePtr; 00240 BOOLEAN Packable; 00241 HSTORAGE_TYPE Storage; 00242 ULONG i; 00243 00244 VERIFY_KEY_CELL(ParentKeyCell); 00245 00246 /* Skip leading backslash */ 00247 if (SubKeyName->Buffer[0] == L'\\') 00248 { 00249 NamePtr = &SubKeyName->Buffer[1]; 00250 NameLength = SubKeyName->Length - sizeof(WCHAR); 00251 } 00252 else 00253 { 00254 NamePtr = SubKeyName->Buffer; 00255 NameLength = SubKeyName->Length; 00256 } 00257 00258 /* Check whether key name can be packed */ 00259 Packable = TRUE; 00260 for (i = 0; i < NameLength / sizeof(WCHAR); i++) 00261 { 00262 if (NamePtr[i] & 0xFF00) 00263 { 00264 Packable = FALSE; 00265 break; 00266 } 00267 } 00268 00269 /* Adjust name size */ 00270 if (Packable) 00271 { 00272 NameLength = NameLength / sizeof(WCHAR); 00273 } 00274 00275 Status = STATUS_SUCCESS; 00276 00277 Storage = (CreateOptions & REG_OPTION_VOLATILE) ? Volatile : Stable; 00278 NewBlockSize = FIELD_OFFSET(CM_KEY_NODE, Name) + NameLength; 00279 NKBOffset = HvAllocateCell(&RegistryHive->Hive, NewBlockSize, Storage, HCELL_NIL); 00280 if (NKBOffset == HCELL_NIL) 00281 { 00282 Status = STATUS_INSUFFICIENT_RESOURCES; 00283 } 00284 else 00285 { 00286 NewKeyCell = (PCM_KEY_NODE)HvGetCell (&RegistryHive->Hive, NKBOffset); 00287 NewKeyCell->Signature = CM_KEY_NODE_SIGNATURE; 00288 if (CreateOptions & REG_OPTION_VOLATILE) 00289 { 00290 NewKeyCell->Flags = KEY_IS_VOLATILE; 00291 } 00292 else 00293 { 00294 NewKeyCell->Flags = 0; 00295 } 00296 KeQuerySystemTime(&NewKeyCell->LastWriteTime); 00297 NewKeyCell->Parent = HCELL_NIL; 00298 NewKeyCell->SubKeyCounts[Stable] = 0; 00299 NewKeyCell->SubKeyCounts[Volatile] = 0; 00300 NewKeyCell->SubKeyLists[Stable] = HCELL_NIL; 00301 NewKeyCell->SubKeyLists[Volatile] = HCELL_NIL; 00302 NewKeyCell->ValueList.Count = 0; 00303 NewKeyCell->ValueList.List = HCELL_NIL; 00304 NewKeyCell->Security = HCELL_NIL; 00305 NewKeyCell->Class = HCELL_NIL; 00306 00307 /* Pack the key name */ 00308 NewKeyCell->NameLength = NameLength; 00309 if (Packable) 00310 { 00311 NewKeyCell->Flags |= KEY_COMP_NAME; 00312 for (i = 0; i < NameLength; i++) 00313 { 00314 ((PCHAR)NewKeyCell->Name)[i] = (CHAR)(NamePtr[i] & 0x00FF); 00315 } 00316 } 00317 else 00318 { 00319 RtlCopyMemory( 00320 NewKeyCell->Name, 00321 NamePtr, 00322 NameLength); 00323 } 00324 00325 VERIFY_KEY_CELL(NewKeyCell); 00326 } 00327 00328 if (!NT_SUCCESS(Status)) 00329 { 00330 return Status; 00331 } 00332 00333 if (ParentKeyCell->SubKeyLists[Storage] == HCELL_NIL) 00334 { 00335 Status = CmiAllocateHashTableCell ( 00336 RegistryHive, 00337 &HashBlock, 00338 &ParentKeyCell->SubKeyLists[Storage], 00339 REG_INIT_HASH_TABLE_SIZE, 00340 Storage); 00341 if (!NT_SUCCESS(Status)) 00342 { 00343 return(Status); 00344 } 00345 } 00346 else 00347 { 00348 HashBlock = (PCM_KEY_FAST_INDEX)HvGetCell ( 00349 &RegistryHive->Hive, 00350 ParentKeyCell->SubKeyLists[Storage]); 00351 ASSERT(HashBlock->Signature == CM_KEY_FAST_LEAF); 00352 00353 if (HashBlock->Count == 00354 ((HvGetCellSize(&RegistryHive->Hive, HashBlock) - FIELD_OFFSET(CM_KEY_FAST_INDEX, List)) / sizeof(CM_INDEX))) 00355 { 00356 PCM_KEY_FAST_INDEX NewHashBlock; 00357 HCELL_INDEX HTOffset; 00358 00359 /* Reallocate the hash table cell */ 00360 Status = CmiAllocateHashTableCell ( 00361 RegistryHive, 00362 &NewHashBlock, 00363 &HTOffset, 00364 HashBlock->Count + 00365 REG_EXTEND_HASH_TABLE_SIZE, 00366 Storage); 00367 if (!NT_SUCCESS(Status)) 00368 { 00369 return Status; 00370 } 00371 RtlCopyMemory( 00372 &NewHashBlock->List[0], 00373 &HashBlock->List[0], 00374 sizeof(NewHashBlock->List[0]) * HashBlock->Count); 00375 NewHashBlock->Count = HashBlock->Count; 00376 HvFreeCell (&RegistryHive->Hive, ParentKeyCell->SubKeyLists[Storage]); 00377 ParentKeyCell->SubKeyLists[Storage] = HTOffset; 00378 HashBlock = NewHashBlock; 00379 } 00380 } 00381 00382 Status = CmiAddKeyToHashTable( 00383 RegistryHive, 00384 HashBlock, 00385 ParentKeyCell->SubKeyLists[Storage], 00386 NewKeyCell, 00387 NKBOffset); 00388 if (NT_SUCCESS(Status)) 00389 { 00390 ParentKeyCell->SubKeyCounts[Storage]++; 00391 if (Packable) 00392 { 00393 if (NameLength*sizeof(WCHAR) > ParentKeyCell->MaxNameLen) 00394 ParentKeyCell->MaxNameLen = NameLength*sizeof(WCHAR); 00395 } 00396 else 00397 { 00398 if (NameLength > ParentKeyCell->MaxNameLen) 00399 ParentKeyCell->MaxNameLen = NameLength; 00400 } 00401 if (NewKeyCell->ClassLength > ParentKeyCell->MaxClassLen) 00402 ParentKeyCell->MaxClassLen = NewKeyCell->ClassLength; 00403 00404 *pSubKeyCell = NewKeyCell; 00405 *pBlockOffset = NKBOffset; 00406 } 00407 00408 KeQuerySystemTime(&ParentKeyCell->LastWriteTime); 00409 HvMarkCellDirty(&RegistryHive->Hive, ParentKeyCellOffset, FALSE); 00410 00411 return Status; 00412 } 00413 00414 static BOOLEAN 00415 CmiCompareHash( 00416 IN PCUNICODE_STRING KeyName, 00417 IN PCHAR HashString) 00418 { 00419 CHAR Buffer[4]; 00420 00421 Buffer[0] = (KeyName->Length >= 2) ? (CHAR)KeyName->Buffer[0] : 0; 00422 Buffer[1] = (KeyName->Length >= 4) ? (CHAR)KeyName->Buffer[1] : 0; 00423 Buffer[2] = (KeyName->Length >= 6) ? (CHAR)KeyName->Buffer[2] : 0; 00424 Buffer[3] = (KeyName->Length >= 8) ? (CHAR)KeyName->Buffer[3] : 0; 00425 00426 return (strncmp(Buffer, HashString, 4) == 0); 00427 } 00428 00429 00430 BOOLEAN 00431 CmiCompareHashI( 00432 IN PCUNICODE_STRING KeyName, 00433 IN PCHAR HashString) 00434 { 00435 CHAR Buffer[4]; 00436 00437 Buffer[0] = (KeyName->Length >= 2) ? (CHAR)KeyName->Buffer[0] : 0; 00438 Buffer[1] = (KeyName->Length >= 4) ? (CHAR)KeyName->Buffer[1] : 0; 00439 Buffer[2] = (KeyName->Length >= 6) ? (CHAR)KeyName->Buffer[2] : 0; 00440 Buffer[3] = (KeyName->Length >= 8) ? (CHAR)KeyName->Buffer[3] : 0; 00441 00442 return (strncasecmp(Buffer, HashString, 4) == 0); 00443 } 00444 00445 static BOOLEAN 00446 CmiCompareKeyNames( 00447 IN PCUNICODE_STRING KeyName, 00448 IN PCM_KEY_NODE KeyCell) 00449 { 00450 PWCHAR UnicodeName; 00451 USHORT i; 00452 00453 if (KeyCell->Flags & KEY_COMP_NAME) 00454 { 00455 if (KeyName->Length != KeyCell->NameLength * sizeof(WCHAR)) 00456 return FALSE; 00457 00458 for (i = 0; i < KeyCell->NameLength; i++) 00459 { 00460 if (KeyName->Buffer[i] != ((PCHAR)KeyCell->Name)[i]) 00461 return FALSE; 00462 } 00463 } 00464 else 00465 { 00466 if (KeyName->Length != KeyCell->NameLength) 00467 return FALSE; 00468 00469 UnicodeName = (PWCHAR)KeyCell->Name; 00470 for (i = 0; i < KeyCell->NameLength / sizeof(WCHAR); i++) 00471 { 00472 if (KeyName->Buffer[i] != UnicodeName[i]) 00473 return FALSE; 00474 } 00475 } 00476 00477 return TRUE; 00478 } 00479 00480 static BOOLEAN 00481 CmiCompareKeyNamesI( 00482 IN PCUNICODE_STRING KeyName, 00483 IN PCM_KEY_NODE KeyCell) 00484 { 00485 PWCHAR UnicodeName; 00486 USHORT i; 00487 00488 DPRINT("Flags: %hx\n", KeyCell->Flags); 00489 00490 if (KeyCell->Flags & KEY_COMP_NAME) 00491 { 00492 if (KeyName->Length != KeyCell->NameLength * sizeof(WCHAR)) 00493 return FALSE; 00494 00495 /* FIXME: use _strnicmp */ 00496 for (i = 0; i < KeyCell->NameLength; i++) 00497 { 00498 if (RtlUpcaseUnicodeChar(KeyName->Buffer[i]) != 00499 RtlUpcaseUnicodeChar(((PCHAR)KeyCell->Name)[i])) 00500 return FALSE; 00501 } 00502 } 00503 else 00504 { 00505 if (KeyName->Length != KeyCell->NameLength) 00506 return FALSE; 00507 00508 UnicodeName = (PWCHAR)KeyCell->Name; 00509 /* FIXME: use _strnicmp */ 00510 for (i = 0; i < KeyCell->NameLength / sizeof(WCHAR); i++) 00511 { 00512 if (RtlUpcaseUnicodeChar(KeyName->Buffer[i]) != 00513 RtlUpcaseUnicodeChar(UnicodeName[i])) 00514 return FALSE; 00515 } 00516 } 00517 00518 return TRUE; 00519 } 00520 00521 NTSTATUS 00522 CmiScanForSubKey( 00523 IN PCMHIVE RegistryHive, 00524 IN PCM_KEY_NODE KeyCell, 00525 IN PCUNICODE_STRING SubKeyName, 00526 IN ULONG Attributes, 00527 OUT PCM_KEY_NODE *pSubKeyCell, 00528 OUT HCELL_INDEX *pBlockOffset) 00529 { 00530 PCM_KEY_FAST_INDEX HashBlock; 00531 PCM_KEY_NODE CurSubKeyCell; 00532 ULONG Storage; 00533 ULONG i; 00534 00535 VERIFY_KEY_CELL(KeyCell); 00536 00537 ASSERT(RegistryHive); 00538 00539 *pSubKeyCell = NULL; 00540 00541 for (Storage = Stable; Storage < HTYPE_COUNT; Storage++) 00542 { 00543 if (KeyCell->SubKeyLists[Storage] == HCELL_NIL) 00544 { 00545 /* The key does not have any subkeys */ 00546 continue; 00547 } 00548 00549 /* Get hash table */ 00550 HashBlock = (PCM_KEY_FAST_INDEX)HvGetCell (&RegistryHive->Hive, KeyCell->SubKeyLists[Storage]); 00551 if (!HashBlock || HashBlock->Signature != CM_KEY_FAST_LEAF) 00552 return STATUS_UNSUCCESSFUL; 00553 00554 for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++) 00555 { 00556 if (Attributes & OBJ_CASE_INSENSITIVE) 00557 { 00558 if ((HashBlock->List[i].HashKey == 0 00559 || CmiCompareHashI(SubKeyName, (PCHAR)&HashBlock->List[i].HashKey))) 00560 { 00561 CurSubKeyCell = (PCM_KEY_NODE)HvGetCell ( 00562 &RegistryHive->Hive, 00563 HashBlock->List[i].Cell); 00564 00565 if (CmiCompareKeyNamesI(SubKeyName, CurSubKeyCell)) 00566 { 00567 *pSubKeyCell = CurSubKeyCell; 00568 *pBlockOffset = HashBlock->List[i].Cell; 00569 return STATUS_SUCCESS; 00570 } 00571 } 00572 } 00573 else 00574 { 00575 if ((HashBlock->List[i].HashKey == 0 00576 || CmiCompareHash(SubKeyName, (PCHAR)&HashBlock->List[i].HashKey))) 00577 { 00578 CurSubKeyCell = (PCM_KEY_NODE)HvGetCell ( 00579 &RegistryHive->Hive, 00580 HashBlock->List[i].Cell); 00581 00582 if (CmiCompareKeyNames(SubKeyName, CurSubKeyCell)) 00583 { 00584 *pSubKeyCell = CurSubKeyCell; 00585 *pBlockOffset = HashBlock->List[i].Cell; 00586 return STATUS_SUCCESS; 00587 } 00588 } 00589 } 00590 } 00591 } 00592 00593 return STATUS_OBJECT_NAME_NOT_FOUND; 00594 } 00595 00596 static USHORT 00597 CmiGetPackedNameLength( 00598 IN PCUNICODE_STRING Name, 00599 OUT PBOOLEAN pPackable) 00600 { 00601 USHORT i; 00602 00603 *pPackable = TRUE; 00604 00605 for (i = 0; i < Name->Length / sizeof(WCHAR); i++) 00606 { 00607 if (Name->Buffer[i] & 0xFF00) 00608 { 00609 *pPackable = FALSE; 00610 return Name->Length; 00611 } 00612 } 00613 00614 return (Name->Length / sizeof(WCHAR)); 00615 } 00616 00617 static NTSTATUS 00618 CmiAllocateValueCell( 00619 IN PCMHIVE RegistryHive, 00620 OUT PCM_KEY_VALUE *ValueCell, 00621 OUT HCELL_INDEX *VBOffset, 00622 IN PCUNICODE_STRING ValueName, 00623 IN HSTORAGE_TYPE Storage) 00624 { 00625 PCM_KEY_VALUE NewValueCell; 00626 BOOLEAN Packable; 00627 USHORT NameLength, i; 00628 NTSTATUS Status; 00629 00630 Status = STATUS_SUCCESS; 00631 00632 NameLength = CmiGetPackedNameLength(ValueName, &Packable); 00633 00634 DPRINT("ValueName->Length %u NameLength %u\n", ValueName->Length, NameLength); 00635 00636 *VBOffset = HvAllocateCell(&RegistryHive->Hive, sizeof(CM_KEY_VALUE) + NameLength, Storage, HCELL_NIL); 00637 if (*VBOffset == HCELL_NIL) 00638 { 00639 Status = STATUS_INSUFFICIENT_RESOURCES; 00640 } 00641 else 00642 { 00643 NewValueCell = (PCM_KEY_VALUE)HvGetCell (&RegistryHive->Hive, *VBOffset); 00644 NewValueCell->Signature = CM_KEY_VALUE_SIGNATURE; 00645 NewValueCell->NameLength = (USHORT)NameLength; 00646 if (Packable) 00647 { 00648 /* Pack the value name */ 00649 for (i = 0; i < NameLength; i++) 00650 ((PCHAR)NewValueCell->Name)[i] = (CHAR)ValueName->Buffer[i]; 00651 NewValueCell->Flags |= VALUE_COMP_NAME; 00652 } 00653 else 00654 { 00655 /* Copy the value name */ 00656 RtlCopyMemory( 00657 NewValueCell->Name, 00658 ValueName->Buffer, 00659 NameLength); 00660 NewValueCell->Flags = 0; 00661 } 00662 NewValueCell->Type = 0; 00663 NewValueCell->DataLength = 0; 00664 NewValueCell->Data = HCELL_NIL; 00665 *ValueCell = NewValueCell; 00666 } 00667 00668 return Status; 00669 } 00670 00671 NTSTATUS 00672 CmiAddValueKey( 00673 IN PCMHIVE RegistryHive, 00674 IN PCM_KEY_NODE KeyCell, 00675 IN HCELL_INDEX KeyCellOffset, 00676 IN PCUNICODE_STRING ValueName, 00677 OUT PCM_KEY_VALUE *pValueCell, 00678 OUT HCELL_INDEX *pValueCellOffset) 00679 { 00680 PVALUE_LIST_CELL ValueListCell; 00681 PCM_KEY_VALUE NewValueCell; 00682 HCELL_INDEX ValueListCellOffset; 00683 HCELL_INDEX NewValueCellOffset; 00684 ULONG CellSize; 00685 HSTORAGE_TYPE Storage; 00686 NTSTATUS Status; 00687 00688 Storage = (KeyCell->Flags & KEY_IS_VOLATILE) ? Volatile : Stable; 00689 if (KeyCell->ValueList.List == HCELL_NIL) 00690 { 00691 /* Allocate some room for the value list */ 00692 CellSize = sizeof(VALUE_LIST_CELL) + (3 * sizeof(HCELL_INDEX)); 00693 ValueListCellOffset = HvAllocateCell(&RegistryHive->Hive, CellSize, Storage, HCELL_NIL); 00694 if (ValueListCellOffset == HCELL_NIL) 00695 return STATUS_INSUFFICIENT_RESOURCES; 00696 00697 ValueListCell = (PVALUE_LIST_CELL)HvGetCell(&RegistryHive->Hive, ValueListCellOffset); 00698 if (!ValueListCell) 00699 return STATUS_UNSUCCESSFUL; 00700 KeyCell->ValueList.List = ValueListCellOffset; 00701 HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset, FALSE); 00702 } 00703 else 00704 { 00705 ValueListCell = (PVALUE_LIST_CELL)HvGetCell(&RegistryHive->Hive, KeyCell->ValueList.List); 00706 if (!ValueListCell) 00707 return STATUS_UNSUCCESSFUL; 00708 CellSize = ABS_VALUE(HvGetCellSize(&RegistryHive->Hive, ValueListCell)); 00709 00710 if (KeyCell->ValueList.Count >= CellSize / sizeof(HCELL_INDEX)) 00711 { 00712 CellSize *= 2; 00713 ValueListCellOffset = HvReallocateCell(&RegistryHive->Hive, KeyCell->ValueList.List, CellSize); 00714 if (ValueListCellOffset == HCELL_NIL) 00715 return STATUS_INSUFFICIENT_RESOURCES; 00716 00717 ValueListCell = (PVALUE_LIST_CELL)HvGetCell(&RegistryHive->Hive, ValueListCellOffset); 00718 if (!ValueListCell) 00719 return STATUS_UNSUCCESSFUL; 00720 KeyCell->ValueList.List = ValueListCellOffset; 00721 HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset, FALSE); 00722 } 00723 } 00724 00725 Status = CmiAllocateValueCell( 00726 RegistryHive, 00727 &NewValueCell, 00728 &NewValueCellOffset, 00729 ValueName, 00730 Storage); 00731 if (!NT_SUCCESS(Status)) 00732 return Status; 00733 00734 ValueListCell->ValueOffset[KeyCell->ValueList.Count] = NewValueCellOffset; 00735 KeyCell->ValueList.Count++; 00736 if (NewValueCell->Flags & VALUE_COMP_NAME) 00737 { 00738 if (NewValueCell->NameLength*sizeof(WCHAR) > KeyCell->MaxValueNameLen) 00739 KeyCell->MaxValueNameLen = NewValueCell->NameLength*sizeof(WCHAR); 00740 } 00741 else 00742 { 00743 if (NewValueCell->NameLength > KeyCell->MaxValueNameLen) 00744 KeyCell->MaxValueNameLen = NewValueCell->NameLength; 00745 } 00746 00747 HvMarkCellDirty(&RegistryHive->Hive, KeyCellOffset, FALSE); 00748 HvMarkCellDirty(&RegistryHive->Hive, KeyCell->ValueList.List, FALSE); 00749 HvMarkCellDirty(&RegistryHive->Hive, NewValueCellOffset, FALSE); 00750 00751 *pValueCell = NewValueCell; 00752 *pValueCellOffset = NewValueCellOffset; 00753 00754 return STATUS_SUCCESS; 00755 } 00756 00757 static BOOLEAN 00758 CmiComparePackedNames( 00759 IN PCUNICODE_STRING Name, 00760 IN PUCHAR NameBuffer, 00761 IN USHORT NameBufferSize, 00762 IN BOOLEAN NamePacked) 00763 { 00764 PWCHAR UNameBuffer; 00765 ULONG i; 00766 00767 if (NamePacked == TRUE) 00768 { 00769 if (Name->Length != NameBufferSize * sizeof(WCHAR)) 00770 return FALSE; 00771 00772 for (i = 0; i < Name->Length / sizeof(WCHAR); i++) 00773 { 00774 if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar((WCHAR)NameBuffer[i])) 00775 return FALSE; 00776 } 00777 } 00778 else 00779 { 00780 if (Name->Length != NameBufferSize) 00781 return FALSE; 00782 00783 UNameBuffer = (PWCHAR)NameBuffer; 00784 00785 for (i = 0; i < Name->Length / sizeof(WCHAR); i++) 00786 { 00787 if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar(UNameBuffer[i])) 00788 return FALSE; 00789 } 00790 } 00791 00792 return TRUE; 00793 } 00794 00795 NTSTATUS 00796 CmiScanForValueKey( 00797 IN PCMHIVE RegistryHive, 00798 IN PCM_KEY_NODE KeyCell, 00799 IN PCUNICODE_STRING ValueName, 00800 OUT PCM_KEY_VALUE *pValueCell, 00801 OUT HCELL_INDEX *pValueCellOffset) 00802 { 00803 PVALUE_LIST_CELL ValueListCell; 00804 PCM_KEY_VALUE CurValueCell; 00805 ULONG i; 00806 00807 *pValueCell = NULL; 00808 *pValueCellOffset = HCELL_NIL; 00809 00810 /* The key does not have any values */ 00811 if (KeyCell->ValueList.List == HCELL_NIL) 00812 { 00813 return STATUS_OBJECT_NAME_NOT_FOUND; 00814 } 00815 00816 ValueListCell = (PVALUE_LIST_CELL)HvGetCell(&RegistryHive->Hive, KeyCell->ValueList.List); 00817 00818 VERIFY_VALUE_LIST_CELL(ValueListCell); 00819 00820 for (i = 0; i < KeyCell->ValueList.Count; i++) 00821 { 00822 CurValueCell = (PCM_KEY_VALUE)HvGetCell( 00823 &RegistryHive->Hive, 00824 ValueListCell->ValueOffset[i]); 00825 00826 if (CmiComparePackedNames( 00827 ValueName, 00828 (PUCHAR)CurValueCell->Name, 00829 CurValueCell->NameLength, 00830 (BOOLEAN)((CurValueCell->Flags & VALUE_COMP_NAME) ? TRUE : FALSE))) 00831 { 00832 *pValueCell = CurValueCell; 00833 *pValueCellOffset = ValueListCell->ValueOffset[i]; 00834 return STATUS_SUCCESS; 00835 } 00836 } 00837 00838 return STATUS_OBJECT_NAME_NOT_FOUND; 00839 } Generated on Sun May 27 2012 04:37:46 for ReactOS by
1.7.6.1
|