/*********************************************************************** * GlobalGetAtomNameW (KERNEL32.@) * * Unicode version of GlobalGetAtomNameA. */ UINT WINAPI GlobalGetAtomNameW( ATOM atom, LPWSTR buffer, INT count ) { char ptr[sizeof(ATOM_BASIC_INFORMATION) + MAX_ATOM_LEN * sizeof(WCHAR)]; ATOM_BASIC_INFORMATION* abi = (ATOM_BASIC_INFORMATION*)ptr; ULONG ptr_size = sizeof(ATOM_BASIC_INFORMATION) + MAX_ATOM_LEN * sizeof(WCHAR); NTSTATUS status; UINT length = 0; if (count <= 0) { SetLastError( ERROR_MORE_DATA ); return 0; } status = NtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL ); if (status) SetLastError( RtlNtStatusToDosError( status ) ); else { length = min( abi->NameLength / sizeof(WCHAR), count); memcpy( buffer, abi->Name, length * sizeof(WCHAR) ); /* yes, the string will not be null terminated if the passed buffer * is one WCHAR too small (and it's not an error) */ if (length < abi->NameLength / sizeof(WCHAR)) { SetLastError( ERROR_MORE_DATA ); length = count; } else if (length < count) buffer[length] = '\0'; } return length; }
static NTSTATUS PhQueryAtomTableEntry( _In_ RTL_ATOM Atom, _Out_ PATOM_BASIC_INFORMATION* AtomInfo ) { NTSTATUS status; PVOID buffer; ULONG bufferSize = 0x1000; buffer = PhAllocate(bufferSize); memset(buffer, 0, bufferSize); status = NtQueryInformationAtom( Atom, AtomBasicInformation, buffer, bufferSize, &bufferSize // Not used... ); if (!NT_SUCCESS(status)) { PhFree(buffer); return status; } *AtomInfo = buffer; return status; }
static NTSTATUS PhEnumAtomTable( _Out_ PATOM_TABLE_INFORMATION* AtomTable ) { NTSTATUS status; PVOID buffer; ULONG bufferSize = 0x1000; buffer = PhAllocate(bufferSize); memset(buffer, 0, bufferSize); status = NtQueryInformationAtom( RTL_ATOM_INVALID_ATOM, AtomTableInformation, buffer, bufferSize, &bufferSize // Not used... ); if (!NT_SUCCESS(status)) { PhFree(buffer); return status; } *AtomTable = buffer; return status; }
UINT WINAPI InternalGetAtomName(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; }