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

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

minor updates

File size: 48.2 KB
Line 
1/* $Id: Fileio.cpp,v 1.52 2001-08-10 19:32:23 sandervl Exp $ */
2
3/*
4 * Win32 File IO API functions for OS/2
5 *
6 * Copyright 1998-2000 Sander van Leeuwen
7 * Copyright 1998 Patrick Haller
8 *
9 * Some parts copied from Wine (CopyFileExA/W)
10 *
11 * Copyright 1993 John Burton
12 * Copyright 1996 Alexandre Julliard
13 *
14 *
15 * Project Odin Software License can be found in LICENSE.TXT
16 *
17 */
18
19
20/*****************************************************************************
21 * Includes *
22 *****************************************************************************/
23
24#include <odin.h>
25#include <odinwrap.h>
26#include <os2sel.h>
27
28#include <os2win.h>
29#include <stdlib.h>
30#include <string.h>
31#include "unicode.h"
32#include <heapstring.h>
33#include "handlemanager.h"
34#include "oslibdos.h"
35
36#define DBG_LOCALLOG DBG_fileio
37#include "dbglocal.h"
38
39ODINDEBUGCHANNEL(KERNEL32-FILEIO)
40
41#include <ctype.h>
42#include "fileio.h"
43
44#if 0
45#define IS_END_OF_NAME(ch) (!(ch) || ((ch) == '/') || ((ch) == '\\'))
46#define INVALID_DOS_CHARS "*?<>|\"+=,;[] \345"
47#define FILE_toupper(a) toupper(a)
48#define FILE_tolower(a) tolower(a)
49
50/***********************************************************************
51 * DOSFS_ValidDOSName
52 *
53 * Return 1 if Unix file 'name' is also a valid MS-DOS name
54 * (i.e. contains only valid DOS chars, lower-case only, fits in 8.3 format).
55 * File name can be terminated by '\0', '\\' or '/'.
56 */
57static int DOSFS_ValidDOSName( const char *name, int ignore_case )
58{
59 static const char invalid_chars[] = INVALID_DOS_CHARS;
60 const char *p = name;
61 const char *invalid = ignore_case ? (invalid_chars + 26) : invalid_chars;
62 int len = 0;
63
64 if (*p == '.')
65 {
66 /* Check for "." and ".." */
67 p++;
68 if (*p == '.') p++;
69 /* All other names beginning with '.' are invalid */
70 return (IS_END_OF_NAME(*p));
71 }
72 while (!IS_END_OF_NAME(*p))
73 {
74 if (strchr( invalid, *p )) return 0; /* Invalid char */
75 if (*p == '.') break; /* Start of the extension */
76 if (++len > 8) return 0; /* Name too long */
77 p++;
78 }
79 if (*p != '.') return 1; /* End of name */
80 p++;
81 if (IS_END_OF_NAME(*p)) return 0; /* Empty extension not allowed */
82 len = 0;
83 while (!IS_END_OF_NAME(*p))
84 {
85 if (strchr( invalid, *p )) return 0; /* Invalid char */
86 if (*p == '.') return 0; /* Second extension not allowed */
87 if (++len > 3) return 0; /* Extension too long */
88 p++;
89 }
90 return 1;
91}
92
93/***********************************************************************
94 * DOSFS_Hash
95 *
96 * Transform a Unix file name into a hashed DOS name. If the name is a valid
97 * DOS name, it is converted to upper-case; otherwise it is replaced by a
98 * hashed version that fits in 8.3 format.
99 * File name can be terminated by '\0', '\\' or '/'.
100 * 'buffer' must be at least 13 characters long.
101 */
102void DOSFS_Hash( LPCSTR name, LPSTR buffer, BOOL dir_format,
103 BOOL ignore_case )
104{
105 static const char invalid_chars[] = INVALID_DOS_CHARS "~.";
106 static const char hash_chars[33] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";
107
108 const char *p, *ext;
109 char *dst;
110 unsigned short hash;
111 int i;
112
113 if (dir_format) strcpy( buffer, " " );
114
115 if (DOSFS_ValidDOSName( name, ignore_case ))
116 {
117 /* Check for '.' and '..' */
118 if (*name == '.')
119 {
120 buffer[0] = '.';
121 if (!dir_format) buffer[1] = buffer[2] = '\0';
122 if (name[1] == '.') buffer[1] = '.';
123 return;
124 }
125
126 /* Simply copy the name, converting to uppercase */
127
128 for (dst = buffer; !IS_END_OF_NAME(*name) && (*name != '.'); name++)
129 *dst++ = FILE_toupper(*name);
130 if (*name == '.')
131 {
132 if (dir_format) dst = buffer + 8;
133 else *dst++ = '.';
134 for (name++; !IS_END_OF_NAME(*name); name++)
135 *dst++ = FILE_toupper(*name);
136 }
137 if (!dir_format) *dst = '\0';
138 return;
139 }
140
141 /* Compute the hash code of the file name */
142 /* If you know something about hash functions, feel free to */
143 /* insert a better algorithm here... */
144 if (ignore_case)
145 {
146 for (p = name, hash = 0xbeef; !IS_END_OF_NAME(p[1]); p++)
147 hash = (hash<<3) ^ (hash>>5) ^ FILE_tolower(*p) ^ (FILE_tolower(p[1]) << 8);
148 hash = (hash<<3) ^ (hash>>5) ^ FILE_tolower(*p); /* Last character*/
149 }
150 else
151 {
152 for (p = name, hash = 0xbeef; !IS_END_OF_NAME(p[1]); p++)
153 hash = (hash << 3) ^ (hash >> 5) ^ *p ^ (p[1] << 8);
154 hash = (hash << 3) ^ (hash >> 5) ^ *p; /* Last character */
155 }
156
157 /* Find last dot for start of the extension */
158 for (p = name+1, ext = NULL; !IS_END_OF_NAME(*p); p++)
159 if (*p == '.') ext = p;
160 if (ext && IS_END_OF_NAME(ext[1]))
161 ext = NULL; /* Empty extension ignored */
162
163 /* Copy first 4 chars, replacing invalid chars with '_' */
164 for (i = 4, p = name, dst = buffer; i > 0; i--, p++)
165 {
166 if (IS_END_OF_NAME(*p) || (p == ext)) break;
167 *dst++ = strchr( invalid_chars, *p ) ? '_' : FILE_toupper(*p);
168 }
169 /* Pad to 5 chars with '~' */
170 while (i-- >= 0) *dst++ = '~';
171
172 /* Insert hash code converted to 3 ASCII chars */
173 *dst++ = hash_chars[(hash >> 10) & 0x1f];
174 *dst++ = hash_chars[(hash >> 5) & 0x1f];
175 *dst++ = hash_chars[hash & 0x1f];
176
177 /* Copy the first 3 chars of the extension (if any) */
178 if (ext)
179 {
180 if (!dir_format) *dst++ = '.';
181 for (i = 3, ext++; (i > 0) && !IS_END_OF_NAME(*ext); i--, ext++)
182 *dst++ = strchr( invalid_chars, *ext ) ? '_' : FILE_toupper(*ext);
183 }
184 if (!dir_format) *dst = '\0';
185}
186#endif
187//******************************************************************************
188//******************************************************************************
189ODINFUNCTION7(HFILE, CreateFileA,
190 LPCSTR, lpszName,
191 DWORD, fdwAccess,
192 DWORD, fdwShareMode,
193 LPSECURITY_ATTRIBUTES, lpsa,
194 DWORD, fdwCreate,
195 DWORD, fdwAttrsAndFlags,
196 HANDLE, hTemplateFile)
197{
198 dprintf(("CreateFileA %s", lpszName));
199 return(HMCreateFile(lpszName,
200 fdwAccess,
201 fdwShareMode,
202 lpsa,
203 fdwCreate,
204 fdwAttrsAndFlags,
205 hTemplateFile));
206}
207
208//******************************************************************************
209//******************************************************************************
210ODINFUNCTION7(HFILE, CreateFileW,
211 LPCWSTR, arg1,
212 DWORD, arg2,
213 DWORD, arg3,
214 PSECURITY_ATTRIBUTES, arg4,
215 DWORD, arg5,
216 DWORD, arg6,
217 HANDLE, arg7)
218{
219 HANDLE rc;
220 char *astring;
221
222 astring = UnicodeToAsciiString((LPWSTR)arg1);
223 rc = CreateFileA(astring, arg2, arg3, arg4, arg5, arg6, arg7);
224 FreeAsciiString(astring);
225 return(rc);
226}
227//******************************************************************************
228//******************************************************************************
229ODINFUNCTION2(HANDLE, FindFirstFileA,
230 LPCSTR, lpFileName,
231 WIN32_FIND_DATAA *, lpFindFileData)
232{
233 HANDLE hFind;
234 char *filename;
235 int namelen;
236
237 dprintf(("FindFirstFileA %s", lpFileName));
238
239 if(lpFileName == NULL || lpFindFileData == NULL)
240 {
241 SetLastError(ERROR_INVALID_PARAMETER);
242 return -1;
243 }
244
245 namelen = strlen(lpFileName);
246 if(lpFileName[namelen-1] == '\\')
247 {
248 filename = (char *)alloca(namelen+1);
249 strcpy(filename, lpFileName);
250 filename[namelen-1] = 0;
251 }
252 else
253 filename = (char *)lpFileName;
254
255 return (HANDLE)OSLibDosFindFirst(filename,lpFindFileData);
256}
257//******************************************************************************
258// internal function for faster access (SHELL32)
259//******************************************************************************
260ODINFUNCTION3(HANDLE, FindFirstFileMultiA,
261 LPCSTR, lpFileName,
262 WIN32_FIND_DATAA *, lpFindFileData,
263 DWORD *,count)
264{
265 return (HANDLE)OSLibDosFindFirstMulti(lpFileName,lpFindFileData,count);
266}
267//******************************************************************************
268//******************************************************************************
269ODINFUNCTION2(HANDLE, FindFirstFileW,
270 LPCWSTR, lpFileName,
271 WIN32_FIND_DATAW *, lpFindFileData)
272{
273 HANDLE rc;
274 char *astring;
275 WIN32_FIND_DATAA wfda;
276
277 astring = UnicodeToAsciiString((LPWSTR)lpFileName);
278 dprintf(("FindFirstFileW %s", astring));
279 rc = (HANDLE)OSLibDosFindFirst(astring,&wfda);
280
281 if(rc == -1) {
282 memset(lpFindFileData, 0, sizeof(WIN32_FIND_DATAW));
283 }
284 else {
285 // convert back the result structure
286 memcpy(lpFindFileData,
287 &wfda,
288 sizeof(WIN32_FIND_DATAA));
289
290 lstrcpynAtoW (lpFindFileData->cFileName,
291 wfda.cFileName,
292 sizeof(wfda.cFileName));
293
294 lstrcpynAtoW (lpFindFileData->cAlternateFileName,
295 wfda.cAlternateFileName,
296 sizeof(wfda.cAlternateFileName));
297 }
298 FreeAsciiString(astring);
299 return(rc);
300}
301//******************************************************************************
302//******************************************************************************
303ODINFUNCTION2(BOOL, FindNextFileA,
304 HANDLE, hFindFile,
305 WIN32_FIND_DATAA *, lpFindFileData)
306{
307 return OSLibDosFindNext(hFindFile,lpFindFileData);
308}
309//******************************************************************************
310// internal function for faster access (SHELL32)
311//******************************************************************************
312ODINFUNCTION3(BOOL, FindNextFileMultiA,
313 HANDLE, hFindFile,
314 WIN32_FIND_DATAA *, lpFindFileData,
315 DWORD *,count)
316{
317 return OSLibDosFindNextMulti(hFindFile,lpFindFileData,count);
318}
319//******************************************************************************
320//******************************************************************************
321ODINFUNCTION2(BOOL, FindNextFileW,
322 HANDLE, hFindFile,
323 WIN32_FIND_DATAW *, lpFindFileData)
324{
325 WIN32_FIND_DATAA wfda;
326 BOOL rc;
327
328 rc = OSLibDosFindNext(hFindFile,&wfda);
329
330 if(rc == 0) {
331 memset(lpFindFileData, 0, sizeof(WIN32_FIND_DATAW));
332 }
333 else {
334 // convert back the result structure
335 memcpy(lpFindFileData,
336 &wfda,
337 sizeof(WIN32_FIND_DATAA));
338
339 lstrcpynAtoW (lpFindFileData->cFileName,
340 wfda.cFileName,
341 sizeof(wfda.cFileName));
342
343 lstrcpynAtoW (lpFindFileData->cAlternateFileName,
344 wfda.cAlternateFileName,
345 sizeof(wfda.cAlternateFileName));
346 }
347 return rc;
348}
349//******************************************************************************
350//******************************************************************************
351ODINFUNCTION1(BOOL, FindClose,
352 HANDLE, hFindFile)
353{
354 return OSLibDosFindClose(hFindFile);
355}
356//******************************************************************************
357//******************************************************************************
358ODINFUNCTION1(DWORD, GetFileType,
359 HANDLE, hFile)
360{
361 return(HMGetFileType(hFile));
362}
363//******************************************************************************
364//******************************************************************************
365ODINFUNCTION2(DWORD, GetFileInformationByHandle,
366 HANDLE, arg1,
367 BY_HANDLE_FILE_INFORMATION *, arg2)
368{
369 return(HMGetFileInformationByHandle(arg1,arg2));
370}
371//******************************************************************************
372//******************************************************************************
373ODINFUNCTION1(BOOL, SetEndOfFile,
374 HANDLE, arg1)
375{
376 return HMSetEndOfFile(arg1);
377}
378//******************************************************************************
379//******************************************************************************
380ODINFUNCTION4(BOOL, SetFileTime,
381 HANDLE, arg1,
382 const FILETIME *, arg2,
383 const FILETIME *, arg3,
384 const FILETIME *, arg4)
385{
386 return HMSetFileTime(arg1,
387 arg2,
388 arg3,
389 arg4);
390}
391//******************************************************************************
392//******************************************************************************
393ODINFUNCTION2(INT, CompareFileTime,
394 FILETIME *, lpft1,
395 FILETIME *, lpft2)
396{
397 if (lpft1 == NULL || lpft2 == NULL) {
398 SetLastError(ERROR_INVALID_PARAMETER);
399 return -1;
400 }
401
402 if(lpft1->dwHighDateTime > lpft2->dwHighDateTime)
403 return 1;
404
405 if(lpft1->dwHighDateTime < lpft2->dwHighDateTime)
406 return -1;
407
408 if(lpft1->dwLowDateTime > lpft2->dwLowDateTime)
409 return 1;
410
411 if(lpft1->dwLowDateTime < lpft2->dwLowDateTime)
412 return -1;
413
414 return 0; //equal
415}
416//******************************************************************************
417//******************************************************************************
418ODINFUNCTION4(BOOL, GetFileTime, HANDLE, hFile, LPFILETIME, arg2, LPFILETIME, arg3, LPFILETIME, arg4)
419{
420 return HMGetFileTime(hFile, arg2, arg3, arg4);
421}
422//******************************************************************************
423//******************************************************************************
424ODINFUNCTION3(BOOL, CopyFileA,
425 LPCSTR, arg1,
426 LPCSTR, arg2,
427 BOOL, arg3)
428{
429 return OSLibDosCopyFile(arg1, arg2, arg3);
430}
431//******************************************************************************
432//SvL: 24-6-'97 - Added
433//******************************************************************************
434ODINFUNCTION3(BOOL, CopyFileW,
435 LPCWSTR, arg1,
436 LPCWSTR, arg2,
437 BOOL, arg3)
438{
439 BOOL rc;
440 char *astring1, *astring2;
441
442 astring1 = UnicodeToAsciiString((LPWSTR)arg1);
443 astring2 = UnicodeToAsciiString((LPWSTR)arg2);
444 rc = CALL_ODINFUNC(CopyFileA)(astring1, astring2, arg3);
445 FreeAsciiString(astring2);
446 FreeAsciiString(astring1);
447 return(rc);
448}
449/*****************************************************************************
450 * Name : BOOL WIN32API CopyFileExA
451 * Purpose : The CopyFileExA function copies an existing file to a new file.
452 * This function preserves extended attributes, OLE structured
453 * storage, NTFS alternate data streams, and file attributes.
454 * Security attributes for the existing file are not copied to
455 * the new file.
456 * Parameters: LPCSTR lpExistingFileName pointer to name of an existing file
457 * LPCSTR lpNewFileName pointer to filename to copy to
458 * LPPROGRESS_ROUTINE lpProgressRoutine pointer to the callback function
459 * LPVOID lpData to be passed to the callback function
460 * LPBOOL pbCancel flag that can be used to cancel the operation
461 * DWORD dwCopyFlags flags that specify how the file is copied
462 * Variables :
463 * Result : f the function succeeds, the return value is nonzero.
464 * If the function fails, the return value is zero.
465 * To get extended error information call GetLastError.
466 * Remark :
467 * Status : UNTESTED STUB
468 *
469 * Author : Markus Montkowski [Thu, 1998/05/19 11:46]
470 *****************************************************************************/
471
472BOOL WIN32API CopyFileExA( LPCSTR lpExistingFileName,
473 LPCSTR lpNewFileName,
474 LPPROGRESS_ROUTINE lpProgressRoutine,
475 LPVOID lpData,
476 LPBOOL pbCancel,
477 DWORD dwCopyFlags)
478{
479
480 dprintf(("KERNEL32: CopyFileExA(%08x,%08x,%08x,%08x,%08x,%08x) not properly implemented\n",
481 lpExistingFileName,
482 lpNewFileName,
483 lpProgressRoutine,
484 lpData,
485 pbCancel,
486 dwCopyFlags
487 ));
488
489 BOOL failIfExists = FALSE;
490
491 /*
492 * Interpret the only flag that CopyFile can interpret.
493 */
494 if((dwCopyFlags & COPY_FILE_FAIL_IF_EXISTS) != 0)
495 {
496 failIfExists = TRUE;
497 }
498
499 return CopyFileA(lpExistingFileName, lpNewFileName, failIfExists);
500}
501
502
503/*****************************************************************************
504 * Name : BOOL WIN32API CopyFileExW
505 * Purpose : The CopyFileExW function copies an existing file to a new file.
506 * This function preserves extended attributes, OLE structured
507 * storage, NTFS alternate data streams, and file attributes.
508 * Security attributes for the existing file are not copied to
509 * the new file.
510 * Parameters: LPCWSTR lpExistingFileName pointer to name of an existing file
511 * LPCWSTR lpNewFileName pointer to filename to copy to
512 * LPPROGRESS_ROUTINE lpProgressRoutine pointer to the callback function
513 * LPVOID lpData to be passed to the callback function
514 * LPBOOL pbCancel flag that can be used to cancel the operation
515 * DWORD dwCopyFlags flags that specify how the file is copied
516 * Variables :
517 * Result : f the function succeeds, the return value is nonzero.
518 * If the function fails, the return value is zero.
519 * To get extended error information call GetLastError.
520 * Remark :
521 * Status : UNTESTED STUB
522 *
523 * Author : Markus Montkowski [Thu, 1998/05/19 11:46]
524 *****************************************************************************/
525
526BOOL WIN32API CopyFileExW( LPCWSTR lpExistingFileName,
527 LPCWSTR lpNewFileName,
528 LPPROGRESS_ROUTINE lpProgressRoutine,
529 LPVOID lpData,
530 LPBOOL pbCancel,
531 DWORD dwCopyFlags)
532{
533 LPSTR sourceA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpExistingFileName );
534 LPSTR destA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpNewFileName );
535
536 BOOL ret = CopyFileExA(sourceA,
537 destA,
538 lpProgressRoutine,
539 lpData,
540 pbCancel,
541 dwCopyFlags);
542
543 HeapFree( GetProcessHeap(), 0, sourceA );
544 HeapFree( GetProcessHeap(), 0, destA );
545
546 return ret;
547}
548//******************************************************************************
549//******************************************************************************
550ODINFUNCTION2(DWORD, GetFileSize,
551 HANDLE, arg1,
552 PDWORD, arg2)
553{
554 return HMGetFileSize(arg1,
555 arg2);
556}
557//******************************************************************************
558//******************************************************************************
559ODINFUNCTION1(BOOL, DeleteFileA,
560 LPCSTR, lpszFile)
561{
562 BOOL rc;
563
564#if 0
565 dprintf(("DeleteFileA %s", lpszFile));
566 return 1;
567#else
568 rc = OSLibDosDelete((LPSTR)lpszFile);
569 if(!rc) {
570 dprintf(("DeleteFileA %s returned FALSE; last error %x", lpszFile, GetLastError()));
571 if(GetLastError() == 20) {
572 return TRUE;
573 }
574 }
575 else dprintf(("DeleteFileA %s", lpszFile));
576
577 return rc;
578#endif
579}
580//******************************************************************************
581//******************************************************************************
582ODINFUNCTION1(BOOL, DeleteFileW,
583 LPCWSTR, arg1)
584{
585 BOOL rc;
586 char *astring;
587
588 astring = UnicodeToAsciiString((LPWSTR)arg1);
589 rc = CALL_ODINFUNC(DeleteFileA)(astring);
590 FreeAsciiString(astring);
591 return(rc);
592}
593//******************************************************************************
594//******************************************************************************
595ODINFUNCTION4(UINT, GetTempFileNameA,
596 LPCSTR, arg1,
597 LPCSTR, arg2,
598 UINT, arg3,
599 LPSTR, arg4)
600{
601 return O32_GetTempFileName(arg1, arg2, arg3, arg4);
602}
603//******************************************************************************
604//******************************************************************************
605ODINFUNCTION4(UINT, GetTempFileNameW,
606 LPCWSTR, lpPathName,
607 LPCWSTR, lpPrefixString,
608 UINT, uUnique,
609 LPWSTR, lpTempFileName)
610{
611 char *asciipath, *asciiprefix;
612 char *asciitemp = (char *)malloc(MAX_PATH+1);
613 UINT rc;
614
615 asciipath = UnicodeToAsciiString((LPWSTR)lpPathName);
616 asciiprefix = UnicodeToAsciiString((LPWSTR)lpPrefixString);
617 rc = O32_GetTempFileName(asciipath, asciiprefix, uUnique, asciitemp);
618 if(rc) AsciiToUnicode(asciitemp, lpTempFileName);
619 FreeAsciiString(asciiprefix);
620 FreeAsciiString(asciipath);
621 free(asciitemp);
622 return(rc);
623}
624//******************************************************************************
625//******************************************************************************
626ODINFUNCTION2(UINT, GetTempPathA,
627 UINT, arg1,
628 LPSTR, arg2)
629{
630 return O32_GetTempPath(arg1, arg2);
631}
632//******************************************************************************
633//******************************************************************************
634ODINFUNCTION2(UINT, GetTempPathW,
635 UINT, nBufferLength,
636 LPWSTR, lpBuffer)
637{
638 char *asciibuffer = (char *)malloc(nBufferLength+1);
639 DWORD rc;
640
641 rc = O32_GetTempPath(nBufferLength, asciibuffer);
642 if(rc) AsciiToUnicode(asciibuffer, lpBuffer);
643 free(asciibuffer);
644 return(rc);
645}
646//******************************************************************************
647//******************************************************************************
648ODINFUNCTION5(BOOL, ReadFile,
649 HANDLE, hFile,
650 PVOID, pBuffer,
651 DWORD, dwLength,
652 PDWORD, lpNumberOfBytesRead,
653 LPOVERLAPPED, lpOverlapped)
654{
655 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//******************************************************************************
929ODINFUNCTION3(BOOL, MoveFileExA,
930 LPCSTR, arg1,
931 LPCSTR, arg2,
932 DWORD, fdwFlags)
933{
934 dprintf(("KERNEL32: MoveFileExA %s to %s %x, not complete!\n", arg1, arg2, fdwFlags));
935 return OSLibDosMoveFile(arg1, arg2);
936}
937//******************************************************************************
938//******************************************************************************
939ODINFUNCTION2(BOOL, MoveFileW,
940 LPCWSTR, lpSrc,
941 LPCWSTR, lpDest)
942{
943 char *asciisrc, *asciidest;
944 BOOL rc;
945
946 asciisrc = UnicodeToAsciiString((LPWSTR)lpSrc);
947 asciidest = UnicodeToAsciiString((LPWSTR)lpDest);
948 rc = MoveFileA(asciisrc, asciidest);
949 FreeAsciiString(asciisrc);
950 FreeAsciiString(asciidest);
951 return(rc);
952}
953//******************************************************************************
954//******************************************************************************
955ODINFUNCTION3(BOOL, MoveFileExW,
956 LPCWSTR, arg1,
957 LPCWSTR, arg2,
958 DWORD, fdwFlags)
959{
960 dprintf(("KERNEL32: MoveFileExW %ls to %ls %x, not complete!", arg1, arg2, fdwFlags));
961 return MoveFileW(arg1, arg2);
962}
963//******************************************************************************
964/*****************************************************************************
965ODINFUNCTION3(*, :,
966 HFILE, WIN32API,
967 OpenFile *, Purpose,
968 :, forwardOpenFile to Open32
969 * Parameters:
970 * Variables :
971 * Result : API returncode
972 * Remark : modified for handle translation support
973 * Status : @@@PH verify if 0 is a valid "invalid handle" :)
974 *
975 * Author : Patrick Haller [Fri, 1998/06/12 02:53]
976 *****************************************************************************/
977
978ODINFUNCTION3(HFILE, OpenFile,
979 LPCSTR, lpszFile,
980 OFSTRUCT *, lpOpenBuff,
981 UINT, fuMode)
982{
983 HFILE hFile;
984
985 dprintf(("KERNEL32: OpenFile(%s, %08xh, %08xh)\n",
986 lpszFile,
987 lpOpenBuff,
988 fuMode));
989
990 hFile = HMOpenFile(lpszFile, /* call open32 */
991 lpOpenBuff,
992 fuMode);
993
994 return (hFile);
995}
996//******************************************************************************
997//******************************************************************************
998ODINFUNCTION5(BOOL, UnlockFile,
999 HANDLE, arg1,
1000 DWORD, arg2,
1001 DWORD, arg3,
1002 DWORD, arg4,
1003 DWORD, arg5)
1004{
1005 return HMUnlockFile(arg1,
1006 arg2,
1007 arg3,
1008 arg4,
1009 arg5);
1010}
1011
1012
1013/*****************************************************************************
1014 * Name : BOOL UnlockFileEx
1015 * Purpose : The UnlockFileEx function unlocks a previously locked byte range in an open file.
1016 * Parameters: HANDLE hFile handle of file to lock
1017 * DWORD dwReserved reserved, must be set to zero
1018 * DWORD nNumberOfBytesToLockLow low-order 32 bits of length to lock
1019 * DWORD nNumberOfBytesToLockHigh high-order 32 bits of length to lock
1020 * LPOVERLAPPED LPOVERLAPPED addr. of structure with lock region start offset
1021 * Variables :
1022 * Result : TRUE / FALSE
1023 * Remark :
1024 * Status : UNTESTED STUB
1025 *
1026 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1027 *****************************************************************************/
1028
1029ODINFUNCTION5(BOOL, UnlockFileEx,
1030 HANDLE, hFile,
1031 DWORD, dwReserved,
1032 DWORD, nNumberOfBytesToLockLow,
1033 DWORD, nNumberOfBytesToLockHigh,
1034 LPOVERLAPPED, lpOverlapped)
1035{
1036 return(HMUnlockFileEx(hFile, dwReserved,
1037 nNumberOfBytesToLockLow,
1038 nNumberOfBytesToLockHigh,
1039 lpOverlapped));
1040}
1041//******************************************************************************
1042//Behaviour in NT 4, SP6:
1043//- converts long filename to 8.3 short filname (TODO: not yet done here!)
1044//- fails on volume that doesn't support 8.3 filenames
1045//- if lpszShortPath 0 or cchBuffer too small -> return required length
1046// (INCLUDING 0 terminator)
1047//- if lpszLongPath == NULL -> ERROR_INVALID_PARAMETER (return 0)
1048//- if lpszLongPath empty -> proceed as if nothing is wrong
1049//- does NOT clear the last error if successful!
1050//- if successful -> return length of string (excluding 0 terminator)
1051//******************************************************************************
1052ODINFUNCTION3(DWORD, GetShortPathNameA,
1053 LPCTSTR, lpszLongPath,
1054 LPTSTR, lpszShortPath,
1055 DWORD, cchBuffer)
1056{
1057 int length;
1058
1059 dprintf(("KERNEL32: GetShortPathNameA of %s, just copying it", lpszLongPath));
1060
1061 if(!lpszLongPath) {
1062 SetLastError(ERROR_INVALID_PARAMETER);
1063 return 0;
1064 }
1065
1066 length = lstrlenA(lpszLongPath) + 1;
1067 if(length > cchBuffer) {
1068 if(lpszShortPath) {
1069 *lpszShortPath = 0;
1070 }
1071 return(length); //return length required (including 0 terminator)
1072 }
1073 lstrcpyA(lpszShortPath, lpszLongPath);
1074 return(length-1);
1075}
1076//******************************************************************************
1077//******************************************************************************
1078ODINFUNCTION3(DWORD, GetShortPathNameW,
1079 LPCWSTR, lpszLongPath,
1080 LPWSTR, lpszShortPath,
1081 DWORD, cchBuffer)
1082{
1083 int length;
1084
1085 dprintf(("KERNEL32: GetShortPathNameW; just copying it"));
1086 if(!lpszLongPath) {
1087 SetLastError(ERROR_INVALID_PARAMETER);
1088 return 0;
1089 }
1090
1091 length = lstrlenW(lpszLongPath) + 1;
1092 if(length > cchBuffer) {
1093 if(lpszShortPath) {
1094 *lpszShortPath = 0;
1095 }
1096 return(length); //return length required (including 0 terminator)
1097 }
1098 lstrcpyW(lpszShortPath, lpszLongPath);
1099 return(length-1);
1100}
1101//******************************************************************************
1102//Behaviour in NT 4, SP6: (presumably the same as GetShortPathNameA; TODO check)
1103//- converts short filename to long filenames (TODO: not yet done here!)
1104//- if lpszShortPath 0 or cchBuffer too small -> return required length
1105// (INCLUDING 0 terminator)
1106//- if lpszLongPath == NULL -> ERROR_INVALID_PARAMETER (return 0)
1107//- if lpszLongPath empty -> proceed as if nothing is wrong
1108//- does NOT clear the last error if successful!
1109//- if successful -> return length of string (excluding 0 terminator)
1110//******************************************************************************
1111DWORD WINAPI GetLongPathNameA( LPCSTR lpszShortPath, LPSTR lpszLongPath,
1112 DWORD cchBuffer )
1113{
1114 int length;
1115
1116 dprintf(("GetLongPathNameA %x %s %d", lpszShortPath, lpszLongPath, cchBuffer));
1117 dprintf(("WARNING: WIN98 ONLY!!"));
1118
1119 if(!lpszShortPath) {
1120 SetLastError(ERROR_INVALID_PARAMETER);
1121 return 0;
1122 }
1123
1124 length = lstrlenA(lpszShortPath) + 1;
1125 if(length > cchBuffer) {
1126 if(lpszLongPath) {
1127 *lpszLongPath = 0;
1128 }
1129 return(length); //return length required (including 0 terminator)
1130 }
1131 lstrcpyA(lpszLongPath, lpszShortPath);
1132 return(length-1);
1133}
1134//******************************************************************************
1135//******************************************************************************
1136DWORD WINAPI GetLongPathNameW( LPCWSTR lpszShortPath, LPWSTR lpszLongPath,
1137 DWORD cchBuffer )
1138{
1139 int length;
1140
1141 dprintf(("GetLongPathNameW %x %ls %d", lpszShortPath, lpszLongPath, cchBuffer));
1142 dprintf(("WARNING: WIN98 ONLY!!"));
1143
1144 if(!lpszShortPath) {
1145 SetLastError(ERROR_INVALID_PARAMETER);
1146 return 0;
1147 }
1148
1149 length = lstrlenW(lpszShortPath) + 1;
1150 if(length > cchBuffer) {
1151 if(lpszLongPath) {
1152 *lpszLongPath = 0;
1153 }
1154 return(length); //return length required (including 0 terminator)
1155 }
1156 lstrcpyW(lpszLongPath, lpszShortPath);
1157 return(length-1);
1158}
1159//******************************************************************************
1160//******************************************************************************
1161ODINPROCEDURE0(SetFileApisToANSI)
1162{
1163 dprintf(("SetFileApisToANSI() stub\n"));
1164}
1165
1166/*****************************************************************************
1167 * Name : DWORD GetCompressedFileSizeA
1168 * Purpose : The GetCompressedFileSizeA function obtains the compressed
1169 * size, in bytes, of a specified file.
1170 * Parameters: LPCTSTR lpFileName, // pointer to name of file
1171 * LPDWORD lpFileSizeHigh // pointer to DWORD to receive
1172 * high-order doubleword of file size
1173 * Variables :
1174 * Result : size of compressed file
1175 * Remark :
1176 * Status : UNTESTED
1177 *
1178 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1179 *****************************************************************************/
1180
1181ODINFUNCTION2(DWORD, GetCompressedFileSizeA,
1182 LPCTSTR, lpFileName,
1183 LPDWORD, lpFileSizeHigh)
1184{
1185 dprintf(("KERNEL32: GetCompressedFileSizeA (%s, %08xh) not implemented.\n",
1186 lpFileName,
1187 lpFileSizeHigh));
1188
1189 /* @@@PH: simply return the standard filesize */
1190 return 0;
1191}
1192
1193
1194/*****************************************************************************
1195 * Name : DWORD GetCompressedFileSizeW
1196 * Purpose : The GetCompressedFileSizeE function obtains the compressed
1197 * size, in bytes, of a specified file.
1198 * Parameters: LPCWSTR lpFileName, // pointer to name of file
1199 * LPDWORD lpFileSizeHigh // pointer to DWORD to receive
1200 * high-order doubleword of file size
1201 * Variables :
1202 * Result : size of compressed file
1203 * Remark :
1204 * Status : UNTESTED
1205 *
1206 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1207 *****************************************************************************/
1208
1209ODINFUNCTION2(DWORD, GetCompressedFileSizeW,
1210 LPCWSTR, lpFileName,
1211 LPDWORD, lpFileSizeHigh)
1212{
1213 LPCTSTR lpAsciiFileName; /* converted filename */
1214 DWORD rc; /* function result */
1215
1216 dprintf(("KERNEL32: GetCompressedFileSizeW (%s, %08xh)\n",
1217 lpFileName,
1218 lpFileSizeHigh));
1219
1220 lpAsciiFileName = UnicodeToAsciiString( (LPWSTR) lpFileName);
1221
1222 rc = GetCompressedFileSizeA(lpAsciiFileName,
1223 lpFileSizeHigh);
1224
1225 FreeAsciiString( (char *) lpAsciiFileName);
1226
1227 return (rc); /* return result */
1228}
1229
1230
1231/*****************************************************************************
1232 * Name : BOOL GetFileAttributesExA
1233 * Purpose :
1234 * Parameters:
1235 * Variables :
1236 * Result :
1237 * Remark : KERNEL32.874
1238 * Status : UNTESTED
1239 *
1240 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1241 *****************************************************************************/
1242
1243ODINFUNCTION3(BOOL, GetFileAttributesExA,
1244 LPCSTR, lpFileName,
1245 GET_FILEEX_INFO_LEVELS, fInfoLevelId,
1246 LPVOID, lpFileInformation)
1247{
1248 BOOL rc;
1249
1250 dprintf(("KERNEL32: GetFileAttributesExA(%s,%08xh,%08xh) mostly implemented.\n",
1251 lpFileName,
1252 fInfoLevelId,
1253 lpFileInformation));
1254
1255 if (lpFileName == NULL) return FALSE;
1256 if (lpFileInformation == NULL) return FALSE;
1257
1258 if (fInfoLevelId == GetFileExInfoStandard)
1259 {
1260 LPWIN32_FILE_ATTRIBUTE_DATA lpFad = (LPWIN32_FILE_ATTRIBUTE_DATA) lpFileInformation;
1261
1262 rc = OSLibDosGetFileAttributesEx((LPSTR)lpFileName,
1263 fInfoLevelId,
1264 lpFileInformation);
1265 return (rc);
1266 }
1267 else
1268 {
1269 dprintf(("KERNEL32: GetFileAttributesExA - invalid info level %d!\n",
1270 fInfoLevelId));
1271 return FALSE;
1272 }
1273}
1274
1275
1276/*****************************************************************************
1277 * Name : BOOL GetFileAttributesExW
1278 * Purpose :
1279 * Parameters:
1280 * Variables :
1281 * Result :
1282 * Remark : KERNEL32.875
1283 * Status : UNTESTED
1284 *
1285 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1286 *****************************************************************************/
1287
1288ODINFUNCTION3(BOOL, GetFileAttributesExW,
1289 LPCWSTR, lpFileName,
1290 GET_FILEEX_INFO_LEVELS, fInfoLevelId,
1291 LPVOID, lpFileInformation)
1292{
1293 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFileName );
1294 BOOL res = GetFileAttributesExA( nameA, fInfoLevelId, lpFileInformation);
1295 HeapFree( GetProcessHeap(), 0, nameA );
1296 return res;
1297}
1298
1299//******************************************************************************
1300//******************************************************************************
1301ODINFUNCTION3(HANDLE, FindFirstChangeNotificationA,
1302 LPCSTR, lpPathName,
1303 BOOL, bWatchSubtree,
1304 DWORD, dwNotifyFilter)
1305{
1306 dprintf(("KERNEL32: FindFirstChangeNotificationA %s, Not implemented (faked)", lpPathName));
1307 return -1;
1308}
1309//******************************************************************************
1310//******************************************************************************
1311ODINFUNCTION1(BOOL, FindNextChangeNotification,
1312 HANDLE, hChange)
1313{
1314 dprintf(("KERNEL32: FindNextChangeNotification (%08xh), Not implemented\n",
1315 hChange));
1316
1317 return FALSE;
1318}
1319//******************************************************************************
1320//******************************************************************************
1321ODINFUNCTION1(BOOL, FindCloseChangeNotification, HANDLE, hChange)
1322{
1323 dprintf(("KERNEL32: OS2FindNextChangeNotification, Not implemented\n"));
1324
1325 return(TRUE);
1326}
1327/*****************************************************************************
1328 * Name : HANDLE WIN32API FindFirstChangeNotificationW
1329 * Purpose : The FindFirstChangeNotification function creates a change
1330 * notification handle and sets up initial change notification
1331 * filter conditions. A wait on a notification handle succeeds when
1332 * a change matching the filter conditions occurs in the specified
1333 * directory or subtree.
1334 * Parameters: LPCWSTR lpPathName pointer to name of directory to watch
1335 * BOOL bWatchSubtree flag for monitoring directory or
1336 * directory tree
1337 * DWORD dwNotifyFilter filter conditions to watch for
1338 * Variables :
1339 * Result : If the function succeeds, the return value is a handle to a find
1340 * change notification object.
1341 * If the function fails, the return value is INVALID_HANDLE_VALUE
1342 * Remark :
1343 * Status : UNTESTED STUB
1344 *
1345 * Author : Markus Montkowski [Tha, 1998/05/21 20:57]
1346 *****************************************************************************/
1347ODINFUNCTION3(HANDLE, FindFirstChangeNotificationW, LPCWSTR, lpPathName,
1348 BOOL, bWatchSubtree,
1349 DWORD, dwNotifyFilter)
1350{
1351 LPSTR lpAsciiPath;
1352 HANDLE hChange;
1353
1354 lpAsciiPath = UnicodeToAsciiString( (LPWSTR) lpPathName);
1355 hChange = FindFirstChangeNotificationA(lpAsciiPath, bWatchSubtree,
1356 dwNotifyFilter );
1357 if (lpAsciiPath) FreeAsciiString(lpAsciiPath);
1358 return hChange;
1359}
1360//******************************************************************************
1361//******************************************************************************
1362ODINFUNCTION8(BOOL, DeviceIoControl, HANDLE, hDevice, DWORD, dwIoControlCode,
1363 LPVOID, lpInBuffer, DWORD, nInBufferSize,
1364 LPVOID, lpOutBuffer, DWORD, nOutBufferSize,
1365 LPDWORD, lpBytesReturned, LPOVERLAPPED, lpOverlapped)
1366{
1367 return HMDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize,
1368 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
1369}
1370//******************************************************************************
1371//******************************************************************************
Note: See TracBrowser for help on using the repository browser.