Commit 70342dbc authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

kernel32: Implemented atoms query function on top of ntdll ones.

parent b7607aeb
......@@ -390,59 +390,6 @@ ATOM WINAPI FindAtomW( LPCWSTR str )
}
static UINT ATOM_GetAtomNameA( ATOM atom, LPSTR buffer, INT count, struct atom_table* table )
{
INT len;
if (count <= 0)
{
SetLastError( ERROR_MORE_DATA );
return 0;
}
if (atom < MAXINTATOM)
{
char name[8];
if (!atom)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
len = sprintf( name, "#%d", atom );
lstrcpynA( buffer, name, count );
}
else
{
WCHAR full_name[MAX_ATOM_LEN];
len = 0;
SERVER_START_REQ( get_atom_information )
{
req->atom = atom;
req->table = table;
wine_server_set_reply( req, full_name, sizeof(full_name) );
if (!wine_server_call_err( req ))
{
len = WideCharToMultiByte( CP_ACP, 0, full_name,
wine_server_reply_size(reply) / sizeof(WCHAR),
buffer, count - 1, NULL, NULL );
if (!len) len = count; /* overflow */
else buffer[len] = 0;
}
}
SERVER_END_REQ;
}
if (len && count <= len)
{
SetLastError( ERROR_MORE_DATA );
buffer[count-1] = 0;
return 0;
}
TRACE( "(%s) %x -> %s\n", table ? "local" : "global", atom, debugstr_a(buffer) );
return len;
}
/***********************************************************************
* GlobalGetAtomNameA (KERNEL32.@)
*
......@@ -457,7 +404,25 @@ UINT WINAPI GlobalGetAtomNameA(
LPSTR buffer, /* [out] Pointer to buffer for atom string */
INT count ) /* [in] Size of buffer */
{
return ATOM_GetAtomNameA( atom, buffer, count, NULL );
WCHAR tmpW[MAX_ATOM_LEN + 1];
UINT wlen, len = 0, c;
if (count <= 0) SetLastError( ERROR_MORE_DATA );
else if ((wlen = GlobalGetAtomNameW( atom, tmpW, MAX_ATOM_LEN + 1 )))
{
char tmp[MAX_ATOM_LEN + 1];
len = WideCharToMultiByte( CP_ACP, 0, tmpW, wlen, tmp, MAX_ATOM_LEN + 1, NULL, NULL );
c = min(len, count - 1);
memcpy(buffer, tmp, c);
buffer[c] = '\0';
if (len >= count)
{
len = 0;
SetLastError( ERROR_MORE_DATA );
}
}
return len;
}
......@@ -475,53 +440,24 @@ UINT WINAPI GetAtomNameA(
LPSTR buffer, /* [out] Pointer to string for atom string */
INT count) /* [in] Size of buffer */
{
return ATOM_GetAtomNameA( atom, buffer, count, get_local_table(0) );
}
WCHAR tmpW[MAX_ATOM_LEN + 1];
UINT wlen, len = 0, c;
static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, struct atom_table* table )
{
INT len;
if (count <= 0)
{
SetLastError( ERROR_MORE_DATA );
return 0;
}
if (atom < MAXINTATOM)
if (count <= 0) SetLastError( ERROR_MORE_DATA );
else if ((wlen = GetAtomNameW( atom, tmpW, MAX_ATOM_LEN + 1 )))
{
char name[8];
if (!atom)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
sprintf( name, "#%d", atom );
len = MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, count );
if (!len) buffer[count-1] = 0; /* overflow */
}
else
{
WCHAR full_name[MAX_ATOM_LEN];
char tmp[MAX_ATOM_LEN + 1];
len = 0;
SERVER_START_REQ( get_atom_information )
len = WideCharToMultiByte( CP_ACP, 0, tmpW, wlen, tmp, MAX_ATOM_LEN + 1, NULL, NULL );
c = min(len, count - 1);
memcpy(buffer, tmp, c);
buffer[c] = '\0';
if (len >= count)
{
req->atom = atom;
req->table = table;
wine_server_set_reply( req, full_name, sizeof(full_name) );
if (!wine_server_call_err( req ))
{
len = wine_server_reply_size(reply) / sizeof(WCHAR);
if (count > len) count = len + 1;
memcpy( buffer, full_name, (count-1) * sizeof(WCHAR) );
buffer[count-1] = 0;
}
len = c;
SetLastError( ERROR_MORE_DATA );
}
SERVER_END_REQ;
if (!len) return 0;
}
TRACE( "(%s) %x -> %s\n", table ? "local" : "global", atom, debugstr_w(buffer) );
return len;
}
......@@ -533,7 +469,31 @@ static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, struct atom_
*/
UINT WINAPI GlobalGetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
{
return ATOM_GetAtomNameW( atom, buffer, count, NULL);
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) );
if (length < abi->NameLength / sizeof(WCHAR))
{
SetLastError( ERROR_MORE_DATA );
length = count;
}
else buffer[length] = '\0';
}
return length;
}
......@@ -544,5 +504,28 @@ UINT WINAPI GlobalGetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
*/
UINT WINAPI GetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
{
return ATOM_GetAtomNameW( atom, buffer, count, get_local_table(0) );
NTSTATUS status;
RTL_ATOM_TABLE table;
DWORD length;
WCHAR tmp[MAX_ATOM_LEN + 1];
if (count <= 0)
{
SetLastError( ERROR_MORE_DATA );
return 0;
}
if (!(table = get_local_table( 0 ))) return 0;
length = sizeof(tmp);
status = RtlQueryAtomInAtomTable( table, atom, NULL, NULL, tmp, &length );
if (status)
{
SetLastError( RtlNtStatusToDosError( status ) );
return 0;
}
length = min(length, (count - 1) * sizeof(WCHAR));
if (length) memcpy(buffer, tmp, length);
else SetLastError( ERROR_INSUFFICIENT_BUFFER );
length /= sizeof(WCHAR);
buffer[length] = '\0';
return length;
}
......@@ -262,10 +262,7 @@ static void test_get_atom_name(void)
{
WCHAR res[20];
if (len < 7) /* FIXME: temporary before we fix it */
ok( (len > 1) && (len < 7), "bad length %d\n", len );
else
todo_wine ok( (len > 1) && (len < 7), "bad length %d\n", len );
ok( (len > 1) && (len < 7), "bad length %d\n", len );
print_integral( res, i );
memset( res + lstrlenW(res) + 1, 'a', 10 * sizeof(WCHAR));
ok( !memcmp( res, outW, 10 * sizeof(WCHAR) ), "bad buffer contents for %d\n", i );
......@@ -277,7 +274,7 @@ static void test_get_atom_name(void)
len = GlobalGetAtomNameW( (ATOM)i, outW, 1);
if (i)
{
todo_wine ok(len == 1, "succeed (got %u instead of 1)\n", len);
ok(len == 1, "succeed (got %u instead of 1)\n", len);
ok(outW[1] == DOUBLE('.'), "buffer overwrite\n");
}
else ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "0 badly handled\n");
......@@ -295,13 +292,10 @@ static void test_get_atom_name(void)
ok(outW[255] == '\0', "wrong end of string\n");
memset(outW, '.', sizeof(outW));
len = GlobalGetAtomNameW(atom, outW, 10);
todo_wine ok(len == 10, "succeeded\n");
ok(len == 10, "succeeded\n");
for (i = 0; i < 10; i++)
{
if (i < 9) /* FIXME: temporary */
ok(outW[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, outW[i], "abcdefghij"[i % 10]);
else
todo_wine ok(outW[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, outW[i], "abcdefghij"[i % 10]);
ok(outW[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, outW[i], "abcdefghij"[i % 10]);
}
ok(outW[10] == DOUBLE('.'), "wrote after end of buf\n");
do_initW(inW, "abcdefghij", 256);
......@@ -488,7 +482,7 @@ static void test_local_get_atom_name(void)
ok(out[255] == '\0', "wrong end of string\n");
memset(out, '.', sizeof(out));
len = GetAtomNameA(atom, out, 10);
todo_wine ok(len == 9, "succeeded %d\n", len);
ok(len == 9, "succeeded %d\n", len);
for (i = 0; i < 9; i++)
{
ok(out[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, out[i], "abcdefghij"[i % 10]);
......@@ -516,10 +510,7 @@ static void test_local_get_atom_name(void)
{
WCHAR res[20];
if (len < 7) /* FIXME: temporary before we fix it */
ok( (len > 1) && (len < 7), "bad length %d\n", len );
else
todo_wine ok( (len > 1) && (len < 7), "bad length %d\n", len );
ok( (len > 1) && (len < 7), "bad length %d\n", len );
print_integral( res, i );
memset( res + lstrlenW(res) + 1, 'a', 10 * sizeof(WCHAR));
ok( !memcmp( res, outW, 10 * sizeof(WCHAR) ), "bad buffer contents for %d\n", i );
......@@ -547,7 +538,7 @@ static void test_local_get_atom_name(void)
ok(outW[255] == '\0', "wrong end of string\n");
memset(outW, '.', sizeof(outW));
len = GetAtomNameW(atom, outW, 10);
todo_wine ok(len == 9, "succeeded %d\n", len);
ok(len == 9, "succeeded %d\n", len);
for (i = 0; i < 9; i++)
{
ok(outW[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, outW[i], "abcdefghij"[i % 10]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment