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

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

replaced heap alloc by stack alloc

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