Author: fireball
Date: Sat Jul 25 11:56:27 2009
New Revision: 42201
URL:
http://svn.reactos.org/svn/reactos?rev=42201&view=rev
Log:
- Hack atom support in kernel32 to call user server for global atom information. Ugly,
crappy, will be deprecated once the move to proper atoms support happens. But for now it
provides consistency with win32k/user32.
Modified:
branches/arwinss/reactos/dll/win32/kernel32/kernel32.rbuild
branches/arwinss/reactos/dll/win32/kernel32/misc/atom.c
Modified: branches/arwinss/reactos/dll/win32/kernel32/kernel32.rbuild
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/kerne…
==============================================================================
--- branches/arwinss/reactos/dll/win32/kernel32/kernel32.rbuild [iso-8859-1] (original)
+++ branches/arwinss/reactos/dll/win32/kernel32/kernel32.rbuild [iso-8859-1] Sat Jul 25
11:56:27 2009
@@ -146,6 +146,7 @@
<library>kernel32_base</library>
<library>wine</library>
<library>pseh</library>
+ <library>win32ksys</library>
<file>kernel32.rc</file>
Modified: branches/arwinss/reactos/dll/win32/kernel32/misc/atom.c
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/kerne…
==============================================================================
--- branches/arwinss/reactos/dll/win32/kernel32/misc/atom.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/dll/win32/kernel32/misc/atom.c [iso-8859-1] Sat Jul 25
11:56:27 2009
@@ -8,6 +8,7 @@
/* INCLUDES ******************************************************************/
#include <k32.h>
+#include "wine/server.h"
#define NDEBUG
#include <debug.h>
@@ -15,6 +16,206 @@
/* GLOBALS *******************************************************************/
PRTL_ATOM_TABLE BaseLocalAtomTable = NULL;
+
+/* DEAR GOD, FORGIVE ME ******************************************************/
+
+#define MAX_ATOM_LEN 255
+
+/******************************************************************
+ * is_integral_atom
+ * Returns STATUS_SUCCESS if integral atom and 'pAtom' is filled
+ * STATUS_INVALID_PARAMETER if 'atomstr' is too long
+ * STATUS_MORE_ENTRIES otherwise
+ */
+static NTSTATUS is_integral_atom( LPCWSTR atomstr, size_t len, RTL_ATOM* pAtom )
+{
+ RTL_ATOM atom;
+
+ if (HIWORD( atomstr ))
+ {
+ const WCHAR* ptr = atomstr;
+ if (!len) return STATUS_OBJECT_NAME_INVALID;
+
+ if (*ptr++ == '#')
+ {
+ atom = 0;
+ while (ptr < atomstr + len && *ptr >= '0' &&
*ptr <= '9')
+ {
+ atom = atom * 10 + *ptr++ - '0';
+ }
+ if (ptr > atomstr + 1 && ptr == atomstr + len) goto done;
+ }
+ if (len > MAX_ATOM_LEN) return STATUS_INVALID_PARAMETER;
+ return STATUS_MORE_ENTRIES;
+ }
+ else atom = LOWORD( atomstr );
+done:
+ if (!atom || atom >= MAXINTATOM) return STATUS_INVALID_PARAMETER;
+ *pAtom = atom;
+ return STATUS_SUCCESS;
+}
+
+/******************************************************************
+ * integral_atom_name (internal)
+ *
+ * Helper for fetching integral (local/global) atoms names.
+ */
+static ULONG integral_atom_name(WCHAR* buffer, ULONG len, RTL_ATOM atom)
+{
+ static const WCHAR fmt[] = {'#','%','u',0};
+ WCHAR tmp[16];
+ int ret;
+
+ ret = swprintf( tmp, fmt, atom );
+ if (!len) return ret * sizeof(WCHAR);
+ if (len <= ret) ret = len - 1;
+ memcpy( buffer, tmp, ret * sizeof(WCHAR) );
+ buffer[ret] = 0;
+ return ret * sizeof(WCHAR);
+}
+
+/*************************************************
+ * Global handle table management
+ *************************************************/
+
+/******************************************************************
+ * NtAddAtom (NTDLL.@)
+ */
+NTSTATUS WINAPI WineNtAddAtom( const WCHAR* name, ULONG length, RTL_ATOM* atom )
+{
+ NTSTATUS status;
+
+ status = is_integral_atom( name, length / sizeof(WCHAR), atom );
+ if (status == STATUS_MORE_ENTRIES)
+ {
+ SERVER_START_REQ( add_atom )
+ {
+ wine_server_add_data( req, name, length );
+ req->table = 0;
+ status = wine_server_call( req );
+ *atom = reply->atom;
+ }
+ SERVER_END_REQ;
+ }
+ //TRACE( "%s -> %x\n",
+ // debugstr_wn(name, length/sizeof(WCHAR)), status == STATUS_SUCCESS ? *atom :
0 );
+ return status;
+}
+
+/******************************************************************
+ * NtDeleteAtom (NTDLL.@)
+ */
+NTSTATUS WINAPI WineNtDeleteAtom(RTL_ATOM atom)
+{
+ NTSTATUS status;
+
+ SERVER_START_REQ( delete_atom )
+ {
+ req->atom = atom;
+ req->table = 0;
+ status = wine_server_call( req );
+ }
+ SERVER_END_REQ;
+ return status;
+}
+
+/******************************************************************
+ * NtFindAtom (NTDLL.@)
+ */
+NTSTATUS WINAPI WineNtFindAtom( const WCHAR* name, ULONG length, RTL_ATOM* atom )
+{
+ NTSTATUS status;
+
+ status = is_integral_atom( name, length / sizeof(WCHAR), atom );
+ if (status == STATUS_MORE_ENTRIES)
+ {
+ SERVER_START_REQ( find_atom )
+ {
+ wine_server_add_data( req, name, length );
+ req->table = 0;
+ status = wine_server_call( req );
+ *atom = reply->atom;
+ }
+ SERVER_END_REQ;
+ }
+ //TRACE( "%s -> %x\n",
+ // debugstr_wn(name, length/sizeof(WCHAR)), status == STATUS_SUCCESS ? *atom :
0 );
+ return status;
+}
+
+/******************************************************************
+ * NtQueryInformationAtom (NTDLL.@)
+ */
+NTSTATUS WINAPI WineNtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS class,
+ PVOID ptr, ULONG size, PULONG psize )
+{
+ NTSTATUS status;
+
+ switch (class)
+ {
+ case AtomBasicInformation:
+ {
+ ULONG name_len;
+ ATOM_BASIC_INFORMATION* abi = ptr;
+
+ if (size < sizeof(ATOM_BASIC_INFORMATION))
+ return STATUS_INVALID_PARAMETER;
+ name_len = size - sizeof(ATOM_BASIC_INFORMATION);
+
+ if (atom < MAXINTATOM)
+ {
+ if (atom)
+ {
+ abi->NameLength = integral_atom_name( abi->Name, name_len, atom
);
+ status = (name_len) ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL;
+ //abi->ReferenceCount = 1;
+ //abi->Pinned = 1;
+ }
+ else status = STATUS_INVALID_PARAMETER;
+ }
+ else
+ {
+ SERVER_START_REQ( get_atom_information )
+ {
+ req->atom = atom;
+ req->table = 0;
+ if (name_len) wine_server_set_reply( req, abi->Name, name_len );
+ status = wine_server_call( req );
+ if (status == STATUS_SUCCESS)
+ {
+ name_len = wine_server_reply_size( reply );
+ if (name_len)
+ {
+ abi->NameLength = name_len;
+ abi->Name[name_len / sizeof(WCHAR)] = '\0';
+ }
+ else
+ {
+ name_len = reply->total;
+ abi->NameLength = name_len;
+ status = STATUS_BUFFER_TOO_SMALL;
+ }
+ //abi->ReferenceCount = reply->count;
+ //abi->Pinned = reply->pinned;
+ }
+ else name_len = 0;
+ }
+ SERVER_END_REQ;
+ }
+ //TRACE( "%x -> %s (%u)\n",
+ // atom, debugstr_wn(abi->Name, abi->NameLength /
sizeof(WCHAR)),
+ // status );
+ if (psize)
+ *psize = sizeof(ATOM_BASIC_INFORMATION) + name_len;
+ }
+ break;
+ default:
+ DPRINT1( "Unsupported class %u\n", class );
+ status = STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+ return status;
+}
/* FUNCTIONS *****************************************************************/
@@ -38,6 +239,11 @@
UNICODE_STRING UnicodeString;
PUNICODE_STRING AtomNameString;
ATOM Atom = INVALID_ATOM;
+
+ if (Unicode)
+ DPRINT("InternalAddAtom local %d name %S\n", Local, AtomName);
+ else
+ DPRINT("InternalAddAtom local %d name %s\n", Local, AtomName);
/* Check if it's an integer atom */
if ((ULONG_PTR)AtomName <= 0xFFFF)
@@ -109,7 +315,7 @@
else
{
/* Do a global add */
- Status = NtAddAtom(AtomNameString->Buffer,
+ Status = WineNtAddAtom(AtomNameString->Buffer,
AtomNameString->Length,
&Atom);
}
@@ -139,6 +345,11 @@
UNICODE_STRING UnicodeString;
PUNICODE_STRING AtomNameString;
ATOM Atom = INVALID_ATOM;
+
+ if (Unicode)
+ DPRINT("InternalFindAtom local %d name %S\n", Local, AtomName);
+ else
+ DPRINT("InternalFindAtom local %d name %s\n", Local, AtomName);
/* Check if it's an integer atom */
if ((ULONG_PTR)AtomName <= 0xFFFF)
@@ -220,7 +431,7 @@
else
{
/* Call the global function */
- Status = NtFindAtom(AtomNameString->Buffer,
+ Status = WineNtFindAtom(AtomNameString->Buffer,
AtomNameString->Length,
&Atom);
}
@@ -247,6 +458,8 @@
{
NTSTATUS Status;
+ DPRINT("InternalDeleteAtom local %d atom %x\n", Local, Atom);
+
/* Validate it */
if (Atom >= MAXINTATOM)
{
@@ -259,7 +472,7 @@
else
{
/* Delete it globall */
- Status = NtDeleteAtom(Atom);
+ Status = WineNtDeleteAtom(Atom);
}
/* Check for success */
@@ -293,6 +506,8 @@
ULONG AtomNameLength;
PATOM_BASIC_INFORMATION AtomInfo;
+ DPRINT("InternalGetAtomName local %d atom %x size %x\n", Local, Atom,
Size);
+
/* Normalize the size as not to overflow */
if (!Unicode && Size > 0x7000) Size = 0x7000;
@@ -347,7 +562,7 @@
}
/* Query the name */
- Status = NtQueryInformationAtom(Atom,
+ Status = WineNtQueryInformationAtom(Atom,
AtomBasicInformation,
AtomInfo,
AtomInfoLength,
@@ -415,6 +630,11 @@
SetLastErrorByStatus(Status);
}
+ if (Unicode)
+ DPRINT("InternalGetAtomName name %S\n", AtomName);
+ else
+ DPRINT("InternalGetAtomName name %s\n", AtomName);
+
/* Return length */
return RetVal;
}