00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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;
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
00836
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 }