Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencmvalue.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/config/cmvalue.c 00005 * PURPOSE: Configuration Manager - Cell Values 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 00011 #include "ntoskrnl.h" 00012 #define NDEBUG 00013 #include "debug.h" 00014 00015 /* FUNCTIONS *****************************************************************/ 00016 00017 BOOLEAN 00018 NTAPI 00019 CmpMarkValueDataDirty(IN PHHIVE Hive, 00020 IN PCM_KEY_VALUE Value) 00021 { 00022 ULONG KeySize; 00023 PAGED_CODE(); 00024 00025 /* Make sure there's actually any data */ 00026 if (Value->Data != HCELL_NIL) 00027 { 00028 /* If this is a small key, there's no need to have it dirty */ 00029 if (CmpIsKeyValueSmall(&KeySize, Value->DataLength)) return TRUE; 00030 00031 /* Check if this is a big key */ 00032 ASSERT_VALUE_BIG(Hive, KeySize); 00033 00034 /* Normal value, just mark it dirty */ 00035 HvMarkCellDirty(Hive, Value->Data, FALSE); 00036 } 00037 00038 /* Operation complete */ 00039 return TRUE; 00040 } 00041 00042 BOOLEAN 00043 NTAPI 00044 CmpFreeValueData(IN PHHIVE Hive, 00045 IN HCELL_INDEX DataCell, 00046 IN ULONG DataLength) 00047 { 00048 ULONG KeySize; 00049 PAGED_CODE(); 00050 00051 /* If this is a small key, the data is built-in */ 00052 if (!CmpIsKeyValueSmall(&KeySize, DataLength)) 00053 { 00054 /* If there's no data cell, there's nothing to do */ 00055 if (DataCell == HCELL_NIL) return TRUE; 00056 00057 /* Make sure the data cell is allocated */ 00058 //ASSERT(HvIsCellAllocated(Hive, DataCell)); 00059 00060 /* Unsupported value type */ 00061 ASSERT_VALUE_BIG(Hive, KeySize); 00062 00063 /* Normal value, just free the data cell */ 00064 HvFreeCell(Hive, DataCell); 00065 } 00066 00067 /* Operation complete */ 00068 return TRUE; 00069 } 00070 00071 BOOLEAN 00072 NTAPI 00073 CmpFreeValue(IN PHHIVE Hive, 00074 IN HCELL_INDEX Cell) 00075 { 00076 PCM_KEY_VALUE Value; 00077 PAGED_CODE(); 00078 00079 /* Get the cell data */ 00080 Value = (PCM_KEY_VALUE)HvGetCell(Hive, Cell); 00081 if (!Value) ASSERT(FALSE); 00082 00083 /* Free it */ 00084 if (!CmpFreeValueData(Hive, Value->Data, Value->DataLength)) 00085 { 00086 /* We failed to free the data, return failure */ 00087 HvReleaseCell(Hive, Cell); 00088 return FALSE; 00089 } 00090 00091 /* Release the cell and free it */ 00092 HvReleaseCell(Hive, Cell); 00093 HvFreeCell(Hive, Cell); 00094 return TRUE; 00095 } 00096 00097 HCELL_INDEX 00098 NTAPI 00099 CmpFindValueByName(IN PHHIVE Hive, 00100 IN PCM_KEY_NODE KeyNode, 00101 IN PUNICODE_STRING Name) 00102 { 00103 HCELL_INDEX CellIndex; 00104 00105 /* Call the main function */ 00106 if (!CmpFindNameInList(Hive, 00107 &KeyNode->ValueList, 00108 Name, 00109 NULL, 00110 &CellIndex)) 00111 { 00112 /* Santy check */ 00113 ASSERT(CellIndex == HCELL_NIL); 00114 } 00115 00116 /* Return the index */ 00117 return CellIndex; 00118 } 00119 00120 BOOLEAN 00121 NTAPI 00122 CmpGetValueData(IN PHHIVE Hive, 00123 IN PCM_KEY_VALUE Value, 00124 IN PULONG Length, 00125 OUT PVOID *Buffer, 00126 OUT PBOOLEAN BufferAllocated, 00127 OUT PHCELL_INDEX CellToRelease) 00128 { 00129 PAGED_CODE(); 00130 00131 /* Sanity check */ 00132 ASSERT(Value->Signature == CM_KEY_VALUE_SIGNATURE); 00133 00134 /* Set failure defaults */ 00135 *BufferAllocated = FALSE; 00136 *Buffer = NULL; 00137 *CellToRelease = HCELL_NIL; 00138 00139 /* Check if this is a small key */ 00140 if (CmpIsKeyValueSmall(Length, Value->DataLength)) 00141 { 00142 /* Return the data immediately */ 00143 *Buffer = &Value->Data; 00144 return TRUE; 00145 } 00146 00147 /* Unsupported */ 00148 ASSERT_VALUE_BIG(Hive, *Length); 00149 00150 /* Get the data from the cell */ 00151 *Buffer = HvGetCell(Hive, Value->Data); 00152 if (!(*Buffer)) return FALSE; 00153 00154 /* Return success and the cell to be released */ 00155 *CellToRelease = Value->Data; 00156 return TRUE; 00157 } 00158 00159 PCELL_DATA 00160 NTAPI 00161 CmpValueToData(IN PHHIVE Hive, 00162 IN PCM_KEY_VALUE Value, 00163 OUT PULONG Length) 00164 { 00165 PCELL_DATA Buffer; 00166 BOOLEAN BufferAllocated; 00167 HCELL_INDEX CellToRelease; 00168 PAGED_CODE(); 00169 00170 /* Sanity check */ 00171 ASSERT(Hive->ReleaseCellRoutine == NULL); 00172 00173 /* Get the actual data */ 00174 if (!CmpGetValueData(Hive, 00175 Value, 00176 Length, 00177 (PVOID)&Buffer, 00178 &BufferAllocated, 00179 &CellToRelease)) 00180 { 00181 /* We failed */ 00182 ASSERT(BufferAllocated == FALSE); 00183 ASSERT(Buffer == NULL); 00184 return NULL; 00185 } 00186 00187 /* This should never happen!*/ 00188 if (BufferAllocated) 00189 { 00190 /* Free the buffer and bugcheck */ 00191 CmpFree(Buffer, 0); 00192 KeBugCheckEx(REGISTRY_ERROR, 8, 0, (ULONG_PTR)Hive, (ULONG_PTR)Value); 00193 } 00194 00195 /* Otherwise, return the cell data */ 00196 return Buffer; 00197 } 00198 00199 NTSTATUS 00200 NTAPI 00201 CmpAddValueToList(IN PHHIVE Hive, 00202 IN HCELL_INDEX ValueCell, 00203 IN ULONG Index, 00204 IN ULONG Type, 00205 IN OUT PCHILD_LIST ChildList) 00206 { 00207 HCELL_INDEX ListCell; 00208 ULONG ChildCount, Length, i; 00209 PCELL_DATA CellData; 00210 PAGED_CODE(); 00211 00212 /* Sanity check */ 00213 ASSERT((((LONG)Index) >= 0) && (Index <= ChildList->Count)); 00214 00215 /* Get the number of entries in the child list */ 00216 ChildCount = ChildList->Count; 00217 ChildCount++; 00218 if (ChildCount > 1) 00219 { 00220 /* The cell should be dirty at this point */ 00221 ASSERT(HvIsCellDirty(Hive, ChildList->List)); 00222 00223 /* Check if we have less then 100 children */ 00224 if (ChildCount < 100) 00225 { 00226 /* Allocate just enough as requested */ 00227 Length = ChildCount * sizeof(HCELL_INDEX); 00228 } 00229 else 00230 { 00231 /* Otherwise, we have quite a few, so allocate a batch */ 00232 Length = ROUND_UP(ChildCount, 100) * sizeof(HCELL_INDEX); 00233 if (Length > HBLOCK_SIZE) 00234 { 00235 /* But make sure we don't allocate beyond our block size */ 00236 Length = ROUND_UP(Length, HBLOCK_SIZE); 00237 } 00238 } 00239 00240 /* Perform the allocation */ 00241 ListCell = HvReallocateCell(Hive, ChildList->List, Length); 00242 } 00243 else 00244 { 00245 /* This is our first child, so allocate a single cell */ 00246 ListCell = HvAllocateCell(Hive, sizeof(HCELL_INDEX), Type, HCELL_NIL); 00247 } 00248 00249 /* Fail if we couldn't get a cell */ 00250 if (ListCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES; 00251 00252 /* Set this cell as the child list's list cell */ 00253 ChildList->List = ListCell; 00254 00255 /* Get the actual key list memory */ 00256 CellData = HvGetCell(Hive, ListCell); 00257 ASSERT(CellData != NULL); 00258 00259 /* Loop all the children */ 00260 for (i = ChildCount - 1; i > Index; i--) 00261 { 00262 /* Move them all down */ 00263 CellData->u.KeyList[i] = CellData->u.KeyList[i - 1]; 00264 } 00265 00266 /* Insert us on top now */ 00267 CellData->u.KeyList[Index] = ValueCell; 00268 ChildList->Count = ChildCount; 00269 00270 /* Release the list cell and make sure the value cell is dirty */ 00271 HvReleaseCell(Hive, ListCell); 00272 ASSERT(HvIsCellDirty(Hive, ValueCell)); 00273 00274 /* We're done here */ 00275 return STATUS_SUCCESS; 00276 } 00277 00278 NTSTATUS 00279 NTAPI 00280 CmpSetValueDataNew(IN PHHIVE Hive, 00281 IN PVOID Data, 00282 IN ULONG DataSize, 00283 IN ULONG StorageType, 00284 IN HCELL_INDEX ValueCell, 00285 OUT PHCELL_INDEX DataCell) 00286 { 00287 PCELL_DATA CellData; 00288 PAGED_CODE(); 00289 ASSERT(DataSize > CM_KEY_VALUE_SMALL); 00290 00291 /* Check if this is a big key */ 00292 ASSERT_VALUE_BIG(Hive, DataSize); 00293 00294 /* Allocate a data cell */ 00295 *DataCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL); 00296 if (*DataCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES; 00297 00298 /* Get the actual data */ 00299 CellData = HvGetCell(Hive, *DataCell); 00300 if (!CellData) ASSERT(FALSE); 00301 00302 /* Copy our buffer into it */ 00303 RtlCopyMemory(CellData, Data, DataSize); 00304 00305 /* All done */ 00306 return STATUS_SUCCESS; 00307 } 00308 00309 NTSTATUS 00310 NTAPI 00311 CmpRemoveValueFromList(IN PHHIVE Hive, 00312 IN ULONG Index, 00313 IN OUT PCHILD_LIST ChildList) 00314 { 00315 ULONG Count; 00316 PCELL_DATA CellData; 00317 HCELL_INDEX NewCell; 00318 PAGED_CODE(); 00319 00320 /* Sanity check */ 00321 ASSERT((((LONG)Index) >= 0) && (Index <= ChildList->Count)); 00322 00323 /* Get the new count after removal */ 00324 Count = ChildList->Count - 1; 00325 if (Count > 0) 00326 { 00327 /* Get the actual list array */ 00328 CellData = HvGetCell(Hive, ChildList->List); 00329 if (!CellData) return STATUS_INSUFFICIENT_RESOURCES; 00330 00331 /* Make sure cells data have been made dirty */ 00332 ASSERT(HvIsCellDirty(Hive, ChildList->List)); 00333 ASSERT(HvIsCellDirty(Hive, CellData->u.KeyList[Index])); 00334 00335 /* Loop the list */ 00336 while (Index < Count) 00337 { 00338 /* Move everything up */ 00339 CellData->u.KeyList[Index] = CellData->u.KeyList[Index + 1]; 00340 Index++; 00341 } 00342 00343 /* Re-allocate the cell for the list by decreasing the count */ 00344 NewCell = HvReallocateCell(Hive, 00345 ChildList->List, 00346 Count * sizeof(HCELL_INDEX)); 00347 ASSERT(NewCell != HCELL_NIL); 00348 HvReleaseCell(Hive,ChildList->List); 00349 00350 /* Update the list cell */ 00351 ChildList->List = NewCell; 00352 } 00353 else 00354 { 00355 /* Otherwise, we were the last entry, so free the list entirely */ 00356 HvFreeCell(Hive, ChildList->List); 00357 ChildList->List = HCELL_NIL; 00358 } 00359 00360 /* Update the child list with the new count */ 00361 ChildList->Count = Count; 00362 return STATUS_SUCCESS; 00363 } Generated on Sat May 26 2012 04:35:59 for ReactOS by
1.7.6.1
|