/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
RtlCreateAtomTable(IN ULONG TableSize,
IN OUT PRTL_ATOM_TABLE *AtomTable)
{
return STATUS_SUCCESS;
}
+ /* Use default if size was incorrect */
+ if (TableSize <= 1) TableSize = 37;
+
/* allocate atom table */
Table = RtlpAllocAtomTable(((TableSize - 1) * sizeof(PRTL_ATOM_TABLE_ENTRY)) +
sizeof(RTL_ATOM_TABLE));
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
RtlDestroyAtomTable(IN PRTL_ATOM_TABLE AtomTable)
{
PRTL_ATOM_TABLE_ENTRY *CurrentBucket, *LastBucket;
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
RtlEmptyAtomTable(PRTL_ATOM_TABLE AtomTable,
BOOLEAN DeletePinned)
{
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
RtlAddAtomToAtomTable(IN PRTL_ATOM_TABLE AtomTable,
IN PWSTR AtomName,
OUT PRTL_ATOM Atom)
if (HashLink != NULL)
{
ULONG AtomNameLen = wcslen(AtomName);
+
+ if (AtomNameLen > RTL_MAXIMUM_ATOM_LENGTH)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ goto end;
+ }
Entry = RtlpAllocAtomTableEntry(sizeof(RTL_ATOM_TABLE_ENTRY) -
sizeof(Entry->Name) +
Status = STATUS_OBJECT_NAME_INVALID;
}
}
-
+end:
RtlpUnlockAtomTable(AtomTable);
return Status;
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
RtlDeleteAtomFromAtomTable(IN PRTL_ATOM_TABLE AtomTable,
IN RTL_ATOM Atom)
{
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
RtlLookupAtomInAtomTable(IN PRTL_ATOM_TABLE AtomTable,
IN PWSTR AtomName,
OUT PRTL_ATOM Atom)
}
RtlpLockAtomTable(AtomTable);
-
Status = STATUS_OBJECT_NAME_NOT_FOUND;
/* string atom */
Entry = RtlpHashAtomName(AtomTable,
AtomName,
&HashLink);
-
if (Entry != NULL)
{
Status = STATUS_SUCCESS;
FoundAtom = (RTL_ATOM)Entry->Atom;
}
-
RtlpUnlockAtomTable(AtomTable);
-
if (NT_SUCCESS(Status) && Atom != NULL)
{
*Atom = FoundAtom;
}
-
return Status;
}
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
RtlPinAtomInAtomTable(IN PRTL_ATOM_TABLE AtomTable,
IN RTL_ATOM Atom)
{
/*
* @implemented
+ *
+ * This API is really messed up with regards to NameLength. If you pass in a
+ * valid buffer for AtomName, NameLength should be the size of the buffer
+ * (in bytes, not characters). So if you expect the string to be 6 char long,
+ * you need to allocate a buffer of 7 WCHARs and pass 14 for NameLength.
+ * The AtomName returned is always null terminated. If the NameLength you pass
+ * is smaller than 4 (4 would leave room for 1 character) the function will
+ * return with status STATUS_BUFFER_TOO_SMALL. If you pass more than 4, the
+ * return status will be STATUS_SUCCESS, even if the buffer is not large enough
+ * to hold the complete string. In that case, the string is silently truncated
+ * and made to fit in the provided buffer. On return NameLength is set to the
+ * number of bytes (but EXCLUDING the bytes for the null terminator) copied.
+ * So, if the string is 6 char long, you pass a buffer of 10 bytes, on return
+ * NameLength will be set to 8.
+ * If you pass in a NULL value for AtomName, the length of the string in bytes
+ * (again EXCLUDING the null terminator) is returned in NameLength, at least
+ * on Win2k, XP and ReactOS. NT4 will return 0 in that case.
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
RtlQueryAtomInAtomTable(PRTL_ATOM_TABLE AtomTable,
RTL_ATOM Atom,
PULONG RefCount,
PULONG NameLength)
{
ULONG Length;
+ BOOL Unlock = FALSE;
+
+ union
+ {
+ /* A RTL_ATOM_TABLE_ENTRY has a "WCHAR Name[1]" entry at the end.
+ * Make sure we reserve enough room to facilitate a 12 character name */
+ RTL_ATOM_TABLE_ENTRY AtomTableEntry;
+ WCHAR StringBuffer[sizeof(RTL_ATOM_TABLE_ENTRY) / sizeof(WCHAR) + 12];
+ } NumberEntry;
PRTL_ATOM_TABLE_ENTRY Entry;
NTSTATUS Status = STATUS_SUCCESS;
if (Atom < 0xC000)
{
- if (RefCount != NULL)
- {
- *RefCount = 1;
- }
-
- if (PinCount != NULL)
- {
- *PinCount = 1;
- }
-
- if ((AtomName != NULL) && (NameLength != NULL) && (NameLength > 0))
- {
- WCHAR NameString[12];
-
- Length = swprintf(NameString, L"#%lu", (ULONG)Atom) * sizeof(WCHAR);
-
- if (*NameLength < Length + sizeof(WCHAR))
- {
- *NameLength = Length;
- Status = STATUS_BUFFER_TOO_SMALL;
- }
- else
- {
- RtlCopyMemory(AtomName,
- NameString,
- Length);
- AtomName[Length / sizeof(WCHAR)] = L'\0';
- *NameLength = Length;
- }
- }
- else if (NameLength != NULL)
- {
- *NameLength = (Entry->NameLength + 1) * sizeof(WCHAR);
- }
-
- return Status;
+ /* Synthesize an entry */
+ NumberEntry.AtomTableEntry.Atom = Atom;
+ NumberEntry.AtomTableEntry.NameLength = swprintf(NumberEntry.AtomTableEntry.Name,
+ L"#%lu",
+ (ULONG)Atom);
+ NumberEntry.AtomTableEntry.ReferenceCount = 1;
+ NumberEntry.AtomTableEntry.Flags = RTL_ATOM_IS_PINNED;
+ Entry = &NumberEntry.AtomTableEntry;
}
+ else
+ {
+ RtlpLockAtomTable(AtomTable);
+ Unlock = TRUE;
- RtlpLockAtomTable(AtomTable);
-
- Entry = RtlpGetAtomEntry(AtomTable,
- (ULONG)((USHORT)Atom - 0xC000));
+ Entry = RtlpGetAtomEntry(AtomTable,
+ (ULONG)((USHORT)Atom - 0xC000));
+ }
if (Entry != NULL && Entry->Atom == (USHORT)Atom)
{
*PinCount = ((Entry->Flags & RTL_ATOM_IS_PINNED) != 0);
}
- if ((AtomName != NULL) && (NameLength != NULL))
+ if (NULL != NameLength)
{
Length = Entry->NameLength * sizeof(WCHAR);
-
- if (*NameLength < Length + sizeof(WCHAR))
+ if (NULL != AtomName)
{
- *NameLength = Length;
- Status = STATUS_BUFFER_TOO_SMALL;
+ if (*NameLength < Length + sizeof(WCHAR))
+ {
+ if (*NameLength < 4)
+ {
+ *NameLength = Length;
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ Length = *NameLength - sizeof(WCHAR);
+ }
+ }
+ if (NT_SUCCESS(Status))
+ {
+ RtlCopyMemory(AtomName,
+ Entry->Name,
+ Length);
+ AtomName[Length / sizeof(WCHAR)] = L'\0';
+ *NameLength = Length;
+ }
}
else
{
- RtlCopyMemory(AtomName,
- Entry->Name,
- Length);
- AtomName[Length / sizeof(WCHAR)] = L'\0';
*NameLength = Length;
}
}
- else if (NameLength != NULL)
+ else if (NULL != AtomName)
{
- *NameLength = (Entry->NameLength + 1) * sizeof(WCHAR);
+ Status = STATUS_INVALID_PARAMETER;
}
}
else
Status = STATUS_INVALID_HANDLE;
}
- RtlpUnlockAtomTable(AtomTable);
+ if (Unlock) RtlpUnlockAtomTable(AtomTable);
return Status;
}
/*
* @private - only used by NtQueryInformationAtom
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
RtlQueryAtomListInAtomTable(IN PRTL_ATOM_TABLE AtomTable,
IN ULONG MaxAtomCount,
OUT ULONG *AtomCount,