winedos: win16 tests

Markus Amsler markus.amsler at oribi.org
Fri Oct 15 09:56:42 CDT 2004


Changelog:
* add win16 test suite.
-------------- next part --------------
diff -urN dlls/winedos_filesep/tests_win16/dosmem.c dlls/winedos/tests_win16/dosmem.c
--- dlls/winedos_filesep/tests_win16/dosmem.c	1970-01-01 01:00:00.000000000 +0100
+++ dlls/winedos/tests_win16/dosmem.c	2004-09-18 16:56:32.000000000 +0200
@@ -0,0 +1,326 @@
+/*
+ * win16 dos memory test programm
+ *
+ * Copyright 2004 Markus Amsler
+ *
+ * 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
+ */
+ 
+/*
+ * Compiled with Open Watcom C16 Version 1.3 (http://www.openwatcom.org)
+ *   > wcl -l=windows dosmem.c
+ *
+ * Tests following functions:
+ *   GlobalDosAlloc
+ *   GlobalDosFree
+ *   GlobalFree
+ *   GlobalReAlloc
+ *   GlobelHandle
+ *   GlobalSize
+ *
+ * FIXME: test more functions
+ *
+ * direct DOS memory manipulation with int 21 didn't work in win 3.11 nor in 
+ * ntvdm (but in wine :-) ).
+ *
+ * FIXME: add dpmi memory tests
+ * FIXME: fill allocated memory
+ */
+ 
+#include <stdio.h>
+#include <windows.h>
+#include <toolhelp.h>
+#include <i86.h>
+
+
+// #define DEBUG 0;
+/* a few useful undocumented KERNEL functions */
+extern DWORD FAR PASCAL GetSelectorBase(unsigned sel);
+extern DWORD FAR PASCAL GetSelectorLimit(unsigned sel);
+extern void FAR PASCAL SetSelectorBase(unsigned sel, DWORD base);
+extern void FAR PASCAL SetSelectorLimit(unsigned sel, DWORD limit);
+
+
+
+
+
+int dos_free_paragraphs (void){
+	union REGS rin;
+	union REGS rout;
+
+	rin.x.ax=0x4800;
+	rin.x.bx=0xffff;
+
+	int86(0x21,&rin,&rout);
+
+	if (!rout.x.cflag){
+		printf("dos_free_paragraphs failed!\n");
+		printf(" context in: ");
+		dump_context (&rin);
+		printf(" context out: ");
+		dump_context (&rout);
+		return 0;
+	}
+	return rout.x.bx;
+}
+
+void dump_context (union REGS *r){
+	printf ("ax=%04x bx=%04xh cx=%04xh dx=%04xh cflag=%04xh\n", r->x.ax, r->x.bx, r->x.cx, r->x.dx, r->x.cflag); 
+	
+}
+
+int dos_alloc (WORD paras){
+	union REGS rin;
+	union REGS rout;
+
+	rin.x.ax=0x4800;
+	rin.x.bx=paras;
+
+	int86(0x21,&rin,&rout);
+#ifdef DEBUG
+  dump_context (&rout);
+#endif
+
+	if (rout.x.cflag){
+		printf("dos_alloc failed!\n");
+		printf(" context in: ");
+		dump_context (&rin);
+		printf(" context out: ");
+		dump_context (&rout);
+		return 0;
+	}
+	return 1;
+}
+
+
+
+
+
+
+
+
+
+
+/*
+ * checks wether the given amount of memory could be reserved
+ */
+BOOL got_memory (DWORD size){
+	DWORD ret;
+	WORD sel;
+	
+	ret = GlobalDosAlloc (size);
+	if (!ret) return FALSE;
+	GlobalDosFree (LOWORD(ret));
+	return TRUE;
+}
+
+/*
+ * returns the largest block size in bytes that could be reserved.
+ * pretty time consuming, but good testing. It probes with alloc / free
+ */
+DWORD dos_largest (void){
+	DWORD max, current, step;
+	BOOL gotit;
+	
+	/* do some sort of binary search */
+	max = 0x100000; 
+	current = max >> 1;
+	step = max >> 2;
+	
+	while (step>0){
+		gotit = got_memory(current);
+#ifdef DEBUG
+		printf ("dos_largest max=%04x%04xh current=%04x%04xh step=%04x%04xh gotit=%d\n", HIWORD(max), LOWORD(max), 
+		           HIWORD(current), LOWORD(current), HIWORD(step), LOWORD(step), gotit);
+#endif
+		if (gotit){
+			current += step;	
+		}else{
+			current -= step;
+		}
+		step = step >> 1;
+	}
+
+	if (current==1){
+		/* FIXME: 1 byte is not eactly no memory */
+		return 0;
+	}
+
+	if (! got_memory(current-1)){
+		printf("ERROR: didn't got_memory(current-1) should not happen\n");
+		return 0;
+	}
+
+	if (got_memory(current)){
+		printf("ERROR: got_memory(current) should not happen\n");
+		return 0;
+	}
+
+	if (got_memory(current+1)){
+		printf("ERROR: got_memory(current+1) should not happen\n");
+		return 0;
+	}
+
+	return current-1;
+}
+
+
+/*
+ * The total amount of DOS memory in bytes.
+ * pretty time consuming, but good testing. It sums up the largest blocks recursivly.
+ */
+DWORD dos_available(void){
+	DWORD ret, largest, avail;
+	WORD sel;
+	
+	largest = dos_largest();
+	if (!largest){
+		/* recursion termination: no DOS memory */
+#ifdef DEBUG
+		printf("dos_available return 0\n");
+#endif
+		return 0;
+	}
+
+	ret = GlobalDosAlloc (largest);
+	if (!ret) return 0;
+	avail = dos_available();
+	GlobalDosFree (LOWORD(ret));
+
+#ifdef DEBUG
+	printf("dos_available largest=%04x%04xh available=%04x%04xh\n", HIWORD(largest), LOWORD(largest)
+	          , HIWORD(avail), LOWORD(avail));
+#endif
+	return largest + avail;
+}
+
+/* returns allocation overhead for given block size or -1 on error */
+int dos_alloc_overhead (DWORD size){
+	DWORD largest_start, avail_start;
+	DWORD avail,dos;
+	int ret;
+	
+	avail = dos_available();
+	dos = GlobalDosAlloc (size);
+	if (!dos){
+		return -1;
+	}
+	ret = avail - dos_available() - size;
+	GlobalDosFree(LOWORD (dos));
+	return ret;
+}
+
+
+int main (int argc, char** argv){
+	DWORD largest_start, avail_start;
+	DWORD test_size;
+	DWORD avail, avail2, avail3, size;
+	DWORD dos, dos2, ret;
+	WORD sel, sel2, seg, seg2;
+	DWORD handle, h2, h3, h4;
+
+	printf ("Win16 DOS memory test programm\n\n");
+
+	/* 
+	 * First check if dos_largest and dos_available works.
+	 * Very good test for GlobasDosAlloc and GlobalDosFree
+	 */
+	printf ("Checking available memory\n");
+	largest_start = dos_largest();
+	printf ("  Largest Block %04x%04xh bytes\n", HIWORD(largest_start), LOWORD(largest_start));
+
+	avail_start = dos_available();
+	printf ("  Available memory %04x%04xh bytes\n", HIWORD(avail_start), LOWORD(avail_start));
+
+	/* 
+	 */
+	printf ("\nTesting GlobalReAlloc and GlobalHandle\n");
+	test_size = (largest_start/3) & 0xfffff000;
+#ifdef DEBUG
+	printf ("  test_size %04x%04xh bytes\n", HIWORD(test_size), LOWORD(test_size));
+#endif
+  dos = GlobalDosAlloc (test_size);
+  if (!dos){
+		printf("ERROR: GlobalDosAlloc (0x1000) failed\n");  	
+  }
+	avail = dos_available();
+#ifdef DEBUG
+	printf ("  avail %04x%04xh bytes\n", HIWORD(avail), LOWORD(avail));
+#endif
+ 	handle = GlobalHandle (LOWORD(dos));
+  if (!handle){
+		printf("ERROR: GlobalHandle failed\n");  	
+  }
+	/* test shrinking */
+  h2 = GlobalReAlloc(handle, test_size>>1, 0);
+#ifdef DEBUG
+	printf ("  handle %04x%04xh\n", HIWORD(handle), LOWORD(handle));
+	printf ("  h2 %04x%04xh\n", HIWORD(h2), LOWORD(h2));
+#endif
+  if (!h2){
+		printf("ERROR: GlobalReAlloc 1 failed\n");  	
+  }
+	avail2 = dos_available();
+#ifdef DEBUG
+	printf ("  avail2 %04x%04xh bytes\n", HIWORD(avail2), LOWORD(avail2));
+#endif
+  if ( (avail+ (test_size>>1)) !=avail2 ){
+		printf("ERROR: shrink arithmetic failed\n");  	
+	  printf ("  avail %04x%04xh bytes\n", HIWORD(avail), LOWORD(avail));
+	  printf ("  avail2 %04x%04xh bytes\n", HIWORD(avail2), LOWORD(avail2));
+	  printf ("  test_size>>1 %04x%04xh bytes\n", HIWORD(test_size>>1), LOWORD(test_size>>1));
+  }
+	/* test growing */
+  h2 = GlobalReAlloc(h2, test_size<<1, 0);
+#ifdef DEBUG
+	printf ("  h2 %04x%04xh\n", HIWORD(h2), LOWORD(h2));
+#endif
+  if (!h2){
+		printf("ERROR: GlobalReAlloc 2 failed\n");  	
+  }
+	avail2 = dos_available();
+#ifdef DEBUG
+	printf ("  avail2 %04x%04xh bytes\n", HIWORD(avail2), LOWORD(avail2));
+#endif
+  if ( (avail-test_size) !=avail2 ){
+		printf("ERROR: grow arithmetic failed\n");  	
+	  printf ("  avail %04x%04xh bytes\n", HIWORD(avail), LOWORD(avail));
+	  printf ("  avail2 %04x%04xh bytes\n", HIWORD(avail2), LOWORD(avail2));
+	  printf ("  test_size %04x%04xh bytes\n", HIWORD(test_size), LOWORD(test_size));
+  }
+
+  GlobalDosFree(h2);
+	avail3 = dos_available();
+#ifdef DEBUG
+	printf ("  avail3 %04x%04xh bytes\n", HIWORD(avail3), LOWORD(avail3));
+#endif
+  if (avail3==avail2){
+		printf("ERROR: GlobalDosFree had no effect\n");
+	}
+
+
+	printf ("\nTesting wether cleanup worked\n");
+  if (avail_start!=avail3){
+		printf("ERROR: not all memory was freed\n");
+	}
+  if (largest_start!=dos_largest()){
+		printf("ERROR: largest differ\n");
+	}  
+  
+
+	printf ("\n\nDONE\n");
+
+	return 0;
+}
diff -urN dlls/winedos_filesep/tests_win16/file.c dlls/winedos/tests_win16/file.c
--- dlls/winedos_filesep/tests_win16/file.c	1970-01-01 01:00:00.000000000 +0100
+++ dlls/winedos/tests_win16/file.c	2004-10-15 01:08:59.000000000 +0200
@@ -0,0 +1,1426 @@
+/*
+ * Unit tests for win16 file functions
+ *
+ * Copyright (c) 2002, 2004 Jakob Eriksson
+ * Copyright (c) 2004 Markus Amsler
+ *
+ * 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
+ *
+ */
+
+/*
+ * Compiled with Open Watcom C16 Version 1.3 (http://www.openwatcom.org)
+ *   > wcl -l=windows file.c
+ *
+ */
+ 
+#include <stdio.h>
+#include <io.h>
+
+#include "windows.h"
+
+#define HFILE_ERROR     ((HFILE)-1)
+#define FILE_BEGIN              0
+
+#define LPTR (LMEM_FIXED | LMEM_ZEROINIT)
+#define LHND (LMEM_MOVEABLE | LMEM_ZEROINIT)
+#define FILE_ATTRIBUTE_NORMAL S_IREAD|S_IWRITE
+
+#define FILE_BEGIN              0
+#define FILE_CURRENT            1
+#define FILE_END                2
+
+#define MAX_PATH 260
+#define INT    int
+#define strlen lstrlen
+
+LONG        WINAPI _hread(HFILE,LPVOID,LONG);
+LONG        WINAPI _hwrite(HFILE,LPCSTR,LONG);
+HFILE     WINAPI _lcreat(LPCSTR,INT);
+HFILE     WINAPI _lclose(HFILE);
+LONG        WINAPI _llseek(HFILE,LONG,INT);
+HFILE     WINAPI _lopen(LPCSTR,INT);
+INT       WINAPI lstrlen(LPCSTR);
+
+#define ok     winetest_ok
+
+
+BOOL WINAPI DeleteFile(LPCSTR str){
+     int ret;
+     ret = unlink( (char const *)str);
+     if (ret)
+         ret = 0;
+     else
+         ret = -1;
+     return ret;
+}
+
+BOOL WINAPI SetFileAttributes(LPCSTR file, DWORD attr){
+     int ret;
+     ret = chmod(file, attr);
+     if (ret)
+         ret = 0;
+     else
+         ret = -1;
+     return ret;
+}
+
+INT GetLastError()
+{
+    return 0;
+}
+
+int winetest_ok( int condition, const char *msg, ... )
+{
+    
+    if (!condition)
+        printf ("%s", msg);
+    
+    return 1;
+}
+
+LPCSTR filename = "testfile.xxx";
+LPCSTR sillytext =
+"en larvig liten text dx \033 gx hej 84 hej 4484 ! \001\033 bla bl\na.. bla bla."
+"1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
+"1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
+"1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
+"1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
+"1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
+"1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
+"1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
+"1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
+"sdlkfjasdlkfj a dslkj adsklf  \n  \nasdklf askldfa sdlkf \nsadklf asdklf asdf ";
+
+int max_open_files(){
+    HFILE fhs[255];
+    char fn [255];
+    int i, ret=0;
+    
+    for(i=0;i<255;i++){
+        sprintf(fn, "file_%d.xxx", i );
+        fhs[i] = _lcreat( fn, 0);
+        if (fhs[i]==HFILE_ERROR){
+            ret=i;
+            goto err;
+        }
+    }
+
+err:    
+    for(i=0;i<ret;i++){
+        ok( HFILE_ERROR != _lclose(fhs[i]), "_lclose complains\n" );
+        sprintf(fn, "file_%d.xxx", i );
+        DeleteFile (fn);
+    }
+    return ret;
+}
+
+static void test_SetHandleCount( void )
+{
+    ok(max_open_files()==15, "max_open_files != 15\n");
+    ok(SetHandleCount(0)==20, "SetHandleCount(0) != 20\n");
+    ok(SetHandleCount(19)==20, "SetHandleCount(19) != 20\n");
+    ok(SetHandleCount(20)==20, "SetHandleCount(20) != 20\n");
+    ok(max_open_files()==15, "max_open_files != 15\n");
+    ok(SetHandleCount(21)==21, "SetHandleCount(21) != 21\n");
+    ok(max_open_files()==16, "max_open_files != 16\n");
+    ok(SetHandleCount(100)==100, "SetHandleCount(100) != 100\n");
+    ok(SetHandleCount(33)==100, "SetHandleCount shouldn't shrink\n");
+    ok(max_open_files()==95, "max_open_files != 95\n");
+    ok(SetHandleCount(254)==254, "SetHandleCount(254) != 254\n");
+    ok(SetHandleCount(255)==255, "SetHandleCount(255) != 255\n");
+    ok(SetHandleCount(256)==255, "SetHandleCount(256) != 255\n");
+    ok(SetHandleCount(257)==255, "SetHandleCount(257) != 255\n");
+    ok(SetHandleCount(20)==255, "SetHandleCount shouldn't shrink\n");    
+}
+
+
+static void test__hread( void )
+{
+    HFILE filehandle;
+    char buffer[1000];
+    long bytes_read;
+    long bytes_wanted;
+    long i;
+
+    SetFileAttributes(filename,FILE_ATTRIBUTE_NORMAL); /* be sure to remove stale files */
+    DeleteFile( filename );
+    filehandle = _lcreat( filename, 0 );
+    if (filehandle == HFILE_ERROR)
+    {
+        ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
+        return;
+    }
+
+    ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
+
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+    filehandle = _lopen( filename, OF_READ );
+
+    ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%ld)\n", filename, GetLastError(  ) );
+
+    bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
+
+    ok( lstrlen( sillytext ) == bytes_read, "file read size error\n" );
+
+    for (bytes_wanted = 0; bytes_wanted < lstrlen( sillytext ); bytes_wanted++)
+    {
+        ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
+        ok( _hread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value\n" );
+        for (i = 0; i < bytes_wanted; i++)
+        {
+            ok( buffer[i] == sillytext[i], "that's not what's written\n" );
+        }
+    }
+
+    ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
+
+    ok( DeleteFile( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
+}
+
+
+static void test__hwrite( void )
+{
+    HFILE filehandle;
+    char buffer[1000];
+    long bytes_read;
+    long bytes_written;
+    long blocks;
+    long i;
+    char *contents;
+    HLOCAL memory_object;
+    char checksum[1];
+
+    filehandle = _lcreat( filename, 0 );
+    if (filehandle == HFILE_ERROR)
+    {
+        ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
+        return;
+    }
+
+    ok( HFILE_ERROR != _hwrite( filehandle, "", 0 ), "_hwrite complains\n" );
+
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+    filehandle = _lopen( filename, OF_READ );
+
+    bytes_read = _hread( filehandle, buffer, 1);
+
+    ok( 0 == bytes_read, "file read size error\n" );
+
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+    filehandle = _lopen( filename, OF_READWRITE );
+
+    bytes_written = 0;
+    checksum[0] = '\0';
+    srand( (unsigned)time( NULL ) );
+    for (blocks = 0; blocks < 10; blocks++)
+    {
+        for (i = 0; i < (long)sizeof( buffer ); i++)
+        {
+            buffer[i] = rand(  );
+            checksum[0] = checksum[0] + buffer[i];
+        }
+        ok( HFILE_ERROR != _hwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" );
+        bytes_written = bytes_written + sizeof( buffer );
+    }
+    
+    ok( HFILE_ERROR != _hwrite( filehandle, checksum, 1 ), "_hwrite complains\n" );
+    bytes_written++;
+
+    ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
+
+    memory_object = LocalAlloc( LPTR, bytes_written );
+
+    ok( 0 != memory_object, "LocalAlloc fails. (Could be out of memory.)\n" );
+
+    contents = LocalLock( memory_object );
+
+    filehandle = _lopen( filename, OF_READ );
+
+    contents = LocalLock( memory_object );
+
+    ok( NULL != contents, "LocalLock whines\n" );
+    
+    bytes_read = _hread( filehandle, contents, bytes_written);
+    ok( bytes_written == bytes_read, "read length differ from write length\n" );
+    
+    checksum[0] = '\0';
+    i = 0;
+    do
+    {
+        checksum[0] = checksum[0] + contents[i];
+        i++;
+    }
+    while (i < bytes_written - 1);
+
+    ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" );
+
+    ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
+
+    ok( DeleteFile( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
+}
+
+
+static void test__lclose( void )
+{
+    HFILE filehandle;
+
+    filehandle = _lcreat( filename, 0 );
+    if (filehandle == HFILE_ERROR)
+    {
+        ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
+        return;
+    }
+
+    ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
+
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+    ok( DeleteFile( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
+}
+
+
+static void test__lcreat( void )
+{
+    HFILE filehandle;
+    char buffer[1000];
+    char slashname[] = "testfi/";
+    int err;
+    HANDLE find;
+    int len,len2;
+    
+    filehandle = _lcreat( filename, 0 );
+    if (filehandle == HFILE_ERROR)
+    {
+        ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
+        return;
+    }
+
+    ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
+    
+    ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
+
+    ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  lstrlen( sillytext ), "erratic _hread return value\n" );
+
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+//    ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should be able to find file\n" );
+
+    ok( DeleteFile(filename) != 0, "DeleteFile failed (%ld)\n", GetLastError());
+
+    filehandle = _lcreat( filename, 1 ); /* readonly */
+    ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError(  ) );
+
+    ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write never the less\n" );
+
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+//    ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should be able to find file\n" );
+
+    ok( 0 == DeleteFile( filename ), "shouldn't be able to delete a readonly file\n" );
+
+    ok( SetFileAttributes(filename, FILE_ATTRIBUTE_NORMAL ) != 0, "couldn't change attributes on file\n" );
+
+    ok( DeleteFile( filename ) != 0, "now it should be possible to delete the file!\n" );
+
+    filehandle = _lcreat( filename, 2 );
+    ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError(  ) );
+
+    ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
+
+    ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
+
+    ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  lstrlen( sillytext ), "erratic _hread return value\n" );
+
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+//    ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should STILL be able to find file\n" );
+
+    ok( DeleteFile( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
+
+    filehandle = _lcreat( filename, 4 ); /* SYSTEM file */
+    ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError(  ) );
+
+    ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
+
+    ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
+
+    ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  lstrlen( sillytext ), "erratic _hread return value\n" );
+
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+//    ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should STILL be able to find file\n" );
+
+    ok( DeleteFile( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
+
+#if 0    
+    filehandle=_lcreat (slashname, 0); /* illegal name */
+    if (HFILE_ERROR==filehandle) {
+      err=GetLastError ();
+      ok (err==ERROR_INVALID_NAME || err==ERROR_PATH_NOT_FOUND,
+          "creating file \"%s\" failed with error %d\n", slashname, err);
+    } else { /* only NT succeeds */
+      _lclose(filehandle);
+      find=FindFirstFileA (slashname, &search_results);
+      if (INVALID_HANDLE_VALUE!=find)
+      {
+        ok (0!=FindClose (find), "FindClose complains (%ld)\n", GetLastError ());
+        slashname[strlen(slashname)-1]=0;
+        ok (!strcmp (slashname, search_results.cFileName),
+            "found unexpected name \"%s\"\n", search_results.cFileName);
+        ok (FILE_ATTRIBUTE_ARCHIVE==search_results.dwFileAttributes,
+            "attributes of file \"%s\" are 0x%04lx\n", search_results.cFileName,
+            search_results.dwFileAttributes);
+      }
+      ok (0!=DeleteFile (slashname), "Can't delete \"%s\" (%ld)\n", slashname,
+          GetLastError ());
+    }
+    
+    filehandle=_lcreat (filename, 8); /* illegal attribute */
+    if (HFILE_ERROR==filehandle)
+      ok (0, "couldn't create volume label \"%s\"\n", filename);
+    else {
+      _lclose(filehandle);
+      find=FindFirstFileA (filename, &search_results);
+      if (INVALID_HANDLE_VALUE==find)
+        ok (0, "file \"%s\" not found\n", filename);
+      else {
+        ok (0!=FindClose (find), "FindClose complains (%ld)\n", GetLastError ());
+        ok (!strcmp (filename, search_results.cFileName),
+            "found unexpected name \"%s\"\n", search_results.cFileName);
+        ok (FILE_ATTRIBUTE_ARCHIVE==search_results.dwFileAttributes,
+            "attributes of file \"%s\" are 0x%04lx\n", search_results.cFileName,
+            search_results.dwFileAttributes);
+      }
+      ok (0!=DeleteFile (filename), "Can't delete \"%s\" (%ld)\n", slashname,
+          GetLastError ());
+    }
+#endif
+
+}
+
+
+static void test__llseek( void )
+{
+    int i;
+    HFILE filehandle;
+    char buffer[1];
+    long bytes_read;
+
+    filehandle = _lcreat( filename, 0 );
+    if (filehandle == HFILE_ERROR)
+    {
+        ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
+        return;
+    }
+
+    for (i = 0; i < 400; i++)
+    {
+        ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
+    }
+    ok( HFILE_ERROR != _llseek( filehandle, 400 * strlen( sillytext ), FILE_CURRENT ), "should be able to seek\n" );
+    ok( HFILE_ERROR != _llseek( filehandle, 27 + 35 * strlen( sillytext ), FILE_BEGIN ), "should be able to seek\n" );
+
+    bytes_read = _hread( filehandle, buffer, 1);
+    ok( 1 == bytes_read, "file read size error\n" );
+    ok( buffer[0] == sillytext[27], "_llseek error, it got lost seeking\n" );
+/* This fails on win3.11, win16 xp and wine why? */    
+    ok( HFILE_ERROR != _llseek( filehandle, -400 * strlen( sillytext ), FILE_END ), "should be able to seek\n" );
+    ok( HFILE_ERROR != _llseek( filehandle, 0, FILE_BEGIN ), "should be able to seek\n" );
+
+    bytes_read = _hread( filehandle, buffer, 1);
+    ok( 1 == bytes_read, "file read size error\n" );
+    ok( buffer[0] == sillytext[0], "_llseek error, it got lost seeking\n" );
+    ok( HFILE_ERROR != _llseek( filehandle, 1000000, FILE_END ), "should be able to seek past file; poor, poor Windows programmers\n" );
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+    ok( DeleteFile( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
+}
+
+
+static void test__llopen( void )
+{
+    HFILE filehandle;
+    UINT bytes_read;
+    char buffer[1000];
+
+    filehandle = _lcreat( filename, 0 );
+    if (filehandle == HFILE_ERROR)
+    {
+        ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
+        return;
+    }
+
+    ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+    filehandle = _lopen( filename, OF_READ );
+    ok( HFILE_ERROR == _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write!\n" );
+    bytes_read = _hread( filehandle, buffer, strlen( sillytext ) );
+    ok( strlen( sillytext )  == bytes_read, "file read size error\n" );
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+    filehandle = _lopen( filename, OF_READWRITE );
+    bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
+    ok( strlen( sillytext )  == bytes_read, "file read size error\n" );
+    ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine\n" );
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+    filehandle = _lopen( filename, OF_WRITE );
+    ok( HFILE_ERROR == _hread( filehandle, buffer, 1 ), "you should only be able to write this file\n" );
+    ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine\n" );
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+    ok( DeleteFile( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
+    /* TODO - add tests for the SHARE modes  -  use two processes to pull this one off */
+}
+
+
+static void test__lread( void )
+{
+    HFILE filehandle;
+    char buffer[1000];
+    long bytes_read;
+    UINT bytes_wanted;
+    UINT i;
+
+    filehandle = _lcreat( filename, 0 );
+    if (filehandle == HFILE_ERROR)
+    {
+        ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
+        return;
+    }
+
+    ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
+
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+    filehandle = _lopen( filename, OF_READ );
+
+    ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%ld)\n", filename, GetLastError());
+
+    bytes_read = _lread( filehandle, buffer, 2 * strlen( sillytext ) );
+
+    ok( lstrlen( sillytext ) == bytes_read, "file read size error\n" );
+
+    for (bytes_wanted = 0; bytes_wanted < strlen( sillytext ); bytes_wanted++)
+    {
+        ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
+        ok( _lread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value\n" );
+        for (i = 0; i < bytes_wanted; i++)
+        {
+            ok( buffer[i] == sillytext[i], "that's not what's written\n" );
+        }
+    }
+
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+    ok( DeleteFile( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
+}
+
+
+static void test__lwrite( void )
+{
+    HFILE filehandle;
+    char buffer[1000];
+    long bytes_read;
+    long bytes_written;
+    long blocks;
+    long i;
+    char *contents;
+    HLOCAL memory_object;
+    char checksum[1];
+
+    filehandle = _lcreat( filename, 0 );
+    if (filehandle == HFILE_ERROR)
+    {
+        ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
+        return;
+    }
+
+    ok( HFILE_ERROR != _lwrite( filehandle, "", 0 ), "_hwrite complains\n" );
+
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+    filehandle = _lopen( filename, OF_READ );
+
+    bytes_read = _hread( filehandle, buffer, 1);
+
+    ok( 0 == bytes_read, "file read size error\n" );
+
+    ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
+
+    filehandle = _lopen( filename, OF_READWRITE );
+
+    bytes_written = 0;
+    checksum[0] = '\0';
+    srand( (unsigned)time( NULL ) );
+    for (blocks = 0; blocks < 10; blocks++)
+    {
+        for (i = 0; i < (long)sizeof( buffer ); i++)
+        {
+            buffer[i] = rand(  );
+            checksum[0] = checksum[0] + buffer[i];
+        }
+        ok( HFILE_ERROR != _lwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" );
+        bytes_written = bytes_written + sizeof( buffer );
+    }
+    
+    ok( HFILE_ERROR != _lwrite( filehandle, checksum, 1 ), "_hwrite complains\n" );
+    bytes_written++;
+
+    ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
+
+    memory_object = LocalAlloc( LPTR, bytes_written );
+
+    ok( 0 != memory_object, "LocalAlloc fails, could be out of memory\n" );
+
+    contents = LocalLock( memory_object );
+
+    filehandle = _lopen( filename, OF_READ );
+
+    contents = LocalLock( memory_object );
+
+    ok( NULL != contents, "LocalLock whines\n" );
+
+    ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" );
+
+    checksum[0] = '\0';
+    i = 0;
+    do
+    {
+        checksum[0] += contents[i];
+        i++;
+    }
+    while (i < bytes_written - 1);
+
+    ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" );
+
+    ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
+
+    ok( DeleteFile( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
+}
+
+#if 0
+static void test_CopyFileA(void)
+{
+    char temp_path[MAX_PATH];
+    char source[MAX_PATH], dest[MAX_PATH];
+    static const char prefix[] = "pfx";
+    HANDLE hfile;
+    char buf[10];
+    DWORD ret;
+
+    ret = GetTempPathA(MAX_PATH, temp_path);
+    ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
+    ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
+
+    ret = GetTempFileNameA(temp_path, prefix, 0, source);
+    ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
+
+    /* make the source have not zero size */
+    hfile = CreateFileA(source, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
+    ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
+    ok(WriteFile(hfile, prefix, sizeof(prefix), &ret, NULL ) && ret == sizeof(prefix),
+       "WriteFile error %ld\n", GetLastError());
+    ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n");
+    CloseHandle(hfile);
+
+    ret = GetTempFileNameA(temp_path, prefix, 0, dest);
+    ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = CopyFileA(source, dest, TRUE);
+    ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
+       "CopyFileA: unexpected error %ld\n", GetLastError());
+
+    ret = CopyFileA(source, dest, FALSE);
+    ok(ret, "CopyFileA: error %ld\n", GetLastError());
+
+    /* make sure that destination has correct size */
+    hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+    ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
+    ret = GetFileSize(hfile, NULL);
+    ok(ret == sizeof(prefix), "destination file has wrong size %ld\n", ret);
+
+    SetLastError(0xdeadbeef);
+    ret = CopyFileA(source, dest, FALSE);
+    ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION,
+       "CopyFileA: ret = %ld, unexpected error %ld\n", ret, GetLastError());
+
+    /* make sure that destination still has correct size */
+    ret = GetFileSize(hfile, NULL);
+    ok(ret == sizeof(prefix), "destination file has wrong size %ld\n", ret);
+    ok(ReadFile(hfile, buf, sizeof(buf), &ret, NULL) && ret == sizeof(prefix),
+       "ReadFile: error %ld\n", GetLastError());
+    ok(!memcmp(prefix, buf, sizeof(prefix)), "buffer contents mismatch\n");
+    CloseHandle(hfile);
+
+    ret = DeleteFile(source);
+    ok(ret, "DeleteFile: error %ld\n", GetLastError());
+    ret = DeleteFile(dest);
+    ok(ret, "DeleteFile: error %ld\n", GetLastError());
+}
+
+static void test_CopyFileW(void)
+{
+    WCHAR temp_path[MAX_PATH];
+    WCHAR source[MAX_PATH], dest[MAX_PATH];
+    static const WCHAR prefix[] = {'p','f','x',0};
+    DWORD ret;
+
+    ret = GetTempPathW(MAX_PATH, temp_path);
+    if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+        return;
+    ok(ret != 0, "GetTempPathW error %ld\n", GetLastError());
+    ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
+
+    ret = GetTempFileNameW(temp_path, prefix, 0, source);
+    ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
+
+    ret = GetTempFileNameW(temp_path, prefix, 0, dest);
+    ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
+
+    ret = CopyFileW(source, dest, TRUE);
+    ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
+       "CopyFileW: unexpected error %ld\n", GetLastError());
+
+    ret = CopyFileW(source, dest, FALSE);
+    ok(ret, "CopyFileW: error %ld\n", GetLastError());
+
+    ret = DeleteFileW(source);
+    ok(ret, "DeleteFileW: error %ld\n", GetLastError());
+    ret = DeleteFileW(dest);
+    ok(ret, "DeleteFileW: error %ld\n", GetLastError());
+}
+
+static void test_CreateFileA(void)
+{
+    HANDLE hFile;
+    char temp_path[MAX_PATH];
+    char filename[MAX_PATH];
+    static const char prefix[] = "pfx";
+    DWORD ret;
+
+    ret = GetTempPathA(MAX_PATH, temp_path);
+    ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
+    ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
+
+    ret = GetTempFileNameA(temp_path, prefix, 0, filename);
+    ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
+
+    hFile = CreateFileA(filename, GENERIC_READ, 0, NULL,
+                        CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
+    ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
+        "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
+
+    ret = DeleteFile(filename);
+    ok(ret, "DeleteFile: error %ld\n", GetLastError());
+}
+
+static void test_CreateFileW(void)
+{
+    HANDLE hFile;
+    WCHAR temp_path[MAX_PATH];
+    WCHAR filename[MAX_PATH];
+    static const WCHAR emptyW[]={'\0'};
+    static const WCHAR prefix[] = {'p','f','x',0};
+    static const WCHAR bogus[] = { '\\', '\\', '.', '\\', 'B', 'O', 'G', 'U', 'S', 0 };
+    DWORD ret;
+
+    ret = GetTempPathW(MAX_PATH, temp_path);
+    if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+        return;
+    ok(ret != 0, "GetTempPathW error %ld\n", GetLastError());
+    ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
+
+    ret = GetTempFileNameW(temp_path, prefix, 0, filename);
+    ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
+
+    hFile = CreateFileW(filename, GENERIC_READ, 0, NULL,
+                        CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
+    ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
+        "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
+
+    ret = DeleteFileW(filename);
+    ok(ret, "DeleteFileW: error %ld\n", GetLastError());
+
+    hFile = CreateFileW(NULL, GENERIC_READ, 0, NULL,
+                        CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
+    ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
+       "CreateFileW(NULL) returned ret=%p error=%ld\n",hFile,GetLastError());
+
+    hFile = CreateFileW(emptyW, GENERIC_READ, 0, NULL,
+                        CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
+    ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
+       "CreateFileW(\"\") returned ret=%p error=%ld\n",hFile,GetLastError());
+
+    /* test the result of opening a non-existent driver name */
+    hFile = CreateFileW(bogus, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND,
+       "CreateFileW on invalid VxD name returned ret=%p error=%ld\n",hFile,GetLastError());
+}
+
+static void test_GetTempFileNameA()
+{
+    UINT result;
+    char out[MAX_PATH];
+    char expected[MAX_PATH + 10];
+    char windowsdir[MAX_PATH + 10];
+    char windowsdrive[3];
+
+    result = GetWindowsDirectory(windowsdir, sizeof(windowsdir));
+    ok(result < sizeof(windowsdir), "windowsdir is abnormally long!\n");
+    ok(result != 0, "GetWindowsDirectory: error %ld\n", GetLastError());
+
+    /* If the Windows directory is the root directory, it ends in backslash, not else. */
+    if (strlen(windowsdir) != 3) /* As in  "C:\"  or  "F:\"  */
+    {
+        strcat(windowsdir, "\\");
+    }
+
+    windowsdrive[0] = windowsdir[0];
+    windowsdrive[1] = windowsdir[1];
+    windowsdrive[2] = '\0';
+
+    result = GetTempFileNameA(windowsdrive, "abc", 1, out);
+    ok(result != 0, "GetTempFileNameA: error %ld\n", GetLastError());
+    ok(((out[0] == windowsdrive[0]) && (out[1] == ':')) && (out[2] == '\\'),
+       "GetTempFileNameA: first three characters should be %c:\\, string was actually %s\n",
+       windowsdrive[0], out);
+
+    result = GetTempFileNameA(windowsdir, "abc", 2, out);
+    ok(result != 0, "GetTempFileNameA: error %ld\n", GetLastError());
+    expected[0] = '\0';
+    strcat(expected, windowsdir);
+    strcat(expected, "abc2.tmp");
+    ok(lstrcmpiA(out, expected) == 0, "GetTempFileNameA: Unexpected output \"%s\" vs \"%s\"\n",
+       out, expected);
+}
+
+static void test_DeleteFile( void )
+{
+    BOOL ret;
+
+    ret = DeleteFile(NULL);
+    ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER ||
+                GetLastError() == ERROR_PATH_NOT_FOUND),
+       "DeleteFile(NULL) returned ret=%d error=%ld\n",ret,GetLastError());
+
+    ret = DeleteFile("");
+    ok(!ret && (GetLastError() == ERROR_PATH_NOT_FOUND ||
+                GetLastError() == ERROR_BAD_PATHNAME),
+       "DeleteFile(\"\") returned ret=%d error=%ld\n",ret,GetLastError());
+
+    ret = DeleteFile("nul");
+    ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
+                GetLastError() == ERROR_INVALID_PARAMETER ||
+                GetLastError() == ERROR_ACCESS_DENIED),
+       "DeleteFile(\"nul\") returned ret=%d error=%ld\n",ret,GetLastError());
+}
+
+static void test_DeleteFileW( void )
+{
+    BOOL ret;
+    static const WCHAR emptyW[]={'\0'};
+
+    ret = DeleteFileW(NULL);
+    if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+        return;
+    ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
+       "DeleteFileW(NULL) returned ret=%d error=%ld\n",ret,GetLastError());
+
+    ret = DeleteFileW(emptyW);
+    ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
+       "DeleteFileW(\"\") returned ret=%d error=%ld\n",ret,GetLastError());
+}
+
+#define IsDotDir(x)     ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0))))
+
+static void test_MoveFileA(void)
+{
+    char tempdir[MAX_PATH];
+    char source[MAX_PATH], dest[MAX_PATH];
+    static const char prefix[] = "pfx";
+    DWORD ret;
+
+    ret = GetTempPathA(MAX_PATH, tempdir);
+    ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
+    ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
+
+    ret = GetTempFileNameA(tempdir, prefix, 0, source);
+    ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
+
+    ret = GetTempFileNameA(tempdir, prefix, 0, dest);
+    ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
+
+    ret = MoveFileA(source, dest);
+    ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS,
+       "MoveFileA: unexpected error %ld\n", GetLastError());
+
+    ret = DeleteFile(dest);
+    ok(ret, "DeleteFile: error %ld\n", GetLastError());
+
+    ret = MoveFileA(source, dest);
+    ok(ret, "MoveFileA: failed, error %ld\n", GetLastError());
+
+    lstrcatA(tempdir, "Remove Me");
+    ret = CreateDirectoryA(tempdir, NULL);
+    ok(ret == TRUE, "CreateDirectoryA failed\n");
+
+    lstrcpyA(source, dest);
+    lstrcpyA(dest, tempdir);
+    lstrcatA(dest, "\\wild?.*");
+    /* FIXME: if we create a file with wildcards we can't delete it now that DeleteFile works correctly */
+    ret = MoveFileA(source, dest);
+    ok(!ret, "MoveFileA: shouldn't move to wildcard file\n");
+    ok(GetLastError() == ERROR_INVALID_NAME || /* NT */
+       GetLastError() == ERROR_FILE_NOT_FOUND, /* Win9x */
+       "MoveFileA: with wildcards, unexpected error %ld\n", GetLastError());
+    if (ret || (GetLastError() != ERROR_INVALID_NAME))
+    {
+        WIN32_FIND_DATAA fd;
+        char temppath[MAX_PATH];
+        HANDLE hFind;
+
+        lstrcpyA(temppath, tempdir);
+        lstrcatA(temppath, "\\*.*");
+        hFind = FindFirstFileA(temppath, &fd);
+        if (INVALID_HANDLE_VALUE != hFind)
+        {
+          LPSTR lpName;
+          do
+          {
+            lpName = fd.cAlternateFileName;
+            if (!lpName[0])
+              lpName = fd.cFileName;
+            ok(IsDotDir(lpName), "MoveFileA: wildcards file created!\n");
+          }
+          while (FindNextFileA(hFind, &fd));
+          FindClose(hFind);
+        }
+    }
+    ret = DeleteFile(source);
+    ok(ret, "DeleteFile: error %ld\n", GetLastError());
+    ret = DeleteFile(dest);
+    ok(!ret, "DeleteFile: error %ld\n", GetLastError());
+    ret = RemoveDirectoryA(tempdir);
+    ok(ret, "DeleteDirectoryA: error %ld\n", GetLastError());
+}
+
+static void test_MoveFileW(void)
+{
+    WCHAR temp_path[MAX_PATH];
+    WCHAR source[MAX_PATH], dest[MAX_PATH];
+    static const WCHAR prefix[] = {'p','f','x',0};
+    DWORD ret;
+
+    ret = GetTempPathW(MAX_PATH, temp_path);
+    if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+        return;
+    ok(ret != 0, "GetTempPathW error %ld\n", GetLastError());
+    ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
+
+    ret = GetTempFileNameW(temp_path, prefix, 0, source);
+    ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
+
+    ret = GetTempFileNameW(temp_path, prefix, 0, dest);
+    ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
+
+    ret = MoveFileW(source, dest);
+    ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS,
+       "CopyFileW: unexpected error %ld\n", GetLastError());
+
+    ret = DeleteFileW(source);
+    ok(ret, "DeleteFileW: error %ld\n", GetLastError());
+    ret = DeleteFileW(dest);
+    ok(ret, "DeleteFileW: error %ld\n", GetLastError());
+}
+
+#define PATTERN_OFFSET 0x10
+
+static void test_offset_in_overlapped_structure(void)
+{
+    HANDLE hFile;
+    OVERLAPPED ov;
+    DWORD done;
+    BOOL rc;
+    BYTE buf[256], pattern[] = "TeSt";
+    UINT i;
+    char temp_path[MAX_PATH], temp_fname[MAX_PATH];
+
+    ok(GetTempPathA(MAX_PATH, temp_path) != 0, "GetTempPathA error %ld\n", GetLastError());
+    ok(GetTempFileNameA(temp_path, "pfx", 0, temp_fname) != 0, "GetTempFileNameA error %ld\n", GetLastError());
+
+    /*** Write File *****************************************************/
+
+    hFile = CreateFileA(temp_fname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+    ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %ld\n", GetLastError());
+
+    for(i = 0; i < sizeof(buf); i++) buf[i] = i;
+    ok(WriteFile(hFile, buf, sizeof(buf), &done, NULL), "WriteFile error %ld\n", GetLastError());
+    ok(done == sizeof(buf), "expected number of bytes written %lu\n", done);
+
+    memset(&ov, 0, sizeof(ov));
+    ov.Offset = PATTERN_OFFSET;
+    ov.OffsetHigh = 0;
+    rc=WriteFile(hFile, pattern, sizeof(pattern), &done, &ov);
+    /* Win 9x does not support the overlapped I/O on files */
+    if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
+        ok(rc, "WriteFile error %ld\n", GetLastError());
+        ok(done == sizeof(pattern), "expected number of bytes written %lu\n", done);
+        /*trace("Current offset = %04lx\n", SetFilePointer(hFile, 0, NULL, FILE_CURRENT));*/
+        ok(SetFilePointer(hFile, 0, NULL, FILE_CURRENT) == (PATTERN_OFFSET + sizeof(pattern)),
+           "expected file offset %d\n", PATTERN_OFFSET + sizeof(pattern));
+
+        ov.Offset = sizeof(buf) * 2;
+        ov.OffsetHigh = 0;
+        ok(WriteFile(hFile, pattern, sizeof(pattern), &done, &ov), "WriteFile error %ld\n", GetLastError());
+        ok(done == sizeof(pattern), "expected number of bytes written %lu\n", done);
+        /*trace("Current offset = %04lx\n", SetFilePointer(hFile, 0, NULL, FILE_CURRENT));*/
+        ok(SetFilePointer(hFile, 0, NULL, FILE_CURRENT) == (sizeof(buf) * 2 + sizeof(pattern)),
+           "expected file offset %d\n", sizeof(buf) * 2 + sizeof(pattern));
+    }
+
+    CloseHandle(hFile);
+
+    /*** Read File *****************************************************/
+
+    hFile = CreateFileA(temp_fname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
+    ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %ld\n", GetLastError());
+
+    memset(buf, 0, sizeof(buf));
+    memset(&ov, 0, sizeof(ov));
+    ov.Offset = PATTERN_OFFSET;
+    ov.OffsetHigh = 0;
+    rc=ReadFile(hFile, buf, sizeof(pattern), &done, &ov);
+    /* Win 9x does not support the overlapped I/O on files */
+    if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
+        ok(rc, "ReadFile error %ld\n", GetLastError());
+        ok(done == sizeof(pattern), "expected number of bytes read %lu\n", done);
+        /*trace("Current offset = %04lx\n", SetFilePointer(hFile, 0, NULL, FILE_CURRENT));*/
+        ok(SetFilePointer(hFile, 0, NULL, FILE_CURRENT) == (PATTERN_OFFSET + sizeof(pattern)),
+           "expected file offset %d\n", PATTERN_OFFSET + sizeof(pattern));
+        ok(!memcmp(buf, pattern, sizeof(pattern)), "pattern match failed\n");
+    }
+
+    CloseHandle(hFile);
+
+    ok(DeleteFile(temp_fname), "DeleteFile error %ld\n", GetLastError());
+}
+
+static void test_LockFile(void)
+{
+    HANDLE handle;
+    DWORD written;
+    OVERLAPPED overlapped;
+    int limited_LockFile;
+    int limited_UnLockFile;
+    int lockfileex_capable;
+
+    handle = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
+                          FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+                          CREATE_ALWAYS, 0, 0 );
+    if (handle == INVALID_HANDLE_VALUE)
+    {
+        ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
+        return;
+    }
+    ok( WriteFile( handle, sillytext, strlen(sillytext), &written, NULL ), "write failed\n" );
+
+    ok( LockFile( handle, 0, 0, 0, 0 ), "LockFile failed\n" );
+    ok( UnlockFile( handle, 0, 0, 0, 0 ), "UnlockFile failed\n" );
+
+    limited_UnLockFile = 0;
+    if (UnlockFile( handle, 0, 0, 0, 0 ))
+    {
+        limited_UnLockFile = 1;
+    }
+
+    ok( LockFile( handle, 10, 0, 20, 0 ), "LockFile 10,20 failed\n" );
+    /* overlapping locks must fail */
+    ok( !LockFile( handle, 12, 0, 10, 0 ), "LockFile 12,10 succeeded\n" );
+    ok( !LockFile( handle, 5, 0, 6, 0 ), "LockFile 5,6 succeeded\n" );
+    /* non-overlapping locks must succeed */
+    ok( LockFile( handle, 5, 0, 5, 0 ), "LockFile 5,5 failed\n" );
+
+    ok( !UnlockFile( handle, 10, 0, 10, 0 ), "UnlockFile 10,10 succeeded\n" );
+    ok( UnlockFile( handle, 10, 0, 20, 0 ), "UnlockFile 10,20 failed\n" );
+    ok( !UnlockFile( handle, 10, 0, 20, 0 ), "UnlockFile 10,20 again succeeded\n" );
+    ok( UnlockFile( handle, 5, 0, 5, 0 ), "UnlockFile 5,5 failed\n" );
+
+    overlapped.Offset = 100;
+    overlapped.OffsetHigh = 0;
+    overlapped.hEvent = 0;
+
+    lockfileex_capable = dll_capable("kernel32", "LockFileEx");
+    if (lockfileex_capable)
+    {
+        /* Test for broken LockFileEx a la Windows 95 OSR2. */
+        if (LockFileEx( handle, 0, 0, 100, 0, &overlapped ))
+        {
+            /* LockFileEx is probably OK, test it more. */
+            ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ),
+                "LockFileEx 100,100 failed\n" );
+	}
+    }
+
+    /* overlapping shared locks are OK */
+    overlapped.Offset = 150;
+    limited_UnLockFile || ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ), "LockFileEx 150,100 failed\n" );
+
+    /* but exclusive is not */
+    if (lockfileex_capable)
+    {
+        ok( !LockFileEx( handle, LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
+                         0, 50, 0, &overlapped ),
+                         "LockFileEx exclusive 150,50 succeeded\n" );
+	if (dll_capable("kernel32.dll", "UnlockFileEx"))
+        {
+            if (!UnlockFileEx( handle, 0, 100, 0, &overlapped ))
+            { /* UnLockFile is capable. */
+                overlapped.Offset = 100;
+                ok( !UnlockFileEx( handle, 0, 100, 0, &overlapped ),
+                    "UnlockFileEx 150,100 again succeeded\n" );
+	    }
+	}
+    }
+
+    ok( LockFile( handle, 0, 0x10000000, 0, 0xf0000000 ), "LockFile failed\n" );
+    ok( !LockFile( handle, ~0, ~0, 1, 0 ), "LockFile ~0,1 succeeded\n" );
+    ok( !LockFile( handle, 0, 0x20000000, 20, 0 ), "LockFile 0x20000000,20 succeeded\n" );
+    ok( UnlockFile( handle, 0, 0x10000000, 0, 0xf0000000 ), "UnlockFile failed\n" );
+
+    /* wrap-around lock should not do anything */
+    /* (but still succeeds on NT4 so we don't check result) */
+    LockFile( handle, 0, 0x10000000, 0, 0xf0000001 );
+
+    limited_LockFile = 0;
+    if (!LockFile( handle, ~0, ~0, 1, 0 ))
+    {
+        limited_LockFile = 1;
+    }
+
+    limited_UnLockFile || ok( UnlockFile( handle, ~0, ~0, 1, 0 ), "Unlockfile ~0,1 failed\n" );
+
+    /* zero-byte lock */
+    ok( LockFile( handle, 100, 0, 0, 0 ), "LockFile 100,0 failed\n" );
+    limited_LockFile || ok( !LockFile( handle, 98, 0, 4, 0 ), "LockFile 98,4 succeeded\n" );
+    ok( LockFile( handle, 90, 0, 10, 0 ), "LockFile 90,10 failed\n" );
+    limited_LockFile || ok( !LockFile( handle, 100, 0, 10, 0 ), "LockFile 100,10 failed\n" );
+
+    ok( UnlockFile( handle, 90, 0, 10, 0 ), "UnlockFile 90,10 failed\n" );
+    !ok( UnlockFile( handle, 100, 0, 10, 0 ), "UnlockFile 100,10 failed\n" );
+
+    ok( UnlockFile( handle, 100, 0, 0, 0 ), "UnlockFile 100,0 failed\n" );
+
+    CloseHandle( handle );
+    DeleteFile( filename );
+}
+
+static inline int is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2 )
+{
+    if (!access1 || !access2) return 1;
+    if ((access1 & GENERIC_READ) && !(sharing2 & FILE_SHARE_READ)) return 0;
+    if ((access1 & GENERIC_WRITE) && !(sharing2 & FILE_SHARE_WRITE)) return 0;
+    if ((access2 & GENERIC_READ) && !(sharing1 & FILE_SHARE_READ)) return 0;
+    if ((access2 & GENERIC_WRITE) && !(sharing1 & FILE_SHARE_WRITE)) return 0;
+    return 1;
+}
+
+static void test_file_sharing(void)
+{
+    static const DWORD access_modes[4] = { 0, GENERIC_READ, GENERIC_WRITE, GENERIC_READ|GENERIC_WRITE };
+    static const DWORD sharing_modes[4] = { 0, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE };
+    int a1, s1, a2, s2;
+    int ret;
+
+    /* make sure the file exists */
+    HANDLE h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
+    CloseHandle( h );
+
+    for (a1 = 0; a1 < 4; a1++)
+    {
+        for (s1 = 0; s1 < 4; s1++)
+        {
+            HANDLE h = CreateFileA( filename, access_modes[a1], sharing_modes[s1],
+                                    NULL, OPEN_EXISTING, 0, 0 );
+            if (h == INVALID_HANDLE_VALUE)
+            {
+                ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
+                return;
+            }
+            for (a2 = 0; a2 < 4; a2++)
+            {
+                for (s2 = 0; s2 < 4; s2++)
+                {
+                    HANDLE h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2],
+                                          NULL, OPEN_EXISTING, 0, 0 );
+                    if (is_sharing_compatible( access_modes[a1], sharing_modes[s1],
+                                               access_modes[a2], sharing_modes[s2] ))
+                    {
+                        ret = GetLastError();
+                        ok( ERROR_SHARING_VIOLATION == ret || 0 == ret,
+                            "Windows 95 sets GetLastError() = ERROR_SHARING_VIOLATION and\n"
+                            "  Windows XP GetLastError() = 0, but now it is %d.\n"
+                            "  indexes = %d, %d, %d, %d\n"
+                            "  modes   =\n  %lx/%lx/%lx/%lx\n",
+			    ret,
+                            a1, s1, a2, s2, 
+                            access_modes[a1], sharing_modes[s1],
+			    access_modes[a2], sharing_modes[s2]
+                            );
+                    }
+                    else
+                    {
+                        ok( h2 == INVALID_HANDLE_VALUE,
+                            "open succeeded for modes %lx/%lx/%lx/%lx\n",
+                            access_modes[a1], sharing_modes[s1],
+                            access_modes[a2], sharing_modes[s2] );
+                        if (h2 == INVALID_HANDLE_VALUE)
+                            ok( GetLastError() == ERROR_SHARING_VIOLATION,
+                                "wrong error code %ld\n", GetLastError() );
+                    }
+                    if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
+                }
+            }
+            CloseHandle( h );
+        }
+    }
+    DeleteFile( filename );
+}
+
+static char get_windows_drive()
+{
+    char windowsdir[MAX_PATH];
+    GetWindowsDirectory(windowsdir, sizeof(windowsdir));
+    return windowsdir[0];
+}
+
+static void test_FindFirstFileA()
+{
+    HANDLE handle;
+    WIN32_FIND_DATAA search_results;
+    int err;
+    char buffer[5] = "C:\\";
+
+    /* try FindFirstFileA on "C:\" */
+    buffer[0] = get_windows_drive();
+    handle = FindFirstFileA(buffer,&search_results);
+    err = GetLastError();
+    ok ( handle == INVALID_HANDLE_VALUE , "FindFirstFile on root directory should Fail\n");
+    if (handle == INVALID_HANDLE_VALUE)
+      ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err);
+
+    /* try FindFirstFileA on "C:\*" */
+    strcat(buffer, "*");
+    handle = FindFirstFileA(buffer,&search_results);
+    ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer );
+    ok ( FindClose(handle) == TRUE, "Failed to close handle\n");
+}
+
+static void test_FindNextFileA()
+{
+    HANDLE handle;
+    WIN32_FIND_DATAA search_results;
+    int err;
+    char buffer[5] = "C:\\*";
+
+    buffer[0] = get_windows_drive();
+    handle = FindFirstFileA(buffer,&search_results);
+    ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on C:\\* should succeed\n" );
+    while (FindNextFile(handle, &search_results))
+    {
+        /* get to the end of the files */
+    }
+    ok ( FindClose(handle) == TRUE, "Failed to close handle\n");
+    err = GetLastError();
+    ok ( err == ERROR_NO_MORE_FILES, "GetLastError should return ERROR_NO_MORE_FILES\n");
+}
+
+static int test_Mapfile_createtemp(HANDLE *handle)
+{
+    SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL);
+    DeleteFile(filename);
+    *handle = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, 0,
+                         CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (*handle != INVALID_HANDLE_VALUE) {
+
+        return 1;
+    }
+
+    return 0;
+}
+
+static void test_MapFile()
+{
+    HANDLE handle;
+    HANDLE hmap;
+
+    ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
+
+    hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0x1000, "named_file_map" );
+    ok( hmap != NULL, "mapping should work, I named it!\n" );
+
+    ok( CloseHandle( hmap ), "can't close mapping handle\n");
+
+    /* We have to close file before we try new stuff with mapping again.
+       Else we would always succeed on XP or block descriptors on 95. */
+    hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
+    ok( hmap != NULL, "We should still be able to map!\n" );
+    ok( CloseHandle( hmap ), "can't close mapping handle\n");
+    ok( CloseHandle( handle ), "can't close file handle\n");
+    handle = NULL;
+
+    ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
+
+    hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
+    ok( hmap == NULL, "mapped zero size file\n");
+    ok( GetLastError() == ERROR_FILE_INVALID, "not ERROR_FILE_INVALID\n");
+
+    hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x1000, 0, NULL );
+    ok( hmap == NULL, "mapping should fail\n");
+    /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
+
+    hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x1000, 0x10000, NULL );
+    ok( hmap == NULL, "mapping should fail\n");
+    /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
+
+    /* On XP you can now map again, on Win 95 you can not. */
+
+    ok( CloseHandle( handle ), "can't close file handle\n");
+    ok( DeleteFile( filename ), "DeleteFile failed after map\n" );
+}
+
+static void test_GetFileType(void)
+{
+    DWORD type;
+    HANDLE h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
+    ok( h != INVALID_HANDLE_VALUE, "open %s failed\n", filename );
+    type = GetFileType(h);
+    ok( type == FILE_TYPE_DISK, "expected type disk got %ld\n", type );
+    CloseHandle( h );
+    h = CreateFileA( "nul", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
+    ok( h != INVALID_HANDLE_VALUE, "open nul failed\n" );
+    type = GetFileType(h);
+    ok( type == FILE_TYPE_CHAR, "expected type char for nul got %ld\n", type );
+    CloseHandle( h );
+    DeleteFile( filename );
+}
+
+static int completion_count;
+
+static void CALLBACK FileIOComplete(DWORD dwError, DWORD dwBytes, LPOVERLAPPED ovl)
+{
+/*	printf("(%ld, %ld, %p { %ld, %ld, %ld, %ld, %p })\n", dwError, dwBytes, ovl, ovl->Internal, ovl->InternalHigh, ovl->Offset, ovl->OffsetHigh, ovl->hEvent);*/
+	ReleaseSemaphore(ovl->hEvent, 1, NULL);
+	completion_count++;
+}
+
+static void test_async_file_errors(void)
+{
+    char szFile[MAX_PATH];
+    HANDLE hSem = CreateSemaphoreW(NULL, 1, 1, NULL);
+    HANDLE hFile;
+    LPVOID lpBuffer = HeapAlloc(GetProcessHeap(), 0, 4096);
+    OVERLAPPED ovl;
+    ovl.Offset = 0;
+    ovl.OffsetHigh = 0;
+    ovl.hEvent = hSem;
+    completion_count = 0;
+    szFile[0] = '\0';
+    GetWindowsDirectoryA(szFile, sizeof(szFile)/sizeof(szFile[0])-1-strlen("\\win.ini"));
+    strcat(szFile, "\\win.ini");
+    hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
+    ok(hFile != NULL, "CreateFileA(%s ...) failed\n", szFile);
+    while (TRUE)
+    {
+        BOOL res;
+        while (WaitForSingleObjectEx(hSem, INFINITE, TRUE) == WAIT_IO_COMPLETION)
+            ;
+        res = ReadFileEx(hFile, lpBuffer, 4096, &ovl, FileIOComplete);
+        /*printf("Offset = %ld, result = %s\n", ovl.Offset, res ? "TRUE" : "FALSE");*/
+        if (!res)
+            break;
+        ovl.Offset += 4096;
+        /* i/o completion routine only called if ReadFileEx returned success.
+         * we only care about violations of this rule so undo what should have
+         * been done */
+        completion_count--;
+    }
+    ok(completion_count == 0, "completion routine should only be called when ReadFileEx succeeds (this rule was violated %d times)\n", completion_count);
+    /*printf("Error = %ld\n", GetLastError());*/
+}
+
+
+#endif
+
+
+int main()
+{
+    /*
+    printf("SetHandleCount(21)=%d\n", SetHandleCount(21));
+    printf("max_open_files()=%d\n", max_open_files());
+//    return 0;
+*/
+    ok(0, "hello\n");
+    test_SetHandleCount(  );
+    printf("test_SetHandleCount\n");
+    test__lclose(  );
+    printf("test__lclose\n");
+    test__hread(  );
+    printf("test__hread\n");
+    test__hwrite(  );
+    printf("test__hwrite\n");
+    test__lclose(  );
+    printf("test__lclose\n");
+    test__lcreat(  );
+    printf("test__lcreat\n");
+    test__llseek(  );
+    printf("test__llseek\n");
+    test__llopen(  );
+    printf("test__llopen\n");
+    test__lread(  );
+    printf("test__lread\n");
+    test__lwrite(  );
+    printf("test__lwrite\n");
+
+    printf("\nDONE\n");
+        
+    return 0;
+#if 0    
+    test_GetTempFileNameA();
+    test_CopyFileA();
+    test_CopyFileW();
+    test_CreateFileA();
+    test_CreateFileW();
+    test_DeleteFile();
+    test_DeleteFileW();
+    test_MoveFileA();
+    test_MoveFileW();
+    test_FindFirstFileA();
+    test_FindNextFileA();
+    test_LockFile();
+    test_file_sharing();
+    test_offset_in_overlapped_structure();
+    test_MapFile();
+    test_GetFileType();
+    test_async_file_errors();
+#endif
+}


More information about the wine-patches mailing list