Check access rights before renaming or deleting files (based on
[wine] / dlls / kernel / tests / file.c
1 /*
2  * Unit tests for file functions in Wine
3  *
4  * Copyright (c) 2002 Jakob Eriksson
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include <stdlib.h>
23 #include <time.h>
24
25 #include "wine/test.h"
26 #include "winbase.h"
27 #include "winerror.h"
28
29
30 LPCSTR filename = "testfile.xxx";
31 LPCSTR sillytext =
32 "en larvig liten text dx \033 gx hej 84 hej 4484 ! \001\033 bla bl\na.. bla bla."
33 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
34 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
35 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
36 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
37 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
38 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
39 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
40 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
41 "sdlkfjasdlkfj a dslkj adsklf  \n  \nasdklf askldfa sdlkf \nsadklf asdklf asdf ";
42
43
44 static void test__hread( void )
45 {
46     HFILE filehandle;
47     char buffer[10000];
48     long bytes_read;
49     long bytes_wanted;
50     UINT i;
51
52     SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL); /* be sure to remove stale files */
53     DeleteFileA( filename );
54     filehandle = _lcreat( filename, 0 );
55     if (filehandle == HFILE_ERROR)
56     {
57         ok(0,"couldn't create file \"%s\" (err=%d)",filename,GetLastError());
58         return;
59     }
60
61     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains" );
62
63     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
64
65     filehandle = _lopen( filename, OF_READ );
66
67     ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%d)", filename, GetLastError(  ) );
68
69     bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
70
71     ok( strlen( sillytext ) == bytes_read, "file read size error" );
72
73     for (bytes_wanted = 0; bytes_wanted < strlen( sillytext ); bytes_wanted++)
74     {
75         ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains" );
76         ok( _hread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value" );
77         for (i = 0; i < bytes_wanted; i++)
78         {
79             ok( buffer[i] == sillytext[i], "that's not what's written" );
80         }
81     }
82
83     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains" );
84
85     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%d)", GetLastError(  ) );
86 }
87
88
89 static void test__hwrite( void )
90 {
91     HFILE filehandle;
92     char buffer[10000];
93     long bytes_read;
94     UINT bytes_written;
95     UINT blocks;
96     UINT i;
97     char *contents;
98     HLOCAL memory_object;
99     char checksum[1];
100
101     filehandle = _lcreat( filename, 0 );
102     if (filehandle == HFILE_ERROR)
103     {
104         ok(0,"couldn't create file \"%s\" (err=%d)",filename,GetLastError());
105         return;
106     }
107
108     ok( HFILE_ERROR != _hwrite( filehandle, "", 0 ), "_hwrite complains" );
109
110     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
111
112     filehandle = _lopen( filename, OF_READ );
113
114     bytes_read = _hread( filehandle, buffer, 1);
115
116     ok( 0 == bytes_read, "file read size error" );
117
118     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
119
120     filehandle = _lopen( filename, OF_READWRITE );
121
122     bytes_written = 0;
123     checksum[0] = '\0';
124     srand( (unsigned)time( NULL ) );
125     for (blocks = 0; blocks < 100; blocks++)
126     {
127         for (i = 0; i < sizeof( buffer ); i++)
128         {
129             buffer[i] = rand(  );
130             checksum[0] = checksum[0] + buffer[i];
131         }
132         ok( HFILE_ERROR != _hwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains" );
133         bytes_written = bytes_written + sizeof( buffer );
134     }
135
136     ok( HFILE_ERROR != _hwrite( filehandle, checksum, 1 ), "_hwrite complains" );
137     bytes_written++;
138
139     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains" );
140
141     memory_object = LocalAlloc( LPTR, bytes_written );
142
143     ok( 0 != memory_object, "LocalAlloc fails. (Could be out of memory.)" );
144
145     contents = LocalLock( memory_object );
146
147     filehandle = _lopen( filename, OF_READ );
148
149     contents = LocalLock( memory_object );
150
151     ok( NULL != contents, "LocalLock whines" );
152
153     ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length" );
154
155     checksum[0] = '\0';
156     i = 0;
157     do
158     {
159         checksum[0] = checksum[0] + contents[i];
160         i++;
161     }
162     while (i < bytes_written - 1);
163
164     ok( checksum[0] == contents[i], "stored checksum differ from computed checksum" );
165
166     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains" );
167
168     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%d)", GetLastError(  ) );
169 }
170
171
172 static void test__lclose( void )
173 {
174     HFILE filehandle;
175
176     filehandle = _lcreat( filename, 0 );
177     if (filehandle == HFILE_ERROR)
178     {
179         ok(0,"couldn't create file \"%s\" (err=%d)",filename,GetLastError());
180         return;
181     }
182
183     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains" );
184
185     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
186
187     ok( HFILE_ERROR == _lclose(filehandle), "_lclose should whine about this" );
188
189     ok( HFILE_ERROR == _lclose(filehandle), "_lclose should whine about this" );
190
191     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%d)", GetLastError(  ) );
192 }
193
194
195 static void test__lcreat( void )
196 {
197     HFILE filehandle;
198     char buffer[10000];
199     WIN32_FIND_DATAA search_results;
200
201     filehandle = _lcreat( filename, 0 );
202     if (filehandle == HFILE_ERROR)
203     {
204         ok(0,"couldn't create file \"%s\" (err=%d)",filename,GetLastError());
205         return;
206     }
207
208     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains" );
209
210     ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains" );
211
212     ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  strlen( sillytext ), "erratic _hread return value" );
213
214     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
215
216     ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should be able to find file" );
217
218     ok( DeleteFileA(filename) != 0, "DeleteFile failed (%d)", GetLastError());
219
220     filehandle = _lcreat( filename, 1 ); /* readonly */
221     ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%d)", filename, GetLastError(  ) );
222
223     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write never the less" );
224
225     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
226
227     ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should be able to find file" );
228
229     ok( 0 == DeleteFileA( filename ), "shouldn't be able to delete a readonly file" );
230
231     ok( SetFileAttributesA(filename, FILE_ATTRIBUTE_NORMAL ) != 0, "couldn't change attributes on file" );
232
233     ok( DeleteFileA( filename ) != 0, "now it should be possible to delete the file!" );
234
235     filehandle = _lcreat( filename, 2 );
236     ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%d)", filename, GetLastError(  ) );
237
238     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains" );
239
240     ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains" );
241
242     ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  strlen( sillytext ), "erratic _hread return value" );
243
244     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
245
246     ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should STILL be able to find file" );
247
248     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%d)", GetLastError(  ) );
249
250     filehandle = _lcreat( filename, 4 ); /* SYSTEM file */
251     ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%d)", filename, GetLastError(  ) );
252
253     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains" );
254
255     ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains" );
256
257     ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  strlen( sillytext ), "erratic _hread return value" );
258
259     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
260
261     ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should STILL be able to find file" );
262
263     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%d)", GetLastError(  ) );
264 }
265
266
267 void test__llseek( void )
268 {
269     INT i;
270     HFILE filehandle;
271     char buffer[1];
272     long bytes_read;
273
274     filehandle = _lcreat( filename, 0 );
275     if (filehandle == HFILE_ERROR)
276     {
277         ok(0,"couldn't create file \"%s\" (err=%d)",filename,GetLastError());
278         return;
279     }
280
281     for (i = 0; i < 400; i++)
282     {
283         ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains" );
284     }
285     ok( HFILE_ERROR != _llseek( filehandle, 400 * strlen( sillytext ), FILE_CURRENT ), "should be able to seek" );
286     ok( HFILE_ERROR != _llseek( filehandle, 27 + 35 * strlen( sillytext ), FILE_BEGIN ), "should be able to seek" );
287
288     bytes_read = _hread( filehandle, buffer, 1);
289     ok( 1 == bytes_read, "file read size error" );
290     ok( buffer[0] == sillytext[27], "_llseek error, it got lost seeking" );
291     ok( HFILE_ERROR != _llseek( filehandle, -400 * strlen( sillytext ), FILE_END ), "should be able to seek" );
292
293     bytes_read = _hread( filehandle, buffer, 1);
294     ok( 1 == bytes_read, "file read size error" );
295     ok( buffer[0] == sillytext[0], "_llseek error, it got lost seeking" );
296     ok( HFILE_ERROR != _llseek( filehandle, 1000000, FILE_END ), "should be able to seek past file; poor, poor Windows programmers" );
297     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
298
299     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%d)", GetLastError(  ) );
300 }
301
302
303 static void test__llopen( void )
304 {
305     HFILE filehandle;
306     UINT bytes_read;
307     char buffer[10000];
308
309     filehandle = _lcreat( filename, 0 );
310     if (filehandle == HFILE_ERROR)
311     {
312         ok(0,"couldn't create file \"%s\" (err=%d)",filename,GetLastError());
313         return;
314     }
315
316     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains" );
317     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
318
319     filehandle = _lopen( filename, OF_READ );
320     ok( HFILE_ERROR == _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write!" );
321     bytes_read = _hread( filehandle, buffer, strlen( sillytext ) );
322     ok( strlen( sillytext )  == bytes_read, "file read size error" );
323     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
324
325     filehandle = _lopen( filename, OF_READWRITE );
326     bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
327     ok( strlen( sillytext )  == bytes_read, "file read size error" );
328     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine" );
329     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
330
331     filehandle = _lopen( filename, OF_WRITE );
332     ok( HFILE_ERROR == _hread( filehandle, buffer, 1 ), "you should only be able to write this file" );
333     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine" );
334     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
335
336     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%d)", GetLastError(  ) );
337     /* TODO - add tests for the SHARE modes  -  use two processes to pull this one off */
338 }
339
340
341 static void test__lread( void )
342 {
343     HFILE filehandle;
344     char buffer[10000];
345     long bytes_read;
346     UINT bytes_wanted;
347     UINT i;
348
349     filehandle = _lcreat( filename, 0 );
350     if (filehandle == HFILE_ERROR)
351     {
352         ok(0,"couldn't create file \"%s\" (err=%d)",filename,GetLastError());
353         return;
354     }
355
356     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains" );
357
358     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
359
360     filehandle = _lopen( filename, OF_READ );
361
362     ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%d)", filename, GetLastError());
363
364     bytes_read = _lread( filehandle, buffer, 2 * strlen( sillytext ) );
365
366     ok( strlen( sillytext ) == bytes_read, "file read size error" );
367
368     for (bytes_wanted = 0; bytes_wanted < strlen( sillytext ); bytes_wanted++)
369     {
370         ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains" );
371         ok( _lread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value" );
372         for (i = 0; i < bytes_wanted; i++)
373         {
374             ok( buffer[i] == sillytext[i], "that's not what's written" );
375         }
376     }
377
378     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
379
380     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%d)", GetLastError(  ) );
381 }
382
383
384 static void test__lwrite( void )
385 {
386     HFILE filehandle;
387     char buffer[10000];
388     long bytes_read;
389     UINT bytes_written;
390     UINT blocks;
391     UINT i;
392     char *contents;
393     HLOCAL memory_object;
394     char checksum[1];
395
396     filehandle = _lcreat( filename, 0 );
397     if (filehandle == HFILE_ERROR)
398     {
399         ok(0,"couldn't create file \"%s\" (err=%d)",filename,GetLastError());
400         return;
401     }
402
403     ok( HFILE_ERROR != _lwrite( filehandle, "", 0 ), "_hwrite complains" );
404
405     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
406
407     filehandle = _lopen( filename, OF_READ );
408
409     bytes_read = _hread( filehandle, buffer, 1);
410
411     ok( 0 == bytes_read, "file read size error" );
412
413     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains" );
414
415     filehandle = _lopen( filename, OF_READWRITE );
416
417     bytes_written = 0;
418     checksum[0] = '\0';
419     srand( (unsigned)time( NULL ) );
420     for (blocks = 0; blocks < 100; blocks++)
421     {
422         for (i = 0; i < sizeof( buffer ); i++)
423         {
424             buffer[i] = rand(  );
425             checksum[0] = checksum[0] + buffer[i];
426         }
427         ok( HFILE_ERROR != _lwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains" );
428         bytes_written = bytes_written + sizeof( buffer );
429     }
430
431     ok( HFILE_ERROR != _lwrite( filehandle, checksum, 1 ), "_hwrite complains" );
432     bytes_written++;
433
434     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains" );
435
436     memory_object = LocalAlloc( LPTR, bytes_written );
437
438     ok( 0 != memory_object, "LocalAlloc fails, could be out of memory" );
439
440     contents = LocalLock( memory_object );
441
442     filehandle = _lopen( filename, OF_READ );
443
444     contents = LocalLock( memory_object );
445
446     ok( NULL != contents, "LocalLock whines" );
447
448     ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length" );
449
450     checksum[0] = '\0';
451     i = 0;
452     do
453     {
454         checksum[0] += contents[i];
455         i++;
456     }
457     while (i < bytes_written - 1);
458
459     ok( checksum[0] == contents[i], "stored checksum differ from computed checksum" );
460
461     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains" );
462
463     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%d)", GetLastError(  ) );
464 }
465
466
467 START_TEST(file)
468 {
469     test__hread(  );
470     test__hwrite(  );
471     test__lclose(  );
472     test__lcreat(  );
473     test__llseek(  );
474     test__llopen(  );
475     test__lread(  );
476     test__lwrite(  );
477 }