NT4/private/ntos/ex/exatom.c
2020-09-30 17:12:29 +02:00

216 lines
5.1 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
exatom.c
Abstract:
This file contains functions for manipulating global atom tables
stored in kernel space.
Author:
Steve Wood (stevewo) 13-Dec-1995
Revision History:
--*/
#include "exp.h"
#pragma hdrstop
PVOID
ExpGetGlobalAtomTable( void );
#if defined(ALLOC_PRAGMA)
#pragma alloc_text(PAGE, NtAddAtom)
#pragma alloc_text(PAGE, NtFindAtom)
#pragma alloc_text(PAGE, NtDeleteAtom)
#pragma alloc_text(PAGE, NtQueryInformationAtom)
#pragma alloc_text(PAGE, ExpGetGlobalAtomTable)
#endif
NTSYSAPI
NTSTATUS
NTAPI
NtAddAtom(
IN PWSTR AtomName OPTIONAL,
IN OUT PRTL_ATOM Atom OPTIONAL
)
{
NTSTATUS Status;
PVOID AtomTable = ExpGetGlobalAtomTable();
PAGED_CODE();
if (AtomTable == NULL) {
return STATUS_ACCESS_DENIED;
}
Status = RtlAddAtomToAtomTable( AtomTable, AtomName, Atom );
return Status;
}
NTSYSAPI
NTSTATUS
NTAPI
NtFindAtom(
IN PWSTR AtomName,
OUT PRTL_ATOM Atom OPTIONAL
)
{
NTSTATUS Status;
PVOID AtomTable = ExpGetGlobalAtomTable();
PAGED_CODE();
if (AtomTable == NULL) {
return STATUS_ACCESS_DENIED;
}
Status = RtlLookupAtomInAtomTable( AtomTable, AtomName, Atom );
return Status;
}
NTSYSAPI
NTSTATUS
NTAPI
NtDeleteAtom(
IN RTL_ATOM Atom
)
{
NTSTATUS Status;
PVOID AtomTable = ExpGetGlobalAtomTable();
PAGED_CODE();
if (AtomTable == NULL) {
return STATUS_ACCESS_DENIED;
}
Status = RtlDeleteAtomFromAtomTable( AtomTable, Atom );
return Status;
}
NTSYSAPI
NTSTATUS
NTAPI
NtQueryInformationAtom(
IN RTL_ATOM Atom,
IN ATOM_INFORMATION_CLASS AtomInformationClass,
OUT PVOID AtomInformation,
IN ULONG AtomInformationLength,
OUT PULONG ReturnLength OPTIONAL
)
{
NTSTATUS Status;
KPROCESSOR_MODE PreviousMode;
ULONG UsageCount;
ULONG NameLength;
ULONG AtomFlags;
PATOM_BASIC_INFORMATION BasicInfo;
PATOM_TABLE_INFORMATION TableInfo;
PVOID AtomTable = ExpGetGlobalAtomTable();
PAGED_CODE();
if (AtomTable == NULL) {
return STATUS_ACCESS_DENIED;
}
//
// Assume successful completion.
//
Status = STATUS_SUCCESS;
try {
//
// Get previous processor mode and probe output argument if necessary.
//
PreviousMode = KeGetPreviousMode();
if (PreviousMode != KernelMode) {
ProbeForWrite( AtomInformation,
AtomInformationLength,
sizeof( ULONG )
);
if (ARGUMENT_PRESENT( ReturnLength )) {
ProbeForWriteUlong( ReturnLength );
}
}
switch (AtomInformationClass) {
case AtomBasicInformation:
if (AtomInformationLength < FIELD_OFFSET( ATOM_BASIC_INFORMATION, Name )) {
return STATUS_INFO_LENGTH_MISMATCH;
}
BasicInfo = (PATOM_BASIC_INFORMATION)AtomInformation;
UsageCount = 0;
NameLength = AtomInformationLength -
FIELD_OFFSET( ATOM_BASIC_INFORMATION, Name );
BasicInfo->Name[ 0 ] = UNICODE_NULL;
Status = RtlQueryAtomInAtomTable( AtomTable,
Atom,
&UsageCount,
&AtomFlags,
&BasicInfo->Name[0],
&NameLength
);
BasicInfo->UsageCount = (USHORT)UsageCount;
BasicInfo->Flags = (USHORT)AtomFlags;
BasicInfo->NameLength = (USHORT)NameLength;
break;
case AtomTableInformation:
if (AtomInformationLength < FIELD_OFFSET( ATOM_TABLE_INFORMATION, Atoms )) {
return STATUS_INFO_LENGTH_MISMATCH;
}
TableInfo = (PATOM_TABLE_INFORMATION)AtomInformation;
Status = RtlQueryAtomsInAtomTable( AtomTable,
(AtomInformationLength - FIELD_OFFSET( ATOM_TABLE_INFORMATION, Atoms )) / sizeof( RTL_ATOM ),
&TableInfo->NumberOfAtoms,
&TableInfo->Atoms[0]
);
break;
default:
Status = STATUS_INVALID_INFO_CLASS;
break;
}
}
except (EXCEPTION_EXECUTE_HANDLER) {
Status = GetExceptionCode();
}
return Status;
}
PKWIN32_GLOBALATOMTABLE_CALLOUT ExGlobalAtomTableCallout;
PVOID
ExpGetGlobalAtomTable( void )
{
if (ExGlobalAtomTableCallout != NULL) {
return ((*ExGlobalAtomTableCallout)());
}
else {
#if DBG
DbgPrint( "EX: ExpGetGlobalAtomTable is about to return NULL!\n" );
DbgBreakPoint();
#endif
return NULL;
}
}