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

atom.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1990 Microsoft Corporation 00004 00005 Module Name: 00006 00007 atom.c 00008 00009 Abstract: 00010 00011 This file contains the common code to implement atom tables. It is called 00012 by both the user mode Win32 Atom API functions (Local/GlobalxxxAtom) and 00013 by the kernel mode window manager code to access global atoms. 00014 00015 Author: 00016 00017 Steve Wood (stevewo) 26-Oct-1990 00018 00019 Revision History: 00020 00021 --*/ 00022 00023 #include "ntrtlp.h" 00024 #include "atom.h" 00025 00026 ULONG RtlpAtomAllocateTag; 00027 00028 PVOID 00029 RtlpAllocateAtom( 00030 IN ULONG NumberOfBytes 00031 ) 00032 { 00033 #if defined(NTOS_KERNEL_RUNTIME) 00034 return ExAllocatePoolWithTag( NonPagedPool, NumberOfBytes, RtlpAtomAllocateTag ); 00035 #else 00036 return RtlAllocateHeap( RtlProcessHeap(), RtlpAtomAllocateTag, NumberOfBytes ); 00037 #endif 00038 } 00039 00040 00041 void 00042 RtlpFreeAtom( 00043 IN PVOID p 00044 ) 00045 { 00046 #if defined(NTOS_KERNEL_RUNTIME) 00047 ExFreePool( p ); 00048 #else 00049 RtlFreeHeap( RtlProcessHeap(), 0, p ); 00050 #endif 00051 return; 00052 } 00053 00054 00055 void 00056 RtlpInitializeLockAtomTable( 00057 IN OUT PRTL_ATOM_TABLE AtomTable 00058 ) 00059 { 00060 #if defined(NTOS_KERNEL_RUNTIME) 00061 ExInitializeFastMutex( &AtomTable->FastMutex ); 00062 #else 00063 RtlInitializeCriticalSection( &AtomTable->CriticalSection ); 00064 #endif 00065 return; 00066 } 00067 00068 BOOLEAN 00069 RtlpLockAtomTable( 00070 IN PRTL_ATOM_TABLE AtomTable 00071 ) 00072 { 00073 if (AtomTable == NULL || AtomTable->Signature != RTL_ATOM_TABLE_SIGNATURE) { 00074 return FALSE; 00075 } 00076 00077 #if defined(NTOS_KERNEL_RUNTIME) 00078 ExAcquireFastMutex( &AtomTable->FastMutex ); 00079 #else 00080 RtlEnterCriticalSection( &AtomTable->CriticalSection ); 00081 #endif 00082 00083 return TRUE; 00084 } 00085 00086 void 00087 RtlpUnlockAtomTable( 00088 IN PRTL_ATOM_TABLE AtomTable 00089 ) 00090 { 00091 #if defined(NTOS_KERNEL_RUNTIME) 00092 ExReleaseFastMutex( &AtomTable->FastMutex ); 00093 #else 00094 RtlLeaveCriticalSection( &AtomTable->CriticalSection ); 00095 #endif 00096 } 00097 00098 00099 void 00100 RtlpDestroyLockAtomTable( 00101 IN OUT PRTL_ATOM_TABLE AtomTable 00102 ) 00103 { 00104 #if defined(NTOS_KERNEL_RUNTIME) 00105 #else 00106 RtlDeleteCriticalSection( &AtomTable->CriticalSection ); 00107 #endif 00108 } 00109 00110 00111 BOOLEAN 00112 RtlpInitializeHandleTableForAtomTable( 00113 PRTL_ATOM_TABLE AtomTable 00114 ) 00115 { 00116 #if defined(NTOS_KERNEL_RUNTIME) 00117 AtomTable->ExHandleTable = ExCreateHandleTable( NULL ); 00118 if (AtomTable->ExHandleTable != NULL) { 00119 // 00120 // Make sure atom handle tables are NOT part of object handle enumeration 00121 // 00122 00123 ExRemoveHandleTable( AtomTable->ExHandleTable ); 00124 return TRUE; 00125 } 00126 else { 00127 return FALSE; 00128 } 00129 #else 00130 RtlInitializeHandleTable( (ULONG)(USHORT)~RTL_ATOM_MAXIMUM_INTEGER_ATOM, 00131 sizeof( RTL_ATOM_HANDLE_TABLE_ENTRY ), 00132 &AtomTable->RtlHandleTable 00133 ); 00134 return TRUE; 00135 #endif 00136 } 00137 00138 void 00139 RtlpDestroyHandleTableForAtomTable( 00140 PRTL_ATOM_TABLE AtomTable 00141 ) 00142 { 00143 #if defined(NTOS_KERNEL_RUNTIME) 00144 ExDestroyHandleTable( AtomTable->ExHandleTable, NULL ); 00145 #else 00146 RtlDestroyHandleTable( &AtomTable->RtlHandleTable ); 00147 #endif 00148 return; 00149 } 00150 00151 PRTL_ATOM_TABLE_ENTRY 00152 RtlpAtomMapAtomToHandleEntry( 00153 IN PRTL_ATOM_TABLE AtomTable, 00154 IN ULONG HandleIndex 00155 ) 00156 { 00157 #if defined(NTOS_KERNEL_RUNTIME) 00158 PHANDLE_TABLE_ENTRY ExHandleEntry; 00159 PRTL_ATOM_TABLE_ENTRY a; 00160 EXHANDLE ExHandle; 00161 00162 ExHandle.Index = HandleIndex; 00163 00164 ExHandleEntry = ExMapHandleToPointer( AtomTable->ExHandleTable, 00165 ExHandle.GenericHandleOverlay 00166 ); 00167 if (ExHandleEntry != NULL) { 00168 a = ExHandleEntry->Object; 00169 ExUnlockHandleTableEntry( AtomTable->ExHandleTable, ExHandleEntry ); 00170 return a; 00171 } 00172 #else 00173 PRTL_ATOM_HANDLE_TABLE_ENTRY HandleEntry; 00174 00175 if (RtlIsValidIndexHandle( &AtomTable->RtlHandleTable, 00176 HandleIndex, 00177 (PRTL_HANDLE_TABLE_ENTRY *)&HandleEntry 00178 ) 00179 ) { 00180 return HandleEntry->Atom; 00181 } 00182 #endif 00183 return NULL; 00184 } 00185 00186 BOOLEAN 00187 RtlpCreateHandleForAtom( 00188 PRTL_ATOM_TABLE p, 00189 PRTL_ATOM_TABLE_ENTRY a 00190 ) 00191 { 00192 #if defined(NTOS_KERNEL_RUNTIME) 00193 EXHANDLE ExHandle; 00194 HANDLE_TABLE_ENTRY ExHandleEntry; 00195 00196 ExHandleEntry.Object = a; 00197 ExHandleEntry.GrantedAccess = 0; 00198 ExHandle.GenericHandleOverlay = ExCreateHandle( p->ExHandleTable, &ExHandleEntry ); 00199 if (ExHandle.GenericHandleOverlay != NULL) { 00200 a->HandleIndex = (USHORT)ExHandle.Index; 00201 a->Atom = (RTL_ATOM)((USHORT)a->HandleIndex | RTL_ATOM_MAXIMUM_INTEGER_ATOM); 00202 return TRUE; 00203 } 00204 #else 00205 PRTL_ATOM_HANDLE_TABLE_ENTRY HandleEntry; 00206 ULONG HandleIndex; 00207 00208 HandleEntry = (PRTL_ATOM_HANDLE_TABLE_ENTRY)RtlAllocateHandle( &p->RtlHandleTable, 00209 &HandleIndex 00210 ); 00211 if (HandleEntry != NULL) { 00212 if (HandleIndex < RTL_ATOM_MAXIMUM_INTEGER_ATOM) { 00213 a->HandleIndex = (USHORT)HandleIndex; 00214 a->Atom = (RTL_ATOM)((USHORT)HandleIndex | RTL_ATOM_MAXIMUM_INTEGER_ATOM); 00215 HandleEntry->Atom = a; 00216 HandleEntry->LockCount = 0; 00217 HandleEntry->Flags = RTL_HANDLE_ALLOCATED; 00218 return TRUE; 00219 } 00220 00221 RtlFreeHandle( &p->RtlHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry ); 00222 } 00223 #endif 00224 return FALSE; 00225 } 00226 00227 void 00228 RtlpFreeHandleForAtom( 00229 PRTL_ATOM_TABLE p, 00230 PRTL_ATOM_TABLE_ENTRY a 00231 ) 00232 { 00233 #if defined(NTOS_KERNEL_RUNTIME) 00234 EXHANDLE ExHandle; 00235 00236 ExHandle.Index = a->HandleIndex; 00237 ExDestroyHandle( p->ExHandleTable, ExHandle.GenericHandleOverlay, NULL ); 00238 #else 00239 PRTL_ATOM_HANDLE_TABLE_ENTRY HandleEntry; 00240 00241 if (RtlIsValidIndexHandle( &p->RtlHandleTable, 00242 a->HandleIndex, 00243 (PRTL_HANDLE_TABLE_ENTRY *)&HandleEntry 00244 ) 00245 ) { 00246 RtlFreeHandle( &p->RtlHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry ); 00247 } 00248 #endif 00249 return; 00250 } 00251 00252 NTSTATUS 00253 RtlInitializeAtomPackage( 00254 IN ULONG AllocationTag 00255 ) 00256 { 00257 RtlpAtomAllocateTag = AllocationTag; 00258 return STATUS_SUCCESS; 00259 } 00260 00261 NTSTATUS 00262 RtlCreateAtomTable( 00263 IN ULONG NumberOfBuckets, 00264 OUT PVOID *AtomTableHandle 00265 ) 00266 { 00267 NTSTATUS Status; 00268 PRTL_ATOM_TABLE p; 00269 ULONG Size; 00270 00271 Status = STATUS_SUCCESS; 00272 if (*AtomTableHandle == NULL) { 00273 if (NumberOfBuckets <= 1) { 00274 NumberOfBuckets = RTL_ATOM_TABLE_DEFAULT_NUMBER_OF_BUCKETS; 00275 } 00276 00277 Size = sizeof( RTL_ATOM_TABLE ) + 00278 (sizeof( RTL_ATOM_TABLE_ENTRY ) * (NumberOfBuckets-1)); 00279 00280 p = (PRTL_ATOM_TABLE)RtlpAllocateAtom( Size ); 00281 if (p == NULL) { 00282 Status = STATUS_NO_MEMORY; 00283 } 00284 else { 00285 RtlZeroMemory( p, Size ); 00286 p->NumberOfBuckets = NumberOfBuckets; 00287 if (RtlpInitializeHandleTableForAtomTable( p )) { 00288 RtlpInitializeLockAtomTable( p ); 00289 p->Signature = RTL_ATOM_TABLE_SIGNATURE; 00290 *AtomTableHandle = p; 00291 } 00292 else { 00293 Status = STATUS_NO_MEMORY; 00294 RtlpFreeAtom( p ); 00295 } 00296 } 00297 } 00298 00299 return Status; 00300 } 00301 00302 00303 NTSTATUS 00304 RtlDestroyAtomTable( 00305 IN PVOID AtomTableHandle 00306 ) 00307 { 00308 NTSTATUS Status; 00309 PRTL_ATOM_TABLE p = (PRTL_ATOM_TABLE)AtomTableHandle; 00310 PRTL_ATOM_TABLE_ENTRY a, aNext, *pa; 00311 ULONG i; 00312 00313 Status = STATUS_SUCCESS; 00314 if (!RtlpLockAtomTable( p )) { 00315 return STATUS_INVALID_PARAMETER; 00316 } 00317 try { 00318 pa = &p->Buckets[ 0 ]; 00319 for (i=0; i<p->NumberOfBuckets; i++) { 00320 aNext = *pa; 00321 *pa++ = NULL; 00322 while ((a = aNext) != NULL) { 00323 aNext = a->HashLink; 00324 a->HashLink = NULL; 00325 RtlpFreeAtom( a ); 00326 } 00327 } 00328 p->Signature = 0; 00329 RtlpUnlockAtomTable( p ); 00330 00331 RtlpDestroyHandleTableForAtomTable( p ); 00332 RtlpDestroyLockAtomTable( p ); 00333 RtlZeroMemory( p, sizeof( RTL_ATOM_TABLE ) ); 00334 RtlpFreeAtom( p ); 00335 } 00336 except (EXCEPTION_EXECUTE_HANDLER) { 00337 Status = GetExceptionCode(); 00338 } 00339 00340 return Status; 00341 } 00342 00343 NTSTATUS 00344 RtlEmptyAtomTable( 00345 IN PVOID AtomTableHandle, 00346 IN BOOLEAN IncludePinnedAtoms 00347 ) 00348 { 00349 NTSTATUS Status; 00350 PRTL_ATOM_TABLE p = (PRTL_ATOM_TABLE)AtomTableHandle; 00351 PRTL_ATOM_TABLE_ENTRY a, aNext, *pa, *pa1; 00352 ULONG i; 00353 00354 Status = STATUS_SUCCESS; 00355 if (!RtlpLockAtomTable( p )) { 00356 return STATUS_INVALID_PARAMETER; 00357 } 00358 try { 00359 pa = &p->Buckets[ 0 ]; 00360 for (i=0; i<p->NumberOfBuckets; i++) { 00361 pa1 = pa++; 00362 while ((a = *pa1) != NULL) { 00363 if (IncludePinnedAtoms || !(a->Flags & RTL_ATOM_PINNED)) { 00364 *pa1 = a->HashLink; 00365 a->HashLink = NULL; 00366 RtlpFreeHandleForAtom( p, a ); 00367 RtlpFreeAtom( a ); 00368 } 00369 else { 00370 pa1 = &a->HashLink; 00371 } 00372 } 00373 } 00374 00375 RtlpUnlockAtomTable( p ); 00376 } 00377 except (EXCEPTION_EXECUTE_HANDLER) { 00378 Status = GetExceptionCode(); 00379 } 00380 00381 return Status; 00382 } 00383 00384 BOOLEAN 00385 RtlpGetIntegerAtom( 00386 PWSTR Name, 00387 PRTL_ATOM Atom OPTIONAL 00388 ) 00389 { 00390 NTSTATUS Status; 00391 UNICODE_STRING UnicodeString; 00392 PWSTR s; 00393 ULONG n; 00394 RTL_ATOM Temp; 00395 00396 if (((ULONG_PTR)Name & -0x10000) == 0) { 00397 Temp = (RTL_ATOM)(USHORT)PtrToUlong(Name); 00398 if (Temp >= RTL_ATOM_MAXIMUM_INTEGER_ATOM) { 00399 return FALSE; 00400 } 00401 else { 00402 if (Temp == RTL_ATOM_INVALID_ATOM) { 00403 Temp = RTL_ATOM_MAXIMUM_INTEGER_ATOM; 00404 } 00405 00406 if (ARGUMENT_PRESENT( Atom )) { 00407 *Atom = Temp; 00408 } 00409 00410 return TRUE; 00411 } 00412 } 00413 else 00414 if (*Name != L'#') { 00415 return FALSE; 00416 } 00417 00418 s = ++Name; 00419 while (*s != UNICODE_NULL) { 00420 if (*s < L'0' || *s > L'9') { 00421 return FALSE; 00422 } 00423 else { 00424 s++; 00425 } 00426 } 00427 00428 n = 0; 00429 UnicodeString.Buffer = Name; 00430 UnicodeString.Length = (USHORT)((PCHAR)s - (PCHAR)Name); 00431 UnicodeString.MaximumLength = UnicodeString.Length; 00432 Status = RtlUnicodeStringToInteger( &UnicodeString, 10, &n ); 00433 if (NT_SUCCESS( Status )) { 00434 if (ARGUMENT_PRESENT( Atom )) { 00435 if (n == 0 || n > RTL_ATOM_MAXIMUM_INTEGER_ATOM) { 00436 *Atom = RTL_ATOM_MAXIMUM_INTEGER_ATOM; 00437 } 00438 else { 00439 *Atom = (RTL_ATOM)n; 00440 } 00441 } 00442 00443 return TRUE; 00444 } 00445 else { 00446 return FALSE; 00447 } 00448 } 00449 00450 PRTL_ATOM_TABLE_ENTRY 00451 RtlpHashStringToAtom( 00452 IN PRTL_ATOM_TABLE p, 00453 IN PWSTR Name, 00454 OUT PRTL_ATOM_TABLE_ENTRY **PreviousAtom OPTIONAL, 00455 OUT PULONG NameLength 00456 ) 00457 { 00458 ULONG Length, Hash; 00459 WCHAR c; 00460 PWCH s; 00461 RTL_ATOM Atom; 00462 PRTL_ATOM_TABLE_ENTRY *pa, a; 00463 00464 if (((ULONG_PTR)Name & -0x10000) == 0) { 00465 Atom = (RTL_ATOM)(USHORT)PtrToUlong(Name); 00466 a = NULL; 00467 if (Atom >= RTL_ATOM_MAXIMUM_INTEGER_ATOM) { 00468 a = RtlpAtomMapAtomToHandleEntry( p, 00469 (ULONG)(Atom & (USHORT)~RTL_ATOM_MAXIMUM_INTEGER_ATOM) 00470 ); 00471 } 00472 00473 if (ARGUMENT_PRESENT( PreviousAtom )) { 00474 *PreviousAtom = NULL; 00475 } 00476 00477 return a; 00478 } 00479 00480 s = Name; 00481 Hash = 0; 00482 while (*s != UNICODE_NULL) { 00483 c = RtlUpcaseUnicodeChar( *s++ ); 00484 Hash = Hash + (c << 1) + (c >> 1) + c; 00485 } 00486 Length = (ULONG) (s - Name); 00487 if (Length > RTL_ATOM_MAXIMUM_NAME_LENGTH) { 00488 pa = NULL; 00489 a = NULL; 00490 } 00491 else { 00492 pa = &p->Buckets[ Hash % p->NumberOfBuckets ]; 00493 while (a = *pa) { 00494 if (a->NameLength == Length && !_wcsicmp( a->Name, Name )) { 00495 break; 00496 } 00497 else { 00498 pa = &a->HashLink; 00499 } 00500 } 00501 } 00502 00503 if (ARGUMENT_PRESENT( PreviousAtom )) { 00504 *PreviousAtom = pa; 00505 } 00506 00507 if (a == NULL && ARGUMENT_PRESENT( NameLength )) { 00508 *NameLength = Length * sizeof( WCHAR ); 00509 } 00510 00511 return a; 00512 } 00513 00514 00515 NTSTATUS 00516 RtlAddAtomToAtomTable( 00517 IN PVOID AtomTableHandle, 00518 IN PWSTR AtomName OPTIONAL, 00519 IN OUT PRTL_ATOM Atom OPTIONAL 00520 ) 00521 { 00522 NTSTATUS Status; 00523 PRTL_ATOM_TABLE p = (PRTL_ATOM_TABLE)AtomTableHandle; 00524 PRTL_ATOM_TABLE_ENTRY a, *pa; 00525 ULONG NameLength; 00526 RTL_ATOM Temp; 00527 00528 if (!RtlpLockAtomTable( p )) { 00529 return STATUS_INVALID_PARAMETER; 00530 } 00531 try { 00532 if (RtlpGetIntegerAtom( AtomName, &Temp )) { 00533 if (Temp >= RTL_ATOM_MAXIMUM_INTEGER_ATOM) { 00534 Temp = RTL_ATOM_INVALID_ATOM; 00535 Status = STATUS_INVALID_PARAMETER; 00536 } 00537 else { 00538 Status = STATUS_SUCCESS; 00539 } 00540 00541 if (ARGUMENT_PRESENT( Atom )) { 00542 *Atom = Temp; 00543 } 00544 } 00545 else 00546 if (*AtomName == UNICODE_NULL) { 00547 Status = STATUS_OBJECT_NAME_INVALID; 00548 } 00549 else { 00550 a = RtlpHashStringToAtom( p, AtomName, &pa, &NameLength ); 00551 if (a == NULL) { 00552 if (pa != NULL) { 00553 Status = STATUS_NO_MEMORY; 00554 a = RtlpAllocateAtom( FIELD_OFFSET( RTL_ATOM_TABLE_ENTRY, Name ) + 00555 NameLength + sizeof( UNICODE_NULL ) 00556 ); 00557 if (a != NULL) { 00558 a->HashLink = NULL; 00559 a->ReferenceCount = 1; 00560 a->Flags = 0; 00561 RtlMoveMemory( a->Name, AtomName, NameLength ); 00562 a->NameLength = (UCHAR)(NameLength / sizeof( WCHAR )); 00563 a->Name[ a->NameLength ] = UNICODE_NULL; 00564 if (RtlpCreateHandleForAtom( p, a )) { 00565 a->Atom = (RTL_ATOM)a->HandleIndex | RTL_ATOM_MAXIMUM_INTEGER_ATOM; 00566 *pa = a; 00567 if (ARGUMENT_PRESENT( Atom )) { 00568 *Atom = a->Atom; 00569 } 00570 00571 Status = STATUS_SUCCESS; 00572 } 00573 else { 00574 RtlpFreeAtom( a ); 00575 } 00576 } 00577 } 00578 else { 00579 Status = STATUS_INVALID_PARAMETER; 00580 } 00581 } 00582 else { 00583 if (!(a->Flags & RTL_ATOM_PINNED)) { 00584 if (a->ReferenceCount == 0xFFFF) { 00585 KdPrint(( "RTL: Pinning atom (%x) as reference count about to wrap\n", Atom )); 00586 a->Flags |= RTL_ATOM_PINNED; 00587 } 00588 else { 00589 a->ReferenceCount += 1; 00590 } 00591 } 00592 00593 if (ARGUMENT_PRESENT( Atom )) { 00594 *Atom = a->Atom; 00595 } 00596 00597 Status = STATUS_SUCCESS; 00598 } 00599 } 00600 } 00601 except (EXCEPTION_EXECUTE_HANDLER) { 00602 Status = GetExceptionCode(); 00603 } 00604 00605 RtlpUnlockAtomTable( p ); 00606 00607 return Status; 00608 } 00609 00610 NTSTATUS 00611 RtlLookupAtomInAtomTable( 00612 IN PVOID AtomTableHandle, 00613 IN PWSTR AtomName, 00614 OUT PRTL_ATOM Atom OPTIONAL 00615 ) 00616 { 00617 NTSTATUS Status; 00618 PRTL_ATOM_TABLE p = (PRTL_ATOM_TABLE)AtomTableHandle; 00619 PRTL_ATOM_TABLE_ENTRY a; 00620 RTL_ATOM Temp; 00621 00622 if (!RtlpLockAtomTable( p )) { 00623 return STATUS_INVALID_PARAMETER; 00624 } 00625 try { 00626 if (RtlpGetIntegerAtom( AtomName, &Temp )) { 00627 if (Temp >= RTL_ATOM_MAXIMUM_INTEGER_ATOM) { 00628 Temp = RTL_ATOM_INVALID_ATOM; 00629 Status = STATUS_INVALID_PARAMETER; 00630 } 00631 else { 00632 Status = STATUS_SUCCESS; 00633 } 00634 00635 if (ARGUMENT_PRESENT( Atom )) { 00636 *Atom = Temp; 00637 } 00638 } 00639 else 00640 if (*AtomName == UNICODE_NULL) { 00641 Status = STATUS_OBJECT_NAME_INVALID; 00642 } 00643 else { 00644 a = RtlpHashStringToAtom( p, AtomName, NULL, NULL ); 00645 if (a == NULL) { 00646 Status = STATUS_OBJECT_NAME_NOT_FOUND; 00647 } 00648 else { 00649 if (RtlpAtomMapAtomToHandleEntry( p, (ULONG)a->HandleIndex ) != NULL) { 00650 Status = STATUS_SUCCESS; 00651 if (ARGUMENT_PRESENT( Atom )) { 00652 *Atom = a->Atom; 00653 } 00654 } 00655 else { 00656 Status = STATUS_INVALID_HANDLE; 00657 } 00658 } 00659 } 00660 } 00661 except (EXCEPTION_EXECUTE_HANDLER) { 00662 Status = GetExceptionCode(); 00663 } 00664 00665 RtlpUnlockAtomTable( p ); 00666 00667 return Status; 00668 } 00669 00670 00671 NTSTATUS 00672 RtlDeleteAtomFromAtomTable( 00673 IN PVOID AtomTableHandle, 00674 IN RTL_ATOM Atom 00675 ) 00676 { 00677 NTSTATUS Status; 00678 PRTL_ATOM_TABLE p = (PRTL_ATOM_TABLE)AtomTableHandle; 00679 PRTL_ATOM_TABLE_ENTRY a, *pa; 00680 00681 if (!RtlpLockAtomTable( p )) { 00682 return STATUS_INVALID_PARAMETER; 00683 } 00684 try { 00685 Status = STATUS_INVALID_HANDLE; 00686 if (Atom >= RTL_ATOM_MAXIMUM_INTEGER_ATOM) { 00687 a = RtlpAtomMapAtomToHandleEntry( p, 00688 (ULONG)(Atom & (USHORT)~RTL_ATOM_MAXIMUM_INTEGER_ATOM) 00689 ); 00690 if (a != NULL && a->Atom == Atom) { 00691 Status = STATUS_SUCCESS; 00692 if (a->Flags & RTL_ATOM_PINNED) { 00693 KdPrint(( "RTL: Ignoring attempt to delete a pinned atom (%x)\n", Atom )); 00694 Status = STATUS_WAS_LOCKED; // This is a success status code! 00695 } 00696 else 00697 if (--a->ReferenceCount == 0) { 00698 a = RtlpHashStringToAtom( p, a->Name, &pa, NULL ); 00699 if (a != NULL) { 00700 *pa = a->HashLink; 00701 RtlpFreeHandleForAtom( p, a ); 00702 RtlpFreeAtom( a ); 00703 } 00704 } 00705 } 00706 } 00707 else 00708 if (Atom != RTL_ATOM_INVALID_ATOM) { 00709 Status = STATUS_SUCCESS; 00710 } 00711 } 00712 except (EXCEPTION_EXECUTE_HANDLER) { 00713 Status = GetExceptionCode(); 00714 } 00715 00716 RtlpUnlockAtomTable( p ); 00717 00718 return Status; 00719 } 00720 00721 NTSTATUS 00722 RtlPinAtomInAtomTable( 00723 IN PVOID AtomTableHandle, 00724 IN RTL_ATOM Atom 00725 ) 00726 { 00727 NTSTATUS Status; 00728 PRTL_ATOM_TABLE p = (PRTL_ATOM_TABLE)AtomTableHandle; 00729 PRTL_ATOM_TABLE_ENTRY a, *pa; 00730 00731 if (!RtlpLockAtomTable( p )) { 00732 return STATUS_INVALID_PARAMETER; 00733 } 00734 try { 00735 Status = STATUS_INVALID_HANDLE; 00736 if (Atom >= RTL_ATOM_MAXIMUM_INTEGER_ATOM) { 00737 a = RtlpAtomMapAtomToHandleEntry( p, 00738 (ULONG)(Atom & (USHORT)~RTL_ATOM_MAXIMUM_INTEGER_ATOM) 00739 ); 00740 if (a != NULL && a->Atom == Atom) { 00741 Status = STATUS_SUCCESS; 00742 a->Flags |= RTL_ATOM_PINNED; 00743 } 00744 } 00745 else 00746 if (Atom != RTL_ATOM_INVALID_ATOM) { 00747 Status = STATUS_SUCCESS; 00748 } 00749 } 00750 except (EXCEPTION_EXECUTE_HANDLER) { 00751 Status = GetExceptionCode(); 00752 } 00753 00754 RtlpUnlockAtomTable( p ); 00755 00756 return Status; 00757 } 00758 00759 NTSTATUS 00760 RtlQueryAtomInAtomTable( 00761 IN PVOID AtomTableHandle, 00762 IN RTL_ATOM Atom, 00763 OUT PULONG AtomUsage OPTIONAL, 00764 OUT PULONG AtomFlags OPTIONAL, 00765 IN OUT PWSTR AtomName OPTIONAL, 00766 IN OUT PULONG AtomNameLength OPTIONAL 00767 ) 00768 { 00769 NTSTATUS Status; 00770 PRTL_ATOM_TABLE p = (PRTL_ATOM_TABLE)AtomTableHandle; 00771 PRTL_ATOM_TABLE_ENTRY a; 00772 WCHAR AtomNameBuffer[ 16 ]; 00773 ULONG CopyLength; 00774 00775 if (!RtlpLockAtomTable( p )) { 00776 return STATUS_INVALID_PARAMETER; 00777 } 00778 try { 00779 if (Atom < RTL_ATOM_MAXIMUM_INTEGER_ATOM) { 00780 if (Atom == RTL_ATOM_INVALID_ATOM) { 00781 Status = STATUS_INVALID_PARAMETER; 00782 } 00783 else { 00784 Status = STATUS_SUCCESS; 00785 if (ARGUMENT_PRESENT( AtomUsage )) { 00786 *AtomUsage = 1; 00787 } 00788 00789 if (ARGUMENT_PRESENT( AtomFlags )) { 00790 *AtomFlags = RTL_ATOM_PINNED; 00791 } 00792 00793 if (ARGUMENT_PRESENT( AtomName )) { 00794 CopyLength = _snwprintf( AtomNameBuffer, 00795 sizeof( AtomNameBuffer ) / sizeof( WCHAR ), 00796 L"#%u", 00797 Atom 00798 ) * sizeof( WCHAR ); 00799 if (CopyLength >= *AtomNameLength) { 00800 if (*AtomNameLength >= sizeof( UNICODE_NULL )) { 00801 CopyLength = *AtomNameLength - sizeof( UNICODE_NULL ); 00802 } 00803 else { 00804 CopyLength = 0; 00805 } 00806 } 00807 00808 if (CopyLength != 0) { 00809 RtlMoveMemory( AtomName, AtomNameBuffer, CopyLength ); 00810 AtomName[ CopyLength / sizeof( WCHAR ) ] = UNICODE_NULL; 00811 *AtomNameLength = CopyLength; 00812 } 00813 else { 00814 Status = STATUS_BUFFER_TOO_SMALL; 00815 } 00816 } 00817 } 00818 } 00819 else { 00820 a = RtlpAtomMapAtomToHandleEntry( p, 00821 (ULONG)(Atom & (USHORT)~RTL_ATOM_MAXIMUM_INTEGER_ATOM) 00822 ); 00823 if (a != NULL && a->Atom == Atom) { 00824 Status = STATUS_SUCCESS; 00825 if (ARGUMENT_PRESENT( AtomUsage )) { 00826 *AtomUsage = a->ReferenceCount; 00827 } 00828 00829 if (ARGUMENT_PRESENT( AtomFlags )) { 00830 *AtomFlags = a->Flags; 00831 } 00832 00833 if (ARGUMENT_PRESENT( AtomName )) { 00834 // 00835 // Fill in as much of the atom string as possible, and 00836 // always zero terminate. This is what win3.1 does. 00837 // 00838 00839 CopyLength = a->NameLength * sizeof( WCHAR ); 00840 if (CopyLength >= *AtomNameLength) { 00841 if (*AtomNameLength >= sizeof( UNICODE_NULL )) { 00842 CopyLength = *AtomNameLength - sizeof( UNICODE_NULL ); 00843 } 00844 else { 00845 *AtomNameLength = CopyLength; 00846 CopyLength = 0; 00847 } 00848 } 00849 if (CopyLength != 0) { 00850 RtlMoveMemory( AtomName, a->Name, CopyLength ); 00851 AtomName[ CopyLength / sizeof( WCHAR ) ] = UNICODE_NULL; 00852 *AtomNameLength = CopyLength; 00853 } 00854 else { 00855 Status = STATUS_BUFFER_TOO_SMALL; 00856 } 00857 } 00858 } 00859 else { 00860 Status = STATUS_INVALID_HANDLE; 00861 } 00862 } 00863 } 00864 except (EXCEPTION_EXECUTE_HANDLER) { 00865 Status = GetExceptionCode(); 00866 } 00867 00868 RtlpUnlockAtomTable( p ); 00869 00870 return Status; 00871 } 00872 00873 NTSTATUS 00874 RtlQueryAtomsInAtomTable( 00875 IN PVOID AtomTableHandle, 00876 IN ULONG MaximumNumberOfAtoms, 00877 OUT PULONG NumberOfAtoms, 00878 OUT PRTL_ATOM Atoms 00879 ) 00880 { 00881 NTSTATUS Status; 00882 PRTL_ATOM_TABLE p = (PRTL_ATOM_TABLE)AtomTableHandle; 00883 PRTL_ATOM_TABLE_ENTRY a; 00884 ULONG i; 00885 ULONG CurrentAtomIndex; 00886 00887 if (!RtlpLockAtomTable( p )) { 00888 return STATUS_INVALID_PARAMETER; 00889 } 00890 00891 Status = STATUS_SUCCESS; 00892 try { 00893 CurrentAtomIndex = 0; 00894 for (i=0; i<p->NumberOfBuckets; i++) { 00895 a = p->Buckets[ i ]; 00896 while (a) { 00897 if (CurrentAtomIndex < MaximumNumberOfAtoms) { 00898 Atoms[ CurrentAtomIndex ] = a->Atom; 00899 } 00900 else { 00901 Status = STATUS_INFO_LENGTH_MISMATCH; 00902 } 00903 00904 CurrentAtomIndex += 1; 00905 a = a->HashLink; 00906 } 00907 } 00908 00909 *NumberOfAtoms = CurrentAtomIndex; 00910 } 00911 except (EXCEPTION_EXECUTE_HANDLER) { 00912 Status = GetExceptionCode(); 00913 } 00914 00915 RtlpUnlockAtomTable( p ); 00916 00917 return Status; 00918 }

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