added kernel32 wine tests
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

Added: trunk/reactos/regtests/winetests/kernel32/alloc.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
   + *

Added: trunk/reactos/regtests/winetests/kernel32/atom.c
--- 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
   + *

Added: trunk/reactos/regtests/winetests/kernel32/change.c
--- 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]