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

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

partly implemented FindFirstFileExA/W

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