source: trunk/src/kernel32/Fileio.cpp@ 7518

Last change on this file since 7518 was 7518, checked in by sandervl, 24 years ago

minor update

File size: 53.1 KB
Line 
1/* $Id: Fileio.cpp,v 1.57 2001-12-01 19:26:40 sandervl Exp $ */
2
3/*
4 * Win32 File IO API functions for OS/2
5 *
6 * Copyright 1998-2000 Sander van Leeuwen
7 * Copyright 1998 Patrick Haller
8 *
9 * Some parts copied from Wine (CopyFileExA/W)
10 *
11 * Copyright 1993 John Burton
12 * Copyright 1996 Alexandre Julliard
13 *
14 *
15 * Project Odin Software License can be found in LICENSE.TXT
16 *
17 */
18
19
20/*****************************************************************************
21 * Includes *
22 *****************************************************************************/
23
24#include <odin.h>
25#include <odinwrap.h>
26#include <os2sel.h>
27
28#include <os2win.h>
29#include <stdlib.h>
30#include <string.h>
31#include "unicode.h"
32#include <heapstring.h>
33#include "handlemanager.h"
34#include "oslibdos.h"
35
36#define DBG_LOCALLOG DBG_fileio
37#include "dbglocal.h"
38
39ODINDEBUGCHANNEL(KERNEL32-FILEIO)
40
41#include <ctype.h>
42#include "fileio.h"
43
44#if 0
45#define IS_END_OF_NAME(ch) (!(ch) || ((ch) == '/') || ((ch) == '\\'))
46#define INVALID_DOS_CHARS "*?<>|\"+=,;[] \345"
47#define FILE_toupper(a) toupper(a)
48#define FILE_tolower(a) tolower(a)
49
50/***********************************************************************
51 * DOSFS_ValidDOSName
52 *
53 * Return 1 if Unix file 'name' is also a valid MS-DOS name
54 * (i.e. contains only valid DOS chars, lower-case only, fits in 8.3 format).
55 * File name can be terminated by '\0', '\\' or '/'.
56 */
57static int DOSFS_ValidDOSName( const char *name, int ignore_case )
58{
59 static const char invalid_chars[] = INVALID_DOS_CHARS;
60 const char *p = name;
61 const char *invalid = ignore_case ? (invalid_chars + 26) : invalid_chars;
62 int len = 0;
63
64 if (*p == '.')
65 {
66 /* Check for "." and ".." */
67 p++;
68 if (*p == '.') p++;
69 /* All other names beginning with '.' are invalid */
70 return (IS_END_OF_NAME(*p));
71 }
72 while (!IS_END_OF_NAME(*p))
73 {
74 if (strchr( invalid, *p )) return 0; /* Invalid char */
75 if (*p == '.') break; /* Start of the extension */
76 if (++len > 8) return 0; /* Name too long */
77 p++;
78 }
79 if (*p != '.') return 1; /* End of name */
80 p++;
81 if (IS_END_OF_NAME(*p)) return 0; /* Empty extension not allowed */
82 len = 0;
83 while (!IS_END_OF_NAME(*p))
84 {
85 if (strchr( invalid, *p )) return 0; /* Invalid char */
86 if (*p == '.') return 0; /* Second extension not allowed */
87 if (++len > 3) return 0; /* Extension too long */
88 p++;
89 }
90 return 1;
91}
92
93/***********************************************************************
94 * DOSFS_Hash
95 *
96 * Transform a Unix file name into a hashed DOS name. If the name is a valid
97 * DOS name, it is converted to upper-case; otherwise it is replaced by a
98 * hashed version that fits in 8.3 format.
99 * File name can be terminated by '\0', '\\' or '/'.
100 * 'buffer' must be at least 13 characters long.
101 */
102void DOSFS_Hash( LPCSTR name, LPSTR buffer, BOOL dir_format,
103 BOOL ignore_case )
104{
105 static const char invalid_chars[] = INVALID_DOS_CHARS "~.";
106 static const char hash_chars[33] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";
107
108 const char *p, *ext;
109 char *dst;
110 unsigned short hash;
111 int i;
112
113 if (dir_format) strcpy( buffer, " " );
114
115 if (DOSFS_ValidDOSName( name, ignore_case ))
116 {
117 /* Check for '.' and '..' */
118 if (*name == '.')
119 {
120 buffer[0] = '.';
121 if (!dir_format) buffer[1] = buffer[2] = '\0';
122 if (name[1] == '.') buffer[1] = '.';
123 return;
124 }
125
126 /* Simply copy the name, converting to uppercase */
127
128 for (dst = buffer; !IS_END_OF_NAME(*name) && (*name != '.'); name++)
129 *dst++ = FILE_toupper(*name);
130 if (*name == '.')
131 {
132 if (dir_format) dst = buffer + 8;
133 else *dst++ = '.';
134 for (name++; !IS_END_OF_NAME(*name); name++)
135 *dst++ = FILE_toupper(*name);
136 }
137 if (!dir_format) *dst = '\0';
138 return;
139 }
140
141 /* Compute the hash code of the file name */
142 /* If you know something about hash functions, feel free to */
143 /* insert a better algorithm here... */
144 if (ignore_case)
145 {
146 for (p = name, hash = 0xbeef; !IS_END_OF_NAME(p[1]); p++)
147 hash = (hash<<3) ^ (hash>>5) ^ FILE_tolower(*p) ^ (FILE_tolower(p[1]) << 8);
148 hash = (hash<<3) ^ (hash>>5) ^ FILE_tolower(*p); /* Last character*/
149 }
150 else
151 {
152 for (p = name, hash = 0xbeef; !IS_END_OF_NAME(p[1]); p++)
153 hash = (hash << 3) ^ (hash >> 5) ^ *p ^ (p[1] << 8);
154 hash = (hash << 3) ^ (hash >> 5) ^ *p; /* Last character */
155 }
156
157 /* Find last dot for start of the extension */
158 for (p = name+1, ext = NULL; !IS_END_OF_NAME(*p); p++)
159 if (*p == '.') ext = p;
160 if (ext && IS_END_OF_NAME(ext[1]))
161 ext = NULL; /* Empty extension ignored */
162
163 /* Copy first 4 chars, replacing invalid chars with '_' */
164 for (i = 4, p = name, dst = buffer; i > 0; i--, p++)
165 {
166 if (IS_END_OF_NAME(*p) || (p == ext)) break;
167 *dst++ = strchr( invalid_chars, *p ) ? '_' : FILE_toupper(*p);
168 }
169 /* Pad to 5 chars with '~' */
170 while (i-- >= 0) *dst++ = '~';
171
172 /* Insert hash code converted to 3 ASCII chars */
173 *dst++ = hash_chars[(hash >> 10) & 0x1f];
174 *dst++ = hash_chars[(hash >> 5) & 0x1f];
175 *dst++ = hash_chars[hash & 0x1f];
176
177 /* Copy the first 3 chars of the extension (if any) */
178 if (ext)
179 {
180 if (!dir_format) *dst++ = '.';
181 for (i = 3, ext++; (i > 0) && !IS_END_OF_NAME(*ext); i--, ext++)
182 *dst++ = strchr( invalid_chars, *ext ) ? '_' : FILE_toupper(*ext);
183 }
184 if (!dir_format) *dst = '\0';
185}
186#endif
187//******************************************************************************
188//******************************************************************************
189ODINFUNCTION7(HFILE, CreateFileA,
190 LPCSTR, lpszName,
191 DWORD, fdwAccess,
192 DWORD, fdwShareMode,
193 LPSECURITY_ATTRIBUTES, lpsa,
194 DWORD, fdwCreate,
195 DWORD, fdwAttrsAndFlags,
196 HANDLE, hTemplateFile)
197{
198 dprintf(("CreateFileA %s", lpszName));
199 return(HMCreateFile(lpszName,
200 fdwAccess,
201 fdwShareMode,
202 lpsa,
203 fdwCreate,
204 fdwAttrsAndFlags,
205 hTemplateFile));
206}
207
208//******************************************************************************
209//******************************************************************************
210ODINFUNCTION7(HFILE, CreateFileW,
211 LPCWSTR, arg1,
212 DWORD, arg2,
213 DWORD, arg3,
214 PSECURITY_ATTRIBUTES, arg4,
215 DWORD, arg5,
216 DWORD, arg6,
217 HANDLE, arg7)
218{
219 HANDLE rc;
220 char *astring;
221
222 astring = UnicodeToAsciiString((LPWSTR)arg1);
223 rc = CreateFileA(astring, arg2, arg3, arg4, arg5, arg6, arg7);
224 FreeAsciiString(astring);
225 return(rc);
226}
227//******************************************************************************
228//******************************************************************************
229ODINFUNCTION2(HANDLE, FindFirstFileA,
230 LPCSTR, lpFileName,
231 WIN32_FIND_DATAA *, lpFindFileData)
232{
233 HANDLE hFind;
234 char *filename;
235 int namelen;
236
237 dprintf(("FindFirstFileA %s", lpFileName));
238
239 if(lpFileName == NULL || lpFindFileData == NULL)
240 {
241 SetLastError(ERROR_INVALID_PARAMETER);
242 return -1;
243 }
244
245 namelen = strlen(lpFileName);
246 if(lpFileName[namelen-1] == '\\')
247 {
248 filename = (char *)alloca(namelen+1);
249 strcpy(filename, lpFileName);
250 filename[namelen-1] = 0;
251 }
252 else
253 filename = (char *)lpFileName;
254
255 return (HANDLE)OSLibDosFindFirst(filename,lpFindFileData);
256}
257//******************************************************************************
258// internal function for faster access (SHELL32)
259//******************************************************************************
260ODINFUNCTION3(HANDLE, FindFirstFileMultiA,
261 LPCSTR, lpFileName,
262 WIN32_FIND_DATAA *, lpFindFileData,
263 DWORD *,count)
264{
265 return (HANDLE)OSLibDosFindFirstMulti(lpFileName,lpFindFileData,count);
266}
267//******************************************************************************
268//******************************************************************************
269ODINFUNCTION2(HANDLE, FindFirstFileW,
270 LPCWSTR, lpFileName,
271 WIN32_FIND_DATAW *, lpFindFileData)
272{
273 HANDLE rc;
274 char *astring;
275 WIN32_FIND_DATAA wfda;
276
277 astring = UnicodeToAsciiString((LPWSTR)lpFileName);
278 dprintf(("FindFirstFileW %s", astring));
279 rc = (HANDLE)OSLibDosFindFirst(astring,&wfda);
280
281 if(rc == -1) {
282 memset(lpFindFileData, 0, sizeof(WIN32_FIND_DATAW));
283 }
284 else {
285 // convert back the result structure
286 memcpy(lpFindFileData,
287 &wfda,
288 sizeof(WIN32_FIND_DATAA));
289
290 lstrcpynAtoW (lpFindFileData->cFileName,
291 wfda.cFileName,
292 sizeof(wfda.cFileName));
293
294 lstrcpynAtoW (lpFindFileData->cAlternateFileName,
295 wfda.cAlternateFileName,
296 sizeof(wfda.cAlternateFileName));
297 }
298 FreeAsciiString(astring);
299 return(rc);
300}
301//******************************************************************************
302//******************************************************************************
303ODINFUNCTION2(BOOL, FindNextFileA,
304 HANDLE, hFindFile,
305 WIN32_FIND_DATAA *, lpFindFileData)
306{
307 return OSLibDosFindNext(hFindFile,lpFindFileData);
308}
309//******************************************************************************
310// internal function for faster access (SHELL32)
311//******************************************************************************
312ODINFUNCTION3(BOOL, FindNextFileMultiA,
313 HANDLE, hFindFile,
314 WIN32_FIND_DATAA *, lpFindFileData,
315 DWORD *,count)
316{
317 return OSLibDosFindNextMulti(hFindFile,lpFindFileData,count);
318}
319//******************************************************************************
320//******************************************************************************
321ODINFUNCTION2(BOOL, FindNextFileW,
322 HANDLE, hFindFile,
323 WIN32_FIND_DATAW *, lpFindFileData)
324{
325 WIN32_FIND_DATAA wfda;
326 BOOL rc;
327
328 rc = OSLibDosFindNext(hFindFile,&wfda);
329
330 if(rc == 0) {
331 memset(lpFindFileData, 0, sizeof(WIN32_FIND_DATAW));
332 }
333 else {
334 // convert back the result structure
335 memcpy(lpFindFileData,
336 &wfda,
337 sizeof(WIN32_FIND_DATAA));
338
339 lstrcpynAtoW (lpFindFileData->cFileName,
340 wfda.cFileName,
341 sizeof(wfda.cFileName));
342
343 lstrcpynAtoW (lpFindFileData->cAlternateFileName,
344 wfda.cAlternateFileName,
345 sizeof(wfda.cAlternateFileName));
346 }
347 return rc;
348}
349//******************************************************************************
350//******************************************************************************
351ODINFUNCTION1(BOOL, FindClose,
352 HANDLE, hFindFile)
353{
354 return OSLibDosFindClose(hFindFile);
355}
356//******************************************************************************
357//******************************************************************************
358ODINFUNCTION1(DWORD, GetFileType,
359 HANDLE, hFile)
360{
361 return(HMGetFileType(hFile));
362}
363//******************************************************************************
364//******************************************************************************
365ODINFUNCTION2(DWORD, GetFileInformationByHandle,
366 HANDLE, arg1,
367 BY_HANDLE_FILE_INFORMATION *, arg2)
368{
369 return(HMGetFileInformationByHandle(arg1,arg2));
370}
371//******************************************************************************
372//******************************************************************************
373ODINFUNCTION1(BOOL, SetEndOfFile,
374 HANDLE, arg1)
375{
376 return HMSetEndOfFile(arg1);
377}
378//******************************************************************************
379//******************************************************************************
380ODINFUNCTION4(BOOL, SetFileTime,
381 HANDLE, arg1,
382 const FILETIME *, arg2,
383 const FILETIME *, arg3,
384 const FILETIME *, arg4)
385{
386 return HMSetFileTime(arg1,
387 arg2,
388 arg3,
389 arg4);
390}
391//******************************************************************************
392//******************************************************************************
393ODINFUNCTION2(INT, CompareFileTime,
394 FILETIME *, lpft1,
395 FILETIME *, lpft2)
396{
397 if (lpft1 == NULL || lpft2 == NULL) {
398 SetLastError(ERROR_INVALID_PARAMETER);
399 return -1;
400 }
401
402 if(lpft1->dwHighDateTime > lpft2->dwHighDateTime)
403 return 1;
404
405 if(lpft1->dwHighDateTime < lpft2->dwHighDateTime)
406 return -1;
407
408 if(lpft1->dwLowDateTime > lpft2->dwLowDateTime)
409 return 1;
410
411 if(lpft1->dwLowDateTime < lpft2->dwLowDateTime)
412 return -1;
413
414 return 0; //equal
415}
416//******************************************************************************
417//******************************************************************************
418ODINFUNCTION4(BOOL, GetFileTime, HANDLE, hFile, LPFILETIME, arg2, LPFILETIME, arg3, LPFILETIME, arg4)
419{
420 return HMGetFileTime(hFile, arg2, arg3, arg4);
421}
422//******************************************************************************
423//******************************************************************************
424ODINFUNCTION3(BOOL, CopyFileA,
425 LPCSTR, arg1,
426 LPCSTR, arg2,
427 BOOL, arg3)
428{
429 return OSLibDosCopyFile(arg1, arg2, arg3);
430}
431//******************************************************************************
432//SvL: 24-6-'97 - Added
433//******************************************************************************
434ODINFUNCTION3(BOOL, CopyFileW,
435 LPCWSTR, arg1,
436 LPCWSTR, arg2,
437 BOOL, arg3)
438{
439 BOOL rc;
440 char *astring1, *astring2;
441
442 astring1 = UnicodeToAsciiString((LPWSTR)arg1);
443 astring2 = UnicodeToAsciiString((LPWSTR)arg2);
444 rc = CALL_ODINFUNC(CopyFileA)(astring1, astring2, arg3);
445 FreeAsciiString(astring2);
446 FreeAsciiString(astring1);
447 return(rc);
448}
449/*****************************************************************************
450 * Name : BOOL WIN32API CopyFileExA
451 * Purpose : The CopyFileExA function copies an existing file to a new file.
452 * This function preserves extended attributes, OLE structured
453 * storage, NTFS alternate data streams, and file attributes.
454 * Security attributes for the existing file are not copied to
455 * the new file.
456 * Parameters: LPCSTR lpExistingFileName pointer to name of an existing file
457 * LPCSTR lpNewFileName pointer to filename to copy to
458 * LPPROGRESS_ROUTINE lpProgressRoutine pointer to the callback function
459 * LPVOID lpData to be passed to the callback function
460 * LPBOOL pbCancel flag that can be used to cancel the operation
461 * DWORD dwCopyFlags flags that specify how the file is copied
462 * Variables :
463 * Result : f the function succeeds, the return value is nonzero.
464 * If the function fails, the return value is zero.
465 * To get extended error information call GetLastError.
466 * Remark :
467 * Status : UNTESTED STUB
468 *
469 * Author : Markus Montkowski [Thu, 1998/05/19 11:46]
470 *****************************************************************************/
471
472BOOL WIN32API CopyFileExA( LPCSTR lpExistingFileName,
473 LPCSTR lpNewFileName,
474 LPPROGRESS_ROUTINE lpProgressRoutine,
475 LPVOID lpData,
476 LPBOOL pbCancel,
477 DWORD dwCopyFlags)
478{
479
480 dprintf(("KERNEL32: CopyFileExA(%08x,%08x,%08x,%08x,%08x,%08x) not properly implemented\n",
481 lpExistingFileName,
482 lpNewFileName,
483 lpProgressRoutine,
484 lpData,
485 pbCancel,
486 dwCopyFlags
487 ));
488
489 BOOL failIfExists = FALSE;
490
491 /*
492 * Interpret the only flag that CopyFile can interpret.
493 */
494 if((dwCopyFlags & COPY_FILE_FAIL_IF_EXISTS) != 0)
495 {
496 failIfExists = TRUE;
497 }
498
499 return CopyFileA(lpExistingFileName, lpNewFileName, failIfExists);
500}
501
502
503/*****************************************************************************
504 * Name : BOOL WIN32API CopyFileExW
505 * Purpose : The CopyFileExW function copies an existing file to a new file.
506 * This function preserves extended attributes, OLE structured
507 * storage, NTFS alternate data streams, and file attributes.
508 * Security attributes for the existing file are not copied to
509 * the new file.
510 * Parameters: LPCWSTR lpExistingFileName pointer to name of an existing file
511 * LPCWSTR lpNewFileName pointer to filename to copy to
512 * LPPROGRESS_ROUTINE lpProgressRoutine pointer to the callback function
513 * LPVOID lpData to be passed to the callback function
514 * LPBOOL pbCancel flag that can be used to cancel the operation
515 * DWORD dwCopyFlags flags that specify how the file is copied
516 * Variables :
517 * Result : f the function succeeds, the return value is nonzero.
518 * If the function fails, the return value is zero.
519 * To get extended error information call GetLastError.
520 * Remark :
521 * Status : UNTESTED STUB
522 *
523 * Author : Markus Montkowski [Thu, 1998/05/19 11:46]
524 *****************************************************************************/
525
526BOOL WIN32API CopyFileExW( LPCWSTR lpExistingFileName,
527 LPCWSTR lpNewFileName,
528 LPPROGRESS_ROUTINE lpProgressRoutine,
529 LPVOID lpData,
530 LPBOOL pbCancel,
531 DWORD dwCopyFlags)
532{
533 LPSTR sourceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpExistingFileName );
534 LPSTR destA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpNewFileName );
535
536 BOOL ret = CopyFileExA(sourceA,
537 destA,
538 lpProgressRoutine,
539 lpData,
540 pbCancel,
541 dwCopyFlags);
542
543 HeapFree( GetProcessHeap(), 0, sourceA );
544 HeapFree( GetProcessHeap(), 0, destA );
545
546 return ret;
547}
548//******************************************************************************
549//******************************************************************************
550ODINFUNCTION2(DWORD, GetFileSize,
551 HANDLE, arg1,
552 PDWORD, arg2)
553{
554 return HMGetFileSize(arg1,
555 arg2);
556}
557//******************************************************************************
558//******************************************************************************
559ODINFUNCTION1(BOOL, DeleteFileA,
560 LPCSTR, lpszFile)
561{
562 BOOL rc;
563
564#if 0
565 dprintf(("DeleteFileA %s", lpszFile));
566 return 1;
567#else
568 rc = OSLibDosDelete((LPSTR)lpszFile);
569 if(!rc) {
570 dprintf(("DeleteFileA %s returned FALSE; last error %x", lpszFile, GetLastError()));
571 if(GetLastError() == 20) {
572 return TRUE;
573 }
574 }
575 else dprintf(("DeleteFileA %s", lpszFile));
576
577 return rc;
578#endif
579}
580//******************************************************************************
581//******************************************************************************
582ODINFUNCTION1(BOOL, DeleteFileW,
583 LPCWSTR, arg1)
584{
585 BOOL rc;
586 char *astring;
587
588 astring = UnicodeToAsciiString((LPWSTR)arg1);
589 rc = CALL_ODINFUNC(DeleteFileA)(astring);
590 FreeAsciiString(astring);
591 return(rc);
592}
593//******************************************************************************
594//******************************************************************************
595ODINFUNCTION4(UINT, GetTempFileNameA,
596 LPCSTR, arg1,
597 LPCSTR, arg2,
598 UINT, arg3,
599 LPSTR, arg4)
600{
601 return O32_GetTempFileName(arg1, arg2, arg3, arg4);
602}
603//******************************************************************************
604//******************************************************************************
605ODINFUNCTION4(UINT, GetTempFileNameW,
606 LPCWSTR, lpPathName,
607 LPCWSTR, lpPrefixString,
608 UINT, uUnique,
609 LPWSTR, lpTempFileName)
610{
611 char *asciipath, *asciiprefix;
612 char *asciitemp = (char *)malloc(MAX_PATH+1);
613 UINT rc;
614
615 asciipath = UnicodeToAsciiString((LPWSTR)lpPathName);
616 asciiprefix = UnicodeToAsciiString((LPWSTR)lpPrefixString);
617 rc = O32_GetTempFileName(asciipath, asciiprefix, uUnique, asciitemp);
618 if(rc) AsciiToUnicode(asciitemp, lpTempFileName);
619 FreeAsciiString(asciiprefix);
620 FreeAsciiString(asciipath);
621 free(asciitemp);
622 return(rc);
623}
624//******************************************************************************
625//******************************************************************************
626ODINFUNCTION2(UINT, GetTempPathA,
627 UINT, arg1,
628 LPSTR, arg2)
629{
630 return O32_GetTempPath(arg1, arg2);
631}
632//******************************************************************************
633//******************************************************************************
634ODINFUNCTION2(UINT, GetTempPathW,
635 UINT, nBufferLength,
636 LPWSTR, lpBuffer)
637{
638 char *asciibuffer = (char *)malloc(nBufferLength+1);
639 DWORD rc;
640
641 rc = O32_GetTempPath(nBufferLength, asciibuffer);
642 if(rc) AsciiToUnicode(asciibuffer, lpBuffer);
643 free(asciibuffer);
644 return(rc);
645}
646//******************************************************************************
647//******************************************************************************
648ODINFUNCTION5(BOOL, ReadFile,
649 HANDLE, hFile,
650 PVOID, pBuffer,
651 DWORD, dwLength,
652 PDWORD, lpNumberOfBytesRead,
653 LPOVERLAPPED, lpOverlapped)
654{
655 if(lpNumberOfBytesRead) *lpNumberOfBytesRead = 0;
656 if(dwLength == 0) {
657 dprintf(("!WARNING!: Nothing to do"));
658 //TODO: should we fail here instead?? (wine doesn't)
659 return TRUE;
660 }
661 return (HMReadFile(hFile,
662 pBuffer,
663 dwLength,
664 lpNumberOfBytesRead,
665 lpOverlapped));
666}
667//******************************************************************************
668//******************************************************************************
669ODINFUNCTION5(BOOL, ReadFileEx,
670 HANDLE, hFile,
671 LPVOID, lpBuffer,
672 DWORD, nNumberOfBytesToRead,
673 LPOVERLAPPED, lpOverlapped,
674 LPOVERLAPPED_COMPLETION_ROUTINE, lpCompletionRoutine)
675{
676 if(nNumberOfBytesToRead == 0) {
677 dprintf(("!WARNING!: Nothing to do"));
678 //TODO: should we fail here instead?? (wine doesn't)
679 return TRUE;
680 }
681 return (HMReadFileEx(hFile,
682 lpBuffer,
683 nNumberOfBytesToRead,
684 lpOverlapped, lpCompletionRoutine));
685}
686//******************************************************************************
687//******************************************************************************
688ODINFUNCTION5(BOOL, WriteFile,
689 HANDLE, hFile,
690 LPCVOID, buffer,
691 DWORD, nrbytes,
692 LPDWORD, nrbyteswritten,
693 LPOVERLAPPED, lpOverlapped)
694{
695 if(nrbyteswritten) *nrbyteswritten = 0;
696 if(nrbytes == 0) {
697 dprintf(("!WARNING!: Nothing to do"));
698 //TODO: should we fail here instead?? (wine doesn't)
699 return TRUE;
700 }
701
702 return (HMWriteFile(hFile,
703 buffer,
704 nrbytes,
705 nrbyteswritten,
706 lpOverlapped));
707}
708/*****************************************************************************
709 * Name : BOOL WriteFileEx
710 * Purpose : The WriteFileEx function writes data to a file. It is designed
711 * solely for asynchronous operation, unlike WriteFile, which is
712 * designed for both synchronous and asynchronous operation.
713 * WriteFileEx reports its completion status asynchronously,
714 * calling a specified completion routine when writing is completed
715 * and the calling thread is in an alertable wait state.
716 * Parameters: HANDLE hFile handle of file to write
717 * LPVOID lpBuffer address of buffer
718 * DWORD nNumberOfBytesToRead number of bytes to write
719 * LPOVERLAPPED lpOverlapped address of offset
720 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
721 * Variables :
722 * Result : TRUE / FALSE
723 * Remark :
724 * Status : UNTESTED STUB
725 *
726 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
727 *****************************************************************************/
728
729ODINFUNCTION5(BOOL, WriteFileEx,
730 HANDLE, hFile,
731 LPCVOID, lpBuffer,
732 DWORD, nNumberOfBytesToWrite,
733 LPOVERLAPPED, lpOverlapped,
734 LPOVERLAPPED_COMPLETION_ROUTINE, lpCompletionRoutine)
735{
736 if(nNumberOfBytesToWrite == 0) {
737 dprintf(("!WARNING!: Nothing to do"));
738 //TODO: should we fail here instead?? (wine doesn't)
739 return TRUE;
740 }
741
742 return (HMWriteFileEx(hFile,
743 (LPVOID)lpBuffer,
744 nNumberOfBytesToWrite,
745 lpOverlapped, lpCompletionRoutine));
746}
747//******************************************************************************
748//******************************************************************************
749ODINFUNCTION4(DWORD, SetFilePointer,
750 HANDLE, hFile,
751 LONG, lDistanceToMove,
752 PLONG, lpDistanceToMoveHigh,
753 DWORD, dwMoveMethod)
754{
755 return(HMSetFilePointer(hFile,
756 lDistanceToMove,
757 lpDistanceToMoveHigh,
758 dwMoveMethod));
759}
760//******************************************************************************
761//******************************************************************************
762ODINFUNCTION1(DWORD, GetFileAttributesA,
763 LPCSTR, lpszFileName)
764{
765 DWORD rc, error;
766
767 if((NULL!=lpszFileName) && strlen(lpszFileName)==2 && lpszFileName[1] == ':')
768 {
769 char szDrive[4];
770 szDrive[0] = lpszFileName[0];
771 szDrive[1] = lpszFileName[1];
772 szDrive[2] = '\\';
773 szDrive[3] = 0x00;
774 rc = O32_GetFileAttributes((LPSTR)szDrive);
775 }
776 else {
777 rc = O32_GetFileAttributes((LPSTR)lpszFileName);
778 if(rc == -1 && lpszFileName[strlen(lpszFileName)-1] != '\\') {
779 char *filename = (char *)alloca(strlen(lpszFileName)+2); //+2!!!!!!
780 strcpy(filename, lpszFileName);
781 strcat(filename, "\\");
782 rc = O32_GetFileAttributes((LPSTR)filename);
783 }
784 }
785 //SvL: Open32 returns FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_NORMAL for
786 // directories whereas NT 4 (SP6) only returns FILE_ATTRIBUTE_DIRECTORY
787 if(rc != -1 && (rc & FILE_ATTRIBUTE_DIRECTORY)) {
788 rc = FILE_ATTRIBUTE_DIRECTORY;
789 }
790
791#if 0 // need more tests, maybe there is also a better way to hide simulated b:
792 if(rc == -1 && lpszFileName != NULL && !strnicmp(lpszFileName, "B:", 2))
793 {
794 error = GetLastError();
795 if(error = ERROR_DISK_CHANGE)
796 SetLastError(ERROR_NOT_READY);
797 else
798 SetLastError(error);
799 }
800#endif
801 dprintf(("KERNEL32: GetFileAttributes of %s returned %d\n", lpszFileName, rc));
802 return(rc);
803}
804//******************************************************************************
805//******************************************************************************
806ODINFUNCTION1(DWORD, GetFileAttributesW,
807 LPCWSTR, arg1)
808{
809 DWORD rc;
810 char *astring;
811
812 astring = UnicodeToAsciiString((LPWSTR)arg1);
813 rc = CALL_ODINFUNC(GetFileAttributesA)(astring);
814 FreeAsciiString(astring);
815 return(rc);
816}
817//******************************************************************************
818//******************************************************************************
819ODINFUNCTION2(BOOL, SetFileAttributesA,
820 LPCSTR, arg1,
821 DWORD, arg2)
822{
823 dprintf(("KERNEL32: SetFileAttributes of %s\n", arg1));
824 return O32_SetFileAttributes(arg1, arg2);
825}
826//******************************************************************************
827//******************************************************************************
828ODINFUNCTION2(BOOL, SetFileAttributesW,
829 LPCWSTR, lpFileName,
830 DWORD, dwFileAttributes)
831{
832 char *asciifile;
833 BOOL rc;
834
835 asciifile = UnicodeToAsciiString((LPWSTR)lpFileName);
836 rc = O32_SetFileAttributes(asciifile, dwFileAttributes);
837 FreeAsciiString(asciifile);
838 return(rc);
839}
840//******************************************************************************
841//******************************************************************************
842ODINFUNCTION4(DWORD, GetFullPathNameA,
843 LPCSTR, arg1,
844 DWORD, arg2,
845 LPSTR, arg3,
846 LPSTR *, arg4)
847{
848 char *ptr;
849 DWORD rc;
850 dprintf(("KERNEL32: GetFullPathName called with %s %d %x", arg1, arg2, arg3));
851 while((ptr = strchr(arg1, '/')) != NULL)
852 *ptr = '\\';
853
854 return O32_GetFullPathName(arg1, arg2, arg3, arg4);
855}
856//******************************************************************************
857//******************************************************************************
858ODINFUNCTION4(DWORD, GetFullPathNameW,
859 LPCWSTR, lpFileName,
860 DWORD, nBufferLength,
861 LPWSTR, lpBuffer,
862 LPWSTR *, lpFilePart)
863{
864 char *astring, *asciibuffer, *asciipart;
865 DWORD rc;
866
867 asciibuffer = (char *)malloc(nBufferLength+1);
868 astring = UnicodeToAsciiString((LPWSTR)lpFileName);
869
870 rc = CALL_ODINFUNC(GetFullPathNameA)(astring,
871 nBufferLength,
872 asciibuffer,
873 &asciipart);
874
875 dprintf(("KERNEL32: GetFullPathNameW %s returns %s\n",
876 astring,
877 asciibuffer));
878
879 if(rc)
880 AsciiToUnicode(asciibuffer,
881 lpBuffer);
882
883 if(lpFilePart) {
884 if (asciipart == NULL)
885 *lpFilePart = NULL;
886 else
887 *lpFilePart = lpBuffer + ((int)asciipart - (int)asciibuffer);
888 }
889
890 FreeAsciiString(astring);
891 free(asciibuffer);
892 return(rc);
893}
894//******************************************************************************
895//******************************************************************************
896ODINFUNCTION5(BOOL, LockFile,
897 HANDLE, arg1,
898 DWORD, arg2,
899 DWORD, arg3,
900 DWORD, arg4,
901 DWORD, arg5)
902{
903 return HMLockFile(arg1,
904 arg2,
905 arg3,
906 arg4,
907 arg5);
908}
909
910
911/*****************************************************************************
912 * Name : BOOL LockFileEx
913 * Purpose : The LockFileEx function locks a byte range within an open file for shared or exclusive access.
914 * Parameters: HANDLE hFile handle of file to lock
915 * DWORD dwFlags functional behavior modification flags
916 * DWORD dwReserved reserved, must be set to zero
917 * DWORD nNumberOfBytesToLockLow low-order 32 bits of length to lock
918 * DWORD nNumberOfBytesToLockHigh high-order 32 bits of length to lock
919 * LPOVERLAPPED LPOVERLAPPED addr. of structure with lock region start offset
920 * Variables :
921 * Result : TRUE / FALSE
922 * Remark :
923 * Status : UNTESTED STUB
924 *
925 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
926 *****************************************************************************/
927
928ODINFUNCTION6(BOOL, LockFileEx,
929 HANDLE, hFile,
930 DWORD, dwFlags,
931 DWORD, dwReserved,
932 DWORD, nNumberOfBytesToLockLow,
933 DWORD, nNumberOfBytesToLockHigh,
934 LPOVERLAPPED, lpOverlapped)
935{
936 return(HMLockFile(hFile,
937 lpOverlapped->Offset,
938 lpOverlapped->OffsetHigh,
939 nNumberOfBytesToLockLow,
940 nNumberOfBytesToLockHigh));
941}
942//******************************************************************************
943//******************************************************************************
944ODINFUNCTION2(BOOL, MoveFileA,
945 LPCSTR, arg1,
946 LPCSTR, arg2)
947{
948 dprintf(("KERNEL32: MoveFileA %s %s", arg1, arg2));
949 return OSLibDosMoveFile(arg1, arg2);
950}
951//******************************************************************************
952//******************************************************************************
953
954
955/*****************************************************************************
956 * Name : MoveFileExA
957 * Purpose : Move or delete a file
958 * Parameters: LPCSTR lpExistingFileName
959 * LPCSTR lpNewFileName
960 * DWORD dwFlags
961 * Variables :
962 * Result :
963 * Remark : "delete on system-reboot" feature is not supported!
964 * Status :
965 *
966 * Author : Patrick Haller [2001-08-30]
967 *****************************************************************************/
968
969ODINFUNCTION3(BOOL, MoveFileExA,
970 LPCSTR, lpszOldFilename,
971 LPCSTR, lpszNewFilename,
972 DWORD, fdwFlags)
973{
974 dprintf(("KERNEL32: MoveFileExA %s to %s %x, not complete!\n",
975 lpszOldFilename,
976 lpszNewFilename,
977 fdwFlags));
978
979 // this parameter combination is illegal
980 if ( (fdwFlags & MOVEFILE_DELAY_UNTIL_REBOOT) &&
981 (fdwFlags & MOVEFILE_COPY_ALLOWED) )
982 {
983 // Note: error code not verified
984 SetLastError(ERROR_INVALID_PARAMETER);
985 return FALSE;
986 }
987
988 // first, we take care about the special cases
989 if (fdwFlags && MOVEFILE_DELAY_UNTIL_REBOOT)
990 {
991 // We cannot really support this in any other way than
992 // to call the IBMCSFLK driver. As the first place I've encountered
993 // this call is Microsoft ACMSETUP wanting to replace OLEPRO32.DLL
994 // in the ODIN system directory, we are better skipping the call.
995
996 // Anyway, this is only supported under Windows NT
997 fdwFlags &= ~MOVEFILE_DELAY_UNTIL_REBOOT;
998
999 // Until we support this, we have to intercept
1000 // lpszNewFilename == NULL
1001 if (NULL == lpszNewFilename)
1002 {
1003 // try to delete the filename
1004 dprintf(("KERNEL32-MoveFileExA: trying to delete file [%s], skipped.",
1005 lpszOldFilename));
1006
1007 SetLastError( NO_ERROR );
1008 return TRUE;
1009 }
1010 }
1011
1012 if (fdwFlags && MOVEFILE_COPY_ALLOWED)
1013 {
1014 // if lpszOldFilename and lpszNewFilename refer to different
1015 // volumes, this flag controls if a copy operation is allowed.
1016 }
1017
1018 if (fdwFlags && MOVEFILE_REPLACE_EXISTING)
1019 {
1020 // We can only attempt to
1021 // 1 move away the current file if existing,
1022 // 2 do the current move operation
1023 // 3 if succesful, delete the backup
1024 // otherwise restore the original file
1025 }
1026
1027 return OSLibDosMoveFile(lpszOldFilename,
1028 lpszNewFilename);
1029}
1030//******************************************************************************
1031//******************************************************************************
1032ODINFUNCTION2(BOOL, MoveFileW,
1033 LPCWSTR, lpSrc,
1034 LPCWSTR, lpDest)
1035{
1036 char *asciisrc, *asciidest;
1037 BOOL rc;
1038
1039 asciisrc = UnicodeToAsciiString((LPWSTR)lpSrc);
1040 asciidest = UnicodeToAsciiString((LPWSTR)lpDest);
1041 rc = MoveFileA(asciisrc, asciidest);
1042 FreeAsciiString(asciisrc);
1043 FreeAsciiString(asciidest);
1044 return(rc);
1045}
1046//******************************************************************************
1047//******************************************************************************
1048ODINFUNCTION3(BOOL, MoveFileExW,
1049 LPCWSTR, lpSrc,
1050 LPCWSTR, lpDest,
1051 DWORD, fdwFlags)
1052{
1053 dprintf(("KERNEL32: MoveFileExW %ls to %ls %x",
1054 lpSrc,
1055 lpDest,
1056 fdwFlags));
1057
1058 char *asciisrc,
1059 *asciidest;
1060 BOOL rc;
1061
1062 asciisrc = UnicodeToAsciiString((LPWSTR)lpSrc);
1063 if (NULL != lpDest)
1064 asciidest = UnicodeToAsciiString((LPWSTR)lpDest);
1065 else
1066 asciidest = NULL;
1067
1068 rc = MoveFileExA(asciisrc,
1069 asciidest,
1070 fdwFlags);
1071
1072 if (NULL != asciidest)
1073 FreeAsciiString(asciidest);
1074
1075 FreeAsciiString(asciisrc);
1076
1077 return(rc);
1078}
1079//******************************************************************************
1080/*****************************************************************************
1081ODINFUNCTION3(*, :,
1082 HFILE, WIN32API,
1083 OpenFile *, Purpose,
1084 :, forwardOpenFile to Open32
1085 * Parameters:
1086 * Variables :
1087 * Result : API returncode
1088 * Remark : modified for handle translation support
1089 * Status : @@@PH verify if 0 is a valid "invalid handle" :)
1090 *
1091 * Author : Patrick Haller [Fri, 1998/06/12 02:53]
1092 *****************************************************************************/
1093
1094ODINFUNCTION3(HFILE, OpenFile,
1095 LPCSTR, lpszFile,
1096 OFSTRUCT *, lpOpenBuff,
1097 UINT, fuMode)
1098{
1099 HFILE hFile;
1100
1101 dprintf(("KERNEL32: OpenFile(%s, %08xh, %08xh)\n",
1102 lpszFile,
1103 lpOpenBuff,
1104 fuMode));
1105
1106 hFile = HMOpenFile(lpszFile, /* call open32 */
1107 lpOpenBuff,
1108 fuMode);
1109
1110 return (hFile);
1111}
1112//******************************************************************************
1113//******************************************************************************
1114ODINFUNCTION5(BOOL, UnlockFile,
1115 HANDLE, arg1,
1116 DWORD, arg2,
1117 DWORD, arg3,
1118 DWORD, arg4,
1119 DWORD, arg5)
1120{
1121 return HMUnlockFile(arg1,
1122 arg2,
1123 arg3,
1124 arg4,
1125 arg5);
1126}
1127
1128
1129/*****************************************************************************
1130 * Name : BOOL UnlockFileEx
1131 * Purpose : The UnlockFileEx function unlocks a previously locked byte range in an open file.
1132 * Parameters: HANDLE hFile handle of file to lock
1133 * DWORD dwReserved reserved, must be set to zero
1134 * DWORD nNumberOfBytesToLockLow low-order 32 bits of length to lock
1135 * DWORD nNumberOfBytesToLockHigh high-order 32 bits of length to lock
1136 * LPOVERLAPPED LPOVERLAPPED addr. of structure with lock region start offset
1137 * Variables :
1138 * Result : TRUE / FALSE
1139 * Remark :
1140 * Status : UNTESTED STUB
1141 *
1142 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1143 *****************************************************************************/
1144
1145ODINFUNCTION5(BOOL, UnlockFileEx,
1146 HANDLE, hFile,
1147 DWORD, dwReserved,
1148 DWORD, nNumberOfBytesToLockLow,
1149 DWORD, nNumberOfBytesToLockHigh,
1150 LPOVERLAPPED, lpOverlapped)
1151{
1152 return(HMUnlockFileEx(hFile, dwReserved,
1153 nNumberOfBytesToLockLow,
1154 nNumberOfBytesToLockHigh,
1155 lpOverlapped));
1156}
1157//******************************************************************************
1158//Behaviour in NT 4, SP6:
1159//- converts long filename to 8.3 short filname (TODO: not yet done here!)
1160//- fails on volume that doesn't support 8.3 filenames
1161//- if lpszShortPath 0 or cchBuffer too small -> return required length
1162// (INCLUDING 0 terminator)
1163//- if lpszLongPath == NULL -> ERROR_INVALID_PARAMETER (return 0)
1164//- if lpszLongPath empty -> proceed as if nothing is wrong
1165//- does NOT clear the last error if successful!
1166//- if successful -> return length of string (excluding 0 terminator)
1167//******************************************************************************
1168ODINFUNCTION3(DWORD, GetShortPathNameA,
1169 LPCTSTR, lpszLongPath,
1170 LPTSTR, lpszShortPath,
1171 DWORD, cchBuffer)
1172{
1173 int length;
1174
1175 dprintf(("KERNEL32: GetShortPathNameA of %s, just copying it", lpszLongPath));
1176
1177 if(!lpszLongPath) {
1178 SetLastError(ERROR_INVALID_PARAMETER);
1179 return 0;
1180 }
1181
1182 length = lstrlenA(lpszLongPath) + 1;
1183 if(length > cchBuffer) {
1184 if(lpszShortPath) {
1185 *lpszShortPath = 0;
1186 }
1187 return(length); //return length required (including 0 terminator)
1188 }
1189 lstrcpyA(lpszShortPath, lpszLongPath);
1190 return(length-1);
1191}
1192//******************************************************************************
1193//******************************************************************************
1194ODINFUNCTION3(DWORD, GetShortPathNameW,
1195 LPCWSTR, lpszLongPath,
1196 LPWSTR, lpszShortPath,
1197 DWORD, cchBuffer)
1198{
1199 int length;
1200
1201 dprintf(("KERNEL32: GetShortPathNameW; just copying it"));
1202 if(!lpszLongPath) {
1203 SetLastError(ERROR_INVALID_PARAMETER);
1204 return 0;
1205 }
1206
1207 length = lstrlenW(lpszLongPath) + 1;
1208 if(length > cchBuffer) {
1209 if(lpszShortPath) {
1210 *lpszShortPath = 0;
1211 }
1212 return(length); //return length required (including 0 terminator)
1213 }
1214 lstrcpyW(lpszShortPath, lpszLongPath);
1215 return(length-1);
1216}
1217//******************************************************************************
1218//Behaviour in NT 4, SP6: (presumably the same as GetShortPathNameA; TODO check)
1219//- converts short filename to long filenames (TODO: not yet done here!)
1220//- if lpszShortPath 0 or cchBuffer too small -> return required length
1221// (INCLUDING 0 terminator)
1222//- if lpszLongPath == NULL -> ERROR_INVALID_PARAMETER (return 0)
1223//- if lpszLongPath empty -> proceed as if nothing is wrong
1224//- does NOT clear the last error if successful!
1225//- if successful -> return length of string (excluding 0 terminator)
1226//******************************************************************************
1227DWORD WINAPI GetLongPathNameA( LPCSTR lpszShortPath, LPSTR lpszLongPath,
1228 DWORD cchBuffer )
1229{
1230 int length;
1231
1232 dprintf(("GetLongPathNameA %x %s %d", lpszShortPath, lpszLongPath, cchBuffer));
1233 dprintf(("WARNING: WIN98 ONLY!!"));
1234
1235 if(!lpszShortPath) {
1236 SetLastError(ERROR_INVALID_PARAMETER);
1237 return 0;
1238 }
1239
1240 length = lstrlenA(lpszShortPath) + 1;
1241 if(length > cchBuffer) {
1242 if(lpszLongPath) {
1243 *lpszLongPath = 0;
1244 }
1245 return(length); //return length required (including 0 terminator)
1246 }
1247 lstrcpyA(lpszLongPath, lpszShortPath);
1248 return(length-1);
1249}
1250//******************************************************************************
1251//******************************************************************************
1252DWORD WINAPI GetLongPathNameW( LPCWSTR lpszShortPath, LPWSTR lpszLongPath,
1253 DWORD cchBuffer )
1254{
1255 int length;
1256
1257 dprintf(("GetLongPathNameW %x %ls %d", lpszShortPath, lpszLongPath, cchBuffer));
1258 dprintf(("WARNING: WIN98 ONLY!!"));
1259
1260 if(!lpszShortPath) {
1261 SetLastError(ERROR_INVALID_PARAMETER);
1262 return 0;
1263 }
1264
1265 length = lstrlenW(lpszShortPath) + 1;
1266 if(length > cchBuffer) {
1267 if(lpszLongPath) {
1268 *lpszLongPath = 0;
1269 }
1270 return(length); //return length required (including 0 terminator)
1271 }
1272 lstrcpyW(lpszLongPath, lpszShortPath);
1273 return(length-1);
1274}
1275//******************************************************************************
1276//******************************************************************************
1277ODINPROCEDURE0(SetFileApisToANSI)
1278{
1279 dprintf(("SetFileApisToANSI() stub\n"));
1280}
1281
1282/*****************************************************************************
1283 * Name : DWORD GetCompressedFileSizeA
1284 * Purpose : The GetCompressedFileSizeA function obtains the compressed
1285 * size, in bytes, of a specified file.
1286 * Parameters: LPCTSTR lpFileName, // pointer to name of file
1287 * LPDWORD lpFileSizeHigh // pointer to DWORD to receive
1288 * high-order doubleword of file size
1289 * Variables :
1290 * Result : size of compressed file
1291 * Remark :
1292 * Status : UNTESTED
1293 *
1294 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1295 *****************************************************************************/
1296
1297ODINFUNCTION2(DWORD, GetCompressedFileSizeA,
1298 LPCTSTR, lpFileName,
1299 LPDWORD, lpFileSizeHigh)
1300{
1301 dprintf(("KERNEL32: GetCompressedFileSizeA (%s, %08xh) not implemented.\n",
1302 lpFileName,
1303 lpFileSizeHigh));
1304
1305 /* @@@PH: simply return the standard filesize */
1306 return 0;
1307}
1308
1309
1310/*****************************************************************************
1311 * Name : DWORD GetCompressedFileSizeW
1312 * Purpose : The GetCompressedFileSizeE function obtains the compressed
1313 * size, in bytes, of a specified file.
1314 * Parameters: LPCWSTR lpFileName, // pointer to name of file
1315 * LPDWORD lpFileSizeHigh // pointer to DWORD to receive
1316 * high-order doubleword of file size
1317 * Variables :
1318 * Result : size of compressed file
1319 * Remark :
1320 * Status : UNTESTED
1321 *
1322 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1323 *****************************************************************************/
1324
1325ODINFUNCTION2(DWORD, GetCompressedFileSizeW,
1326 LPCWSTR, lpFileName,
1327 LPDWORD, lpFileSizeHigh)
1328{
1329 LPCTSTR lpAsciiFileName; /* converted filename */
1330 DWORD rc; /* function result */
1331
1332 dprintf(("KERNEL32: GetCompressedFileSizeW (%s, %08xh)\n",
1333 lpFileName,
1334 lpFileSizeHigh));
1335
1336 lpAsciiFileName = UnicodeToAsciiString( (LPWSTR) lpFileName);
1337
1338 rc = GetCompressedFileSizeA(lpAsciiFileName,
1339 lpFileSizeHigh);
1340
1341 FreeAsciiString( (char *) lpAsciiFileName);
1342
1343 return (rc); /* return result */
1344}
1345
1346
1347/*****************************************************************************
1348 * Name : BOOL GetFileAttributesExA
1349 * Purpose :
1350 * Parameters:
1351 * Variables :
1352 * Result :
1353 * Remark : KERNEL32.874
1354 * Status : UNTESTED
1355 *
1356 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1357 *****************************************************************************/
1358
1359ODINFUNCTION3(BOOL, GetFileAttributesExA,
1360 LPCSTR, lpFileName,
1361 GET_FILEEX_INFO_LEVELS, fInfoLevelId,
1362 LPVOID, lpFileInformation)
1363{
1364 BOOL rc;
1365
1366 dprintf(("KERNEL32: GetFileAttributesExA(%s,%08xh,%08xh) mostly implemented.\n",
1367 lpFileName,
1368 fInfoLevelId,
1369 lpFileInformation));
1370
1371 if (lpFileName == NULL) return FALSE;
1372 if (lpFileInformation == NULL) return FALSE;
1373
1374 if (fInfoLevelId == GetFileExInfoStandard)
1375 {
1376 LPWIN32_FILE_ATTRIBUTE_DATA lpFad = (LPWIN32_FILE_ATTRIBUTE_DATA) lpFileInformation;
1377
1378 rc = OSLibDosGetFileAttributesEx((LPSTR)lpFileName,
1379 fInfoLevelId,
1380 lpFileInformation);
1381 return (rc);
1382 }
1383 else
1384 {
1385 dprintf(("KERNEL32: GetFileAttributesExA - invalid info level %d!\n",
1386 fInfoLevelId));
1387 return FALSE;
1388 }
1389}
1390
1391
1392/*****************************************************************************
1393 * Name : BOOL GetFileAttributesExW
1394 * Purpose :
1395 * Parameters:
1396 * Variables :
1397 * Result :
1398 * Remark : KERNEL32.875
1399 * Status : UNTESTED
1400 *
1401 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1402 *****************************************************************************/
1403
1404ODINFUNCTION3(BOOL, GetFileAttributesExW,
1405 LPCWSTR, lpFileName,
1406 GET_FILEEX_INFO_LEVELS, fInfoLevelId,
1407 LPVOID, lpFileInformation)
1408{
1409 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFileName );
1410 BOOL res = GetFileAttributesExA( nameA, fInfoLevelId, lpFileInformation);
1411 HeapFree( GetProcessHeap(), 0, nameA );
1412 return res;
1413}
1414
1415//******************************************************************************
1416//******************************************************************************
1417ODINFUNCTION3(HANDLE, FindFirstChangeNotificationA,
1418 LPCSTR, lpPathName,
1419 BOOL, bWatchSubtree,
1420 DWORD, dwNotifyFilter)
1421{
1422 dprintf(("KERNEL32: FindFirstChangeNotificationA %s, Not implemented (faked)", lpPathName));
1423 return -1;
1424}
1425//******************************************************************************
1426//******************************************************************************
1427ODINFUNCTION1(BOOL, FindNextChangeNotification,
1428 HANDLE, hChange)
1429{
1430 dprintf(("KERNEL32: FindNextChangeNotification (%08xh), Not implemented\n",
1431 hChange));
1432
1433 return FALSE;
1434}
1435//******************************************************************************
1436//******************************************************************************
1437ODINFUNCTION1(BOOL, FindCloseChangeNotification, HANDLE, hChange)
1438{
1439 dprintf(("KERNEL32: OS2FindNextChangeNotification, Not implemented\n"));
1440
1441 return(TRUE);
1442}
1443/*****************************************************************************
1444 * Name : HANDLE WIN32API FindFirstChangeNotificationW
1445 * Purpose : The FindFirstChangeNotification function creates a change
1446 * notification handle and sets up initial change notification
1447 * filter conditions. A wait on a notification handle succeeds when
1448 * a change matching the filter conditions occurs in the specified
1449 * directory or subtree.
1450 * Parameters: LPCWSTR lpPathName pointer to name of directory to watch
1451 * BOOL bWatchSubtree flag for monitoring directory or
1452 * directory tree
1453 * DWORD dwNotifyFilter filter conditions to watch for
1454 * Variables :
1455 * Result : If the function succeeds, the return value is a handle to a find
1456 * change notification object.
1457 * If the function fails, the return value is INVALID_HANDLE_VALUE
1458 * Remark :
1459 * Status : UNTESTED STUB
1460 *
1461 * Author : Markus Montkowski [Tha, 1998/05/21 20:57]
1462 *****************************************************************************/
1463ODINFUNCTION3(HANDLE, FindFirstChangeNotificationW, LPCWSTR, lpPathName,
1464 BOOL, bWatchSubtree,
1465 DWORD, dwNotifyFilter)
1466{
1467 LPSTR lpAsciiPath;
1468 HANDLE hChange;
1469
1470 lpAsciiPath = UnicodeToAsciiString( (LPWSTR) lpPathName);
1471 hChange = FindFirstChangeNotificationA(lpAsciiPath, bWatchSubtree,
1472 dwNotifyFilter );
1473 if (lpAsciiPath) FreeAsciiString(lpAsciiPath);
1474 return hChange;
1475}
1476//******************************************************************************
1477//******************************************************************************
1478ODINFUNCTION8(BOOL, DeviceIoControl, HANDLE, hDevice, DWORD, dwIoControlCode,
1479 LPVOID, lpInBuffer, DWORD, nInBufferSize,
1480 LPVOID, lpOutBuffer, DWORD, nOutBufferSize,
1481 LPDWORD, lpBytesReturned, LPOVERLAPPED, lpOverlapped)
1482{
1483 return HMDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize,
1484 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
1485}
1486/*****************************************************************************
1487 * Name : BOOL WIN32API CancelIo
1488 * Purpose : The CancelIO function cancels all pending input and output
1489 * (I/O) operations that were issued by the calling thread for
1490 * the specified file handle. The function does not cancel
1491 * I/O operations issued for the file handle by other threads.
1492 * Parameters: HANDLE hFile file handle for which to cancel I/O
1493 * Variables :
1494 * Result : If the function succeeds, the return value is nonzero All pending
1495 * I/O operations issued by the calling thread for the file handle
1496 * were successfully canceled.
1497 * If the function fails, the return value is zero.
1498 * To get extended error information, call GetLastError.
1499 * Remark : If there are any I/O operations in progress for the specified
1500 * file handle, and they were issued by the calling thread, the
1501 * CancelIO function cancels them.
1502 * Note that the I/O operations must have been issued as
1503 * overlapped I/O. If they were not, the I/O operations would not
1504 * have returned to allow the thread to call the CancelIO function.
1505 * Calling the CancelIO function with a file handle that was not
1506 * opened with FILE_FLAG_OVERLAPPED does nothing.
1507 * All I/O operations that are canceled will complete with the
1508 * error ERROR_OPERATION_ABORTED. All completion notifications
1509 * for the I/O operations will occur normally.
1510 * Status : UNTESTED STUB
1511 *
1512 * Author : Markus Montkowski [Thu, 1998/05/19 11:46]
1513 *****************************************************************************/
1514ODINFUNCTION1(BOOL, CancelIo, HANDLE, hFile)
1515{
1516 return HMCancelIo(hFile);
1517}
1518//******************************************************************************
1519//******************************************************************************
Note: See TracBrowser for help on using the repository browser.