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

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

minor comment update

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