ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

cmvalue.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.