sync ntdll tests to 0.9.14

svn path=/trunk/; revision=22056
This commit is contained in:
Steven Edwards 2006-05-26 17:54:55 +00:00
parent 6dcf87a3d9
commit 93ee7df2aa
18 changed files with 1500 additions and 596 deletions

View file

@ -14,7 +14,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES
* We use function pointers here as there is no import library for NTDLL on
@ -35,7 +35,6 @@
#include "winreg.h"
#include "winnls.h"
#include "wine/test.h"
#include "wine/unicode.h"
#include "winternl.h"
#ifndef __WINE_WINTERNL_H
@ -112,14 +111,14 @@ static DWORD RtlAtomTestThread(LPVOID Table)
ok(!res, "Failed with longenough buffer, retval: %lx\n", res);
ok(RefCount == 1, "Refcount was not 1 but %lx\n", RefCount);
ok(PinCount == 1, "Pincount was not 1 but %lx\n", PinCount);
ok(!strcmpW(Name, testAtom2), "We found wrong atom!!\n");
ok((strlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
ok(!lstrcmpW(Name, testAtom2), "We found wrong atom!!\n");
ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
Len = 64;
res = pRtlQueryAtomInAtomTable(AtomTable, Atom, NULL, NULL, Name, &Len);
ok(!res, "RtlQueryAtomInAtomTable with optional args invalid failed, retval: %lx\n", res);
ok(!strcmpW(Name, testAtom2), "Found Wrong atom!\n");
ok((strlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
ok(!lstrcmpW(Name, testAtom2), "Found Wrong atom!\n");
ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
res = pRtlPinAtomInAtomTable(AtomTable, Atom);
ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res);
@ -184,8 +183,8 @@ static void test_NtAtom(void)
ok(!res, "Unable to query atom in atom table, retval: %lx\n", res);
ok(RefCount == 1, "RefCount is not 1 but %lx\n", RefCount);
ok(PinCount == 1, "PinCount is not 1 but %lx\n", PinCount);
ok(!strcmpW(Name, testAtom2), "We found wrong atom\n");
ok((strlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
ok(!lstrcmpW(Name, testAtom2), "We found wrong atom\n");
ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
res = pRtlEmptyAtomTable(AtomTable, FALSE);
ok(!res, "Unable to empty atom table, retval %lx\n", res);
@ -195,8 +194,8 @@ static void test_NtAtom(void)
ok(!res, "It seems RtlEmptyAtomTable deleted our pinned atom eaven though we asked it not to, retval: %lx\n", res);
ok(RefCount == 1, "RefCount is not 1 but %lx\n", RefCount);
ok(PinCount == 1, "PinCount is not 1 but %lx\n", PinCount);
ok(!strcmpW(Name, testAtom2), "We found wrong atom\n");
ok((strlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
ok(!lstrcmpW(Name, testAtom2), "We found wrong atom\n");
ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
Len = 8;
Name[0] = Name[1] = Name[2] = Name[3] = Name[4] = 0x55AA;
@ -267,7 +266,7 @@ static void test_NtAtom(void)
Len = 0;
res = pRtlQueryAtomInAtomTable(AtomTable, Atom1, NULL, NULL, Name, &Len);
ok(res == STATUS_BUFFER_TOO_SMALL, "Got wrong retval, retval: %lx\n", res);
ok((strlenW(testAtom1) * sizeof(WCHAR)) == Len, "Got wrong length %lx\n", Len);
ok((lstrlenW(testAtom1) * sizeof(WCHAR)) == Len, "Got wrong length %lx\n", Len);
res = pRtlPinAtomInAtomTable(AtomTable, Atom1);
ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res);
@ -360,8 +359,8 @@ static void test_NtIntAtom(void)
ok(!res, "Unable to query atom in atom table, retval: %lx\n", res);
ok(PinCount == 1, "Expected pincount 1 but got %lx\n", PinCount);
ok(RefCount == 1, "Expected refcount 1 but got %lx\n", RefCount);
ok(!strcmpW(testAtomOTT, Name), "Got wrong atom name\n");
ok((strlenW(testAtomOTT) * sizeof(WCHAR)) == Len, "Got wrong len %ld\n", Len);
ok(!lstrcmpW(testAtomOTT, Name), "Got wrong atom name\n");
ok((lstrlenW(testAtomOTT) * sizeof(WCHAR)) == Len, "Got wrong len %ld\n", Len);
res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
ok(!res, "Unable to pin int atom, retval: %lx\n", res);

View file

@ -0,0 +1,332 @@
/*
* File change notification tests
*
* Copyright 2006 Mike McCormack for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <ntstatus.h>
#define WIN32_NO_STATUS
#include <windows.h>
#include <winnt.h>
#include <winternl.h>
#include <winerror.h>
#include <stdio.h>
#include "wine/test.h"
typedef NTSTATUS (WINAPI *fnNtNotifyChangeDirectoryFile)(
HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,
PIO_STATUS_BLOCK,PVOID,ULONG,ULONG,BOOLEAN);
fnNtNotifyChangeDirectoryFile pNtNotifyChangeDirectoryFile;
typedef NTSTATUS (WINAPI *fnNtCancelIoFile)(HANDLE,PIO_STATUS_BLOCK);
fnNtCancelIoFile pNtCancelIoFile;
static void test_ntncdf(void)
{
NTSTATUS r;
HANDLE hdir, hEvent;
char buffer[0x1000];
DWORD fflags, filter = 0;
IO_STATUS_BLOCK iosb;
WCHAR path[MAX_PATH], subdir[MAX_PATH];
static const WCHAR szBoo[] = { '\\','b','o','o',0 };
static const WCHAR szHoo[] = { '\\','h','o','o',0 };
PFILE_NOTIFY_INFORMATION pfni;
r = GetTempPathW( MAX_PATH, path );
ok( r != 0, "temp path failed\n");
if (!r)
return;
lstrcatW( path, szBoo );
lstrcpyW( subdir, path );
lstrcatW( subdir, szHoo );
RemoveDirectoryW( subdir );
RemoveDirectoryW( path );
r = CreateDirectoryW(path, NULL);
ok( r == TRUE, "failed to create directory\n");
r = pNtNotifyChangeDirectoryFile(NULL,NULL,NULL,NULL,NULL,NULL,0,0,0);
ok(r==STATUS_ACCESS_VIOLATION, "should return access violation\n");
fflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED;
hdir = CreateFileW(path, GENERIC_READ|SYNCHRONIZE, FILE_SHARE_READ, NULL,
OPEN_EXISTING, fflags, NULL);
ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
hEvent = CreateEvent( NULL, 0, 0, NULL );
r = pNtNotifyChangeDirectoryFile(hdir,NULL,NULL,NULL,&iosb,NULL,0,0,0);
ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,NULL,0,0,0);
ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
filter = FILE_NOTIFY_CHANGE_FILE_NAME;
filter |= FILE_NOTIFY_CHANGE_DIR_NAME;
filter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
filter |= FILE_NOTIFY_CHANGE_SIZE;
filter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
filter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
filter |= FILE_NOTIFY_CHANGE_CREATION;
filter |= FILE_NOTIFY_CHANGE_SECURITY;
U(iosb).Status = 1;
iosb.Information = 1;
r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,-1,0);
ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
ok( U(iosb).Status == 1, "information wrong\n");
ok( iosb.Information == 1, "information wrong\n");
U(iosb).Status = 1;
iosb.Information = 0;
r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
ok(r==STATUS_PENDING, "should return status pending\n");
r = WaitForSingleObject( hEvent, 0 );
ok( r == STATUS_TIMEOUT, "should timeout\n" );
r = WaitForSingleObject( hdir, 0 );
ok( r == STATUS_TIMEOUT, "should timeout\n" );
r = CreateDirectoryW( subdir, NULL );
ok( r == TRUE, "failed to create directory\n");
r = WaitForSingleObject( hdir, 0 );
ok( r == STATUS_TIMEOUT, "should timeout\n" );
r = WaitForSingleObject( hEvent, 0 );
ok( r == WAIT_OBJECT_0, "event should be ready\n" );
ok( U(iosb).Status == STATUS_SUCCESS, "information wrong\n");
ok( iosb.Information == 0x12, "information wrong\n");
pfni = (PFILE_NOTIFY_INFORMATION) buffer;
ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
ok( pfni->Action == FILE_ACTION_ADDED, "action wrong\n" );
ok( pfni->FileNameLength == 6, "len wrong\n" );
ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,0,0);
ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,0,0);
ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
filter = FILE_NOTIFY_CHANGE_SIZE;
U(iosb).Status = 1;
iosb.Information = 1;
r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,NULL,0,filter,0);
ok(r==STATUS_PENDING, "should status pending\n");
ok( U(iosb).Status == 1, "information wrong\n");
ok( iosb.Information == 1, "information wrong\n");
r = WaitForSingleObject( hdir, 0 );
ok( r == STATUS_TIMEOUT, "should timeout\n" );
r = RemoveDirectoryW( subdir );
ok( r == TRUE, "failed to remove directory\n");
r = WaitForSingleObject( hdir, 100 );
ok( r == WAIT_OBJECT_0, "should be ready\n" );
r = WaitForSingleObject( hdir, 100 );
ok( r == WAIT_OBJECT_0, "should be ready\n" );
ok( U(iosb).Status == STATUS_NOTIFY_ENUM_DIR, "information wrong\n");
ok( iosb.Information == 0, "information wrong\n");
CloseHandle(hdir);
CloseHandle(hEvent);
r = RemoveDirectoryW( path );
ok( r == TRUE, "failed to remove directory\n");
}
static void test_ntncdf_async(void)
{
NTSTATUS r;
HANDLE hdir, hEvent;
char buffer[0x1000];
DWORD fflags, filter = 0;
IO_STATUS_BLOCK iosb, iosb2;
WCHAR path[MAX_PATH], subdir[MAX_PATH];
static const WCHAR szBoo[] = { '\\','b','o','o',0 };
static const WCHAR szHoo[] = { '\\','h','o','o',0 };
PFILE_NOTIFY_INFORMATION pfni;
r = GetTempPathW( MAX_PATH, path );
ok( r != 0, "temp path failed\n");
if (!r)
return;
lstrcatW( path, szBoo );
lstrcpyW( subdir, path );
lstrcatW( subdir, szHoo );
RemoveDirectoryW( subdir );
RemoveDirectoryW( path );
r = CreateDirectoryW(path, NULL);
ok( r == TRUE, "failed to create directory\n");
r = pNtNotifyChangeDirectoryFile(NULL,NULL,NULL,NULL,NULL,NULL,0,0,0);
ok(r==STATUS_ACCESS_VIOLATION, "should return access violation\n");
fflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED;
hdir = CreateFileW(path, GENERIC_READ|SYNCHRONIZE, FILE_SHARE_READ, NULL,
OPEN_EXISTING, fflags, NULL);
ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
hEvent = CreateEvent( NULL, 0, 0, NULL );
filter = FILE_NOTIFY_CHANGE_FILE_NAME;
filter |= FILE_NOTIFY_CHANGE_DIR_NAME;
filter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
filter |= FILE_NOTIFY_CHANGE_SIZE;
filter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
filter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
filter |= FILE_NOTIFY_CHANGE_CREATION;
filter |= FILE_NOTIFY_CHANGE_SECURITY;
U(iosb).Status = 0x01234567;
iosb.Information = 0x12345678;
r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
ok(r==STATUS_PENDING, "should status pending\n");
ok(U(iosb).Status == 0x01234567, "status set too soon\n");
ok(iosb.Information == 0x12345678, "info set too soon\n");
r = CreateDirectoryW( subdir, NULL );
ok( r == TRUE, "failed to create directory\n");
r = WaitForSingleObject( hdir, 100 );
ok( r == WAIT_OBJECT_0, "should be ready\n" );
ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n");
ok(iosb.Information == 0x12, "info not set\n");
pfni = (PFILE_NOTIFY_INFORMATION) buffer;
ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
ok( pfni->Action == FILE_ACTION_ADDED, "action wrong\n" );
ok( pfni->FileNameLength == 6, "len wrong\n" );
ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
ok(r==STATUS_PENDING, "should status pending\n");
r = RemoveDirectoryW( subdir );
ok( r == TRUE, "failed to remove directory\n");
r = WaitForSingleObject( hdir, 0 );
ok( r == WAIT_OBJECT_0, "should be ready\n" );
ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n");
ok(iosb.Information == 0x12, "info not set\n");
ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
ok( pfni->Action == FILE_ACTION_REMOVED, "action wrong\n" );
ok( pfni->FileNameLength == 6, "len wrong\n" );
ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
/* check APCs */
U(iosb).Status = 0;
iosb.Information = 0;
r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,NULL,0,filter,0);
ok(r==STATUS_PENDING, "should status pending\n");
r = CreateDirectoryW( subdir, NULL );
ok( r == TRUE, "failed to create directory\n");
r = WaitForSingleObject( hdir, 0 );
ok( r == WAIT_OBJECT_0, "should be ready\n" );
ok(U(iosb).Status == STATUS_NOTIFY_ENUM_DIR, "status not successful\n");
ok(iosb.Information == 0, "info not set\n");
U(iosb).Status = 0;
iosb.Information = 0;
r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
ok(r==STATUS_PENDING, "should status pending\n");
r = RemoveDirectoryW( subdir );
ok( r == TRUE, "failed to remove directory\n");
r = WaitForSingleObject( hEvent, 0 );
ok( r == WAIT_OBJECT_0, "should be ready\n" );
ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n");
ok(iosb.Information == 0x12, "info not set\n");
U(iosb).Status = 0x01234567;
iosb.Information = 0x12345678;
r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
ok(r==STATUS_PENDING, "should status pending\n");
U(iosb2).Status = 0x01234567;
iosb2.Information = 0x12345678;
r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb2,buffer,sizeof buffer,filter,0);
ok(r==STATUS_PENDING, "should status pending\n");
ok(U(iosb).Status == 0x01234567, "status set too soon\n");
ok(iosb.Information == 0x12345678, "info set too soon\n");
todo_wine {
r = pNtCancelIoFile(hdir, &iosb);
ok( r == STATUS_SUCCESS, "cancel failed\n");
CloseHandle(hdir);
ok(U(iosb).Status == STATUS_SUCCESS, "status wrong\n");
ok(U(iosb2).Status == STATUS_CANCELLED, "status wrong\n");
}
ok(iosb.Information == 0, "info wrong\n");
ok(iosb2.Information == 0, "info wrong\n");
r = RemoveDirectoryW( path );
ok( r == TRUE, "failed to remove directory\n");
CloseHandle(hEvent);
}
START_TEST(change)
{
HMODULE hntdll = GetModuleHandle("ntdll");
pNtNotifyChangeDirectoryFile = (fnNtNotifyChangeDirectoryFile)
GetProcAddress(hntdll, "NtNotifyChangeDirectoryFile");
pNtCancelIoFile = (fnNtCancelIoFile)
GetProcAddress(hntdll, "NtCancelIoFile");
if (!pNtNotifyChangeDirectoryFile)
return;
if (!pNtCancelIoFile)
return;
test_ntncdf();
test_ntncdf_async();
}

View file

@ -15,13 +15,12 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
#include "ntdll_test.h"
#include "wine/unicode.h"
static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen,
LPCSTR src, DWORD srclen );
@ -108,8 +107,8 @@ static void testQuery(void)
pRtlMultiByteToUnicodeN( bn, sizeof(bn), NULL, test->val, strlen(test->val)+1 );
ok( value.Length == strlen(test->val) * sizeof(WCHAR), "Wrong length %d/%d for %s\n",
value.Length, strlen(test->val) * sizeof(WCHAR), test->var );
ok((value.Length == strlen(test->val) * sizeof(WCHAR) && strncmpW(bv, bn, test->len) == 0) ||
strcmpW(bv, bn) == 0,
ok((value.Length == strlen(test->val) * sizeof(WCHAR) && memcmp(bv, bn, test->len*sizeof(WCHAR)) == 0) ||
lstrcmpW(bv, bn) == 0,
"Wrong result for %s/%d\n", test->var, test->len);
ok(bv[test->len] == '@', "Writing too far away in the buffer for %s/%d\n", test->var, test->len);
break;
@ -151,7 +150,7 @@ static void testSetHelper(LPWSTR* env, const char* var, const char* val, NTSTATU
switch (nts)
{
case STATUS_SUCCESS:
ok(strcmpW(bval1, bval2) == 0, "Cannot get value written to environment\n");
ok(lstrcmpW(bval1, bval2) == 0, "Cannot get value written to environment\n");
break;
case STATUS_VARIABLE_NOT_FOUND:
ok(val == NULL, "Couldn't find variable, but didn't delete it. val = %s\n", val);
@ -257,7 +256,7 @@ static void testExpand(void)
ok(ul == strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR),
"Wrong returned length for %s: %lu <> %u\n",
test->src, ul, strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR));
ok(strcmpW(dst, rst) == 0, "Wrong result for %s: expecting %s\n",
ok(lstrcmpW(dst, rst) == 0, "Wrong result for %s: expecting %s\n",
test->src, test->dst);
us_dst.Length = 0;
@ -269,7 +268,7 @@ static void testExpand(void)
ok(ul == strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR),
"Wrong returned length for %s (with buffer too small): %lu <> %u\n",
test->src, ul, strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR));
ok(strncmpW(dst, rst, 8) == 0,
ok(memcmp(dst, rst, 8*sizeof(WCHAR)) == 0,
"Wrong result for %s (with buffer too small): expecting %s\n",
test->src, test->dst);
ok(dst[8] == '-', "Writing too far in buffer (got %c/%d)\n", dst[8], dst[8]);

View file

@ -15,7 +15,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>

View file

@ -0,0 +1,249 @@
/*
* Unit test suite for ntdll exceptions
*
* Copyright 2005 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x500 /* For NTSTATUS */
#endif
#include <stdio.h>
#define WIN32_NO_STATUS
#include <windows.h>
#define NTOS_MODE_USER
#include <ndk/ntndk.h>
#include "wine/test.h"
/*
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winnt.h"
#include "winreg.h"
#include "winternl.h"
#include "excpt.h"
#include "wine/test.h"
*/
#ifdef __i386__
static struct _TEB * (WINAPI *pNtCurrentTeb)(void);
/* Test various instruction combinations that cause a protection fault on the i386,
* and check what the resulting exception looks like.
*/
static const struct exception
{
BYTE code[18]; /* asm code */
BYTE offset; /* offset of faulting instruction */
BYTE length; /* length of faulting instruction */
NTSTATUS status; /* expected status code */
DWORD nb_params; /* expected number of parameters */
DWORD params[4]; /* expected parameters */
} exceptions[] =
{
/* test some privileged instructions */
{ { 0xfb, 0xc3 }, /* sti; ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x6c, 0xc3 }, /* insb (%dx); ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x6d, 0xc3 }, /* insl (%dx); ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x6e, 0xc3 }, /* outsb (%dx); ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x6f, 0xc3 }, /* outsl (%dx); ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xe4, 0x11, 0xc3 }, /* inb $0x11,%al; ret */
0, 2, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xe5, 0x11, 0xc3 }, /* inl $0x11,%eax; ret */
0, 2, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xe6, 0x11, 0xc3 }, /* outb %al,$0x11; ret */
0, 2, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xe7, 0x11, 0xc3 }, /* outl %eax,$0x11; ret */
0, 2, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xed, 0xc3 }, /* inl (%dx),%eax; ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xee, 0xc3 }, /* outb %al,(%dx); ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xef, 0xc3 }, /* outl %eax,(%dx); ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xf4, 0xc3 }, /* hlt; ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xfa, 0xc3 }, /* cli; ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
/* test long jump to invalid selector */
{ { 0xea, 0, 0, 0, 0, 0, 0, 0xc3 }, /* ljmp $0,$0; ret */
0, 7, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
/* test iret to invalid selector */
{ { 0x6a, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0xcf, 0x83, 0xc4, 0x0c, 0xc3 },
/* pushl $0; pushl $0; pushl $0; iret; addl $12,%esp; ret */
6, 1, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
/* test loading an invalid selector */
{ { 0xb8, 0xef, 0xbe, 0x00, 0x00, 0x8e, 0xe8, 0xc3 }, /* mov $beef,%ax; mov %ax,%gs; ret */
5, 2, STATUS_ACCESS_VIOLATION, 2, { 0, 0xbee8 } },
/* test accessing a zero selector */
{ { 0x06, 0x31, 0xc0, 0x8e, 0xc0, 0x26, 0xa1, 0, 0, 0, 0, 0x07, 0xc3 },
/* push %es; xor %eax,%eax; mov %ax,%es; mov %es:(0),%ax; pop %es */
5, 6, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
/* test moving %cs -> %ss */
{ { 0x0e, 0x17, 0x58, 0xc3 }, /* pushl %cs; popl %ss; popl %eax; ret */
1, 1, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
/* test overlong instruction (limit is 16 bytes) */
{ { 0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0xfa,0xc3 },
0, 16, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
{ { 0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0xfa,0xc3 },
0, 15, STATUS_PRIVILEGED_INSTRUCTION, 0 },
/* test invalid interrupt */
{ { 0xcd, 0xff, 0xc3 }, /* int $0xff; ret */
0, 2, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
/* test moves to/from Crx */
{ { 0x0f, 0x20, 0xc0, 0xc3 }, /* movl %cr0,%eax; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x0f, 0x20, 0xe0, 0xc3 }, /* movl %cr4,%eax; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x0f, 0x22, 0xc0, 0xc3 }, /* movl %eax,%cr0; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x0f, 0x22, 0xe0, 0xc3 }, /* movl %eax,%cr4; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
/* test moves to/from Drx */
{ { 0x0f, 0x21, 0xc0, 0xc3 }, /* movl %dr0,%eax; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x0f, 0x21, 0xc8, 0xc3 }, /* movl %dr1,%eax; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x0f, 0x21, 0xf8, 0xc3 }, /* movl %dr7,%eax; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x0f, 0x23, 0xc0, 0xc3 }, /* movl %eax,%dr0; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x0f, 0x23, 0xc8, 0xc3 }, /* movl %eax,%dr1; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x0f, 0x23, 0xf8, 0xc3 }, /* movl %eax,%dr7; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
/* test memory reads */
{ { 0xa1, 0xfc, 0xff, 0xff, 0xff, 0xc3 }, /* movl 0xfffffffc,%eax; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xfffffffc } },
{ { 0xa1, 0xfd, 0xff, 0xff, 0xff, 0xc3 }, /* movl 0xfffffffd,%eax; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
{ { 0xa1, 0xfe, 0xff, 0xff, 0xff, 0xc3 }, /* movl 0xfffffffe,%eax; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
{ { 0xa1, 0xff, 0xff, 0xff, 0xff, 0xc3 }, /* movl 0xffffffff,%eax; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
/* test memory writes */
{ { 0xa3, 0xfc, 0xff, 0xff, 0xff, 0xc3 }, /* movl %eax,0xfffffffc; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 1, 0xfffffffc } },
{ { 0xa3, 0xfd, 0xff, 0xff, 0xff, 0xc3 }, /* movl %eax,0xfffffffd; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
{ { 0xa3, 0xfe, 0xff, 0xff, 0xff, 0xc3 }, /* movl %eax,0xfffffffe; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
{ { 0xa3, 0xff, 0xff, 0xff, 0xff, 0xc3 }, /* movl %eax,0xffffffff; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
};
static int got_exception;
static DWORD handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame,
CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher )
{
const struct exception *except = *(const struct exception **)(frame + 1);
unsigned int i, entry = except - exceptions;
got_exception++;
trace( "exception: %lx flags:%lx addr:%p\n",
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
ok( rec->ExceptionCode == except->status,
"%u: Wrong exception code %lx/%lx\n", entry, rec->ExceptionCode, except->status );
ok( rec->ExceptionAddress == except->code + except->offset,
"%u: Wrong exception address %p/%p\n", entry,
rec->ExceptionAddress, except->code + except->offset );
ok( rec->NumberParameters == except->nb_params,
"%u: Wrong number of parameters %lu/%lu\n", entry, rec->NumberParameters, except->nb_params );
for (i = 0; i < rec->NumberParameters; i++)
ok( rec->ExceptionInformation[i] == except->params[i],
"%u: Wrong parameter %d: %lx/%lx\n",
entry, i, rec->ExceptionInformation[i], except->params[i] );
/* don't handle exception if it's not the address we expected */
if (rec->ExceptionAddress != except->code + except->offset) return ExceptionContinueSearch;
context->Eip += except->length;
return ExceptionContinueExecution;
}
static void test_prot_fault(void)
{
unsigned int i;
struct
{
EXCEPTION_REGISTRATION_RECORD frame;
const struct exception *except;
} exc_frame;
pNtCurrentTeb = (void *)GetProcAddress( GetModuleHandleA("ntdll.dll"), "NtCurrentTeb" );
if (!pNtCurrentTeb)
{
trace( "NtCurrentTeb not found, skipping tests\n" );
return;
}
exc_frame.frame.Handler = handler;
exc_frame.frame.Next = pNtCurrentTeb()->Tib.ExceptionList;
pNtCurrentTeb()->Tib.ExceptionList = &exc_frame.frame;
for (i = 0; i < sizeof(exceptions)/sizeof(exceptions[0]); i++)
{
void (*func)(void) = (void *)exceptions[i].code;
exc_frame.except = &exceptions[i];
got_exception = 0;
func();
if (!i && !got_exception)
{
trace( "No exception, assuming win9x, no point in testing further\n" );
break;
}
ok( got_exception == (exceptions[i].status != 0),
"%u: bad exception count %d\n", i, got_exception );
}
pNtCurrentTeb()->Tib.ExceptionList = exc_frame.frame.Next;
}
#endif /* __i386__ */
START_TEST(exception)
{
#ifdef __i386__
test_prot_fault();
#endif
}

View file

@ -14,7 +14,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
@ -729,7 +729,15 @@ static void test_query_process_handlecount(void)
ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status);
process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, one_before_last_pid);
trace("Handlecount for process with ID : %ld\n", one_before_last_pid);
if (!process)
{
trace("Could not open process with ID : %ld, error : %08lx. Going to use current one.\n", one_before_last_pid, GetLastError());
process = GetCurrentProcess();
trace("ProcessHandleCount for current process\n");
}
else
trace("ProcessHandleCount for process with ID : %ld\n", one_before_last_pid);
status = pNtQueryInformationProcess( process, ProcessHandleCount, &handlecount, sizeof(handlecount), &ReturnLength);
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status);
ok( sizeof(handlecount) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(handlecount), ReturnLength);

View file

@ -14,7 +14,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES
* We use function pointers here as there is no import library for NTDLL on

View file

@ -3,12 +3,15 @@
<define name="__USE_W32API" />
<library>ntdll</library>
<file>atom.c</file>
<file>change.c</file>
<file>env.c</file>
<file>error.c</file>
<file>exception.c</file>
<file>info.c</file>
<file>large_int.c</file>
<file>om.c</file>
<file>path.c</file>
<file>port.c</file>
<file>reg.c</file>
<file>rtlbitmap.c</file>
<file>rtl.c</file>

File diff suppressed because it is too large Load diff

View file

@ -15,7 +15,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "ntdll_test.h"

View file

@ -0,0 +1,305 @@
/* Unit test suite for Ntdll Port API functions
*
* Copyright 2006 James Hawkins
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
#include <stdarg.h>
#include "ntdll_test.h"
#include "windows.h"
#ifndef __WINE_WINTERNL_H
typedef struct _CLIENT_ID
{
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
typedef struct _LPC_SECTION_WRITE
{
ULONG Length;
HANDLE SectionHandle;
ULONG SectionOffset;
ULONG ViewSize;
PVOID ViewBase;
PVOID TargetViewBase;
} LPC_SECTION_WRITE, *PLPC_SECTION_WRITE;
typedef struct _LPC_SECTION_READ
{
ULONG Length;
ULONG ViewSize;
PVOID ViewBase;
} LPC_SECTION_READ, *PLPC_SECTION_READ;
typedef struct _LPC_MESSAGE
{
USHORT DataSize;
USHORT MessageSize;
USHORT MessageType;
USHORT VirtualRangesOffset;
CLIENT_ID ClientId;
ULONG MessageId;
ULONG SectionSize;
UCHAR Data[ANYSIZE_ARRAY];
} LPC_MESSAGE, *PLPC_MESSAGE;
#endif
/* Types of LPC messages */
#define UNUSED_MSG_TYPE 0
#define LPC_REQUEST 1
#define LPC_REPLY 2
#define LPC_DATAGRAM 3
#define LPC_LOST_REPLY 4
#define LPC_PORT_CLOSED 5
#define LPC_CLIENT_DIED 6
#define LPC_EXCEPTION 7
#define LPC_DEBUG_EVENT 8
#define LPC_ERROR_EVENT 9
#define LPC_CONNECTION_REQUEST 10
static const WCHAR PORTNAME[] = {'\\','M','y','P','o','r','t',0};
#define REQUEST1 "Request1"
#define REQUEST2 "Request2"
#define REPLY "Reply"
#define MAX_MESSAGE_LEN 30
UNICODE_STRING port;
static char selfname[MAX_PATH];
static int myARGC;
static char** myARGV;
/* Function pointers for ntdll calls */
static HMODULE hntdll = 0;
static NTSTATUS (WINAPI *pNtCompleteConnectPort)(HANDLE);
static NTSTATUS (WINAPI *pNtAcceptConnectPort)(PHANDLE,ULONG,PLPC_MESSAGE,ULONG,
ULONG,PLPC_SECTION_READ);
static NTSTATUS (WINAPI *pNtReplyPort)(HANDLE,PLPC_MESSAGE);
static NTSTATUS (WINAPI *pNtReplyWaitReceivePort)(PHANDLE,PULONG,PLPC_MESSAGE,
PLPC_MESSAGE);
static NTSTATUS (WINAPI *pNtCreatePort)(PHANDLE,POBJECT_ATTRIBUTES,ULONG,ULONG,ULONG);
static NTSTATUS (WINAPI *pNtRequestWaitReplyPort)(HANDLE,PLPC_MESSAGE,PLPC_MESSAGE);
static NTSTATUS (WINAPI *pNtRequestPort)(HANDLE,PLPC_MESSAGE);
static NTSTATUS (WINAPI *pNtRegisterThreadTerminatePort)(HANDLE);
static NTSTATUS (WINAPI *pNtConnectPort)(PHANDLE,PUNICODE_STRING,
PSECURITY_QUALITY_OF_SERVICE,
PLPC_SECTION_WRITE,PLPC_SECTION_READ,
PVOID,PVOID,PULONG);
static NTSTATUS (WINAPI *pRtlInitUnicodeString)(PUNICODE_STRING,LPCWSTR);
static NTSTATUS (WINAPI *pNtWaitForSingleObject)(HANDLE,BOOLEAN,PLARGE_INTEGER);
static BOOL init_function_ptrs(void)
{
hntdll = LoadLibraryA("ntdll.dll");
if (hntdll)
{
pNtCompleteConnectPort = (void *)GetProcAddress(hntdll, "NtCompleteConnectPort");
pNtAcceptConnectPort = (void *)GetProcAddress(hntdll, "NtAcceptConnectPort");
pNtReplyPort = (void *)GetProcAddress(hntdll, "NtReplyPort");
pNtReplyWaitReceivePort = (void *)GetProcAddress(hntdll, "NtReplyWaitReceivePort");
pNtCreatePort = (void *)GetProcAddress(hntdll, "NtCreatePort");
pNtRequestWaitReplyPort = (void *)GetProcAddress(hntdll, "NtRequestWaitReplyPort");
pNtRequestPort = (void *)GetProcAddress(hntdll, "NtRequestPort");
pNtRegisterThreadTerminatePort = (void *)GetProcAddress(hntdll, "NtRegisterThreadTerminatePort");
pNtConnectPort = (void *)GetProcAddress(hntdll, "NtConnectPort");
pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
pNtWaitForSingleObject = (void *)GetProcAddress(hntdll, "NtWaitForSingleObject");
}
if (!pNtCompleteConnectPort || !pNtAcceptConnectPort ||
!pNtReplyWaitReceivePort || !pNtCreatePort || !pNtRequestWaitReplyPort ||
!pNtRequestPort || !pNtRegisterThreadTerminatePort ||
!pNtConnectPort || !pRtlInitUnicodeString)
{
return FALSE;
}
return TRUE;
}
static void ProcessConnectionRequest(PLPC_MESSAGE LpcMessage, PHANDLE pAcceptPortHandle)
{
NTSTATUS status;
ok(LpcMessage->MessageType == LPC_CONNECTION_REQUEST,
"Expected LPC_CONNECTION_REQUEST, got %d\n", LpcMessage->MessageType);
ok(!*LpcMessage->Data, "Expected empty string!\n");
status = pNtAcceptConnectPort(pAcceptPortHandle, 0, LpcMessage, 1, 0, NULL);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status);
status = pNtCompleteConnectPort(*pAcceptPortHandle);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status);
}
static void ProcessLpcRequest(HANDLE PortHandle, PLPC_MESSAGE LpcMessage)
{
NTSTATUS status;
ok(LpcMessage->MessageType == LPC_REQUEST,
"Expected LPC_REQUEST, got %d\n", LpcMessage->MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->Data, REQUEST2),
"Expected %s, got %s\n", REQUEST2, LpcMessage->Data);
lstrcpy((LPSTR)LpcMessage->Data, REPLY);
status = pNtReplyPort(PortHandle, LpcMessage);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status);
ok(LpcMessage->MessageType == LPC_REQUEST,
"Expected LPC_REQUEST, got %d\n", LpcMessage->MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->Data, REPLY),
"Expected %s, got %s\n", REPLY, LpcMessage->Data);
}
static DWORD WINAPI test_ports_client(LPVOID arg)
{
SECURITY_QUALITY_OF_SERVICE sqos;
LPC_MESSAGE *LpcMessage, *out;
HANDLE PortHandle;
ULONG len, size;
NTSTATUS status;
sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
sqos.ImpersonationLevel = SecurityImpersonation;
sqos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
sqos.EffectiveOnly = TRUE;
status = pNtConnectPort(&PortHandle, &port, &sqos, 0, 0, &len, NULL, NULL);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status);
status = pNtRegisterThreadTerminatePort(PortHandle);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status);
size = FIELD_OFFSET(LPC_MESSAGE, Data) + MAX_MESSAGE_LEN;
LpcMessage = HeapAlloc(GetProcessHeap(), 0, size);
out = HeapAlloc(GetProcessHeap(), 0, size);
memset(LpcMessage, 0, size);
LpcMessage->DataSize = lstrlen(REQUEST1) + 1;
LpcMessage->MessageSize = FIELD_OFFSET(LPC_MESSAGE, Data) + LpcMessage->DataSize;
lstrcpy((LPSTR)LpcMessage->Data, REQUEST1);
status = pNtRequestPort(PortHandle, LpcMessage);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status);
ok(LpcMessage->MessageType == 0, "Expected 0, got %d\n", LpcMessage->MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->Data, REQUEST1),
"Expected %s, got %s\n", REQUEST1, LpcMessage->Data);
/* Fill in the message */
memset(LpcMessage, 0, size);
LpcMessage->DataSize = lstrlen(REQUEST2) + 1;
LpcMessage->MessageSize = FIELD_OFFSET(LPC_MESSAGE, Data) + LpcMessage->DataSize;
lstrcpy((LPSTR)LpcMessage->Data, REQUEST2);
/* Send the message and wait for the reply */
status = pNtRequestWaitReplyPort(PortHandle, LpcMessage, out);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status);
ok(!lstrcmp((LPSTR)out->Data, REPLY), "Expected %s, got %s\n", REPLY, out->Data);
ok(out->MessageType == LPC_REPLY, "Expected LPC_REPLY, got %d\n", out->MessageType);
return 0;
}
static void test_ports_server(void)
{
OBJECT_ATTRIBUTES obj;
HANDLE PortHandle;
HANDLE AcceptPortHandle;
PLPC_MESSAGE LpcMessage;
ULONG size;
NTSTATUS status;
BOOL done = FALSE;
pRtlInitUnicodeString(&port, PORTNAME);
memset(&obj, 0, sizeof(OBJECT_ATTRIBUTES));
obj.Length = sizeof(OBJECT_ATTRIBUTES);
obj.ObjectName = &port;
status = pNtCreatePort(&PortHandle, &obj, 100, 100, 0);
todo_wine
{
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status);
}
size = FIELD_OFFSET(LPC_MESSAGE, Data) + MAX_MESSAGE_LEN;
LpcMessage = HeapAlloc(GetProcessHeap(), 0, size);
memset(LpcMessage, 0, size);
while (TRUE)
{
status = pNtReplyWaitReceivePort(PortHandle, NULL, NULL, LpcMessage);
todo_wine
{
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld(%lx)\n", status, status);
}
/* STATUS_INVALID_HANDLE: win2k without admin rights will perform an
* endless loop here
*/
if ((status == STATUS_NOT_IMPLEMENTED) ||
(status == STATUS_INVALID_HANDLE)) return;
switch (LpcMessage->MessageType)
{
case LPC_CONNECTION_REQUEST:
ProcessConnectionRequest(LpcMessage, &AcceptPortHandle);
break;
case LPC_REQUEST:
ProcessLpcRequest(PortHandle, LpcMessage);
done = TRUE;
break;
case LPC_DATAGRAM:
ok(!lstrcmp((LPSTR)LpcMessage->Data, REQUEST1),
"Expected %s, got %s\n", REQUEST1, LpcMessage->Data);
break;
case LPC_CLIENT_DIED:
ok(done, "Expected LPC request to be completed!\n");
return;
default:
ok(FALSE, "Unexpected message: %d\n", LpcMessage->MessageType);
break;
}
}
}
START_TEST(port)
{
HANDLE thread;
DWORD id;
if (!init_function_ptrs())
return;
myARGC = winetest_get_mainargs(&myARGV);
strcpy(selfname, myARGV[0]);
thread = CreateThread(NULL, 0, test_ports_client, NULL, 0, &id);
ok(thread != NULL, "Expected non-NULL thread handle!\n");
test_ports_server();
CloseHandle(thread);
}

