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