Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendictlib.c
Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (C) Microsoft Corporation, 1990 - 1999 00004 00005 Module Name: 00006 00007 dictlib.c 00008 00009 Abstract: 00010 00011 Support library for maintaining a dictionary list (list of objects 00012 referenced by a key value). 00013 00014 Environment: 00015 00016 kernel mode only 00017 00018 Notes: 00019 00020 This module generates a static library 00021 00022 Revision History: 00023 00024 --*/ 00025 00026 #include "classp.h" 00027 00028 #define DICTIONARY_SIGNATURE 'dsig' 00029 00030 typedef struct _DICTIONARY_HEADER { 00031 struct _DICTIONARY_HEADER* Next; 00032 ULONGLONG Key; 00033 UCHAR Data[0]; 00034 } DICTIONARY_HEADER, *PDICTIONARY_HEADER; 00035 00036 00037 VOID 00038 InitializeDictionary( 00039 IN PDICTIONARY Dictionary 00040 ) 00041 { 00042 RtlZeroMemory(Dictionary, sizeof(DICTIONARY)); 00043 Dictionary->Signature = DICTIONARY_SIGNATURE; 00044 KeInitializeSpinLock(&Dictionary->SpinLock); 00045 return; 00046 } 00047 00048 00049 BOOLEAN 00050 TestDictionarySignature( 00051 IN PDICTIONARY Dictionary 00052 ) 00053 { 00054 return Dictionary->Signature == DICTIONARY_SIGNATURE; 00055 } 00056 00057 NTSTATUS 00058 AllocateDictionaryEntry( 00059 IN PDICTIONARY Dictionary, 00060 IN ULONGLONG Key, 00061 IN ULONG Size, 00062 IN ULONG Tag, 00063 OUT PVOID *Entry 00064 ) 00065 { 00066 PDICTIONARY_HEADER header; 00067 KIRQL oldIrql; 00068 PDICTIONARY_HEADER *entry; 00069 00070 NTSTATUS status = STATUS_SUCCESS; 00071 00072 *Entry = NULL; 00073 00074 header = ExAllocatePoolWithTag(NonPagedPool, 00075 Size + sizeof(DICTIONARY_HEADER), 00076 Tag); 00077 00078 if(header == NULL) { 00079 return STATUS_INSUFFICIENT_RESOURCES; 00080 } 00081 00082 RtlZeroMemory(header, sizeof(DICTIONARY_HEADER) + Size); 00083 header->Key = Key; 00084 00085 // 00086 // Find the correct location for this entry in the dictionary. 00087 // 00088 00089 KeAcquireSpinLock(&(Dictionary->SpinLock), &oldIrql); 00090 00091 TRY { 00092 00093 entry = &(Dictionary->List); 00094 00095 while(*entry != NULL) { 00096 if((*entry)->Key == Key) { 00097 00098 // 00099 // Dictionary must have unique keys. 00100 // 00101 00102 status = STATUS_OBJECT_NAME_COLLISION; 00103 LEAVE; 00104 00105 } else if ((*entry)->Key < Key) { 00106 00107 // 00108 // We will go ahead and insert the key in here. 00109 // 00110 break; 00111 } else { 00112 entry = &((*entry)->Next); 00113 } 00114 } 00115 00116 // 00117 // If we make it here then we will go ahead and do the insertion. 00118 // 00119 00120 header->Next = *entry; 00121 *entry = header; 00122 00123 } FINALLY { 00124 KeReleaseSpinLock(&(Dictionary->SpinLock), oldIrql); 00125 00126 if(!NT_SUCCESS(status)) { 00127 ExFreePool(header); 00128 } else { 00129 *Entry = (PVOID) header->Data; 00130 } 00131 } 00132 return status; 00133 } 00134 00135 00136 PVOID 00137 GetDictionaryEntry( 00138 IN PDICTIONARY Dictionary, 00139 IN ULONGLONG Key 00140 ) 00141 { 00142 PDICTIONARY_HEADER entry; 00143 PVOID data; 00144 KIRQL oldIrql; 00145 00146 00147 data = NULL; 00148 00149 KeAcquireSpinLock(&(Dictionary->SpinLock), &oldIrql); 00150 00151 entry = Dictionary->List; 00152 while (entry != NULL) { 00153 00154 if (entry->Key == Key) { 00155 data = entry->Data; 00156 break; 00157 } else { 00158 entry = entry->Next; 00159 } 00160 } 00161 00162 KeReleaseSpinLock(&(Dictionary->SpinLock), oldIrql); 00163 00164 return data; 00165 } 00166 00167 00168 VOID 00169 FreeDictionaryEntry( 00170 IN PDICTIONARY Dictionary, 00171 IN PVOID Entry 00172 ) 00173 { 00174 PDICTIONARY_HEADER header; 00175 PDICTIONARY_HEADER *entry; 00176 KIRQL oldIrql; 00177 BOOLEAN found; 00178 00179 found = FALSE; 00180 header = CONTAINING_RECORD(Entry, DICTIONARY_HEADER, Data); 00181 00182 KeAcquireSpinLock(&(Dictionary->SpinLock), &oldIrql); 00183 00184 entry = &(Dictionary->List); 00185 while(*entry != NULL) { 00186 00187 if(*entry == header) { 00188 *entry = header->Next; 00189 found = TRUE; 00190 break; 00191 } else { 00192 entry = &(*entry)->Next; 00193 } 00194 } 00195 00196 KeReleaseSpinLock(&(Dictionary->SpinLock), oldIrql); 00197 00198 // 00199 // calling this w/an invalid pointer invalidates the dictionary system, 00200 // so ASSERT() that we never try to Free something not in the list 00201 // 00202 00203 ASSERT(found); 00204 if (found) { 00205 ExFreePool(header); 00206 } 00207 00208 return; 00209 00210 } 00211 00212 Generated on Fri May 25 2012 04:26:37 for ReactOS by
1.7.6.1
|