Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: dll/win32/kernel32/client/atom.c * PURPOSE: Atom functions * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) */
/* INCLUDES ******************************************************************/#include <k32.h>
#define NDEBUG#include <debug.h>
/* GLOBALS *******************************************************************/
PRTL_ATOM_TABLE BaseLocalAtomTable = NULL;
/* FUNCTIONS *****************************************************************/
PVOIDWINAPIInternalInitAtomTable(VOID){ /* Create or return the local table */ if (!BaseLocalAtomTable) RtlCreateAtomTable(0, &BaseLocalAtomTable); return BaseLocalAtomTable;}
ATOMWINAPIInternalAddAtom(BOOLEAN Local, BOOLEAN Unicode, LPCSTR AtomName){ NTSTATUS Status; ANSI_STRING AnsiString; UNICODE_STRING UnicodeString; PUNICODE_STRING AtomNameString; ATOM Atom = INVALID_ATOM;
/* Check if it's an integer atom */ if ((ULONG_PTR)AtomName <= 0xFFFF) { /* Convert the name to an atom */ Atom = (ATOM)PtrToShort((PVOID)AtomName); if (Atom >= MAXINTATOM) { /* Fail, atom number too large */ BaseSetLastNTError(STATUS_INVALID_PARAMETER); return INVALID_ATOM; }
/* Return it */ return Atom; } else { /* Check if this is a unicode atom */ if (Unicode) { /* Use a unicode string */ AtomNameString = &UnicodeString; RtlInitUnicodeString(AtomNameString, (LPWSTR)AtomName); Status = STATUS_SUCCESS; } else { /* Use an ansi string */ RtlInitAnsiString(&AnsiString, AtomName );
/* Check if we can abuse the TEB */ if (AnsiString.MaximumLength > 260) { /* We can't, allocate a new string */ AtomNameString = &UnicodeString; Status = RtlAnsiStringToUnicodeString(AtomNameString, &AnsiString, TRUE); } else { /* We can! Get the TEB String */ AtomNameString = &NtCurrentTeb()->StaticUnicodeString;
/* Convert it into the TEB */ Status = RtlAnsiStringToUnicodeString(AtomNameString, &AnsiString, FALSE); } }
/* Check for failure */ if (!NT_SUCCESS(Status)) { BaseSetLastNTError(Status); return Atom; } }
/* Check if we're doing local add */ if (Local) { /* Do a local add */ Status = RtlAddAtomToAtomTable(InternalInitAtomTable(), AtomNameString->Buffer, &Atom); } else { /* Do a global add */ Status = NtAddAtom(AtomNameString->Buffer, AtomNameString->Length, &Atom); }
/* Check for failure */ if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
/* Check if we were non-static ANSI */ if (!(Unicode) && (AtomNameString == &UnicodeString)) { /* Free the allocated buffer */ RtlFreeUnicodeString(AtomNameString); }
/* Return the atom */ return Atom;}
ATOMWINAPIInternalFindAtom(BOOLEAN Local, BOOLEAN Unicode, LPCSTR AtomName){ NTSTATUS Status; ANSI_STRING AnsiString; UNICODE_STRING UnicodeString; PUNICODE_STRING AtomNameString; ATOM Atom = INVALID_ATOM;
/* Check if it's an integer atom */ if ((ULONG_PTR)AtomName <= 0xFFFF) { /* Convert the name to an atom */ Atom = (ATOM)PtrToShort((PVOID)AtomName); if (Atom >= MAXINTATOM) { /* Fail, atom number too large */ BaseSetLastNTError(STATUS_INVALID_PARAMETER); DPRINT1("Invalid atom\n"); }
/* Return it */ return Atom; } else { /* Check if this is a unicode atom */ if (Unicode) { /* Use a unicode string */ AtomNameString = &UnicodeString; RtlInitUnicodeString(AtomNameString, (LPWSTR)AtomName); Status = STATUS_SUCCESS; } else { /* Use an ansi string */ RtlInitAnsiString(&AnsiString, AtomName);
/* Check if we can abuse the TEB */ if (AnsiString.MaximumLength > 260) { /* We can't, allocate a new string */ AtomNameString = &UnicodeString; Status = RtlAnsiStringToUnicodeString(AtomNameString, &AnsiString, TRUE); } else { /* We can! Get the TEB String */ AtomNameString = &NtCurrentTeb()->StaticUnicodeString;
/* Convert it into the TEB */ Status = RtlAnsiStringToUnicodeString(AtomNameString, &AnsiString, FALSE); } }
/* Check for failure */ if (!NT_SUCCESS(Status)) { DPRINT1("Failed\n"); BaseSetLastNTError(Status); return Atom; } }
/* Check if we're doing local lookup */ if (Local) { /* Do a local lookup */ Status = RtlLookupAtomInAtomTable(InternalInitAtomTable(), AtomNameString->Buffer, &Atom); } else { /* Do a global search */ if (!AtomNameString->Length) { /* This is illegal in win32 */ DPRINT1("No name given\n"); Status = STATUS_OBJECT_NAME_NOT_FOUND; } else { /* Call the global function */ Status = NtFindAtom(AtomNameString->Buffer, AtomNameString->Length, &Atom); } }
/* Check for failure */ if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
/* Check if we were non-static ANSI */ if (!(Unicode) && (AtomNameString == &UnicodeString)) { /* Free the allocated buffer */ RtlFreeUnicodeString(AtomNameString); }
/* Return the atom */ return Atom;}
ATOMWINAPIInternalDeleteAtom(BOOLEAN Local, ATOM Atom){ NTSTATUS Status;
/* Validate it */ if (Atom >= MAXINTATOM) { /* Check if it's a local delete */ if (Local) { /* Delete it locally */ Status = RtlDeleteAtomFromAtomTable(InternalInitAtomTable(), Atom); } else { /* Delete it globall */ Status = NtDeleteAtom(Atom); }
/* Check for success */ if (!NT_SUCCESS(Status)) { /* Fail */ BaseSetLastNTError(Status); return INVALID_ATOM; } }
/* Return failure */ return 0;}
UINTWINAPIInternalGetAtomName(BOOLEAN Local, BOOLEAN Unicode, ATOM Atom, LPSTR AtomName, DWORD Size){ NTSTATUS Status; DWORD RetVal = 0; ANSI_STRING AnsiString; UNICODE_STRING UnicodeString; PVOID TempBuffer = NULL; PWSTR AtomNameString; ULONG AtomInfoLength; ULONG AtomNameLength; PATOM_BASIC_INFORMATION AtomInfo;
/* Normalize the size as not to overflow */ if (!Unicode && Size > 0x7000) Size = 0x7000;
/* Make sure it's valid too */ if (!Size) { BaseSetLastNTError(STATUS_BUFFER_OVERFLOW); return 0; } if (!Atom) { BaseSetLastNTError(STATUS_INVALID_PARAMETER); return 0; }
/* Check if this is a global query */ if (Local) { /* Set the query length */ AtomNameLength = Size * sizeof(WCHAR);
/* If it's unicode, just keep the name */ if (Unicode) { AtomNameString = (PWSTR)AtomName; } else { /* Allocate memory for the ansi buffer */ TempBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, AtomNameLength); AtomNameString = TempBuffer; }
/* Query the name */ Status = RtlQueryAtomInAtomTable(InternalInitAtomTable(), Atom, NULL, NULL, AtomNameString, &AtomNameLength); } else { /* We're going to do a global query, so allocate a buffer */ AtomInfoLength = sizeof(ATOM_BASIC_INFORMATION) + (Size * sizeof(WCHAR)); AtomInfo = TempBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, AtomInfoLength);
if (!AtomInfo) { BaseSetLastNTError(STATUS_NO_MEMORY); return 0; }
/* Query the name */ Status = NtQueryInformationAtom(Atom, AtomBasicInformation, AtomInfo, AtomInfoLength, &AtomInfoLength); if (NT_SUCCESS(Status)) { /* Success. Update the length and get the name */ AtomNameLength = (ULONG)AtomInfo->NameLength; AtomNameString = AtomInfo->Name; } }
/* Check for global success */ if (NT_SUCCESS(Status)) { /* Check if it was unicode */ if (Unicode) { /* We return the length in chars */ RetVal = AtomNameLength / sizeof(WCHAR);
/* Copy the memory if this was a global query */ if (AtomNameString != (PWSTR)AtomName) { RtlMoveMemory(AtomName, AtomNameString, AtomNameLength); }
/* And null-terminate it if the buffer was too large */ if (RetVal < Size) { ((PWCHAR)AtomName)[RetVal] = UNICODE_NULL; } } else { /* First create a unicode string with our data */ UnicodeString.Buffer = AtomNameString; UnicodeString.Length = (USHORT)AtomNameLength; UnicodeString.MaximumLength = (USHORT)(UnicodeString.Length + sizeof(WCHAR));
/* Now prepare an ansi string for conversion */ AnsiString.Buffer = AtomName; AnsiString.Length = 0; AnsiString.MaximumLength = (USHORT)Size;
/* Convert it */ Status = RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE);
/* Return the length */ if (NT_SUCCESS(Status)) RetVal = AnsiString.Length; } }
/* Free the temporary buffer if we have one */ if (TempBuffer) RtlFreeHeap(RtlGetProcessHeap(), 0, TempBuffer);
/* Check for failure */ if (!NT_SUCCESS(Status)) { /* Fail */ DPRINT("Failed: %lx\n", Status); BaseSetLastNTError(Status); }
/* Return length */ return RetVal;}
/* FUNCTIONS *****************************************************************/
/* * @implemented */ATOMWINAPIGlobalAddAtomW(LPCWSTR lpString){ return InternalAddAtom(FALSE, TRUE, (LPSTR)lpString);}
/* * @implemented */ATOMWINAPIGlobalDeleteAtom(ATOM nAtom){ return InternalDeleteAtom(FALSE, nAtom);}
/* * @implemented */ATOMWINAPIGlobalFindAtomW(LPCWSTR lpString){ return InternalFindAtom(FALSE, TRUE, (LPSTR)lpString);}
/* * @implemented */UINTWINAPIGlobalGetAtomNameA(ATOM nAtom, LPSTR lpBuffer, int nSize){ return InternalGetAtomName(FALSE, FALSE, nAtom, lpBuffer, (DWORD)nSize);}
/* * @implemented */UINTWINAPIGlobalGetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize){ return InternalGetAtomName(FALSE, TRUE, nAtom, (LPSTR)lpBuffer, (DWORD)nSize);}
/* * @implemented */BOOLWINAPIInitAtomTable(DWORD nSize){ /* Normalize size */ if (nSize < 4 || nSize > 511) nSize = 37;
DPRINT("Here\n"); return NT_SUCCESS(RtlCreateAtomTable(nSize, &BaseLocalAtomTable));}
/* * @implemented */ATOMWINAPIAddAtomA(LPCSTR lpString){ return InternalAddAtom(TRUE, FALSE, lpString);}
/* * @implemented */ATOMWINAPIAddAtomW(LPCWSTR lpString){ return InternalAddAtom(TRUE, TRUE, (LPSTR)lpString);}
/* * @implemented */ATOMWINAPIDeleteAtom(ATOM nAtom){ return InternalDeleteAtom(TRUE, nAtom);}
/* * @implemented */ATOMWINAPIFindAtomA(LPCSTR lpString){ return InternalFindAtom(TRUE, FALSE, lpString);}
/* * @implemented */ATOMWINAPIFindAtomW(LPCWSTR lpString){ return InternalFindAtom(TRUE, TRUE, (LPSTR)lpString);
}
/* * @implemented */UINTWINAPIGetAtomNameA(ATOM nAtom, LPSTR lpBuffer, int nSize){ return InternalGetAtomName(TRUE, FALSE, nAtom, lpBuffer, (DWORD)nSize);}
/* * @implemented */UINTWINAPIGetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize){ return InternalGetAtomName(TRUE, TRUE, nAtom, (LPSTR)lpBuffer, (DWORD)nSize);}/* EOF */