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

exatom.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1992 Microsoft Corporation 00004 00005 Module Name: 00006 00007 exatom.c 00008 00009 Abstract: 00010 00011 This file contains functions for manipulating global atom tables 00012 stored in kernel space. 00013 00014 Author: 00015 00016 Steve Wood (stevewo) 13-Dec-1995 00017 00018 Revision History: 00019 00020 --*/ 00021 00022 #include "exp.h" 00023 #pragma hdrstop 00024 00025 // 00026 // Local Procedure prototype 00027 // 00028 00029 PVOID 00030 ExpGetGlobalAtomTable ( 00031 ); 00032 00033 #if defined(ALLOC_PRAGMA) 00034 #pragma alloc_text(PAGE, NtAddAtom) 00035 #pragma alloc_text(PAGE, NtFindAtom) 00036 #pragma alloc_text(PAGE, NtDeleteAtom) 00037 #pragma alloc_text(PAGE, NtQueryInformationAtom) 00038 #pragma alloc_text(PAGE, ExpGetGlobalAtomTable) 00039 #endif 00040 00041 00042 NTSYSAPI 00043 NTSTATUS 00044 NTAPI 00045 NtAddAtom ( 00046 IN PWSTR AtomName, 00047 IN ULONG Length, 00048 OUT PRTL_ATOM Atom OPTIONAL 00049 ) 00050 00051 /*++ 00052 00053 Routine Description: 00054 00055 Arguments: 00056 00057 Return Value: 00058 00059 --*/ 00060 00061 { 00062 NTSTATUS Status; 00063 RTL_ATOM ReturnAtom; 00064 PVOID AtomTable = ExpGetGlobalAtomTable(); 00065 KPROCESSOR_MODE PreviousMode; 00066 PWSTR CapturedAtomNameBuffer; 00067 ULONG AllocLength; 00068 00069 PAGED_CODE(); 00070 00071 if (AtomTable == NULL) { 00072 00073 return STATUS_ACCESS_DENIED; 00074 } 00075 00076 if (Length > (RTL_ATOM_MAXIMUM_NAME_LENGTH * sizeof(WCHAR))) { 00077 00078 return STATUS_INVALID_PARAMETER; 00079 } 00080 00081 PreviousMode = KeGetPreviousMode(); 00082 CapturedAtomNameBuffer = NULL; 00083 00084 Status = STATUS_SUCCESS; 00085 00086 if (PreviousMode != KernelMode) { 00087 00088 try { 00089 00090 if (ARGUMENT_PRESENT( AtomName )) { 00091 00092 AllocLength = (Length + sizeof( UNICODE_NULL ))&~(sizeof (WCHAR)-1); 00093 ProbeForRead( AtomName, Length, sizeof( WCHAR ) ); 00094 CapturedAtomNameBuffer = ExAllocatePoolWithTag( PagedPool, AllocLength, 'motA' ); 00095 00096 if (CapturedAtomNameBuffer == NULL) { 00097 00098 return STATUS_INSUFFICIENT_RESOURCES; 00099 } 00100 00101 RtlMoveMemory( CapturedAtomNameBuffer, AtomName, Length ); 00102 CapturedAtomNameBuffer[Length / sizeof (WCHAR)] = '\0'; 00103 } 00104 00105 if (ARGUMENT_PRESENT( Atom )) { 00106 00107 ProbeForWriteUshort( Atom ); 00108 } 00109 00110 } except (EXCEPTION_EXECUTE_HANDLER) { 00111 00112 Status = GetExceptionCode(); 00113 } 00114 00115 } else { 00116 00117 if (ARGUMENT_PRESENT( AtomName )) { 00118 00119 CapturedAtomNameBuffer = AtomName; 00120 } 00121 } 00122 00123 if (NT_SUCCESS( Status )) { 00124 00125 Status = RtlAddAtomToAtomTable( AtomTable, CapturedAtomNameBuffer, &ReturnAtom ); 00126 00127 if (NT_SUCCESS( Status ) && ARGUMENT_PRESENT( Atom )) { 00128 00129 try { 00130 00131 *Atom = ReturnAtom; 00132 00133 } except (EXCEPTION_EXECUTE_HANDLER) { 00134 00135 Status = GetExceptionCode(); 00136 } 00137 } 00138 } 00139 00140 if ((CapturedAtomNameBuffer != NULL) && (CapturedAtomNameBuffer != AtomName)) { 00141 00142 ExFreePool( CapturedAtomNameBuffer ); 00143 } 00144 00145 return Status; 00146 } 00147 00148 00149 NTSYSAPI 00150 NTSTATUS 00151 NTAPI 00152 NtFindAtom ( 00153 IN PWSTR AtomName, 00154 IN ULONG Length, 00155 OUT PRTL_ATOM Atom OPTIONAL 00156 ) 00157 00158 /*++ 00159 00160 Routine Description: 00161 00162 Arguments: 00163 00164 Return Value: 00165 00166 --*/ 00167 00168 { 00169 NTSTATUS Status; 00170 RTL_ATOM ReturnAtom; 00171 PVOID AtomTable = ExpGetGlobalAtomTable(); 00172 KPROCESSOR_MODE PreviousMode; 00173 PWSTR CapturedAtomNameBuffer; 00174 ULONG AllocLength; 00175 00176 PAGED_CODE(); 00177 00178 if (AtomTable == NULL) { 00179 00180 return STATUS_ACCESS_DENIED; 00181 } 00182 00183 if (Length > (RTL_ATOM_MAXIMUM_NAME_LENGTH * sizeof(WCHAR))) { 00184 00185 return STATUS_INVALID_PARAMETER; 00186 } 00187 00188 PreviousMode = KeGetPreviousMode(); 00189 CapturedAtomNameBuffer = NULL; 00190 00191 Status = STATUS_SUCCESS; 00192 00193 if (PreviousMode != KernelMode) { 00194 00195 try { 00196 00197 if (ARGUMENT_PRESENT( AtomName )) { 00198 00199 AllocLength = (Length + sizeof( UNICODE_NULL ))&~(sizeof (WCHAR)-1); 00200 ProbeForRead( AtomName, Length, sizeof( WCHAR ) ); 00201 CapturedAtomNameBuffer = ExAllocatePoolWithTag( PagedPool, AllocLength, 'motA' ); 00202 00203 if (CapturedAtomNameBuffer == NULL) { 00204 00205 return STATUS_INSUFFICIENT_RESOURCES; 00206 } 00207 00208 RtlMoveMemory( CapturedAtomNameBuffer, AtomName, Length ); 00209 CapturedAtomNameBuffer[Length / sizeof (WCHAR)] = '\0'; 00210 00211 } 00212 00213 if (ARGUMENT_PRESENT( Atom )) { 00214 00215 ProbeForWriteUshort( Atom ); 00216 } 00217 00218 } except (EXCEPTION_EXECUTE_HANDLER) { 00219 00220 Status = GetExceptionCode(); 00221 } 00222 00223 } else { 00224 00225 if (ARGUMENT_PRESENT( AtomName )) { 00226 00227 CapturedAtomNameBuffer = AtomName; 00228 } 00229 } 00230 00231 if (NT_SUCCESS( Status )) { 00232 00233 Status = RtlLookupAtomInAtomTable( AtomTable, CapturedAtomNameBuffer, &ReturnAtom ); 00234 00235 if (NT_SUCCESS( Status ) && ARGUMENT_PRESENT( Atom )) { 00236 00237 try { 00238 00239 *Atom = ReturnAtom; 00240 00241 } except (EXCEPTION_EXECUTE_HANDLER) { 00242 00243 Status = GetExceptionCode(); 00244 } 00245 } 00246 } 00247 00248 if (CapturedAtomNameBuffer != NULL && CapturedAtomNameBuffer != AtomName) { 00249 00250 ExFreePool( CapturedAtomNameBuffer ); 00251 } 00252 00253 return Status; 00254 } 00255 00256 00257 NTSYSAPI 00258 NTSTATUS 00259 NTAPI 00260 NtDeleteAtom ( 00261 IN RTL_ATOM Atom 00262 ) 00263 00264 /*++ 00265 00266 Routine Description: 00267 00268 Arguments: 00269 00270 Return Value: 00271 00272 --*/ 00273 00274 { 00275 NTSTATUS Status; 00276 PVOID AtomTable = ExpGetGlobalAtomTable(); 00277 00278 PAGED_CODE(); 00279 00280 if (AtomTable == NULL) { 00281 00282 return STATUS_ACCESS_DENIED; 00283 } 00284 00285 Status = RtlDeleteAtomFromAtomTable( AtomTable, Atom ); 00286 00287 return Status; 00288 } 00289 00290 00291 NTSYSAPI 00292 NTSTATUS 00293 NTAPI 00294 NtQueryInformationAtom( 00295 IN RTL_ATOM Atom, 00296 IN ATOM_INFORMATION_CLASS AtomInformationClass, 00297 OUT PVOID AtomInformation, 00298 IN ULONG AtomInformationLength, 00299 OUT PULONG ReturnLength OPTIONAL 00300 ) 00301 00302 /*++ 00303 00304 Routine Description: 00305 00306 Arguments: 00307 00308 Return Value: 00309 00310 --*/ 00311 00312 { 00313 NTSTATUS Status; 00314 KPROCESSOR_MODE PreviousMode; 00315 ULONG RequiredLength; 00316 ULONG UsageCount; 00317 ULONG NameLength; 00318 ULONG AtomFlags; 00319 PATOM_BASIC_INFORMATION BasicInfo; 00320 PATOM_TABLE_INFORMATION TableInfo; 00321 PVOID AtomTable = ExpGetGlobalAtomTable(); 00322 00323 PAGED_CODE(); 00324 00325 if (AtomTable == NULL) { 00326 00327 return STATUS_ACCESS_DENIED; 00328 } 00329 00330 // 00331 // Assume successful completion. 00332 // 00333 00334 Status = STATUS_SUCCESS; 00335 00336 try { 00337 00338 // 00339 // Get previous processor mode and probe output argument if necessary. 00340 // 00341 00342 PreviousMode = KeGetPreviousMode(); 00343 00344 if (PreviousMode != KernelMode) { 00345 00346 ProbeForWrite( AtomInformation, 00347 AtomInformationLength, 00348 sizeof( ULONG )); 00349 00350 if (ARGUMENT_PRESENT( ReturnLength )) { 00351 00352 ProbeForWriteUlong( ReturnLength ); 00353 } 00354 } 00355 00356 RequiredLength = 0; 00357 00358 switch (AtomInformationClass) { 00359 00360 case AtomBasicInformation: 00361 00362 RequiredLength = FIELD_OFFSET( ATOM_BASIC_INFORMATION, Name ); 00363 00364 if (AtomInformationLength < RequiredLength) { 00365 00366 return STATUS_INFO_LENGTH_MISMATCH; 00367 } 00368 00369 BasicInfo = (PATOM_BASIC_INFORMATION)AtomInformation; 00370 UsageCount = 0; 00371 NameLength = AtomInformationLength - RequiredLength; 00372 BasicInfo->Name[ 0 ] = UNICODE_NULL; 00373 00374 Status = RtlQueryAtomInAtomTable( AtomTable, 00375 Atom, 00376 &UsageCount, 00377 &AtomFlags, 00378 &BasicInfo->Name[0], 00379 &NameLength ); 00380 00381 if (NT_SUCCESS(Status)) { 00382 00383 BasicInfo->UsageCount = (USHORT)UsageCount; 00384 BasicInfo->Flags = (USHORT)AtomFlags; 00385 BasicInfo->NameLength = (USHORT)NameLength; 00386 RequiredLength += NameLength + sizeof( UNICODE_NULL ); 00387 } 00388 00389 break; 00390 00391 case AtomTableInformation: 00392 00393 RequiredLength = FIELD_OFFSET( ATOM_TABLE_INFORMATION, Atoms ); 00394 00395 if (AtomInformationLength < RequiredLength) { 00396 00397 return STATUS_INFO_LENGTH_MISMATCH; 00398 } 00399 00400 TableInfo = (PATOM_TABLE_INFORMATION)AtomInformation; 00401 00402 Status = RtlQueryAtomsInAtomTable( AtomTable, 00403 (AtomInformationLength - RequiredLength) / sizeof( RTL_ATOM ), 00404 &TableInfo->NumberOfAtoms, 00405 &TableInfo->Atoms[0] ); 00406 00407 if (NT_SUCCESS(Status)) { 00408 00409 RequiredLength += TableInfo->NumberOfAtoms * sizeof( RTL_ATOM ); 00410 } 00411 00412 break; 00413 00414 default: 00415 00416 Status = STATUS_INVALID_INFO_CLASS; 00417 00418 break; 00419 } 00420 00421 if (ARGUMENT_PRESENT( ReturnLength )) { 00422 00423 *ReturnLength = RequiredLength; 00424 } 00425 00426 } except (EXCEPTION_EXECUTE_HANDLER) { 00427 00428 Status = GetExceptionCode(); 00429 } 00430 00431 return Status; 00432 } 00433 00434 00435 // 00436 // Local support routine 00437 // 00438 00439 PKWIN32_GLOBALATOMTABLE_CALLOUT ExGlobalAtomTableCallout; 00440 00441 PVOID 00442 ExpGetGlobalAtomTable ( 00443 ) 00444 00445 /*++ 00446 00447 Routine Description: 00448 00449 Arguments: 00450 00451 Return Value: 00452 00453 --*/ 00454 00455 { 00456 if (ExGlobalAtomTableCallout != NULL) { 00457 00458 return ((*ExGlobalAtomTableCallout)()); 00459 00460 } else { 00461 00462 #if DBG 00463 DbgPrint( "EX: ExpGetGlobalAtomTable is about to return NULL!\n" ); 00464 DbgBreakPoint(); 00465 #endif 00466 return NULL; 00467 } 00468 }

Generated on Sat May 15 19:39:57 2004 for test by doxygen 1.3.7