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

Last change on this file since 8675 was 8675, checked in by sandervl, 23 years ago

Check for NULL parameters in GetFullPathNameW

File size: 58.8 KB
Line 
1/* $Id: Fileio.cpp,v 1.66 2002-06-15 11:27:03 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 = NULL, *asciibuffer = NULL, *asciipart = NULL;
896 DWORD rc;
897
898 if(nBufferLength) {
899 asciibuffer = (char *)malloc(nBufferLength+1);
900 }
901 astring = UnicodeToAsciiString((LPWSTR)lpFileName);
902
903 rc = GetFullPathNameA(astring, nBufferLength,
904 asciibuffer, &asciipart);
905
906 dprintf(("KERNEL32: GetFullPathNameW %s returns %s\n",
907 astring,
908 asciibuffer));
909
910 if(rc && asciibuffer)
911 AsciiToUnicode(asciibuffer,
912 lpBuffer);
913
914 if(lpFilePart) {
915 if (asciipart == NULL)
916 *lpFilePart = NULL;
917 else
918 *lpFilePart = lpBuffer + ((int)asciipart - (int)asciibuffer);
919 }
920
921 FreeAsciiString(astring);
922 if(asciibuffer) free(asciibuffer);
923 return(rc);
924}
925//******************************************************************************
926//******************************************************************************
927BOOL WIN32API LockFile(HANDLE arg1, DWORD arg2,
928 DWORD arg3, DWORD arg4,
929 DWORD arg5)
930{
931 return HMLockFile(arg1,
932 arg2,
933 arg3,
934 arg4,
935 arg5);
936}
937
938
939/*****************************************************************************
940 * Name : BOOL LockFileEx
941 * Purpose : The LockFileEx function locks a byte range within an open file for shared or exclusive access.
942 * Parameters: HANDLE hFile handle of file to lock
943 * DWORD dwFlags functional behavior modification flags
944 * DWORD dwReserved reserved, must be set to zero
945 * DWORD nNumberOfBytesToLockLow low-order 32 bits of length to lock
946 * DWORD nNumberOfBytesToLockHigh high-order 32 bits of length to lock
947 * LPOVERLAPPED LPOVERLAPPED addr. of structure with lock region start offset
948 * Variables :
949 * Result : TRUE / FALSE
950 * Remark :
951 * Status : UNTESTED STUB
952 *
953 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
954 *****************************************************************************/
955
956BOOL LockFileEx(HANDLE hFile, DWORD dwFlags, DWORD dwReserved,
957 DWORD nNumberOfBytesToLockLow,
958 DWORD nNumberOfBytesToLockHigh,
959 LPOVERLAPPED lpOverlapped)
960{
961 return(HMLockFile(hFile,
962 lpOverlapped->Offset,
963 lpOverlapped->OffsetHigh,
964 nNumberOfBytesToLockLow,
965 nNumberOfBytesToLockHigh));
966}
967//******************************************************************************
968//******************************************************************************
969BOOL WIN32API MoveFileA(LPCSTR arg1, LPCSTR arg2)
970{
971 dprintf(("KERNEL32: MoveFileA %s %s", arg1, arg2));
972 return OSLibDosMoveFile(arg1, arg2);
973}
974//******************************************************************************
975//******************************************************************************
976
977
978/*****************************************************************************
979 * Name : MoveFileExA
980 * Purpose : Move or delete a file
981 * Parameters: LPCSTR lpExistingFileName
982 * LPCSTR lpNewFileName
983 * DWORD dwFlags
984 * Variables :
985 * Result :
986 * Remark : "delete on system-reboot" feature is not supported!
987 * Status :
988 *
989 * Author : Patrick Haller [2001-08-30]
990 *****************************************************************************/
991
992BOOL WIN32API MoveFileExA(LPCSTR lpszOldFilename,
993 LPCSTR lpszNewFilename,
994 DWORD fdwFlags)
995{
996 dprintf(("KERNEL32: MoveFileExA %s to %s %x, not complete!\n",
997 lpszOldFilename,
998 lpszNewFilename,
999 fdwFlags));
1000
1001 // this parameter combination is illegal
1002 if ( (fdwFlags & MOVEFILE_DELAY_UNTIL_REBOOT) &&
1003 (fdwFlags & MOVEFILE_COPY_ALLOWED) )
1004 {
1005 // Note: error code not verified
1006 SetLastError(ERROR_INVALID_PARAMETER);
1007 return FALSE;
1008 }
1009
1010 // first, we take care about the special cases
1011 if (fdwFlags && MOVEFILE_DELAY_UNTIL_REBOOT)
1012 {
1013 // We cannot really support this in any other way than
1014 // to call the IBMCSFLK driver. As the first place I've encountered
1015 // this call is Microsoft ACMSETUP wanting to replace OLEPRO32.DLL
1016 // in the ODIN system directory, we are better skipping the call.
1017
1018 // Anyway, this is only supported under Windows NT
1019 fdwFlags &= ~MOVEFILE_DELAY_UNTIL_REBOOT;
1020
1021 // Until we support this, we have to intercept
1022 // lpszNewFilename == NULL
1023 if (NULL == lpszNewFilename)
1024 {
1025 // try to delete the filename
1026 dprintf(("KERNEL32-MoveFileExA: trying to delete file [%s], skipped.",
1027 lpszOldFilename));
1028
1029 SetLastError( NO_ERROR );
1030 return TRUE;
1031 }
1032 }
1033
1034 if (fdwFlags && MOVEFILE_COPY_ALLOWED)
1035 {
1036 // if lpszOldFilename and lpszNewFilename refer to different
1037 // volumes, this flag controls if a copy operation is allowed.
1038 }
1039
1040 if (fdwFlags && MOVEFILE_REPLACE_EXISTING)
1041 {
1042 // We can only attempt to
1043 // 1 move away the current file if existing,
1044 // 2 do the current move operation
1045 // 3 if succesful, delete the backup
1046 // otherwise restore the original file
1047 }
1048
1049 return OSLibDosMoveFile(lpszOldFilename,
1050 lpszNewFilename);
1051}
1052//******************************************************************************
1053//******************************************************************************
1054BOOL WIN32API MoveFileW(LPCWSTR lpSrc, LPCWSTR lpDest)
1055{
1056 char *asciisrc, *asciidest;
1057 BOOL rc;
1058
1059 asciisrc = UnicodeToAsciiString((LPWSTR)lpSrc);
1060 asciidest = UnicodeToAsciiString((LPWSTR)lpDest);
1061 rc = MoveFileA(asciisrc, asciidest);
1062 FreeAsciiString(asciisrc);
1063 FreeAsciiString(asciidest);
1064 return(rc);
1065}
1066//******************************************************************************
1067//******************************************************************************
1068BOOL WIN32API MoveFileExW(LPCWSTR lpSrc, LPCWSTR lpDest, DWORD fdwFlags)
1069{
1070 dprintf(("KERNEL32: MoveFileExW %ls to %ls %x",
1071 lpSrc,
1072 lpDest,
1073 fdwFlags));
1074
1075 char *asciisrc,
1076 *asciidest;
1077 BOOL rc;
1078
1079 asciisrc = UnicodeToAsciiString((LPWSTR)lpSrc);
1080 if (NULL != lpDest)
1081 asciidest = UnicodeToAsciiString((LPWSTR)lpDest);
1082 else
1083 asciidest = NULL;
1084
1085 rc = MoveFileExA(asciisrc,
1086 asciidest,
1087 fdwFlags);
1088
1089 if (NULL != asciidest)
1090 FreeAsciiString(asciidest);
1091
1092 FreeAsciiString(asciisrc);
1093
1094 return(rc);
1095}
1096//******************************************************************************
1097/*****************************************************************************
1098ODINFUNCTION3(*, :,
1099 HFILE, WIN32API,
1100 OpenFile *, Purpose,
1101 :, forwardOpenFile to Open32
1102 * Parameters:
1103 * Variables :
1104 * Result : API returncode
1105 * Remark : modified for handle translation support
1106 * Status : @@@PH verify if 0 is a valid "invalid handle" :)
1107 *
1108 * Author : Patrick Haller [Fri, 1998/06/12 02:53]
1109 *****************************************************************************/
1110
1111HFILE WIN32API OpenFile(LPCSTR lpszFile, OFSTRUCT *lpOpenBuff,
1112 UINT fuMode)
1113{
1114 HFILE hFile;
1115
1116 dprintf(("KERNEL32: OpenFile(%s, %08xh, %08xh)\n",
1117 lpszFile,
1118 lpOpenBuff,
1119 fuMode));
1120
1121 hFile = HMOpenFile(lpszFile, /* call open32 */
1122 lpOpenBuff,
1123 fuMode);
1124
1125 return (hFile);
1126}
1127//******************************************************************************
1128//******************************************************************************
1129BOOL WIN32API UnlockFile(HANDLE arg1, DWORD arg2, DWORD arg3,
1130 DWORD arg4, DWORD arg5)
1131{
1132 return HMUnlockFile(arg1,
1133 arg2,
1134 arg3,
1135 arg4,
1136 arg5);
1137}
1138
1139
1140/*****************************************************************************
1141 * Name : BOOL UnlockFileEx
1142 * Purpose : The UnlockFileEx function unlocks a previously locked byte range in an open file.
1143 * Parameters: HANDLE hFile handle of file to lock
1144 * DWORD dwReserved reserved, must be set to zero
1145 * DWORD nNumberOfBytesToLockLow low-order 32 bits of length to lock
1146 * DWORD nNumberOfBytesToLockHigh high-order 32 bits of length to lock
1147 * LPOVERLAPPED LPOVERLAPPED addr. of structure with lock region start offset
1148 * Variables :
1149 * Result : TRUE / FALSE
1150 * Remark :
1151 * Status : UNTESTED STUB
1152 *
1153 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1154 *****************************************************************************/
1155
1156BOOL WIN32API UnlockFileEx(HANDLE hFile, DWORD dwReserved,
1157 DWORD nNumberOfBytesToLockLow,
1158 DWORD nNumberOfBytesToLockHigh,
1159 LPOVERLAPPED lpOverlapped)
1160{
1161 return(HMUnlockFileEx(hFile, dwReserved,
1162 nNumberOfBytesToLockLow,
1163 nNumberOfBytesToLockHigh,
1164 lpOverlapped));
1165}
1166//******************************************************************************
1167//Behaviour in NT 4, SP6:
1168//- converts long filename to 8.3 short filname (TODO: not yet done here!)
1169//- fails on volume that doesn't support 8.3 filenames
1170//- if lpszShortPath 0 or cchBuffer too small -> return required length
1171// (INCLUDING 0 terminator)
1172//- if lpszLongPath == NULL -> ERROR_INVALID_PARAMETER (return 0)
1173//- if lpszLongPath empty -> proceed as if nothing is wrong
1174//- does NOT clear the last error if successful!
1175//- if successful -> return length of string (excluding 0 terminator)
1176//******************************************************************************
1177DWORD WIN32API GetShortPathNameA(LPCTSTR lpszLongPath,
1178 LPTSTR lpszShortPath,
1179 DWORD cchBuffer)
1180{
1181 int length;
1182
1183 dprintf(("KERNEL32: GetShortPathNameA of %s, just copying it", lpszLongPath));
1184
1185 if(!lpszLongPath) {
1186 SetLastError(ERROR_INVALID_PARAMETER);
1187 return 0;
1188 }
1189
1190 length = lstrlenA(lpszLongPath) + 1;
1191 if(length > cchBuffer) {
1192 if(lpszShortPath) {
1193 *lpszShortPath = 0;
1194 }
1195 return(length); //return length required (including 0 terminator)
1196 }
1197 lstrcpyA(lpszShortPath, lpszLongPath);
1198 return(length-1);
1199}
1200//******************************************************************************
1201//******************************************************************************
1202DWORD WIN32API GetShortPathNameW(LPCWSTR lpszLongPath, LPWSTR lpszShortPath,
1203 DWORD cchBuffer)
1204{
1205 int length;
1206
1207 dprintf(("KERNEL32: GetShortPathNameW; just copying it"));
1208 if(!lpszLongPath) {
1209 SetLastError(ERROR_INVALID_PARAMETER);
1210 return 0;
1211 }
1212
1213 length = lstrlenW(lpszLongPath) + 1;
1214 if(length > cchBuffer) {
1215 if(lpszShortPath) {
1216 *lpszShortPath = 0;
1217 }
1218 return(length); //return length required (including 0 terminator)
1219 }
1220 lstrcpyW(lpszShortPath, lpszLongPath);
1221 return(length-1);
1222}
1223//******************************************************************************
1224//Behaviour in NT 4, SP6: (presumably the same as GetShortPathNameA; TODO check)
1225//- converts short filename to long filenames (TODO: not yet done here!)
1226//- if lpszShortPath 0 or cchBuffer too small -> return required length
1227// (INCLUDING 0 terminator)
1228//- if lpszLongPath == NULL -> ERROR_INVALID_PARAMETER (return 0)
1229//- if lpszLongPath empty -> proceed as if nothing is wrong
1230//- does NOT clear the last error if successful!
1231//- if successful -> return length of string (excluding 0 terminator)
1232//******************************************************************************
1233DWORD WINAPI GetLongPathNameA( LPCSTR lpszShortPath, LPSTR lpszLongPath,
1234 DWORD cchBuffer )
1235{
1236 int length;
1237
1238 dprintf(("GetLongPathNameA %x %s %d", lpszShortPath, lpszLongPath, cchBuffer));
1239 dprintf(("WARNING: WIN98 ONLY!!"));
1240
1241 if(!lpszShortPath) {
1242 SetLastError(ERROR_INVALID_PARAMETER);
1243 return 0;
1244 }
1245
1246 length = lstrlenA(lpszShortPath) + 1;
1247 if(length > cchBuffer) {
1248 if(lpszLongPath) {
1249 *lpszLongPath = 0;
1250 }
1251 return(length); //return length required (including 0 terminator)
1252 }
1253 lstrcpyA(lpszLongPath, lpszShortPath);
1254 return(length-1);
1255}
1256//******************************************************************************
1257//******************************************************************************
1258DWORD WINAPI GetLongPathNameW( LPCWSTR lpszShortPath, LPWSTR lpszLongPath,
1259 DWORD cchBuffer )
1260{
1261 int length;
1262
1263 dprintf(("GetLongPathNameW %x %ls %d", lpszShortPath, lpszLongPath, cchBuffer));
1264 dprintf(("WARNING: WIN98 ONLY!!"));
1265
1266 if(!lpszShortPath) {
1267 SetLastError(ERROR_INVALID_PARAMETER);
1268 return 0;
1269 }
1270
1271 length = lstrlenW(lpszShortPath) + 1;
1272 if(length > cchBuffer) {
1273 if(lpszLongPath) {
1274 *lpszLongPath = 0;
1275 }
1276 return(length); //return length required (including 0 terminator)
1277 }
1278 lstrcpyW(lpszLongPath, lpszShortPath);
1279 return(length-1);
1280}
1281//******************************************************************************
1282//******************************************************************************
1283void WIN32API SetFileApisToANSI()
1284{
1285 dprintf(("!WARNING! SetFileApisToANSI() stub\n"));
1286}
1287
1288/*****************************************************************************
1289 * Name : DWORD GetCompressedFileSizeA
1290 * Purpose : The GetCompressedFileSizeA function obtains the compressed
1291 * size, in bytes, of a specified file.
1292 * Parameters: LPCTSTR lpFileName, // pointer to name of file
1293 * LPDWORD lpFileSizeHigh // pointer to DWORD to receive
1294 * high-order doubleword of file size
1295 * Variables :
1296 * Result : size of compressed file
1297 * Remark :
1298 * Status : UNTESTED
1299 *
1300 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1301 *****************************************************************************/
1302
1303DWORD WIN32API GetCompressedFileSizeA(LPCTSTR lpFileName, LPDWORD lpFileSizeHigh)
1304{
1305 dprintf(("KERNEL32: GetCompressedFileSizeA (%s, %08xh) not implemented.\n",
1306 lpFileName,
1307 lpFileSizeHigh));
1308
1309 /* @@@PH: simply return the standard filesize */
1310 return 0;
1311}
1312
1313
1314/*****************************************************************************
1315 * Name : DWORD GetCompressedFileSizeW
1316 * Purpose : The GetCompressedFileSizeE function obtains the compressed
1317 * size, in bytes, of a specified file.
1318 * Parameters: LPCWSTR lpFileName, // pointer to name of file
1319 * LPDWORD lpFileSizeHigh // pointer to DWORD to receive
1320 * high-order doubleword of file size
1321 * Variables :
1322 * Result : size of compressed file
1323 * Remark :
1324 * Status : UNTESTED
1325 *
1326 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1327 *****************************************************************************/
1328
1329DWORD WIN32API GetCompressedFileSizeW(LPCWSTR lpFileName, LPDWORD lpFileSizeHigh)
1330{
1331 LPCTSTR lpAsciiFileName; /* converted filename */
1332 DWORD rc; /* function result */
1333
1334 dprintf(("KERNEL32: GetCompressedFileSizeW (%s, %08xh)\n",
1335 lpFileName,
1336 lpFileSizeHigh));
1337
1338 lpAsciiFileName = UnicodeToAsciiString( (LPWSTR) lpFileName);
1339
1340 rc = GetCompressedFileSizeA(lpAsciiFileName,
1341 lpFileSizeHigh);
1342
1343 FreeAsciiString( (char *) lpAsciiFileName);
1344
1345 return (rc); /* return result */
1346}
1347
1348
1349/*****************************************************************************
1350 * Name : BOOL GetFileAttributesExA
1351 * Purpose :
1352 * Parameters:
1353 * Variables :
1354 * Result :
1355 * Remark : KERNEL32.874
1356 * Status : UNTESTED
1357 *
1358 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1359 *****************************************************************************/
1360
1361BOOL WIN32API GetFileAttributesExA(LPCSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId,
1362 LPVOID lpFileInformation)
1363{
1364 BOOL rc;
1365
1366 dprintf(("KERNEL32: GetFileAttributesExA(%s,%08xh,%08xh) mostly implemented.\n",
1367 lpFileName,
1368 fInfoLevelId,
1369 lpFileInformation));
1370
1371 if (lpFileName == NULL) return FALSE;
1372 if (lpFileInformation == NULL) return FALSE;
1373
1374 if (fInfoLevelId == GetFileExInfoStandard)
1375 {
1376 LPWIN32_FILE_ATTRIBUTE_DATA lpFad = (LPWIN32_FILE_ATTRIBUTE_DATA) lpFileInformation;
1377
1378 rc = OSLibDosGetFileAttributesEx((LPSTR)lpFileName,
1379 fInfoLevelId,
1380 lpFileInformation);
1381 return (rc);
1382 }
1383 else
1384 {
1385 dprintf(("KERNEL32: GetFileAttributesExA - invalid info level %d!\n",
1386 fInfoLevelId));
1387 return FALSE;
1388 }
1389}
1390
1391
1392/*****************************************************************************
1393 * Name : BOOL GetFileAttributesExW
1394 * Purpose :
1395 * Parameters:
1396 * Variables :
1397 * Result :
1398 * Remark : KERNEL32.875
1399 * Status : UNTESTED
1400 *
1401 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1402 *****************************************************************************/
1403
1404BOOL WIN32API GetFileAttributesExW(LPCWSTR lpFileName,
1405 GET_FILEEX_INFO_LEVELS fInfoLevelId,
1406 LPVOID lpFileInformation)
1407{
1408 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFileName );
1409 BOOL res = GetFileAttributesExA( nameA, fInfoLevelId, lpFileInformation);
1410 HeapFree( GetProcessHeap(), 0, nameA );
1411 return res;
1412}
1413
1414//******************************************************************************
1415//******************************************************************************
1416HANDLE WIN32API FindFirstChangeNotificationA(LPCSTR lpPathName,
1417 BOOL bWatchSubtree,
1418 DWORD dwNotifyFilter)
1419{
1420 dprintf(("KERNEL32: FindFirstChangeNotificationA %s, Not implemented (faked)", lpPathName));
1421 return -1;
1422}
1423//******************************************************************************
1424//******************************************************************************
1425BOOL WIN32API FindNextChangeNotification(HANDLE hChange)
1426{
1427 dprintf(("KERNEL32: FindNextChangeNotification (%08xh), Not implemented\n",
1428 hChange));
1429
1430 return FALSE;
1431}
1432//******************************************************************************
1433//******************************************************************************
1434BOOL WIN32API FindCloseChangeNotification(HANDLE hChange)
1435{
1436 dprintf(("KERNEL32: OS2FindNextChangeNotification, Not implemented\n"));
1437
1438 return(TRUE);
1439}
1440/*****************************************************************************
1441 * Name : HANDLE WIN32API FindFirstChangeNotificationW
1442 * Purpose : The FindFirstChangeNotification function creates a change
1443 * notification handle and sets up initial change notification
1444 * filter conditions. A wait on a notification handle succeeds when
1445 * a change matching the filter conditions occurs in the specified
1446 * directory or subtree.
1447 * Parameters: LPCWSTR lpPathName pointer to name of directory to watch
1448 * BOOL bWatchSubtree flag for monitoring directory or
1449 * directory tree
1450 * DWORD dwNotifyFilter filter conditions to watch for
1451 * Variables :
1452 * Result : If the function succeeds, the return value is a handle to a find
1453 * change notification object.
1454 * If the function fails, the return value is INVALID_HANDLE_VALUE
1455 * Remark :
1456 * Status : UNTESTED STUB
1457 *
1458 * Author : Markus Montkowski [Tha, 1998/05/21 20:57]
1459 *****************************************************************************/
1460HANDLE WIN32API FindFirstChangeNotificationW(LPCWSTR lpPathName,
1461 BOOL bWatchSubtree,
1462 DWORD dwNotifyFilter)
1463{
1464 LPSTR lpAsciiPath;
1465 HANDLE hChange;
1466
1467 lpAsciiPath = UnicodeToAsciiString( (LPWSTR) lpPathName);
1468 hChange = FindFirstChangeNotificationA(lpAsciiPath, bWatchSubtree,
1469 dwNotifyFilter );
1470 if (lpAsciiPath) FreeAsciiString(lpAsciiPath);
1471 return hChange;
1472}
1473//******************************************************************************
1474//******************************************************************************
1475BOOL WIN32API DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode,
1476 LPVOID lpInBuffer, DWORD nInBufferSize,
1477 LPVOID lpOutBuffer, DWORD nOutBufferSize,
1478 LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
1479{
1480 return HMDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize,
1481 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
1482}
1483/*****************************************************************************
1484 * Name : BOOL WIN32API CancelIo
1485 * Purpose : The CancelIO function cancels all pending input and output
1486 * (I/O) operations that were issued by the calling thread for
1487 * the specified file handle. The function does not cancel
1488 * I/O operations issued for the file handle by other threads.
1489 * Parameters: HANDLE hFile file handle for which to cancel I/O
1490 * Variables :
1491 * Result : If the function succeeds, the return value is nonzero All pending
1492 * I/O operations issued by the calling thread for the file handle
1493 * were successfully canceled.
1494 * If the function fails, the return value is zero.
1495 * To get extended error information, call GetLastError.
1496 * Remark : If there are any I/O operations in progress for the specified
1497 * file HANDLE and they were issued by the calling thread, the
1498 * CancelIO function cancels them.
1499 * Note that the I/O operations must have been issued as
1500 * overlapped I/O. If they were not, the I/O operations would not
1501 * have returned to allow the thread to call the CancelIO function.
1502 * Calling the CancelIO function with a file handle that was not
1503 * opened with FILE_FLAG_OVERLAPPED does nothing.
1504 * All I/O operations that are canceled will complete with the
1505 * error ERROR_OPERATION_ABORTED. All completion notifications
1506 * for the I/O operations will occur normally.
1507 * Status :
1508 *
1509 * Author : Markus Montkowski [Thu, 1998/05/19 11:46]
1510 *****************************************************************************/
1511BOOL WIN32API CancelIo(HANDLE hFile)
1512{
1513 return HMCancelIo(hFile);
1514}
1515/*****************************************************************************
1516 * Name : BOOL GetOverlappedResult
1517 * Purpose : forward call to Open32
1518 * Parameters:
1519 * Variables :
1520 * Result :
1521 * Remark : handle translation is done in GetOverlappedResult
1522 * Status :
1523 *
1524 * Author : Patrick Haller [Fri, 1999/06/18 03:44]
1525 *****************************************************************************/
1526
1527BOOL WIN32API GetOverlappedResult(HANDLE hFile, /* [in] handle of file to check on */
1528 LPOVERLAPPED lpOverlapped, /* [in/out] pointer to overlapped */
1529 LPDWORD lpTransferred, /* [in/out] number of bytes transferred */
1530 BOOL bWait) /* [in] wait for the transfer to complete ? */
1531{
1532 //NOTE: According to the SDK docs lpOverlapped->hEvent can be 0. This function
1533 // is supposed to wait on the file handle in that case. We don't support
1534 // this, so we just fail.
1535 if(lpOverlapped == NULL || lpOverlapped->hEvent == 0) {
1536 dprintf(("!ERROR!: lpOverlapped == NULL || lpOverlapped->hEvent == 0"));
1537 SetLastError(ERROR_INVALID_PARAMETER);
1538 return FALSE;
1539 }
1540
1541 return HMGetOverlappedResult(hFile,
1542 lpOverlapped,
1543 lpTransferred,
1544 bWait);
1545}
1546//******************************************************************************
1547//******************************************************************************
Note: See TracBrowser for help on using the repository browser.