View file

@ -15,7 +15,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTE: I don't test every RelativeTo value because it would be redundant, all calls go through
* helper function RTL_GetKeyHandle().--Brad DeMorrow

View file

@ -14,7 +14,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES
* We use function pointers here as there is no import library for NTDLL on

View file

@ -14,7 +14,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES
* We use function pointers here as some of the bitmap functions exist only

View file

@ -15,7 +15,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES
* We use function pointers here as there is no import library for NTDLL on
@ -1672,6 +1672,9 @@ static void test_RtlIntegerToChar(void)
static const WCHAR szGuid[] = { '{','0','1','0','2','0','3','0','4','-',
'0','5','0','6','-' ,'0','7','0','8','-','0','9','0','A','-',
'0','B','0','C','0','D','0','E','0','F','0','A','}','\0' };
static const WCHAR szGuid2[] = { '{','0','1','0','2','0','3','0','4','-',
'0','5','0','6','-' ,'0','7','0','8','-','0','9','0','A','-',
'0','B','0','C','0','D','0','E','0','F','0','A',']','\0' };
DEFINE_GUID(IID_Endianess, 0x01020304, 0x0506, 0x0708, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F, 0x0A);
@ -1687,6 +1690,12 @@ static void test_RtlGUIDFromString(void)
ret = pRtlGUIDFromString(&str, &guid);
ok(ret == 0, "expected ret=0, got 0x%0lx\n", ret);
ok(memcmp(&guid, &IID_Endianess, sizeof(guid)) == 0, "Endianess broken\n");
str.Length = str.MaximumLength = (sizeof(szGuid2) - 1) / sizeof(WCHAR);
str.Buffer = (LPWSTR)szGuid2;
ret = pRtlGUIDFromString(&str, &guid);
ok(ret, "expected ret!=0\n");
}
static void test_RtlStringFromGUID(void)

View file

@ -14,7 +14,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES
* We use function pointers here as there is no import library for NTDLL on

View file

@ -27,16 +27,16 @@ extern void func_time(void);
const struct test winetest_testlist[] =
{
{ "atom", func_atom },
// { "change", func_change },
{ "change", func_change },
{ "env", func_env },
{ "error", func_error },
// { "exception", func_exception },
{ "exception", func_exception },
// { "generated", func_generated },
{ "info", func_info },
{ "large_int", func_large_int },
{ "om", func_om },
{ "path", func_path },
// { "port", func_port },
{ "port", func_port },
{ "reg", func_reg },
{ "rtl", func_rtl },
{ "rtlbitmap", func_rtlbitmap },

View file

@ -15,7 +15,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "ntdll_test.h"