Added: trunk/reactos/regtests/winetests/kernel32/
Added: trunk/reactos/regtests/winetests/kernel32/alloc.c
Added: trunk/reactos/regtests/winetests/kernel32/atom.c
Added: trunk/reactos/regtests/winetests/kernel32/change.c
Added: trunk/reactos/regtests/winetests/kernel32/codepage.c
Added: trunk/reactos/regtests/winetests/kernel32/comm.c
Added: trunk/reactos/regtests/winetests/kernel32/console.c
Added: trunk/reactos/regtests/winetests/kernel32/directory.c
Added: trunk/reactos/regtests/winetests/kernel32/drive.c
Added: trunk/reactos/regtests/winetests/kernel32/environ.c
Added: trunk/reactos/regtests/winetests/kernel32/file.c
Added: trunk/reactos/regtests/winetests/kernel32/format_msg.c
Added: trunk/reactos/regtests/winetests/kernel32/heap.c
Added: trunk/reactos/regtests/winetests/kernel32/kernel32_test.xml
Added: trunk/reactos/regtests/winetests/kernel32/locale.c
Added: trunk/reactos/regtests/winetests/kernel32/mailslot.c
Added: trunk/reactos/regtests/winetests/kernel32/module.c
Added: trunk/reactos/regtests/winetests/kernel32/path.c
Added: trunk/reactos/regtests/winetests/kernel32/pipe.c
Added: trunk/reactos/regtests/winetests/kernel32/process.c
Added: trunk/reactos/regtests/winetests/kernel32/profile.c
Added: trunk/reactos/regtests/winetests/kernel32/sync.c
Added: trunk/reactos/regtests/winetests/kernel32/testlist.c
Added: trunk/reactos/regtests/winetests/kernel32/thread.c
Added: trunk/reactos/regtests/winetests/kernel32/time.c
Added: trunk/reactos/regtests/winetests/kernel32/timer.c
Added: trunk/reactos/regtests/winetests/kernel32/virtual.c
--- trunk/reactos/regtests/winetests/kernel32/alloc.c 2005-08-07 03:00:44 UTC (rev 17136)
+++ trunk/reactos/regtests/winetests/kernel32/alloc.c 2005-08-07 03:14:17 UTC (rev 17137)
@@ -0,0 +1,406 @@
+/*
+ * Unit test suite for memory allocation functions.
+ *
+ * Copyright 2002 Geoffrey Hausheer
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#include "wine/test.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+
+
+ /* The following functions don't have tests, because either I don't know how
+ to test them, or they are WinNT only, or require multiple threads.
+ Since the last two issues shouldn't really stop the tests from being
+ written, assume for now that it is all due to the first case
+ HeapCompact
+ HeapLock
+ HeapQueryInformation
+ HeapSetInformation
+ HeapUnlock
+ HeapValidate
+ HeapWalk
+*/
+/* In addition, these features aren't being tested
+ HEAP_NO_SERIALIZE
+ HEAP_GENERATE_EXCEPTIONS
+ STATUS_ACCESS_VIOLATION (error code from HeapAlloc)
+*/
+
+static void test_Heap(void)
+{
+ SYSTEM_INFO sysInfo;
+ ULONG memchunk;
+ HANDLE heap;
+ LPVOID mem1,mem1a,mem3;
+ UCHAR *mem2,*mem2a;
+ UINT error,i;
+ DWORD dwSize;
+
+/* Retrieve the page size for this system */
+ sysInfo.dwPageSize=0;
+ GetSystemInfo(&sysInfo);
+ ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size\n");
+
+/* Create a Heap with a minimum and maximum size */
+/* Note that Windows and Wine seem to behave a bit differently with respect
+ to memory allocation. In Windows, you can't access all the memory
+ specified in the heap (due to overhead), so choosing a reasonable maximum
+ size for the heap was done mostly by trial-and-error on Win2k. It may need
+ more tweaking for otherWindows variants.
+*/
+ memchunk=10*sysInfo.dwPageSize;
+ heap=HeapCreate(0,2*memchunk,5*memchunk);
+
+/* Check that HeapCreate allocated the right amount of ram */
+ todo_wine {
+ /* Today HeapCreate seems to return a memory block larger than specified.
+ MSDN says the maximum heap size should be dwMaximumSize rounded up to the
+ nearest page boundary
+ */
+ mem1=HeapAlloc(heap,0,5*memchunk+1);
+ ok(mem1==NULL,"HeapCreate allocated more Ram than it should have\n");
+ HeapFree(heap,0,mem1);
+ }
+
+/* Check that a normal alloc works */
+ mem1=HeapAlloc(heap,0,memchunk);
+ ok(mem1!=NULL,"HeapAlloc failed\n");
+ if(mem1) {
+ ok(HeapSize(heap,0,mem1)>=memchunk, "HeapAlloc should return a big enough memory block\n");
+ }
+
+/* Check that a 'zeroing' alloc works */
+ mem2=HeapAlloc(heap,HEAP_ZERO_MEMORY,memchunk);
+ ok(mem2!=NULL,"HeapAlloc failed\n");
+ if(mem2) {
+ ok(HeapSize(heap,0,mem2)>=memchunk,"HeapAlloc should return a big enough memory block\n");
+ error=0;
+ for(i=0;i<memchunk;i++) {
+ if(mem2[i]!=0) {
+ error=1;
+ }
+ }
+ ok(!error,"HeapAlloc should have zeroed out it's allocated memory\n");
+ }
+
+/* Check that HeapAlloc returns NULL when requested way too much memory */
+ mem3=HeapAlloc(heap,0,5*memchunk);
+ ok(mem3==NULL,"HeapAlloc should return NULL\n");
+ if(mem3) {
+ ok(HeapFree(heap,0,mem3),"HeapFree didn't pass successfully\n");
+ }
+
+/* Check that HeapRealloc works */
+ mem2a=HeapReAlloc(heap,HEAP_ZERO_MEMORY,mem2,memchunk+5*sysInfo.dwPageSize);
+ ok(mem2a!=NULL,"HeapReAlloc failed\n");
+ if(mem2a) {
+ ok(HeapSize(heap,0,mem2a)>=memchunk+5*sysInfo.dwPageSize,"HeapReAlloc failed\n");
+ error=0;
+ for(i=0;i<5*sysInfo.dwPageSize;i++) {
+ if(mem2a[memchunk+i]!=0) {
+ error=1;
+ }
+ }
+ ok(!error,"HeapReAlloc should have zeroed out it's allocated memory\n");
+ }
+
+/* Check that HeapRealloc honours HEAP_REALLOC_IN_PLACE_ONLY */
+ error=0;
+ mem1a=HeapReAlloc(heap,HEAP_REALLOC_IN_PLACE_ONLY,mem1,memchunk+sysInfo.dwPageSize);
+ if(mem1a!=NULL) {
+ if(mem1a!=mem1) {
+ error=1;
+ }
+ }
+ ok(mem1a==NULL || error==0,"HeapReAlloc didn't honour HEAP_REALLOC_IN_PLACE_ONLY\n");
+
+/* Check that HeapFree works correctly */
+ if(mem1a) {
+ ok(HeapFree(heap,0,mem1a),"HeapFree failed\n");
+ } else {
+ ok(HeapFree(heap,0,mem1),"HeapFree failed\n");
+ }
+ if(mem2a) {
+ ok(HeapFree(heap,0,mem2a),"HeapFree failed\n");
+ } else {
+ ok(HeapFree(heap,0,mem2),"HeapFree failed\n");
+ }
+
+ /* 0-length buffer */
+ mem1 = HeapAlloc(heap, 0, 0);
+ ok(mem1 != NULL, "Reserved memory\n");
+
+ dwSize = HeapSize(heap, 0, mem1);
+ /* should work with 0-length buffer */
+ ok((dwSize >= 0) && (dwSize < 0xFFFFFFFF),
+ "The size of the 0-length buffer\n");
+ ok(HeapFree(heap, 0, mem1), "Freed the 0-length buffer\n");
+
+/* Check that HeapDestry works */
+ ok(HeapDestroy(heap),"HeapDestroy failed\n");
+}
+
+/* The following functions don't have tests, because either I don't know how
+ to test them, or they are WinNT only, or require multiple threads.
+ Since the last two issues shouldn't really stop the tests from being
+ written, assume for now that it is all due to the first case
+ GlobalFlags
+ GlobalMemoryStatus
+ GlobalMemoryStatusEx
+*/
+/* In addition, these features aren't being tested
+ GMEM_DISCADABLE
+ GMEM_NOCOMPACT
+*/
+static void test_Global(void)
+{
+ ULONG memchunk;
+ HGLOBAL mem1,mem2,mem2a,mem2b;
+ UCHAR *mem2ptr;
+ UINT error,i;
+ memchunk=100000;
+
+ SetLastError(NO_ERROR);
+/* Check that a normal alloc works */
+ mem1=GlobalAlloc(0,memchunk);
+ ok(mem1!=NULL,"GlobalAlloc failed\n");
+ if(mem1) {
+ ok(GlobalSize(mem1)>=memchunk, "GlobalAlloc should return a big enough memory block\n");
+ }
+
+/* Check that a 'zeroing' alloc works */
+ mem2=GlobalAlloc(GMEM_ZEROINIT,memchunk);
+ ok(mem2!=NULL,"GlobalAlloc failed: error=%ld\n",GetLastError());
+ if(mem2) {
+ ok(GlobalSize(mem2)>=memchunk,"GlobalAlloc should return a big enough memory block\n");
+ mem2ptr=GlobalLock(mem2);
+ ok(mem2ptr==mem2,"GlobalLock should have returned the same memory as was allocated\n");
+ if(mem2ptr) {
+ error=0;
+ for(i=0;i<memchunk;i++) {
+ if(mem2ptr[i]!=0) {
+ error=1;
+ }
+ }
+ ok(!error,"GlobalAlloc should have zeroed out it's allocated memory\n");
+ }
+ }
+/* Check that GlobalReAlloc works */
+/* Check that we can change GMEM_FIXED to GMEM_MOVEABLE */
+ mem2a=GlobalReAlloc(mem2,0,GMEM_MODIFY | GMEM_MOVEABLE);
+ if(mem2a!=NULL) {
+ mem2=mem2a;
+ mem2ptr=GlobalLock(mem2a);
+ ok(mem2ptr!=NULL && !GlobalUnlock(mem2a)&&GetLastError()==NO_ERROR,
+ "Converting from FIXED to MOVEABLE didn't REALLY work\n");
+ }
+
+/* Check that ReAllocing memory works as expected */
+ mem2a=GlobalReAlloc(mem2,2*memchunk,GMEM_MOVEABLE | GMEM_ZEROINIT);
+ ok(mem2a!=NULL,"GlobalReAlloc failed\n");
+ if(mem2a) {
+ ok(GlobalSize(mem2a)>=2*memchunk,"GlobalReAlloc failed\n");
+ mem2ptr=GlobalLock(mem2a);
+ ok(mem2ptr!=NULL,"GlobalLock Failed\n");
+ if(mem2ptr) {
+ error=0;
+ for(i=0;i<memchunk;i++) {
+ if(mem2ptr[memchunk+i]!=0) {
+ error=1;
+ }
+ }
+ ok(!error,"GlobalReAlloc should have zeroed out it's allocated memory\n");
+
+/* Check that GlobalHandle works */
+ mem2b=GlobalHandle(mem2ptr);
+ ok(mem2b==mem2a,"GlobalHandle didn't return the correct memory handle\n");
+
+/* Check that we can't discard locked memory */
+ mem2b=GlobalDiscard(mem2a);
+ if(mem2b==NULL) {
+ ok(!GlobalUnlock(mem2a) && GetLastError()==NO_ERROR,"GlobalUnlock Failed\n");
+ }
+ }
+ }
+ if(mem1) {
+ ok(GlobalFree(mem1)==NULL,"GlobalFree failed\n");
+ }
+ if(mem2a) {
+ ok(GlobalFree(mem2a)==NULL,"GlobalFree failed\n");
+ } else {
+ ok(GlobalFree(mem2)==NULL,"GlobalFree failed\n");
+ }
+}
+
+
+/* The following functions don't have tests, because either I don't know how
+ to test them, or they are WinNT only, or require multiple threads.
+ Since the last two issues shouldn't really stop the tests from being
+ written, assume for now that it is all due to the first case
+ LocalDiscard
+ LocalFlags
+*/
+/* In addition, these features aren't being tested
+ LMEM_DISCADABLE
+ LMEM_NOCOMPACT
+*/
+static void test_Local(void)
+{
+ ULONG memchunk;
+ HLOCAL mem1,mem2,mem2a,mem2b;
+ UCHAR *mem2ptr;
+ UINT error,i;
+ memchunk=100000;
+
+/* Check that a normal alloc works */
+ mem1=LocalAlloc(0,memchunk);
+ ok(mem1!=NULL,"LocalAlloc failed: error=%ld\n",GetLastError());
+ if(mem1) {
+ ok(LocalSize(mem1)>=memchunk, "LocalAlloc should return a big enough memory block\n");
+ }
+
+/* Check that a 'zeroing' and lock alloc works */
+ mem2=LocalAlloc(LMEM_ZEROINIT|LMEM_MOVEABLE,memchunk);
+ ok(mem2!=NULL,"LocalAlloc failed: error=%ld\n",GetLastError());
+ if(mem2) {
+ ok(LocalSize(mem2)>=memchunk,"LocalAlloc should return a big enough memory block\n");
+ mem2ptr=LocalLock(mem2);
+ ok(mem2ptr!=NULL,"LocalLock: error=%ld\n",GetLastError());
+ if(mem2ptr) {
+ error=0;
+ for(i=0;i<memchunk;i++) {
+ if(mem2ptr[i]!=0) {
+ error=1;
+ }
+ }
+ ok(!error,"LocalAlloc should have zeroed out it's allocated memory\n");
+ SetLastError(0);
+ error=LocalUnlock(mem2);
+ ok(error==0 && GetLastError()==NO_ERROR,
+ "LocalUnlock Failed: rc=%d err=%ld\n",error,GetLastError());
+ }
+ }
+ mem2a=LocalFree(mem2);
+ ok(mem2a==NULL, "LocalFree failed: %p\n",mem2a);
+
+/* Reallocate mem2 as moveable memory */
+ mem2=LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,memchunk);
+ ok(mem2!=NULL, "LocalAlloc failed to create moveable memory, error=%ld\n",GetLastError());
+
+/* Check that ReAllocing memory works as expected */
+ mem2a=LocalReAlloc(mem2,2*memchunk,LMEM_MOVEABLE | LMEM_ZEROINIT);
+ ok(mem2a!=NULL,"LocalReAlloc failed, error=%ld\n",GetLastError());
+ if(mem2a) {
+ ok(LocalSize(mem2a)>=2*memchunk,"LocalReAlloc failed\n");
+ mem2ptr=LocalLock(mem2a);
+ ok(mem2ptr!=NULL,"LocalLock Failed\n");
+ if(mem2ptr) {
+ error=0;
+ for(i=0;i<memchunk;i++) {
+ if(mem2ptr[memchunk+i]!=0) {
+ error=1;
+ }
+ }
+ ok(!error,"LocalReAlloc should have zeroed out it's allocated memory\n");
+/* Check that LocalHandle works */
+ mem2b=LocalHandle(mem2ptr);
+ ok(mem2b==mem2a,"LocalHandle didn't return the correct memory handle\n");
+/* Check that we can't discard locked memory */
+ mem2b=LocalDiscard(mem2a);
+ ok(mem2b==NULL,"Discarded memory we shouldn't have\n");
+ SetLastError(NO_ERROR);
+ ok(!LocalUnlock(mem2a) && GetLastError()==NO_ERROR, "LocalUnlock Failed\n");
+ }
+ }
+ if(mem1) {
+ ok(LocalFree(mem1)==NULL,"LocalFree failed\n");
+ }
+ if(mem2a) {
+ ok(LocalFree(mem2a)==NULL,"LocalFree failed\n");
+ } else {
+ ok(LocalFree(mem2)==NULL,"LocalFree failed\n");
+ }
+}
+
+/* The Virtual* routines are not tested as thoroughly,
+ since I don't really understand how to use them correctly :)
+ The following routines are not tested at all
+ VirtualAllocEx
+ VirtualFreeEx
+ VirtualLock
+ VirtualProtect
+ VirtualProtectEx
+ VirtualQuery
+ VirtualQueryEx
+ VirtualUnlock
+ And the only features (flags) being tested are
+ MEM_COMMIT
+ MEM_RELEASE
+ PAGE_READWRITE
+ Testing the rest requires using exceptions, which I really don't
+ understand well
+*/
+static void test_Virtual(void)
+{
+ SYSTEM_INFO sysInfo;
+ ULONG memchunk;
+ UCHAR *mem1;
+ UINT error,i;
+
+/* Retrieve the page size for this system */
+ sysInfo.dwPageSize=0;
+ GetSystemInfo(&sysInfo);
+ ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size\n");
+
+/* Choose a reasonable allocation size */
+ memchunk=10*sysInfo.dwPageSize;
+
+/* Check that a normal alloc works */
+ mem1=VirtualAlloc(NULL,memchunk,MEM_COMMIT,PAGE_READWRITE);
+ ok(mem1!=NULL,"VirtualAlloc failed\n");
+ if(mem1) {
+/* check that memory is initialized to 0 */
+ error=0;
+ for(i=0;i<memchunk;i++) {
+ if(mem1[i]!=0) {
+ error=1;
+ }
+ }
+ ok(!error,"VirtualAlloc did not initialize memory to '0's\n");
+/* Check that we can read/write to memory */
+ error=0;
+ for(i=0;i<memchunk;i+=100) {
+ mem1[i]='a';
+ if(mem1[i]!='a') {
+ error=1;
+ }
+ }
+ ok(!error,"Virtual memory was not writable\n");
+ }
+ ok(VirtualFree(mem1,0,MEM_RELEASE),"VirtualFree failed\n");
+}
+START_TEST(alloc)
+{
+ test_Heap();
+ test_Global();
+ test_Local();
+ test_Virtual();
+}
Property changes on: trunk/reactos/regtests/winetests/kernel32/alloc.c
___________________________________________________________________
Name: svn:executable
+ *
--- trunk/reactos/regtests/winetests/kernel32/atom.c 2005-08-07 03:00:44 UTC (rev 17136)
+++ trunk/reactos/regtests/winetests/kernel32/atom.c 2005-08-07 03:14:17 UTC (rev 17137)
@@ -0,0 +1,346 @@
+/*
+ * Unit tests for atom functions
+ *
+ * Copyright (c) 2002 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "wine/test.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+
+static const WCHAR foobarW[] = {'f','o','o','b','a','r',0};
+static const WCHAR FOOBARW[] = {'F','O','O','B','A','R',0};
+static const WCHAR _foobarW[] = {'_','f','o','o','b','a','r',0};
+
+static BOOL unicode_OS;
+
+static void test_add_atom(void)
+{
+ ATOM atom, w_atom;
+ int i;
+
+ SetLastError( 0xdeadbeef );
+ atom = GlobalAddAtomA( "foobar" );
+ ok( atom >= 0xc000, "bad atom id %x\n", atom );
+ ok( GetLastError() == 0xdeadbeef, "GlobalAddAtomA set last error\n" );
+
+ /* Verify that it can be found (or not) appropriately */
+ ok( GlobalFindAtomA( "foobar" ) == atom, "could not find atom foobar\n" );
+ ok( GlobalFindAtomA( "FOOBAR" ) == atom, "could not find atom FOOBAR\n" );
+ ok( !GlobalFindAtomA( "_foobar" ), "found _foobar\n" );
+
+ /* Add the same atom, specifying string as unicode; should
+ * find the first one, not add a new one */
+ SetLastError( 0xdeadbeef );
+ w_atom = GlobalAddAtomW( foobarW );
+ if (w_atom && GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ unicode_OS = TRUE;
+ else
+ trace("WARNING: Unicode atom APIs are not supported on this platform\n");
+
+ if (unicode_OS)
+ {
+ ok( w_atom == atom, "Unicode atom does not match ASCII\n" );
+ ok( GetLastError() == 0xdeadbeef, "GlobalAddAtomW set last error\n" );
+ }
+
+ /* Verify that it can be found (or not) appropriately via unicode name */
+ if (unicode_OS)
+ {
+ ok( GlobalFindAtomW( foobarW ) == atom, "could not find atom foobar\n" );
+ ok( GlobalFindAtomW( FOOBARW ) == atom, "could not find atom FOOBAR\n" );
+ ok( !GlobalFindAtomW( _foobarW ), "found _foobar\n" );
+ }
+
+ /* Test integer atoms
+ * (0x0001 .. 0xbfff) should be valid;
+ * (0xc000 .. 0xffff) should be invalid */
+
+ SetLastError( 0xdeadbeef );
+ ok( GlobalAddAtomA(0) == 0 && GetLastError() == 0xdeadbeef, "succeeded to add atom 0\n" );
+ if (unicode_OS)
+ {
+ SetLastError( 0xdeadbeef );
+ ok( GlobalAddAtomW(0) == 0 && GetLastError() == 0xdeadbeef, "succeeded to add atom 0\n" );
+ }
+
+ SetLastError( 0xdeadbeef );
+ for (i = 1; i <= 0xbfff; i++)
+ {
+ SetLastError( 0xdeadbeef );
+ ok( GlobalAddAtomA((LPCSTR)i) == i && GetLastError() == 0xdeadbeef,
+ "failed to add atom %x\n", i );
+ if (unicode_OS)
+ {
+ SetLastError( 0xdeadbeef );
+ ok( GlobalAddAtomW((LPCWSTR)i) == i && GetLastError() == 0xdeadbeef,
+ "failed to add atom %x\n", i );
+ }
+ }
+
+ for (i = 0xc000; i <= 0xffff; i++)
+ {
+ ok( !GlobalAddAtomA((LPCSTR)i), "succeeded adding %x\n", i );
+ if (unicode_OS)
+ ok( !GlobalAddAtomW((LPCWSTR)i), "succeeded adding %x\n", i );
+ }
+}
+
+static void test_get_atom_name(void)
+{
+ char buf[10];
+ WCHAR bufW[10];
+ int i;
+ UINT len;
+ static const WCHAR resultW[] = {'f','o','o','b','a','r',0,'.','.','.'};
+
+ ATOM atom = GlobalAddAtomA( "foobar" );
+
+ /* Get the name of the atom we added above */
+ memset( buf, '.', sizeof(buf) );
+ len = GlobalGetAtomNameA( atom, buf, 10 );
+ ok( len == strlen("foobar"), "bad length %d\n", len );
+ ok( !memcmp( buf, "foobar\0...", 10 ), "bad buffer contents\n" );
+
+ /* Repeat, unicode-style */
+ if (unicode_OS)
+ {
+ for (i = 0; i < 10; i++) bufW[i] = '.';
+ SetLastError( 0xdeadbeef );
+ len = GlobalGetAtomNameW( atom, bufW, 10 );
+ ok( len && GetLastError() == 0xdeadbeef, "GlobalGetAtomNameW failed\n" );
+ ok( len == lstrlenW(foobarW), "bad length %d\n", len );
+ ok( !memcmp( bufW, resultW, 10*sizeof(WCHAR) ), "bad buffer contents\n" );
+ }
+
+ /* Check error code returns */
+ memset(buf, '.', 10);
+ ok( !GlobalGetAtomNameA( atom, buf, 0 ), "succeeded\n" );
+ ok( !memcmp( buf, "..........", 10 ), "should not touch buffer\n" );
+
+ if (unicode_OS)
+ {
+ static const WCHAR sampleW[10] = {'.','.','.','.','.','.','.','.','.','.'};
+
+ for (i = 0; i < 10; i++) bufW[i] = '.';
+ ok( !GlobalGetAtomNameW( atom, bufW, 0 ), "succeeded\n" );
+ ok( !memcmp( bufW, sampleW, 10 * sizeof(WCHAR) ), "should not touch buffer\n" );
+ }
+
+ /* Test integer atoms */
+ for (i = 0; i <= 0xbfff; i++)
+ {
+ memset( buf, 'a', 10 );
+ len = GlobalGetAtomNameA( (ATOM)i, buf, 10 );
+ if (i)
+ {
+ char res[20];
+ ok( (len > 1) && (len < 7), "bad length %d\n", len );
+ sprintf( res, "#%d", i );
+ memset( res + strlen(res) + 1, 'a', 10 );
+ ok( !memcmp( res, buf, 10 ), "bad buffer contents %s\n", buf );
+ }
+ else
+ ok( !len, "bad length %d\n", len );
+ }
+}
+
+static void test_error_handling(void)
+{
+ char buffer[260];
+ WCHAR bufferW[260];
+ int i;
+
+ memset( buffer, 'a', 256 );
+ buffer[256] = 0;
+ ok( !GlobalAddAtomA(buffer), "add succeeded\n" );
+ ok( !GlobalFindAtomA(buffer), "find succeeded\n" );
+
+ if (unicode_OS)
+ {
+ for (i = 0; i < 256; i++) bufferW[i] = 'b';
+ bufferW[256] = 0;
+ ok( !GlobalAddAtomW(bufferW), "add succeeded\n" );
+ ok( !GlobalFindAtomW(bufferW), "find succeeded\n" );
+ }
+}
+
+static void test_local_add_atom(void)
+{
+ ATOM atom, w_atom;
+ int i;
+
+ SetLastError( 0xdeadbeef );
+ atom = AddAtomA( "foobar" );
+ ok( atom >= 0xc000, "bad atom id %x\n", atom );
+ ok( GetLastError() == 0xdeadbeef, "AddAtomA set last error\n" );
+
+ /* Verify that it can be found (or not) appropriately */
+ ok( FindAtomA( "foobar" ) == atom, "could not find atom foobar\n" );
+ ok( FindAtomA( "FOOBAR" ) == atom, "could not find atom FOOBAR\n" );
+ ok( !FindAtomA( "_foobar" ), "found _foobar\n" );
+
+ /* Add the same atom, specifying string as unicode; should
+ * find the first one, not add a new one */
+ SetLastError( 0xdeadbeef );
+ w_atom = AddAtomW( foobarW );
+ if (w_atom && GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ unicode_OS = TRUE;
+ else
+ trace("WARNING: Unicode atom APIs are not supported on this platform\n");
+
+ if (unicode_OS)
+ {
+ ok( w_atom == atom, "Unicode atom does not match ASCII\n" );
+ ok( GetLastError() == 0xdeadbeef, "AddAtomW set last error\n" );
+ }
+
+ /* Verify that it can be found (or not) appropriately via unicode name */
+ if (unicode_OS)
+ {
+ ok( FindAtomW( foobarW ) == atom, "could not find atom foobar\n" );
+ ok( FindAtomW( FOOBARW ) == atom, "could not find atom FOOBAR\n" );
+ ok( !FindAtomW( _foobarW ), "found _foobar\n" );
+ }
+
+ /* Test integer atoms
+ * (0x0001 .. 0xbfff) should be valid;
+ * (0xc000 .. 0xffff) should be invalid */
+
+ SetLastError( 0xdeadbeef );
+ ok( AddAtomA(0) == 0 && GetLastError() == 0xdeadbeef, "succeeded to add atom 0\n" );
+ if (unicode_OS)
+ {
+ SetLastError( 0xdeadbeef );
+ ok( AddAtomW(0) == 0 && GetLastError() == 0xdeadbeef, "succeeded to add atom 0\n" );
+ }
+
+ SetLastError( 0xdeadbeef );
+ for (i = 1; i <= 0xbfff; i++)
+ {
+ SetLastError( 0xdeadbeef );
+ ok( AddAtomA((LPCSTR)i) == i && GetLastError() == 0xdeadbeef,
+ "failed to add atom %x\n", i );
+ if (unicode_OS)
+ {
+ SetLastError( 0xdeadbeef );
+ ok( AddAtomW((LPCWSTR)i) == i && GetLastError() == 0xdeadbeef,
+ "failed to add atom %x\n", i );
+ }
+ }
+
+ for (i = 0xc000; i <= 0xffff; i++)
+ {
+ ok( !AddAtomA((LPCSTR)i), "succeeded adding %x\n", i );
+ if (unicode_OS)
+ ok( !AddAtomW((LPCWSTR)i), "succeeded adding %x\n", i );
+ }
+}
+
+static void test_local_get_atom_name(void)
+{
+ char buf[10];
+ WCHAR bufW[10];
+ int i;
+ UINT len;
+ static const WCHAR resultW[] = {'f','o','o','b','a','r',0,'.','.','.'};
+
+ ATOM atom = AddAtomA( "foobar" );
+
+ /* Get the name of the atom we added above */
+ memset( buf, '.', sizeof(buf) );
+ len = GetAtomNameA( atom, buf, 10 );
+ ok( len == strlen("foobar"), "bad length %d\n", len );
+ ok( !memcmp( buf, "foobar\0...", 10 ), "bad buffer contents\n" );
+
+ /* Repeat, unicode-style */
+ if (unicode_OS)
+ {
+ for (i = 0; i < 10; i++) bufW[i] = '.';
+ SetLastError( 0xdeadbeef );
+ len = GetAtomNameW( atom, bufW, 10 );
+ ok( len && GetLastError() == 0xdeadbeef, "GetAtomNameW failed\n" );
+ ok( len == lstrlenW(foobarW), "bad length %d\n", len );
+ ok( !memcmp( bufW, resultW, 10*sizeof(WCHAR) ), "bad buffer contents\n" );
+ }
+
+ /* Check error code returns */
+ memset(buf, '.', 10);
+ ok( !GetAtomNameA( atom, buf, 0 ), "succeeded\n" );
+ ok( !memcmp( buf, "..........", 10 ), "should not touch buffer\n" );
+
+ if (unicode_OS)
+ {
+ static const WCHAR sampleW[10] = {'.','.','.','.','.','.','.','.','.','.'};
+
+ for (i = 0; i < 10; i++) bufW[i] = '.';
+ ok( !GetAtomNameW( atom, bufW, 0 ), "succeeded\n" );
+ ok( !memcmp( bufW, sampleW, 10 * sizeof(WCHAR) ), "should not touch buffer\n" );
+ }
+
+ /* Test integer atoms */
+ for (i = 0; i <= 0xbfff; i++)
+ {
+ memset( buf, 'a', 10 );
+ len = GetAtomNameA( (ATOM)i, buf, 10 );
+ if (i)
+ {
+ char res[20];
+ ok( (len > 1) && (len < 7), "bad length %d\n", len );
+ sprintf( res, "#%d", i );
+ memset( res + strlen(res) + 1, 'a', 10 );
+ ok( !memcmp( res, buf, 10 ), "bad buffer contents %s\n", buf );
+ }
+ else
+ ok( !len, "bad length %d\n", len );
+ }
+}
+
+static void test_local_error_handling(void)
+{
+ char buffer[260];
+ WCHAR bufferW[260];
+ int i;
+
+ memset( buffer, 'a', 256 );
+ buffer[256] = 0;
+ ok( !AddAtomA(buffer), "add succeeded\n" );
+ ok( !FindAtomA(buffer), "find succeeded\n" );
+
+ if (unicode_OS)
+ {
+ for (i = 0; i < 256; i++) bufferW[i] = 'b';
+ bufferW[256] = 0;
+ ok( !AddAtomW(bufferW), "add succeeded\n" );
+ ok( !FindAtomW(bufferW), "find succeeded\n" );
+ }
+}
+
+
+START_TEST(atom)
+{
+ test_add_atom();
+ test_get_atom_name();
+ test_error_handling();
+ test_local_add_atom();
+ test_local_get_atom_name();
+ test_local_error_handling();
+}
Property changes on: trunk/reactos/regtests/winetests/kernel32/atom.c
___________________________________________________________________
Name: svn:executable
+ *
--- trunk/reactos/regtests/winetests/kernel32/change.c 2005-08-07 03:00:44 UTC (rev 17136)
+++ trunk/reactos/regtests/winetests/kernel32/change.c 2005-08-07 03:14:17 UTC (rev 17137)
@@ -0,0 +1,242 @@
+/*
+ * Tests for file change notification functions
+ *
+ * Copyright (c) 2004 Hans Leidekker
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* TODO: - security attribute changes
+ * - compound filter and multiple notifications
+ * - subtree notifications
+ * - non-documented flags FILE_NOTIFY_CHANGE_LAST_ACCESS and
+ * FILE_NOTIFY_CHANGE_CREATION
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "wine/test.h"
+#include <windef.h>
+#include <winbase.h>
+
+static DWORD CALLBACK NotificationThread(LPVOID arg)
+{
+ HANDLE change = (HANDLE) arg;
+ BOOL ret = FALSE;
+ DWORD status;
+
+ status = WaitForSingleObject(change, 100);
+
+ if (status == WAIT_OBJECT_0 ) {
+ ret = FindNextChangeNotification(change);
+ }
+
+ ret = FindCloseChangeNotification(change);
+ ok( ret, "FindCloseChangeNotification error: %ld\n",
+ GetLastError());
+
+ ExitThread((DWORD)ret);
+}
+
+static HANDLE StartNotificationThread(LPCSTR path, BOOL subtree, DWORD flags)
+{
+ HANDLE change, thread;
+ DWORD threadId;
+
+ change = FindFirstChangeNotificationA(path, subtree, flags);
+ ok(change != INVALID_HANDLE_VALUE, "FindFirstChangeNotification error: %ld\n", GetLastError());
+
+ thread = CreateThread(NULL, 0, NotificationThread, (LPVOID)change,
+ 0, &threadId);
+ ok(thread != INVALID_HANDLE_VALUE, "CreateThread error: %ld\n", GetLastError());
+
+ return thread;
+}
+
+static DWORD FinishNotificationThread(HANDLE thread)
+{
+ DWORD status, exitcode;
+
+ status = WaitForSingleObject(thread, 5000);
+ ok(status == WAIT_OBJECT_0, "WaitForSingleObject status %ld error %ld\n", status, GetLastError());
+
+ ok(GetExitCodeThread(thread, &exitcode), "Could not retrieve thread exit code\n");
+
+ return exitcode;
+}
+
+static void test_FindFirstChangeNotification(void)
+{
+ HANDLE change, file, thread;
+ DWORD attributes, count;
+ BOOL ret;
+
+ char workdir[MAX_PATH], dirname1[MAX_PATH], dirname2[MAX_PATH];
+ char filename1[MAX_PATH], filename2[MAX_PATH];
+ static const char prefix[] = "FCN";
+ char buffer[2048];
+
+ /* pathetic checks */
+
+ change = FindFirstChangeNotificationA("not-a-file", FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
+ ok(change == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND,
+ "FindFirstChangeNotification error: %ld\n", GetLastError());
+
+ if (0) /* This documents win2k behavior. It crashes on win98. */
+ {
+ change = FindFirstChangeNotificationA(NULL, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
+ ok(change == NULL && GetLastError() == ERROR_PATH_NOT_FOUND,
+ "FindFirstChangeNotification error: %ld\n", GetLastError());
+ }
+
+ ret = FindNextChangeNotification(NULL);
+ ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "FindNextChangeNotification error: %ld\n",
+ GetLastError());
+
+ ret = FindCloseChangeNotification(NULL);
+ ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "FindCloseChangeNotification error: %ld\n",
+ GetLastError());
+
+ ret = GetTempPathA(MAX_PATH, workdir);
+ ok(ret, "GetTempPathA error: %ld\n", GetLastError());
+
+ lstrcatA(workdir, "testFileChangeNotification");
+
+ ret = CreateDirectoryA(workdir, NULL);
+ ok(ret, "CreateDirectoryA error: %ld\n", GetLastError());
+
+ ret = GetTempFileNameA(workdir, prefix, 0, filename1);
+ ok(ret, "GetTempFileNameA error: %ld\n", GetLastError());
+
+ file = CreateFileA(filename1, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %ld\n", GetLastError());
+ ret = CloseHandle(file);
+ ok( ret, "CloseHandle error: %ld\n", GetLastError());
+
+ /* Try to register notification for a file. win98 and win2k behave differently here */
+ change = FindFirstChangeNotificationA(filename1, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
+ ok(change == INVALID_HANDLE_VALUE && (GetLastError() == ERROR_DIRECTORY ||
+ GetLastError() == ERROR_FILE_NOT_FOUND),
+ "FindFirstChangeNotification error: %ld\n", GetLastError());
+
+ lstrcpyA(dirname1, filename1);
+ lstrcatA(dirname1, "dir");
+
+ ret = CreateDirectoryA(dirname1, NULL);
+ ok(ret, "CreateDirectoryA error: %ld\n", GetLastError());
+
+ /* What if we remove the directory we registered notification for? */
+ thread = StartNotificationThread(dirname1, FALSE, FILE_NOTIFY_CHANGE_DIR_NAME);
+ ret = RemoveDirectoryA(dirname1);
+ ok(ret, "RemoveDirectoryA error: %ld\n", GetLastError());
+
+ /* win98 and win2k behave differently here */
+ ret = FinishNotificationThread(thread);
+ ok(ret || !ret, "You'll never read this\n");
+
+ /* functional checks */
+
+ /* Create a directory */
+ thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_DIR_NAME);
+ ret = CreateDirectoryA(dirname1, NULL);
+ ok(ret, "CreateDirectoryA error: %ld\n", GetLastError());
+ ok(FinishNotificationThread(thread), "Missed notification\n");
+
+ lstrcpyA(dirname2, dirname1);
+ lstrcatA(dirname2, "new");
+
+ /* Rename a directory */
+ thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_DIR_NAME);
+ ret = MoveFileA(dirname1, dirname2);
+ ok(ret, "MoveFileA error: %ld\n", GetLastError());
+ ok(FinishNotificationThread(thread), "Missed notification\n");
+
+ /* Delete a directory */
+ thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_DIR_NAME);
+ ret = RemoveDirectoryA(dirname2);
+ ok(ret, "RemoveDirectoryA error: %ld\n", GetLastError());
+ ok(FinishNotificationThread(thread), "Missed notification\n");
+
+ lstrcpyA(filename2, filename1);
+ lstrcatA(filename2, "new");
+
+ /* Rename a file */
+ thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
+ ret = MoveFileA(filename1, filename2);
+ ok(ret, "MoveFileA error: %ld\n", GetLastError());
+ ok(FinishNotificationThread(thread), "Missed notification\n");
+
+ /* Delete a file */
+ thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
+ ret = DeleteFileA(filename2);
+ ok(ret, "DeleteFileA error: %ld\n", GetLastError());
+ ok(FinishNotificationThread(thread), "Missed notification\n");
+
+ /* Create a file */
+ thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
+ file = CreateFileA(filename2, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %ld\n", GetLastError());
+ ret = CloseHandle(file);
+ ok( ret, "CloseHandle error: %ld\n", GetLastError());
+ ok(FinishNotificationThread(thread), "Missed notification\n");
+
+ attributes = GetFileAttributesA(filename2);
+ ok(attributes != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA error: %ld\n", GetLastError());
+ attributes &= FILE_ATTRIBUTE_READONLY;
+
+ /* Change file attributes */
+ thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_ATTRIBUTES);
+ ret = SetFileAttributesA(filename2, attributes);
+ ok(ret, "SetFileAttributesA error: %ld\n", GetLastError());
+ ok(FinishNotificationThread(thread), "Missed notification\n");
+
+ /* Change last write time by writing to a file */
+ thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE);
+ file = CreateFileA(filename2, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %ld\n", GetLastError());
+ ret = WriteFile(file, buffer, sizeof(buffer), &count, NULL);
+ ok(ret && count == sizeof(buffer), "WriteFile error: %ld\n", GetLastError());
+ ret = CloseHandle(file);
+ ok( ret, "CloseHandle error: %ld\n", GetLastError());
+ ok(FinishNotificationThread(thread), "Missed notification\n");
+
+ /* Change file size by truncating a file */
+ thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_SIZE);
+ file = CreateFileA(filename2, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %ld\n", GetLastError());
+ ret = WriteFile(file, buffer, sizeof(buffer) / 2, &count, NULL);
+ ok(ret && count == sizeof(buffer) / 2, "WriteFileA error: %ld\n", GetLastError());
[truncated at 1000 lines; 12413 more skipped]