Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenatom.c
Go to the documentation of this file.
00001 /* COPYRIGHT: See COPYING in the top level directory 00002 * PROJECT: ReactOS system libraries 00003 * FILE: lib/rtl/atom.c 00004 * PURPOSE: Atom managment 00005 * PROGRAMMER: Thomas Weidenmueller 00006 */ 00007 00008 /* INCLUDES *****************************************************************/ 00009 00010 #include <rtl.h> 00011 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* PROTOTYPES ****************************************************************/ 00016 00017 extern NTSTATUS RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable); 00018 extern VOID RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable); 00019 extern BOOLEAN RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable); 00020 extern VOID RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable); 00021 00022 extern BOOLEAN RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable); 00023 extern VOID RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable); 00024 00025 extern PRTL_ATOM_TABLE RtlpAllocAtomTable(ULONG Size); 00026 extern VOID RtlpFreeAtomTable(PRTL_ATOM_TABLE AtomTable); 00027 extern PRTL_ATOM_TABLE_ENTRY RtlpAllocAtomTableEntry(ULONG Size); 00028 extern VOID RtlpFreeAtomTableEntry(PRTL_ATOM_TABLE_ENTRY Entry); 00029 00030 extern BOOLEAN RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry); 00031 extern VOID RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry); 00032 extern PRTL_ATOM_TABLE_ENTRY RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable, ULONG Index); 00033 00034 /* FUNCTIONS *****************************************************************/ 00035 00036 static PRTL_ATOM_TABLE_ENTRY 00037 RtlpHashAtomName(IN PRTL_ATOM_TABLE AtomTable, 00038 IN PWSTR AtomName, 00039 OUT PRTL_ATOM_TABLE_ENTRY **HashLink) 00040 { 00041 UNICODE_STRING Name; 00042 ULONG Hash; 00043 00044 RtlInitUnicodeString(&Name, 00045 AtomName); 00046 00047 if (Name.Length != 0 && 00048 NT_SUCCESS(RtlHashUnicodeString(&Name, 00049 TRUE, 00050 HASH_STRING_ALGORITHM_X65599, 00051 &Hash))) 00052 { 00053 PRTL_ATOM_TABLE_ENTRY Current; 00054 PRTL_ATOM_TABLE_ENTRY *Link; 00055 00056 Link = &AtomTable->Buckets[Hash % AtomTable->NumberOfBuckets]; 00057 00058 /* search for an existing entry */ 00059 Current = *Link; 00060 while (Current != NULL) 00061 { 00062 if (Current->NameLength == Name.Length / sizeof(WCHAR) && 00063 !_wcsicmp(Current->Name, Name.Buffer)) 00064 { 00065 *HashLink = Link; 00066 return Current; 00067 } 00068 Link = &Current->HashLink; 00069 Current = Current->HashLink; 00070 } 00071 00072 /* no matching atom found, return the hash link */ 00073 *HashLink = Link; 00074 } 00075 else 00076 *HashLink = NULL; 00077 00078 return NULL; 00079 } 00080 00081 static BOOLEAN 00082 RtlpCheckIntegerAtom(PWSTR AtomName, 00083 PUSHORT AtomValue) 00084 { 00085 UNICODE_STRING AtomString; 00086 ULONG LongValue; 00087 USHORT LoValue; 00088 PWCHAR p; 00089 00090 DPRINT("RtlpCheckIntegerAtom(AtomName '%S' AtomValue %p)\n", 00091 AtomName, AtomValue); 00092 00093 if (!((ULONG_PTR)AtomName & 0xFFFF0000)) 00094 { 00095 LoValue = (USHORT)((ULONG_PTR)AtomName & 0xFFFF); 00096 00097 if (LoValue == 0) 00098 LoValue = 0xC000; 00099 00100 if (AtomValue != NULL) 00101 *AtomValue = LoValue; 00102 00103 return TRUE; 00104 } 00105 00106 if (*AtomName != L'#') 00107 return FALSE; 00108 00109 p = AtomName; 00110 p++; 00111 while (*p) 00112 { 00113 if ((*p < L'0') || (*p > L'9')) 00114 return FALSE; 00115 p++; 00116 } 00117 00118 p = AtomName; 00119 p++; 00120 RtlInitUnicodeString(&AtomString, 00121 p); 00122 00123 DPRINT("AtomString: %wZ\n", &AtomString); 00124 00125 RtlUnicodeStringToInteger(&AtomString,10, &LongValue); 00126 00127 DPRINT("LongValue: %lu\n", LongValue); 00128 00129 *AtomValue = (USHORT)(LongValue & 0x0000FFFF); 00130 00131 return TRUE; 00132 } 00133 00134 00135 /* 00136 * @implemented 00137 */ 00138 NTSTATUS NTAPI 00139 RtlCreateAtomTable(IN ULONG TableSize, 00140 IN OUT PRTL_ATOM_TABLE *AtomTable) 00141 { 00142 PRTL_ATOM_TABLE Table; 00143 NTSTATUS Status; 00144 00145 DPRINT("RtlCreateAtomTable(TableSize %lu AtomTable %p)\n", 00146 TableSize, AtomTable); 00147 00148 if (*AtomTable != NULL) 00149 { 00150 return STATUS_SUCCESS; 00151 } 00152 00153 /* Use default if size was incorrect */ 00154 if (TableSize <= 1) TableSize = 37; 00155 00156 /* allocate atom table */ 00157 Table = RtlpAllocAtomTable(((TableSize - 1) * sizeof(PRTL_ATOM_TABLE_ENTRY)) + 00158 sizeof(RTL_ATOM_TABLE)); 00159 if (Table == NULL) 00160 { 00161 return STATUS_NO_MEMORY; 00162 } 00163 00164 /* initialize atom table */ 00165 Table->NumberOfBuckets = TableSize; 00166 00167 Status = RtlpInitAtomTableLock(Table); 00168 if (!NT_SUCCESS(Status)) 00169 { 00170 RtlpFreeAtomTable(Table); 00171 return Status; 00172 } 00173 00174 if (!RtlpCreateAtomHandleTable(Table)) 00175 { 00176 RtlpDestroyAtomTableLock(Table); 00177 RtlpFreeAtomTable(Table); 00178 return STATUS_NO_MEMORY; 00179 } 00180 00181 *AtomTable = Table; 00182 return STATUS_SUCCESS; 00183 } 00184 00185 00186 /* 00187 * @implemented 00188 */ 00189 NTSTATUS NTAPI 00190 RtlDestroyAtomTable(IN PRTL_ATOM_TABLE AtomTable) 00191 { 00192 PRTL_ATOM_TABLE_ENTRY *CurrentBucket, *LastBucket; 00193 PRTL_ATOM_TABLE_ENTRY CurrentEntry, NextEntry; 00194 00195 DPRINT("RtlDestroyAtomTable (AtomTable %p)\n", AtomTable); 00196 00197 if (!RtlpLockAtomTable(AtomTable)) 00198 { 00199 return (STATUS_INVALID_PARAMETER); 00200 } 00201 00202 /* delete all atoms */ 00203 LastBucket = AtomTable->Buckets + AtomTable->NumberOfBuckets; 00204 for (CurrentBucket = AtomTable->Buckets; 00205 CurrentBucket != LastBucket; 00206 CurrentBucket++) 00207 { 00208 NextEntry = *CurrentBucket; 00209 *CurrentBucket = NULL; 00210 00211 while (NextEntry != NULL) 00212 { 00213 CurrentEntry = NextEntry; 00214 NextEntry = NextEntry->HashLink; 00215 00216 /* no need to delete the atom handle, the handles will all be freed 00217 up when destroying the atom handle table! */ 00218 00219 RtlpFreeAtomTableEntry(CurrentEntry); 00220 } 00221 } 00222 00223 RtlpDestroyAtomHandleTable(AtomTable); 00224 00225 RtlpUnlockAtomTable(AtomTable); 00226 00227 RtlpDestroyAtomTableLock(AtomTable); 00228 00229 RtlpFreeAtomTable(AtomTable); 00230 00231 return STATUS_SUCCESS; 00232 } 00233 00234 00235 /* 00236 * @implemented 00237 */ 00238 NTSTATUS NTAPI 00239 RtlEmptyAtomTable(PRTL_ATOM_TABLE AtomTable, 00240 BOOLEAN DeletePinned) 00241 { 00242 PRTL_ATOM_TABLE_ENTRY *CurrentBucket, *LastBucket; 00243 PRTL_ATOM_TABLE_ENTRY CurrentEntry, NextEntry, *PtrEntry; 00244 00245 DPRINT("RtlEmptyAtomTable (AtomTable %p DeletePinned %x)\n", 00246 AtomTable, DeletePinned); 00247 00248 if (RtlpLockAtomTable(AtomTable) == FALSE) 00249 { 00250 return (STATUS_INVALID_PARAMETER); 00251 } 00252 00253 /* delete all atoms */ 00254 LastBucket = AtomTable->Buckets + AtomTable->NumberOfBuckets; 00255 for (CurrentBucket = AtomTable->Buckets; 00256 CurrentBucket != LastBucket; 00257 CurrentBucket++) 00258 { 00259 NextEntry = *CurrentBucket; 00260 PtrEntry = CurrentBucket; 00261 00262 while (NextEntry != NULL) 00263 { 00264 CurrentEntry = NextEntry; 00265 NextEntry = NextEntry->HashLink; 00266 00267 if (DeletePinned || !(CurrentEntry->Flags & RTL_ATOM_IS_PINNED)) 00268 { 00269 *PtrEntry = NextEntry; 00270 00271 RtlpFreeAtomHandle(AtomTable, 00272 CurrentEntry); 00273 00274 RtlpFreeAtomTableEntry(CurrentEntry); 00275 } 00276 else 00277 { 00278 PtrEntry = &CurrentEntry->HashLink; 00279 } 00280 } 00281 } 00282 00283 RtlpUnlockAtomTable(AtomTable); 00284 00285 return STATUS_SUCCESS; 00286 } 00287 00288 00289 /* 00290 * @implemented 00291 */ 00292 NTSTATUS NTAPI 00293 RtlAddAtomToAtomTable(IN PRTL_ATOM_TABLE AtomTable, 00294 IN PWSTR AtomName, 00295 OUT PRTL_ATOM Atom) 00296 { 00297 USHORT AtomValue; 00298 PRTL_ATOM_TABLE_ENTRY *HashLink; 00299 PRTL_ATOM_TABLE_ENTRY Entry = NULL; 00300 NTSTATUS Status = STATUS_SUCCESS; 00301 00302 DPRINT("RtlAddAtomToAtomTable (AtomTable %p AtomName %S Atom %p)\n", 00303 AtomTable, AtomName, Atom); 00304 00305 if (RtlpCheckIntegerAtom (AtomName, &AtomValue)) 00306 { 00307 /* integer atom */ 00308 if (AtomValue >= 0xC000) 00309 { 00310 Status = STATUS_INVALID_PARAMETER; 00311 } 00312 else if (Atom != NULL) 00313 { 00314 *Atom = (RTL_ATOM)AtomValue; 00315 } 00316 00317 return Status; 00318 } 00319 00320 RtlpLockAtomTable(AtomTable); 00321 00322 /* string atom, hash it and try to find an existing atom with the same name */ 00323 Entry = RtlpHashAtomName(AtomTable, 00324 AtomName, 00325 &HashLink); 00326 00327 if (Entry != NULL) 00328 { 00329 /* found another atom, increment the reference counter unless it's pinned */ 00330 00331 if (!(Entry->Flags & RTL_ATOM_IS_PINNED)) 00332 { 00333 if (++Entry->ReferenceCount == 0) 00334 { 00335 /* FIXME - references overflowed, pin the atom? */ 00336 Entry->Flags |= RTL_ATOM_IS_PINNED; 00337 } 00338 } 00339 00340 if (Atom != NULL) 00341 { 00342 *Atom = (RTL_ATOM)Entry->Atom; 00343 } 00344 } 00345 else 00346 { 00347 /* couldn't find an existing atom, HashLink now points to either the 00348 HashLink pointer of the previous atom or to the bucket so we can 00349 simply add it to the list */ 00350 if (HashLink != NULL) 00351 { 00352 ULONG AtomNameLen = (ULONG)wcslen(AtomName); 00353 00354 if (AtomNameLen > RTL_MAXIMUM_ATOM_LENGTH) 00355 { 00356 Status = STATUS_INVALID_PARAMETER; 00357 goto end; 00358 } 00359 00360 Entry = RtlpAllocAtomTableEntry(sizeof(RTL_ATOM_TABLE_ENTRY) - 00361 sizeof(Entry->Name) + 00362 (AtomNameLen + 1) * sizeof(WCHAR)); 00363 if (Entry != NULL) 00364 { 00365 Entry->HashLink = NULL; 00366 Entry->ReferenceCount = 1; 00367 Entry->Flags = 0x0; 00368 00369 Entry->NameLength = (UCHAR)AtomNameLen; 00370 RtlCopyMemory(Entry->Name, 00371 AtomName, 00372 (AtomNameLen + 1) * sizeof(WCHAR)); 00373 00374 if (RtlpCreateAtomHandle(AtomTable, 00375 Entry)) 00376 { 00377 /* append the atom to the list */ 00378 *HashLink = Entry; 00379 00380 if (Atom != NULL) 00381 { 00382 *Atom = (RTL_ATOM)Entry->Atom; 00383 } 00384 } 00385 else 00386 { 00387 RtlpFreeAtomTableEntry(Entry); 00388 Status = STATUS_NO_MEMORY; 00389 } 00390 } 00391 else 00392 { 00393 Status = STATUS_NO_MEMORY; 00394 } 00395 } 00396 else 00397 { 00398 /* The caller supplied an empty atom name! */ 00399 Status = STATUS_OBJECT_NAME_INVALID; 00400 } 00401 } 00402 end: 00403 RtlpUnlockAtomTable(AtomTable); 00404 00405 return Status; 00406 } 00407 00408 00409 /* 00410 * @implemented 00411 */ 00412 NTSTATUS NTAPI 00413 RtlDeleteAtomFromAtomTable(IN PRTL_ATOM_TABLE AtomTable, 00414 IN RTL_ATOM Atom) 00415 { 00416 PRTL_ATOM_TABLE_ENTRY Entry; 00417 NTSTATUS Status = STATUS_SUCCESS; 00418 00419 DPRINT("RtlDeleteAtomFromAtomTable (AtomTable %p Atom %x)\n", 00420 AtomTable, Atom); 00421 00422 if (Atom >= 0xC000) 00423 { 00424 RtlpLockAtomTable(AtomTable); 00425 00426 Entry = RtlpGetAtomEntry(AtomTable, 00427 (ULONG)((USHORT)Atom - 0xC000)); 00428 00429 if (Entry != NULL && Entry->Atom == (USHORT)Atom) 00430 { 00431 if (!(Entry->Flags & RTL_ATOM_IS_PINNED)) 00432 { 00433 if (--Entry->ReferenceCount == 0) 00434 { 00435 PRTL_ATOM_TABLE_ENTRY *HashLink; 00436 00437 /* it's time to delete the atom. we need to unlink it from 00438 the list. The easiest way is to take the atom name and 00439 hash it again, this way we get the pointer to either 00440 the hash bucket or the previous atom that links to the 00441 one we want to delete. This way we can easily bypass 00442 this item. */ 00443 if (RtlpHashAtomName(AtomTable, 00444 Entry->Name, 00445 &HashLink) != NULL) 00446 { 00447 /* bypass this atom */ 00448 *HashLink = Entry->HashLink; 00449 00450 RtlpFreeAtomHandle(AtomTable, 00451 Entry); 00452 00453 RtlpFreeAtomTableEntry(Entry); 00454 } 00455 else 00456 { 00457 /* WTF?! This should never happen!!! */ 00458 ASSERT(FALSE); 00459 } 00460 } 00461 } 00462 else 00463 { 00464 /* tried to delete a pinned atom, do nothing and return 00465 STATUS_WAS_LOCKED, which is NOT a failure code! */ 00466 Status = STATUS_WAS_LOCKED; 00467 } 00468 } 00469 else 00470 { 00471 Status = STATUS_INVALID_HANDLE; 00472 } 00473 00474 RtlpUnlockAtomTable(AtomTable); 00475 } 00476 00477 return Status; 00478 } 00479 00480 00481 /* 00482 * @implemented 00483 */ 00484 NTSTATUS NTAPI 00485 RtlLookupAtomInAtomTable(IN PRTL_ATOM_TABLE AtomTable, 00486 IN PWSTR AtomName, 00487 OUT PRTL_ATOM Atom) 00488 { 00489 PRTL_ATOM_TABLE_ENTRY Entry, *HashLink; 00490 USHORT AtomValue; 00491 RTL_ATOM FoundAtom = 0; 00492 NTSTATUS Status = STATUS_SUCCESS; 00493 00494 DPRINT("RtlLookupAtomInAtomTable (AtomTable %p AtomName %S Atom %p)\n", 00495 AtomTable, AtomName, Atom); 00496 00497 if (RtlpCheckIntegerAtom (AtomName, &AtomValue)) 00498 { 00499 /* integer atom */ 00500 if (AtomValue >= 0xC000) 00501 { 00502 Status = STATUS_INVALID_PARAMETER; 00503 } 00504 else if (Atom != NULL) 00505 { 00506 *Atom = (RTL_ATOM)AtomValue; 00507 } 00508 00509 return Status; 00510 } 00511 00512 RtlpLockAtomTable(AtomTable); 00513 Status = STATUS_OBJECT_NAME_NOT_FOUND; 00514 00515 /* string atom */ 00516 Entry = RtlpHashAtomName(AtomTable, 00517 AtomName, 00518 &HashLink); 00519 if (Entry != NULL) 00520 { 00521 Status = STATUS_SUCCESS; 00522 FoundAtom = (RTL_ATOM)Entry->Atom; 00523 } 00524 RtlpUnlockAtomTable(AtomTable); 00525 if (NT_SUCCESS(Status) && Atom != NULL) 00526 { 00527 *Atom = FoundAtom; 00528 } 00529 return Status; 00530 } 00531 00532 00533 /* 00534 * @implemented 00535 */ 00536 NTSTATUS NTAPI 00537 RtlPinAtomInAtomTable(IN PRTL_ATOM_TABLE AtomTable, 00538 IN RTL_ATOM Atom) 00539 { 00540 NTSTATUS Status = STATUS_SUCCESS; 00541 00542 DPRINT("RtlPinAtomInAtomTable (AtomTable %p Atom %x)\n", 00543 AtomTable, Atom); 00544 00545 if (Atom >= 0xC000) 00546 { 00547 PRTL_ATOM_TABLE_ENTRY Entry; 00548 00549 RtlpLockAtomTable(AtomTable); 00550 00551 Entry = RtlpGetAtomEntry(AtomTable, 00552 (ULONG)((USHORT)Atom - 0xC000)); 00553 00554 if (Entry != NULL && Entry->Atom == (USHORT)Atom) 00555 { 00556 Entry->Flags |= RTL_ATOM_IS_PINNED; 00557 } 00558 else 00559 { 00560 Status = STATUS_INVALID_HANDLE; 00561 } 00562 00563 RtlpUnlockAtomTable(AtomTable); 00564 } 00565 00566 return Status; 00567 } 00568 00569 00570 /* 00571 * @implemented 00572 * 00573 * This API is really messed up with regards to NameLength. If you pass in a 00574 * valid buffer for AtomName, NameLength should be the size of the buffer 00575 * (in bytes, not characters). So if you expect the string to be 6 char long, 00576 * you need to allocate a buffer of 7 WCHARs and pass 14 for NameLength. 00577 * The AtomName returned is always null terminated. If the NameLength you pass 00578 * is smaller than 4 (4 would leave room for 1 character) the function will 00579 * return with status STATUS_BUFFER_TOO_SMALL. If you pass more than 4, the 00580 * return status will be STATUS_SUCCESS, even if the buffer is not large enough 00581 * to hold the complete string. In that case, the string is silently truncated 00582 * and made to fit in the provided buffer. On return NameLength is set to the 00583 * number of bytes (but EXCLUDING the bytes for the null terminator) copied. 00584 * So, if the string is 6 char long, you pass a buffer of 10 bytes, on return 00585 * NameLength will be set to 8. 00586 * If you pass in a NULL value for AtomName, the length of the string in bytes 00587 * (again EXCLUDING the null terminator) is returned in NameLength, at least 00588 * on Win2k, XP and ReactOS. NT4 will return 0 in that case. 00589 */ 00590 NTSTATUS NTAPI 00591 RtlQueryAtomInAtomTable(PRTL_ATOM_TABLE AtomTable, 00592 RTL_ATOM Atom, 00593 PULONG RefCount, 00594 PULONG PinCount, 00595 PWSTR AtomName, 00596 PULONG NameLength) 00597 { 00598 ULONG Length; 00599 BOOL Unlock = FALSE; 00600 00601 union 00602 { 00603 /* A RTL_ATOM_TABLE_ENTRY has a "WCHAR Name[1]" entry at the end. 00604 * Make sure we reserve enough room to facilitate a 12 character name */ 00605 RTL_ATOM_TABLE_ENTRY AtomTableEntry; 00606 WCHAR StringBuffer[sizeof(RTL_ATOM_TABLE_ENTRY) / sizeof(WCHAR) + 12]; 00607 } NumberEntry; 00608 PRTL_ATOM_TABLE_ENTRY Entry; 00609 NTSTATUS Status = STATUS_SUCCESS; 00610 00611 if (Atom < 0xC000) 00612 { 00613 /* Synthesize an entry */ 00614 NumberEntry.AtomTableEntry.Atom = Atom; 00615 NumberEntry.AtomTableEntry.NameLength = swprintf(NumberEntry.AtomTableEntry.Name, 00616 L"#%lu", 00617 (ULONG)Atom); 00618 NumberEntry.AtomTableEntry.ReferenceCount = 1; 00619 NumberEntry.AtomTableEntry.Flags = RTL_ATOM_IS_PINNED; 00620 Entry = &NumberEntry.AtomTableEntry; 00621 } 00622 else 00623 { 00624 RtlpLockAtomTable(AtomTable); 00625 Unlock = TRUE; 00626 00627 Entry = RtlpGetAtomEntry(AtomTable, 00628 (ULONG)((USHORT)Atom - 0xC000)); 00629 } 00630 00631 if (Entry != NULL && Entry->Atom == (USHORT)Atom) 00632 { 00633 DPRINT("Atom name: %wZ\n", &Entry->Name); 00634 00635 if (RefCount != NULL) 00636 { 00637 *RefCount = Entry->ReferenceCount; 00638 } 00639 00640 if (PinCount != NULL) 00641 { 00642 *PinCount = ((Entry->Flags & RTL_ATOM_IS_PINNED) != 0); 00643 } 00644 00645 if (NULL != NameLength) 00646 { 00647 Length = Entry->NameLength * sizeof(WCHAR); 00648 if (NULL != AtomName) 00649 { 00650 if (*NameLength < Length + sizeof(WCHAR)) 00651 { 00652 if (*NameLength < 4) 00653 { 00654 *NameLength = Length; 00655 Status = STATUS_BUFFER_TOO_SMALL; 00656 } 00657 else 00658 { 00659 Length = *NameLength - sizeof(WCHAR); 00660 } 00661 } 00662 if (NT_SUCCESS(Status)) 00663 { 00664 RtlCopyMemory(AtomName, 00665 Entry->Name, 00666 Length); 00667 AtomName[Length / sizeof(WCHAR)] = L'\0'; 00668 *NameLength = Length; 00669 } 00670 } 00671 else 00672 { 00673 *NameLength = Length; 00674 } 00675 } 00676 else if (NULL != AtomName) 00677 { 00678 Status = STATUS_INVALID_PARAMETER; 00679 } 00680 } 00681 else 00682 { 00683 Status = STATUS_INVALID_HANDLE; 00684 } 00685 00686 if (Unlock) RtlpUnlockAtomTable(AtomTable); 00687 00688 return Status; 00689 } 00690 00691 00692 /* 00693 * @private - only used by NtQueryInformationAtom 00694 */ 00695 NTSTATUS NTAPI 00696 RtlQueryAtomListInAtomTable(IN PRTL_ATOM_TABLE AtomTable, 00697 IN ULONG MaxAtomCount, 00698 OUT ULONG *AtomCount, 00699 OUT RTL_ATOM *AtomList) 00700 { 00701 PRTL_ATOM_TABLE_ENTRY *CurrentBucket, *LastBucket; 00702 PRTL_ATOM_TABLE_ENTRY CurrentEntry; 00703 ULONG Atoms = 0; 00704 NTSTATUS Status = STATUS_SUCCESS; 00705 00706 RtlpLockAtomTable(AtomTable); 00707 00708 LastBucket = AtomTable->Buckets + AtomTable->NumberOfBuckets; 00709 for (CurrentBucket = AtomTable->Buckets; 00710 CurrentBucket != LastBucket; 00711 CurrentBucket++) 00712 { 00713 CurrentEntry = *CurrentBucket; 00714 00715 while (CurrentEntry != NULL) 00716 { 00717 if (MaxAtomCount > 0) 00718 { 00719 *(AtomList++) = (RTL_ATOM)CurrentEntry->Atom; 00720 MaxAtomCount--; 00721 } 00722 else 00723 { 00724 /* buffer too small, but don't bail. we need to determine the 00725 total number of atoms in the table! */ 00726 Status = STATUS_INFO_LENGTH_MISMATCH; 00727 } 00728 00729 Atoms++; 00730 CurrentEntry = CurrentEntry->HashLink; 00731 } 00732 } 00733 00734 *AtomCount = Atoms; 00735 00736 RtlpUnlockAtomTable(AtomTable); 00737 00738 return Status; 00739 } 00740 Generated on Sat May 26 2012 04:22:56 for ReactOS by
1.7.6.1
|