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

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

logging updates

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