00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "exp.h"
00023
#pragma hdrstop
00024
00025
00026
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
00054
00055
00056
00057
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
00161
00162
00163
00164
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
00267
00268
00269
00270
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
00305
00306
00307
00308
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
00332
00333
00334
Status = STATUS_SUCCESS;
00335
00336
try {
00337
00338
00339
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
00437
00438
00439 PKWIN32_GLOBALATOMTABLE_CALLOUT ExGlobalAtomTableCallout;
00440
00441 PVOID
00442 ExpGetGlobalAtomTable (
00443 )
00444
00445
00446
00447
00448
00449
00450
00451
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 }