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

Last change on this file since 6613 was 6613, checked in by phaller, 24 years ago

fix for MoveFile

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