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

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

overlapped io updates

File size: 54.2 KB
Line 
1/* $Id: Fileio.cpp,v 1.59 2001-12-05 18:05:58 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, NULL));
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 if(!lpOverlapped || !lpCompletionRoutine) {
682 dprintf(("!WARNING!: !lpOverlapped || !lpCompletionRoutine"));
683 SetLastError(ERROR_INVALID_PARAMETER);
684 return FALSE;
685 }
686 //SDK docs say ReadFileEx will fail if this condition is true
687 if(GetFileType(hFile) == FILE_TYPE_PIPE && (lpOverlapped->Offset || lpOverlapped->OffsetHigh)) {
688 dprintf(("!WARNING!: lpOverlapped->Offset & lpOverlapped->OffsetHigh must be ZERO for named pipes"));
689 SetLastError(ERROR_INVALID_PARAMETER);
690 return FALSE;
691 }
692 return (HMReadFile(hFile,
693 lpBuffer,
694 nNumberOfBytesToRead, NULL,
695 lpOverlapped, lpCompletionRoutine));
696}
697//******************************************************************************
698//******************************************************************************
699ODINFUNCTION5(BOOL, WriteFile,
700 HANDLE, hFile,
701 LPCVOID, buffer,
702 DWORD, nrbytes,
703 LPDWORD, nrbyteswritten,
704 LPOVERLAPPED, lpOverlapped)
705{
706 if(nrbyteswritten) *nrbyteswritten = 0;
707 if(nrbytes == 0) {
708 dprintf(("!WARNING!: Nothing to do"));
709 //TODO: should we fail here instead?? (wine doesn't)
710 return TRUE;
711 }
712
713 return (HMWriteFile(hFile,
714 buffer,
715 nrbytes,
716 nrbyteswritten,
717 lpOverlapped, NULL));
718}
719/*****************************************************************************
720 * Name : BOOL WriteFileEx
721 * Purpose : The WriteFileEx function writes data to a file. It is designed
722 * solely for asynchronous operation, unlike WriteFile, which is
723 * designed for both synchronous and asynchronous operation.
724 * WriteFileEx reports its completion status asynchronously,
725 * calling a specified completion routine when writing is completed
726 * and the calling thread is in an alertable wait state.
727 * Parameters: HANDLE hFile handle of file to write
728 * LPVOID lpBuffer address of buffer
729 * DWORD nNumberOfBytesToRead number of bytes to write
730 * LPOVERLAPPED lpOverlapped address of offset
731 * LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine address of completion routine
732 * Variables :
733 * Result : TRUE / FALSE
734 * Remark :
735 * Status : UNTESTED STUB
736 *
737 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
738 *****************************************************************************/
739
740ODINFUNCTION5(BOOL, WriteFileEx,
741 HANDLE, hFile,
742 LPCVOID, lpBuffer,
743 DWORD, nNumberOfBytesToWrite,
744 LPOVERLAPPED, lpOverlapped,
745 LPOVERLAPPED_COMPLETION_ROUTINE, lpCompletionRoutine)
746{
747 if(nNumberOfBytesToWrite == 0) {
748 dprintf(("!WARNING!: Nothing to do"));
749 //TODO: should we fail here instead?? (wine doesn't)
750 return TRUE;
751 }
752 if(!lpOverlapped || !lpCompletionRoutine) {
753 dprintf(("!WARNING!: !lpOverlapped || !lpCompletionRoutine"));
754 SetLastError(ERROR_INVALID_PARAMETER);
755 return FALSE;
756 }
757 //SDK docs say WriteFileEx will fail if this condition is true
758 if(GetFileType(hFile) == FILE_TYPE_PIPE && (lpOverlapped->Offset || lpOverlapped->OffsetHigh)) {
759 dprintf(("!WARNING!: lpOverlapped->Offset & lpOverlapped->OffsetHigh must be ZERO for named pipes"));
760 SetLastError(ERROR_INVALID_PARAMETER);
761 return FALSE;
762 }
763 return (HMWriteFile(hFile,
764 (LPVOID)lpBuffer,
765 nNumberOfBytesToWrite, NULL,
766 lpOverlapped, lpCompletionRoutine));
767}
768//******************************************************************************
769//******************************************************************************
770ODINFUNCTION4(DWORD, SetFilePointer,
771 HANDLE, hFile,
772 LONG, lDistanceToMove,
773 PLONG, lpDistanceToMoveHigh,
774 DWORD, dwMoveMethod)
775{
776 return(HMSetFilePointer(hFile,
777 lDistanceToMove,
778 lpDistanceToMoveHigh,
779 dwMoveMethod));
780}
781//******************************************************************************
782//******************************************************************************
783ODINFUNCTION1(DWORD, GetFileAttributesA,
784 LPCSTR, lpszFileName)
785{
786 DWORD rc, error;
787
788 if((NULL!=lpszFileName) && strlen(lpszFileName)==2 && lpszFileName[1] == ':')
789 {
790 char szDrive[4];
791 szDrive[0] = lpszFileName[0];
792 szDrive[1] = lpszFileName[1];
793 szDrive[2] = '\\';
794 szDrive[3] = 0x00;
795 rc = O32_GetFileAttributes((LPSTR)szDrive);
796 }
797 else {
798 rc = O32_GetFileAttributes((LPSTR)lpszFileName);
799 if(rc == -1 && lpszFileName[strlen(lpszFileName)-1] != '\\') {
800 char *filename = (char *)alloca(strlen(lpszFileName)+2); //+2!!!!!!
801 strcpy(filename, lpszFileName);
802 strcat(filename, "\\");
803 rc = O32_GetFileAttributes((LPSTR)filename);
804 }
805 }
806 //SvL: Open32 returns FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_NORMAL for
807 // directories whereas NT 4 (SP6) only returns FILE_ATTRIBUTE_DIRECTORY
808 if(rc != -1 && (rc & FILE_ATTRIBUTE_DIRECTORY)) {
809 rc = FILE_ATTRIBUTE_DIRECTORY;
810 }
811
812#if 0 // need more tests, maybe there is also a better way to hide simulated b:
813 if(rc == -1 && lpszFileName != NULL && !strnicmp(lpszFileName, "B:", 2))
814 {
815 error = GetLastError();
816 if(error = ERROR_DISK_CHANGE)
817 SetLastError(ERROR_NOT_READY);
818 else
819 SetLastError(error);
820 }
821#endif
822 dprintf(("KERNEL32: GetFileAttributes of %s returned %d\n", lpszFileName, rc));
823 return(rc);
824}
825//******************************************************************************
826//******************************************************************************
827ODINFUNCTION1(DWORD, GetFileAttributesW,
828 LPCWSTR, arg1)
829{
830 DWORD rc;
831 char *astring;
832
833 astring = UnicodeToAsciiString((LPWSTR)arg1);
834 rc = CALL_ODINFUNC(GetFileAttributesA)(astring);
835 FreeAsciiString(astring);
836 return(rc);
837}
838//******************************************************************************
839//******************************************************************************
840ODINFUNCTION2(BOOL, SetFileAttributesA,
841 LPCSTR, arg1,
842 DWORD, arg2)
843{
844 dprintf(("KERNEL32: SetFileAttributes of %s\n", arg1));
845 return O32_SetFileAttributes(arg1, arg2);
846}
847//******************************************************************************
848//******************************************************************************
849ODINFUNCTION2(BOOL, SetFileAttributesW,
850 LPCWSTR, lpFileName,
851 DWORD, dwFileAttributes)
852{
853 char *asciifile;
854 BOOL rc;
855
856 asciifile = UnicodeToAsciiString((LPWSTR)lpFileName);
857 rc = O32_SetFileAttributes(asciifile, dwFileAttributes);
858 FreeAsciiString(asciifile);
859 return(rc);
860}
861//******************************************************************************
862//******************************************************************************
863ODINFUNCTION4(DWORD, GetFullPathNameA,
864 LPCSTR, arg1,
865 DWORD, arg2,
866 LPSTR, arg3,
867 LPSTR *, arg4)
868{
869 char *ptr;
870 DWORD rc;
871 dprintf(("KERNEL32: GetFullPathName called with %s %d %x", arg1, arg2, arg3));
872 while((ptr = strchr(arg1, '/')) != NULL)
873 *ptr = '\\';
874
875 return O32_GetFullPathName(arg1, arg2, arg3, arg4);
876}
877//******************************************************************************
878//******************************************************************************
879ODINFUNCTION4(DWORD, GetFullPathNameW,
880 LPCWSTR, lpFileName,
881 DWORD, nBufferLength,
882 LPWSTR, lpBuffer,
883 LPWSTR *, lpFilePart)
884{
885 char *astring, *asciibuffer, *asciipart;
886 DWORD rc;
887
888 asciibuffer = (char *)malloc(nBufferLength+1);
889 astring = UnicodeToAsciiString((LPWSTR)lpFileName);
890
891 rc = CALL_ODINFUNC(GetFullPathNameA)(astring,
892 nBufferLength,
893 asciibuffer,
894 &asciipart);
895
896 dprintf(("KERNEL32: GetFullPathNameW %s returns %s\n",
897 astring,
898 asciibuffer));
899
900 if(rc)
901 AsciiToUnicode(asciibuffer,
902 lpBuffer);
903
904 if(lpFilePart) {
905 if (asciipart == NULL)
906 *lpFilePart = NULL;
907 else
908 *lpFilePart = lpBuffer + ((int)asciipart - (int)asciibuffer);
909 }
910
911 FreeAsciiString(astring);
912 free(asciibuffer);
913 return(rc);
914}
915//******************************************************************************
916//******************************************************************************
917ODINFUNCTION5(BOOL, LockFile,
918 HANDLE, arg1,
919 DWORD, arg2,
920 DWORD, arg3,
921 DWORD, arg4,
922 DWORD, arg5)
923{
924 return HMLockFile(arg1,
925 arg2,
926 arg3,
927 arg4,
928 arg5);
929}
930
931
932/*****************************************************************************
933 * Name : BOOL LockFileEx
934 * Purpose : The LockFileEx function locks a byte range within an open file for shared or exclusive access.
935 * Parameters: HANDLE hFile handle of file to lock
936 * DWORD dwFlags functional behavior modification flags
937 * DWORD dwReserved reserved, must be set to zero
938 * DWORD nNumberOfBytesToLockLow low-order 32 bits of length to lock
939 * DWORD nNumberOfBytesToLockHigh high-order 32 bits of length to lock
940 * LPOVERLAPPED LPOVERLAPPED addr. of structure with lock region start offset
941 * Variables :
942 * Result : TRUE / FALSE
943 * Remark :
944 * Status : UNTESTED STUB
945 *
946 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
947 *****************************************************************************/
948
949ODINFUNCTION6(BOOL, LockFileEx,
950 HANDLE, hFile,
951 DWORD, dwFlags,
952 DWORD, dwReserved,
953 DWORD, nNumberOfBytesToLockLow,
954 DWORD, nNumberOfBytesToLockHigh,
955 LPOVERLAPPED, lpOverlapped)
956{
957 return(HMLockFile(hFile,
958 lpOverlapped->Offset,
959 lpOverlapped->OffsetHigh,
960 nNumberOfBytesToLockLow,
961 nNumberOfBytesToLockHigh));
962}
963//******************************************************************************
964//******************************************************************************
965ODINFUNCTION2(BOOL, MoveFileA,
966 LPCSTR, arg1,
967 LPCSTR, arg2)
968{
969 dprintf(("KERNEL32: MoveFileA %s %s", arg1, arg2));
970 return OSLibDosMoveFile(arg1, arg2);
971}
972//******************************************************************************
973//******************************************************************************
974
975
976/*****************************************************************************
977 * Name : MoveFileExA
978 * Purpose : Move or delete a file
979 * Parameters: LPCSTR lpExistingFileName
980 * LPCSTR lpNewFileName
981 * DWORD dwFlags
982 * Variables :
983 * Result :
984 * Remark : "delete on system-reboot" feature is not supported!
985 * Status :
986 *
987 * Author : Patrick Haller [2001-08-30]
988 *****************************************************************************/
989
990ODINFUNCTION3(BOOL, MoveFileExA,
991 LPCSTR, lpszOldFilename,
992 LPCSTR, lpszNewFilename,
993 DWORD, fdwFlags)
994{
995 dprintf(("KERNEL32: MoveFileExA %s to %s %x, not complete!\n",
996 lpszOldFilename,
997 lpszNewFilename,
998 fdwFlags));
999
1000 // this parameter combination is illegal
1001 if ( (fdwFlags & MOVEFILE_DELAY_UNTIL_REBOOT) &&
1002 (fdwFlags & MOVEFILE_COPY_ALLOWED) )
1003 {
1004 // Note: error code not verified
1005 SetLastError(ERROR_INVALID_PARAMETER);
1006 return FALSE;
1007 }
1008
1009 // first, we take care about the special cases
1010 if (fdwFlags && MOVEFILE_DELAY_UNTIL_REBOOT)
1011 {
1012 // We cannot really support this in any other way than
1013 // to call the IBMCSFLK driver. As the first place I've encountered
1014 // this call is Microsoft ACMSETUP wanting to replace OLEPRO32.DLL
1015 // in the ODIN system directory, we are better skipping the call.
1016
1017 // Anyway, this is only supported under Windows NT
1018 fdwFlags &= ~MOVEFILE_DELAY_UNTIL_REBOOT;
1019
1020 // Until we support this, we have to intercept
1021 // lpszNewFilename == NULL
1022 if (NULL == lpszNewFilename)
1023 {
1024 // try to delete the filename
1025 dprintf(("KERNEL32-MoveFileExA: trying to delete file [%s], skipped.",
1026 lpszOldFilename));
1027
1028 SetLastError( NO_ERROR );
1029 return TRUE;
1030 }
1031 }
1032
1033 if (fdwFlags && MOVEFILE_COPY_ALLOWED)
1034 {
1035 // if lpszOldFilename and lpszNewFilename refer to different
1036 // volumes, this flag controls if a copy operation is allowed.
1037 }
1038
1039 if (fdwFlags && MOVEFILE_REPLACE_EXISTING)
1040 {
1041 // We can only attempt to
1042 // 1 move away the current file if existing,
1043 // 2 do the current move operation
1044 // 3 if succesful, delete the backup
1045 // otherwise restore the original file
1046 }
1047
1048 return OSLibDosMoveFile(lpszOldFilename,
1049 lpszNewFilename);
1050}
1051//******************************************************************************
1052//******************************************************************************
1053ODINFUNCTION2(BOOL, MoveFileW,
1054 LPCWSTR, lpSrc,
1055 LPCWSTR, lpDest)
1056{
1057 char *asciisrc, *asciidest;
1058 BOOL rc;
1059
1060 asciisrc = UnicodeToAsciiString((LPWSTR)lpSrc);
1061 asciidest = UnicodeToAsciiString((LPWSTR)lpDest);
1062 rc = MoveFileA(asciisrc, asciidest);
1063 FreeAsciiString(asciisrc);
1064 FreeAsciiString(asciidest);
1065 return(rc);
1066}
1067//******************************************************************************
1068//******************************************************************************
1069ODINFUNCTION3(BOOL, MoveFileExW,
1070 LPCWSTR, lpSrc,
1071 LPCWSTR, lpDest,
1072 DWORD, fdwFlags)
1073{
1074 dprintf(("KERNEL32: MoveFileExW %ls to %ls %x",
1075 lpSrc,
1076 lpDest,
1077 fdwFlags));
1078
1079 char *asciisrc,
1080 *asciidest;
1081 BOOL rc;
1082
1083 asciisrc = UnicodeToAsciiString((LPWSTR)lpSrc);
1084 if (NULL != lpDest)
1085 asciidest = UnicodeToAsciiString((LPWSTR)lpDest);
1086 else
1087 asciidest = NULL;
1088
1089 rc = MoveFileExA(asciisrc,
1090 asciidest,
1091 fdwFlags);
1092
1093 if (NULL != asciidest)
1094 FreeAsciiString(asciidest);
1095
1096 FreeAsciiString(asciisrc);
1097
1098 return(rc);
1099}
1100//******************************************************************************
1101/*****************************************************************************
1102ODINFUNCTION3(*, :,
1103 HFILE, WIN32API,
1104 OpenFile *, Purpose,
1105 :, forwardOpenFile to Open32
1106 * Parameters:
1107 * Variables :
1108 * Result : API returncode
1109 * Remark : modified for handle translation support
1110 * Status : @@@PH verify if 0 is a valid "invalid handle" :)
1111 *
1112 * Author : Patrick Haller [Fri, 1998/06/12 02:53]
1113 *****************************************************************************/
1114
1115ODINFUNCTION3(HFILE, OpenFile,
1116 LPCSTR, lpszFile,
1117 OFSTRUCT *, lpOpenBuff,
1118 UINT, fuMode)
1119{
1120 HFILE hFile;
1121
1122 dprintf(("KERNEL32: OpenFile(%s, %08xh, %08xh)\n",
1123 lpszFile,
1124 lpOpenBuff,
1125 fuMode));
1126
1127 hFile = HMOpenFile(lpszFile, /* call open32 */
1128 lpOpenBuff,
1129 fuMode);
1130
1131 return (hFile);
1132}
1133//******************************************************************************
1134//******************************************************************************
1135ODINFUNCTION5(BOOL, UnlockFile,
1136 HANDLE, arg1,
1137 DWORD, arg2,
1138 DWORD, arg3,
1139 DWORD, arg4,
1140 DWORD, arg5)
1141{
1142 return HMUnlockFile(arg1,
1143 arg2,
1144 arg3,
1145 arg4,
1146 arg5);
1147}
1148
1149
1150/*****************************************************************************
1151 * Name : BOOL UnlockFileEx
1152 * Purpose : The UnlockFileEx function unlocks a previously locked byte range in an open file.
1153 * Parameters: HANDLE hFile handle of file to lock
1154 * DWORD dwReserved reserved, must be set to zero
1155 * DWORD nNumberOfBytesToLockLow low-order 32 bits of length to lock
1156 * DWORD nNumberOfBytesToLockHigh high-order 32 bits of length to lock
1157 * LPOVERLAPPED LPOVERLAPPED addr. of structure with lock region start offset
1158 * Variables :
1159 * Result : TRUE / FALSE
1160 * Remark :
1161 * Status : UNTESTED STUB
1162 *
1163 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1164 *****************************************************************************/
1165
1166ODINFUNCTION5(BOOL, UnlockFileEx,
1167 HANDLE, hFile,
1168 DWORD, dwReserved,
1169 DWORD, nNumberOfBytesToLockLow,
1170 DWORD, nNumberOfBytesToLockHigh,
1171 LPOVERLAPPED, lpOverlapped)
1172{
1173 return(HMUnlockFileEx(hFile, dwReserved,
1174 nNumberOfBytesToLockLow,
1175 nNumberOfBytesToLockHigh,
1176 lpOverlapped));
1177}
1178//******************************************************************************
1179//Behaviour in NT 4, SP6:
1180//- converts long filename to 8.3 short filname (TODO: not yet done here!)
1181//- fails on volume that doesn't support 8.3 filenames
1182//- if lpszShortPath 0 or cchBuffer too small -> return required length
1183// (INCLUDING 0 terminator)
1184//- if lpszLongPath == NULL -> ERROR_INVALID_PARAMETER (return 0)
1185//- if lpszLongPath empty -> proceed as if nothing is wrong
1186//- does NOT clear the last error if successful!
1187//- if successful -> return length of string (excluding 0 terminator)
1188//******************************************************************************
1189ODINFUNCTION3(DWORD, GetShortPathNameA,
1190 LPCTSTR, lpszLongPath,
1191 LPTSTR, lpszShortPath,
1192 DWORD, cchBuffer)
1193{
1194 int length;
1195
1196 dprintf(("KERNEL32: GetShortPathNameA of %s, just copying it", lpszLongPath));
1197
1198 if(!lpszLongPath) {
1199 SetLastError(ERROR_INVALID_PARAMETER);
1200 return 0;
1201 }
1202
1203 length = lstrlenA(lpszLongPath) + 1;
1204 if(length > cchBuffer) {
1205 if(lpszShortPath) {
1206 *lpszShortPath = 0;
1207 }
1208 return(length); //return length required (including 0 terminator)
1209 }
1210 lstrcpyA(lpszShortPath, lpszLongPath);
1211 return(length-1);
1212}
1213//******************************************************************************
1214//******************************************************************************
1215ODINFUNCTION3(DWORD, GetShortPathNameW,
1216 LPCWSTR, lpszLongPath,
1217 LPWSTR, lpszShortPath,
1218 DWORD, cchBuffer)
1219{
1220 int length;
1221
1222 dprintf(("KERNEL32: GetShortPathNameW; just copying it"));
1223 if(!lpszLongPath) {
1224 SetLastError(ERROR_INVALID_PARAMETER);
1225 return 0;
1226 }
1227
1228 length = lstrlenW(lpszLongPath) + 1;
1229 if(length > cchBuffer) {
1230 if(lpszShortPath) {
1231 *lpszShortPath = 0;
1232 }
1233 return(length); //return length required (including 0 terminator)
1234 }
1235 lstrcpyW(lpszShortPath, lpszLongPath);
1236 return(length-1);
1237}
1238//******************************************************************************
1239//Behaviour in NT 4, SP6: (presumably the same as GetShortPathNameA; TODO check)
1240//- converts short filename to long filenames (TODO: not yet done here!)
1241//- if lpszShortPath 0 or cchBuffer too small -> return required length
1242// (INCLUDING 0 terminator)
1243//- if lpszLongPath == NULL -> ERROR_INVALID_PARAMETER (return 0)
1244//- if lpszLongPath empty -> proceed as if nothing is wrong
1245//- does NOT clear the last error if successful!
1246//- if successful -> return length of string (excluding 0 terminator)
1247//******************************************************************************
1248DWORD WINAPI GetLongPathNameA( LPCSTR lpszShortPath, LPSTR lpszLongPath,
1249 DWORD cchBuffer )
1250{
1251 int length;
1252
1253 dprintf(("GetLongPathNameA %x %s %d", lpszShortPath, lpszLongPath, cchBuffer));
1254 dprintf(("WARNING: WIN98 ONLY!!"));
1255
1256 if(!lpszShortPath) {
1257 SetLastError(ERROR_INVALID_PARAMETER);
1258 return 0;
1259 }
1260
1261 length = lstrlenA(lpszShortPath) + 1;
1262 if(length > cchBuffer) {
1263 if(lpszLongPath) {
1264 *lpszLongPath = 0;
1265 }
1266 return(length); //return length required (including 0 terminator)
1267 }
1268 lstrcpyA(lpszLongPath, lpszShortPath);
1269 return(length-1);
1270}
1271//******************************************************************************
1272//******************************************************************************
1273DWORD WINAPI GetLongPathNameW( LPCWSTR lpszShortPath, LPWSTR lpszLongPath,
1274 DWORD cchBuffer )
1275{
1276 int length;
1277
1278 dprintf(("GetLongPathNameW %x %ls %d", lpszShortPath, lpszLongPath, cchBuffer));
1279 dprintf(("WARNING: WIN98 ONLY!!"));
1280
1281 if(!lpszShortPath) {
1282 SetLastError(ERROR_INVALID_PARAMETER);
1283 return 0;
1284 }
1285
1286 length = lstrlenW(lpszShortPath) + 1;
1287 if(length > cchBuffer) {
1288 if(lpszLongPath) {
1289 *lpszLongPath = 0;
1290 }
1291 return(length); //return length required (including 0 terminator)
1292 }
1293 lstrcpyW(lpszLongPath, lpszShortPath);
1294 return(length-1);
1295}
1296//******************************************************************************
1297//******************************************************************************
1298ODINPROCEDURE0(SetFileApisToANSI)
1299{
1300 dprintf(("SetFileApisToANSI() stub\n"));
1301}
1302
1303/*****************************************************************************
1304 * Name : DWORD GetCompressedFileSizeA
1305 * Purpose : The GetCompressedFileSizeA function obtains the compressed
1306 * size, in bytes, of a specified file.
1307 * Parameters: LPCTSTR lpFileName, // pointer to name of file
1308 * LPDWORD lpFileSizeHigh // pointer to DWORD to receive
1309 * high-order doubleword of file size
1310 * Variables :
1311 * Result : size of compressed file
1312 * Remark :
1313 * Status : UNTESTED
1314 *
1315 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1316 *****************************************************************************/
1317
1318ODINFUNCTION2(DWORD, GetCompressedFileSizeA,
1319 LPCTSTR, lpFileName,
1320 LPDWORD, lpFileSizeHigh)
1321{
1322 dprintf(("KERNEL32: GetCompressedFileSizeA (%s, %08xh) not implemented.\n",
1323 lpFileName,
1324 lpFileSizeHigh));
1325
1326 /* @@@PH: simply return the standard filesize */
1327 return 0;
1328}
1329
1330
1331/*****************************************************************************
1332 * Name : DWORD GetCompressedFileSizeW
1333 * Purpose : The GetCompressedFileSizeE function obtains the compressed
1334 * size, in bytes, of a specified file.
1335 * Parameters: LPCWSTR lpFileName, // pointer to name of file
1336 * LPDWORD lpFileSizeHigh // pointer to DWORD to receive
1337 * high-order doubleword of file size
1338 * Variables :
1339 * Result : size of compressed file
1340 * Remark :
1341 * Status : UNTESTED
1342 *
1343 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1344 *****************************************************************************/
1345
1346ODINFUNCTION2(DWORD, GetCompressedFileSizeW,
1347 LPCWSTR, lpFileName,
1348 LPDWORD, lpFileSizeHigh)
1349{
1350 LPCTSTR lpAsciiFileName; /* converted filename */
1351 DWORD rc; /* function result */
1352
1353 dprintf(("KERNEL32: GetCompressedFileSizeW (%s, %08xh)\n",
1354 lpFileName,
1355 lpFileSizeHigh));
1356
1357 lpAsciiFileName = UnicodeToAsciiString( (LPWSTR) lpFileName);
1358
1359 rc = GetCompressedFileSizeA(lpAsciiFileName,
1360 lpFileSizeHigh);
1361
1362 FreeAsciiString( (char *) lpAsciiFileName);
1363
1364 return (rc); /* return result */
1365}
1366
1367
1368/*****************************************************************************
1369 * Name : BOOL GetFileAttributesExA
1370 * Purpose :
1371 * Parameters:
1372 * Variables :
1373 * Result :
1374 * Remark : KERNEL32.874
1375 * Status : UNTESTED
1376 *
1377 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1378 *****************************************************************************/
1379
1380ODINFUNCTION3(BOOL, GetFileAttributesExA,
1381 LPCSTR, lpFileName,
1382 GET_FILEEX_INFO_LEVELS, fInfoLevelId,
1383 LPVOID, lpFileInformation)
1384{
1385 BOOL rc;
1386
1387 dprintf(("KERNEL32: GetFileAttributesExA(%s,%08xh,%08xh) mostly implemented.\n",
1388 lpFileName,
1389 fInfoLevelId,
1390 lpFileInformation));
1391
1392 if (lpFileName == NULL) return FALSE;
1393 if (lpFileInformation == NULL) return FALSE;
1394
1395 if (fInfoLevelId == GetFileExInfoStandard)
1396 {
1397 LPWIN32_FILE_ATTRIBUTE_DATA lpFad = (LPWIN32_FILE_ATTRIBUTE_DATA) lpFileInformation;
1398
1399 rc = OSLibDosGetFileAttributesEx((LPSTR)lpFileName,
1400 fInfoLevelId,
1401 lpFileInformation);
1402 return (rc);
1403 }
1404 else
1405 {
1406 dprintf(("KERNEL32: GetFileAttributesExA - invalid info level %d!\n",
1407 fInfoLevelId));
1408 return FALSE;
1409 }
1410}
1411
1412
1413/*****************************************************************************
1414 * Name : BOOL GetFileAttributesExW
1415 * Purpose :
1416 * Parameters:
1417 * Variables :
1418 * Result :
1419 * Remark : KERNEL32.875
1420 * Status : UNTESTED
1421 *
1422 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1423 *****************************************************************************/
1424
1425ODINFUNCTION3(BOOL, GetFileAttributesExW,
1426 LPCWSTR, lpFileName,
1427 GET_FILEEX_INFO_LEVELS, fInfoLevelId,
1428 LPVOID, lpFileInformation)
1429{
1430 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFileName );
1431 BOOL res = GetFileAttributesExA( nameA, fInfoLevelId, lpFileInformation);
1432 HeapFree( GetProcessHeap(), 0, nameA );
1433 return res;
1434}
1435
1436//******************************************************************************
1437//******************************************************************************
1438ODINFUNCTION3(HANDLE, FindFirstChangeNotificationA,
1439 LPCSTR, lpPathName,
1440 BOOL, bWatchSubtree,
1441 DWORD, dwNotifyFilter)
1442{
1443 dprintf(("KERNEL32: FindFirstChangeNotificationA %s, Not implemented (faked)", lpPathName));
1444 return -1;
1445}
1446//******************************************************************************
1447//******************************************************************************
1448ODINFUNCTION1(BOOL, FindNextChangeNotification,
1449 HANDLE, hChange)
1450{
1451 dprintf(("KERNEL32: FindNextChangeNotification (%08xh), Not implemented\n",
1452 hChange));
1453
1454 return FALSE;
1455}
1456//******************************************************************************
1457//******************************************************************************
1458ODINFUNCTION1(BOOL, FindCloseChangeNotification, HANDLE, hChange)
1459{
1460 dprintf(("KERNEL32: OS2FindNextChangeNotification, Not implemented\n"));
1461
1462 return(TRUE);
1463}
1464/*****************************************************************************
1465 * Name : HANDLE WIN32API FindFirstChangeNotificationW
1466 * Purpose : The FindFirstChangeNotification function creates a change
1467 * notification handle and sets up initial change notification
1468 * filter conditions. A wait on a notification handle succeeds when
1469 * a change matching the filter conditions occurs in the specified
1470 * directory or subtree.
1471 * Parameters: LPCWSTR lpPathName pointer to name of directory to watch
1472 * BOOL bWatchSubtree flag for monitoring directory or
1473 * directory tree
1474 * DWORD dwNotifyFilter filter conditions to watch for
1475 * Variables :
1476 * Result : If the function succeeds, the return value is a handle to a find
1477 * change notification object.
1478 * If the function fails, the return value is INVALID_HANDLE_VALUE
1479 * Remark :
1480 * Status : UNTESTED STUB
1481 *
1482 * Author : Markus Montkowski [Tha, 1998/05/21 20:57]
1483 *****************************************************************************/
1484ODINFUNCTION3(HANDLE, FindFirstChangeNotificationW, LPCWSTR, lpPathName,
1485 BOOL, bWatchSubtree,
1486 DWORD, dwNotifyFilter)
1487{
1488 LPSTR lpAsciiPath;
1489 HANDLE hChange;
1490
1491 lpAsciiPath = UnicodeToAsciiString( (LPWSTR) lpPathName);
1492 hChange = FindFirstChangeNotificationA(lpAsciiPath, bWatchSubtree,
1493 dwNotifyFilter );
1494 if (lpAsciiPath) FreeAsciiString(lpAsciiPath);
1495 return hChange;
1496}
1497//******************************************************************************
1498//******************************************************************************
1499ODINFUNCTION8(BOOL, DeviceIoControl, HANDLE, hDevice, DWORD, dwIoControlCode,
1500 LPVOID, lpInBuffer, DWORD, nInBufferSize,
1501 LPVOID, lpOutBuffer, DWORD, nOutBufferSize,
1502 LPDWORD, lpBytesReturned, LPOVERLAPPED, lpOverlapped)
1503{
1504 return HMDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize,
1505 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
1506}
1507/*****************************************************************************
1508 * Name : BOOL WIN32API CancelIo
1509 * Purpose : The CancelIO function cancels all pending input and output
1510 * (I/O) operations that were issued by the calling thread for
1511 * the specified file handle. The function does not cancel
1512 * I/O operations issued for the file handle by other threads.
1513 * Parameters: HANDLE hFile file handle for which to cancel I/O
1514 * Variables :
1515 * Result : If the function succeeds, the return value is nonzero All pending
1516 * I/O operations issued by the calling thread for the file handle
1517 * were successfully canceled.
1518 * If the function fails, the return value is zero.
1519 * To get extended error information, call GetLastError.
1520 * Remark : If there are any I/O operations in progress for the specified
1521 * file handle, and they were issued by the calling thread, the
1522 * CancelIO function cancels them.
1523 * Note that the I/O operations must have been issued as
1524 * overlapped I/O. If they were not, the I/O operations would not
1525 * have returned to allow the thread to call the CancelIO function.
1526 * Calling the CancelIO function with a file handle that was not
1527 * opened with FILE_FLAG_OVERLAPPED does nothing.
1528 * All I/O operations that are canceled will complete with the
1529 * error ERROR_OPERATION_ABORTED. All completion notifications
1530 * for the I/O operations will occur normally.
1531 * Status : UNTESTED STUB
1532 *
1533 * Author : Markus Montkowski [Thu, 1998/05/19 11:46]
1534 *****************************************************************************/
1535ODINFUNCTION1(BOOL, CancelIo, HANDLE, hFile)
1536{
1537 return HMCancelIo(hFile);
1538}
1539//******************************************************************************
1540//******************************************************************************
Note: See TracBrowser for help on using the repository browser.