2 * File handling functions
4 * Copyright 1993 John Burton
5 * Copyright 1996 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 * Fix the CopyFileEx methods to implement the "extended" functionality.
23 * Right now, they simply call the CopyFile method.
27 #include "wine/port.h"
37 #include "wine/winbase16.h"
38 #include "kernel16_private.h"
39 #include "wine/unicode.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(file
);
44 #define DOS_TABLE_SIZE 256
46 static HANDLE dos_handles
[DOS_TABLE_SIZE
];
48 /***********************************************************************
49 * FILE_InitProcessDosHandles
51 * Allocates the default DOS handles for a process. Called either by
52 * Win32HandleToDosFileHandle below or by the DOSVM stuff.
54 static void FILE_InitProcessDosHandles( void )
56 HANDLE hStdInput
, hStdOutput
, hStdError
, hNull
;
57 static BOOL init_done
/* = FALSE */;
58 HANDLE cp
= GetCurrentProcess();
60 if (init_done
) return;
62 hStdInput
= GetStdHandle(STD_INPUT_HANDLE
);
63 hStdOutput
= GetStdHandle(STD_OUTPUT_HANDLE
);
64 hStdError
= GetStdHandle(STD_ERROR_HANDLE
);
65 hNull
= CreateFileA("NUL", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
66 /* Invalid console handles need to translate to real DOS handles in a new process */
67 if (!hStdInput
) hStdInput
= hNull
;
68 if (!hStdOutput
) hStdOutput
= hNull
;
69 if (!hStdError
) hStdError
= hNull
;
70 DuplicateHandle(cp
, hStdInput
, cp
, &dos_handles
[0], 0, TRUE
, DUPLICATE_SAME_ACCESS
);
71 DuplicateHandle(cp
, hStdOutput
, cp
, &dos_handles
[1], 0, TRUE
, DUPLICATE_SAME_ACCESS
);
72 DuplicateHandle(cp
, hStdError
, cp
, &dos_handles
[2], 0, TRUE
, DUPLICATE_SAME_ACCESS
);
73 DuplicateHandle(cp
, hStdError
, cp
, &dos_handles
[3], 0, TRUE
, DUPLICATE_SAME_ACCESS
);
74 DuplicateHandle(cp
, hStdError
, cp
, &dos_handles
[4], 0, TRUE
, DUPLICATE_SAME_ACCESS
);
78 /***********************************************************************
79 * DosFileHandleToWin32Handle (KERNEL32.20)
81 * Return the Win32 handle for a DOS handle.
83 * Note: this is not exactly right, since on Win95 the Win32 handles
84 * are on top of DOS handles and we do it the other way
85 * around. Should be good enough though.
87 HANDLE WINAPI
DosFileHandleToWin32Handle( HFILE handle
)
89 HFILE16 hfile
= (HFILE16
)handle
;
90 if (hfile
< 5) FILE_InitProcessDosHandles();
91 if ((hfile
>= DOS_TABLE_SIZE
) || !dos_handles
[hfile
])
93 SetLastError( ERROR_INVALID_HANDLE
);
94 return INVALID_HANDLE_VALUE
;
96 return dos_handles
[hfile
];
99 /***********************************************************************
100 * Win32HandleToDosFileHandle (KERNEL32.21)
102 * Allocate a DOS handle for a Win32 handle. The Win32 handle is no
103 * longer valid after this function (even on failure).
105 * Note: this is not exactly right, since on Win95 the Win32 handles
106 * are on top of DOS handles and we do it the other way
107 * around. Should be good enough though.
109 HFILE WINAPI
Win32HandleToDosFileHandle( HANDLE handle
)
113 if (!handle
|| (handle
== INVALID_HANDLE_VALUE
))
116 FILE_InitProcessDosHandles();
117 for (i
= 0; i
< DOS_TABLE_SIZE
; i
++)
120 dos_handles
[i
] = handle
;
121 TRACE("Got %d for h32 %p\n", i
, handle
);
124 CloseHandle( handle
);
125 SetLastError( ERROR_TOO_MANY_OPEN_FILES
);
129 /***********************************************************************
130 * DisposeLZ32Handle (KERNEL32.22)
132 * Note: this is not entirely correct, we should only close the
133 * 32-bit handle and not the 16-bit one, but we cannot do
134 * this because of the way our DOS handles are implemented.
135 * It shouldn't break anything though.
137 void WINAPI
DisposeLZ32Handle( HANDLE handle
)
141 if (!handle
|| (handle
== INVALID_HANDLE_VALUE
)) return;
143 for (i
= 5; i
< DOS_TABLE_SIZE
; i
++)
144 if (dos_handles
[i
] == handle
)
147 CloseHandle( handle
);
152 /***********************************************************************
153 * GetProfileInt (KERNEL.57)
155 UINT16 WINAPI
GetProfileInt16( LPCSTR section
, LPCSTR entry
, INT16 def_val
)
157 return GetPrivateProfileInt16( section
, entry
, def_val
, "win.ini" );
161 /***********************************************************************
162 * GetProfileString (KERNEL.58)
164 INT16 WINAPI
GetProfileString16( LPCSTR section
, LPCSTR entry
, LPCSTR def_val
,
165 LPSTR buffer
, UINT16 len
)
167 return GetPrivateProfileString16( section
, entry
, def_val
,
168 buffer
, len
, "win.ini" );
172 /***********************************************************************
173 * WriteProfileString (KERNEL.59)
175 BOOL16 WINAPI
WriteProfileString16( LPCSTR section
, LPCSTR entry
,
178 return WritePrivateProfileString16( section
, entry
, string
, "win.ini" );
182 /* get the search path for the current module; helper for OpenFile16 */
183 static char *get_search_path(void)
186 char *ret
, *p
, module
[OFS_MAXPATHNAME
];
189 if (GetCurrentTask() && GetModuleFileName16( GetCurrentTask(), module
, sizeof(module
) ))
191 if (!(p
= strrchr( module
, '\\' ))) p
= module
;
195 len
= (2 + /* search order: first current dir */
196 GetSystemDirectory16( NULL
, 0 ) + 1 + /* then system dir */
197 GetWindowsDirectoryA( NULL
, 0 ) + 1 + /* then windows dir */
198 strlen( module
) + 1 + /* then module path */
199 GetEnvironmentVariableA( "PATH", NULL
, 0 ) + 1); /* then look in PATH */
200 if (!(ret
= HeapAlloc( GetProcessHeap(), 0, len
))) return NULL
;
203 GetSystemDirectory16( p
, ret
+ len
- p
);
206 GetWindowsDirectoryA( p
, ret
+ len
- p
);
215 GetEnvironmentVariableA( "PATH", p
, ret
+ len
- p
);
219 /***********************************************************************
220 * OpenFile (KERNEL.74)
221 * OpenFileEx (KERNEL.360)
223 HFILE16 WINAPI
OpenFile16( LPCSTR name
, OFSTRUCT
*ofs
, UINT16 mode
)
228 WORD filedatetime
[2];
229 const char *p
, *filename
;
231 if (!ofs
) return HFILE_ERROR
;
233 TRACE("%s %s %s %s%s%s%s%s%s%s%s%s\n",debugstr_a(name
),
234 ((mode
& 0x3 )==OF_READ
)?"OF_READ":
235 ((mode
& 0x3 )==OF_WRITE
)?"OF_WRITE":
236 ((mode
& 0x3 )==OF_READWRITE
)?"OF_READWRITE":"unknown",
237 ((mode
& 0x70 )==OF_SHARE_COMPAT
)?"OF_SHARE_COMPAT":
238 ((mode
& 0x70 )==OF_SHARE_DENY_NONE
)?"OF_SHARE_DENY_NONE":
239 ((mode
& 0x70 )==OF_SHARE_DENY_READ
)?"OF_SHARE_DENY_READ":
240 ((mode
& 0x70 )==OF_SHARE_DENY_WRITE
)?"OF_SHARE_DENY_WRITE":
241 ((mode
& 0x70 )==OF_SHARE_EXCLUSIVE
)?"OF_SHARE_EXCLUSIVE":"unknown",
242 ((mode
& OF_PARSE
)==OF_PARSE
)?"OF_PARSE ":"",
243 ((mode
& OF_DELETE
)==OF_DELETE
)?"OF_DELETE ":"",
244 ((mode
& OF_VERIFY
)==OF_VERIFY
)?"OF_VERIFY ":"",
245 ((mode
& OF_SEARCH
)==OF_SEARCH
)?"OF_SEARCH ":"",
246 ((mode
& OF_CANCEL
)==OF_CANCEL
)?"OF_CANCEL ":"",
247 ((mode
& OF_CREATE
)==OF_CREATE
)?"OF_CREATE ":"",
248 ((mode
& OF_PROMPT
)==OF_PROMPT
)?"OF_PROMPT ":"",
249 ((mode
& OF_EXIST
)==OF_EXIST
)?"OF_EXIST ":"",
250 ((mode
& OF_REOPEN
)==OF_REOPEN
)?"OF_REOPEN ":""
255 OpenFile( name
, ofs
, mode
);
259 if (mode
& OF_CREATE
)
261 handle
= (HANDLE
)OpenFile( name
, ofs
, mode
);
262 if (handle
== (HANDLE
)HFILE_ERROR
) goto error
;
266 ofs
->cBytes
= sizeof(OFSTRUCT
);
268 if (mode
& OF_REOPEN
) name
= ofs
->szPathName
;
270 if (!name
) return HFILE_ERROR
;
272 /* the watcom 10.6 IDE relies on a valid path returned in ofs->szPathName
273 Are there any cases where getting the path here is wrong?
274 Uwe Bonnes 1997 Apr 2 */
275 if (!GetFullPathNameA( name
, sizeof(ofs
->szPathName
), ofs
->szPathName
, NULL
)) goto error
;
277 /* If OF_SEARCH is set, ignore the given path */
280 if ((mode
& OF_SEARCH
) && !(mode
& OF_REOPEN
))
282 /* First try the file name as is */
283 if (GetFileAttributesA( filename
) != INVALID_FILE_ATTRIBUTES
) filename
= NULL
;
286 /* Now remove the path */
287 if (filename
[0] && (filename
[1] == ':')) filename
+= 2;
288 if ((p
= strrchr( filename
, '\\' ))) filename
= p
+ 1;
289 if ((p
= strrchr( filename
, '/' ))) filename
= p
+ 1;
292 SetLastError( ERROR_FILE_NOT_FOUND
);
298 /* Now look for the file */
303 char *path
= get_search_path();
305 if (!path
) goto error
;
306 found
= SearchPathA( path
, filename
, NULL
, sizeof(ofs
->szPathName
),
307 ofs
->szPathName
, NULL
);
308 HeapFree( GetProcessHeap(), 0, path
);
309 if (!found
) goto error
;
312 TRACE("found %s\n", debugstr_a(ofs
->szPathName
) );
314 if (mode
& OF_DELETE
)
316 if (!DeleteFileA( ofs
->szPathName
)) goto error
;
317 TRACE("(%s): OF_DELETE return = OK\n", name
);
321 handle
= (HANDLE
)_lopen( ofs
->szPathName
, mode
);
322 if (handle
== INVALID_HANDLE_VALUE
) goto error
;
324 GetFileTime( handle
, NULL
, NULL
, &filetime
);
325 FileTimeToDosDateTime( &filetime
, &filedatetime
[0], &filedatetime
[1] );
326 if ((mode
& OF_VERIFY
) && (mode
& OF_REOPEN
))
328 if (ofs
->Reserved1
!= filedatetime
[0] || ofs
->Reserved2
!= filedatetime
[1] )
330 CloseHandle( handle
);
331 WARN("(%s): OF_VERIFY failed\n", name
);
332 /* FIXME: what error here? */
333 SetLastError( ERROR_FILE_NOT_FOUND
);
337 ofs
->Reserved1
= filedatetime
[0];
338 ofs
->Reserved2
= filedatetime
[1];
341 TRACE("(%s): OK, return = %p\n", name
, handle
);
342 hFileRet
= Win32HandleToDosFileHandle( handle
);
343 if (hFileRet
== HFILE_ERROR16
) goto error
;
344 if (mode
& OF_EXIST
) _lclose16( hFileRet
); /* Return the handle, but close it first */
347 error
: /* We get here if there was an error opening the file */
348 ofs
->nErrCode
= GetLastError();
349 WARN("(%s): return = HFILE_ERROR error= %d\n", name
,ofs
->nErrCode
);
350 return HFILE_ERROR16
;
354 /***********************************************************************
355 * _lclose (KERNEL.81)
357 HFILE16 WINAPI
_lclose16( HFILE16 hFile
)
359 if ((hFile
>= DOS_TABLE_SIZE
) || !dos_handles
[hFile
])
361 SetLastError( ERROR_INVALID_HANDLE
);
362 return HFILE_ERROR16
;
364 TRACE("%d (handle32=%p)\n", hFile
, dos_handles
[hFile
] );
365 CloseHandle( dos_handles
[hFile
] );
366 dos_handles
[hFile
] = 0;
370 /***********************************************************************
371 * _lcreat (KERNEL.83)
373 HFILE16 WINAPI
_lcreat16( LPCSTR path
, INT16 attr
)
375 return Win32HandleToDosFileHandle( (HANDLE
)_lcreat( path
, attr
) );
378 /***********************************************************************
379 * _llseek (KERNEL.84)
382 * Seeking before the start of the file should be allowed for _llseek16,
383 * but cause subsequent I/O operations to fail (cf. interrupt list)
386 LONG WINAPI
_llseek16( HFILE16 hFile
, LONG lOffset
, INT16 nOrigin
)
388 return SetFilePointer( DosFileHandleToWin32Handle(hFile
), lOffset
, NULL
, nOrigin
);
392 /***********************************************************************
395 HFILE16 WINAPI
_lopen16( LPCSTR path
, INT16 mode
)
397 return Win32HandleToDosFileHandle( (HANDLE
)_lopen( path
, mode
) );
401 /***********************************************************************
402 * _lread16 (internal)
404 UINT16 WINAPI
_lread16( HFILE16 hFile
, LPVOID buffer
, UINT16 count
)
406 return (UINT16
)_lread((HFILE
)DosFileHandleToWin32Handle(hFile
), buffer
, (LONG
)count
);
410 /***********************************************************************
411 * _lwrite (KERNEL.86)
413 UINT16 WINAPI
_lwrite16( HFILE16 hFile
, LPCSTR buffer
, UINT16 count
)
415 return (UINT16
)_hwrite( (HFILE
)DosFileHandleToWin32Handle(hFile
), buffer
, (LONG
)count
);
418 /***********************************************************************
419 * _hread (KERNEL.349)
421 LONG WINAPI
WIN16_hread( HFILE16 hFile
, SEGPTR buffer
, LONG count
)
425 TRACE("%d %08x %d\n", hFile
, (DWORD
)buffer
, count
);
427 /* Some programs pass a count larger than the allocated buffer */
428 maxlen
= GetSelectorLimit16( SELECTOROF(buffer
) ) - OFFSETOF(buffer
) + 1;
429 if (count
> maxlen
) count
= maxlen
;
430 return _lread((HFILE
)DosFileHandleToWin32Handle(hFile
), MapSL(buffer
), count
);
434 /***********************************************************************
437 UINT16 WINAPI
WIN16_lread( HFILE16 hFile
, SEGPTR buffer
, UINT16 count
)
439 return (UINT16
)WIN16_hread( hFile
, buffer
, (LONG
)count
);
443 /***********************************************************************
444 * _hwrite (KERNEL.350)
446 LONG WINAPI
_hwrite16( HFILE16 hFile
, LPCSTR buffer
, LONG count
)
448 return _hwrite( (HFILE
)DosFileHandleToWin32Handle(hFile
), buffer
, count
);
452 /***********************************************************************
453 * GetTempDrive (KERNEL.92)
454 * A closer look at krnl386.exe shows what the SDK doesn't mention:
458 * AH: ':' - yes, some kernel code even does stosw with
462 UINT WINAPI
GetTempDrive( BYTE ignored
)
464 WCHAR buffer
[MAX_PATH
];
467 if (GetTempPathW( MAX_PATH
, buffer
)) ret
= (BYTE
)toupperW(buffer
[0]);
469 return MAKELONG( ret
| (':' << 8), 1 );
473 /***********************************************************************
474 * GetTempFileName (KERNEL.97)
476 UINT16 WINAPI
GetTempFileName16( BYTE drive
, LPCSTR prefix
, UINT16 unique
,
479 char temppath
[MAX_PATH
];
480 char *prefix16
= NULL
;
483 if (!(drive
& ~TF_FORCEDRIVE
)) /* drive 0 means current default drive */
485 GetCurrentDirectoryA(sizeof(temppath
), temppath
);
486 drive
|= temppath
[0];
489 if (drive
& TF_FORCEDRIVE
)
493 d
[0] = drive
& ~TF_FORCEDRIVE
;
496 if (GetDriveTypeA(d
) == DRIVE_NO_ROOT_DIR
)
498 drive
&= ~TF_FORCEDRIVE
;
499 WARN("invalid drive %d specified\n", drive
);
503 if (drive
& TF_FORCEDRIVE
)
504 sprintf(temppath
,"%c:", drive
& ~TF_FORCEDRIVE
);
506 GetTempPathA( MAX_PATH
, temppath
);
510 prefix16
= HeapAlloc(GetProcessHeap(), 0, strlen(prefix
) + 2);
512 strcpy(prefix16
+ 1, prefix
);
515 ret
= GetTempFileNameA( temppath
, prefix16
, unique
, buffer
);
517 HeapFree(GetProcessHeap(), 0, prefix16
);
522 /***********************************************************************
523 * GetPrivateProfileInt (KERNEL.127)
525 UINT16 WINAPI
GetPrivateProfileInt16( LPCSTR section
, LPCSTR entry
,
526 INT16 def_val
, LPCSTR filename
)
528 /* we used to have some elaborate return value limitation (<= -32768 etc.)
529 * here, but Win98SE doesn't care about this at all, so I deleted it.
530 * AFAIR versions prior to Win9x had these limits, though. */
531 return (INT16
)GetPrivateProfileIntA(section
,entry
,def_val
,filename
);
535 /***********************************************************************
536 * GetPrivateProfileString (KERNEL.128)
538 INT16 WINAPI
GetPrivateProfileString16( LPCSTR section
, LPCSTR entry
,
539 LPCSTR def_val
, LPSTR buffer
,
540 UINT16 len
, LPCSTR filename
)
542 TRACE("(%s, %s, %s, %p, %u, %s)\n", debugstr_a(section
), debugstr_a(entry
),
543 debugstr_a(def_val
), buffer
, len
, debugstr_a(filename
));
547 if (buffer
&& len
) buffer
[0] = 0;
552 /* We have to return the list of keys in the section but without the values
553 * so we need to massage the results of GetPrivateProfileSectionA.
555 UINT ret
, oldlen
= len
, size
= min( len
, 1024 );
560 if (!(data
= HeapAlloc(GetProcessHeap(), 0, size
))) return 0;
561 ret
= GetPrivateProfileSectionA( section
, data
, size
, filename
);
564 HeapFree( GetProcessHeap(), 0, data
);
565 return GetPrivateProfileStringA( section
, entry
, def_val
, buffer
, len
, filename
);
567 if (ret
!= size
- 2) break;
568 /* overflow, try again */
570 HeapFree( GetProcessHeap(), 0, data
);
576 char *p
= strchr( src
, '=' );
578 /* A valid entry is formed by name = value */
581 src
+= strlen(src
) + 1;
586 memcpy( buffer
, src
, p
- src
);
589 len
-= (p
- src
) + 1;
590 src
+= strlen(src
) + 1;
594 memcpy( buffer
, src
, len
);
599 HeapFree( GetProcessHeap(), 0, data
);
614 return GetPrivateProfileStringA( section
, entry
, def_val
, buffer
, len
, filename
);
618 /***********************************************************************
619 * WritePrivateProfileString (KERNEL.129)
621 BOOL16 WINAPI
WritePrivateProfileString16( LPCSTR section
, LPCSTR entry
,
622 LPCSTR string
, LPCSTR filename
)
624 return WritePrivateProfileStringA(section
,entry
,string
,filename
);
628 /***********************************************************************
629 * GetWindowsDirectory (KERNEL.134)
631 UINT16 WINAPI
GetWindowsDirectory16( LPSTR path
, UINT16 count
)
633 return GetWindowsDirectoryA( path
, count
);
637 /***********************************************************************
638 * GetSystemDirectory (KERNEL.135)
640 UINT16 WINAPI
GetSystemDirectory16( LPSTR path
, UINT16 count
)
642 static const char system16
[] = "\\SYSTEM";
643 char windir
[MAX_PATH
];
646 len
= GetWindowsDirectory16(windir
, sizeof(windir
) - sizeof(system16
) + 1) + sizeof(system16
);
649 lstrcpyA(path
, windir
);
650 lstrcatA(path
, system16
);
651 len
--; /* space for the terminating zero is not included on success */
657 /***********************************************************************
658 * GetDriveType (KERNEL.136)
659 * Get the type of a drive in Win16.
662 * The type of the Drive. For a list see GetDriveTypeW from kernel32.
665 * Note that it returns DRIVE_REMOTE for CD-ROMs, since MSCDEX uses the
666 * remote drive API. The return value DRIVE_REMOTE for CD-ROMs has been
667 * verified on Win 3.11 and Windows 95. Some programs rely on it, so don't
668 * do any pseudo-clever changes.
670 UINT16 WINAPI
GetDriveType16( UINT16 drive
) /* [in] number (NOT letter) of drive */
675 root
[0] = 'A' + drive
;
678 type
= GetDriveTypeW( root
);
679 if (type
== DRIVE_CDROM
) type
= DRIVE_REMOTE
;
680 else if (type
== DRIVE_NO_ROOT_DIR
) type
= DRIVE_UNKNOWN
;
685 /***********************************************************************
686 * GetProfileSectionNames (KERNEL.142)
688 WORD WINAPI
GetProfileSectionNames16(LPSTR buffer
, WORD size
)
691 return GetPrivateProfileSectionNamesA(buffer
,size
,"win.ini");
695 /***********************************************************************
696 * GetPrivateProfileSectionNames (KERNEL.143)
698 WORD WINAPI
GetPrivateProfileSectionNames16( LPSTR buffer
, WORD size
,
701 return GetPrivateProfileSectionNamesA(buffer
,size
,filename
);
705 /***********************************************************************
706 * CreateDirectory (KERNEL.144)
708 BOOL16 WINAPI
CreateDirectory16( LPCSTR path
, LPVOID dummy
)
710 return CreateDirectoryA( path
, NULL
);
714 /***********************************************************************
715 * RemoveDirectory (KERNEL.145)
717 BOOL16 WINAPI
RemoveDirectory16( LPCSTR path
)
719 return RemoveDirectoryA( path
);
723 /***********************************************************************
724 * DeleteFile (KERNEL.146)
726 BOOL16 WINAPI
DeleteFile16( LPCSTR path
)
728 return DeleteFileA( path
);
732 /***********************************************************************
733 * SetHandleCount (KERNEL.199)
735 UINT16 WINAPI
SetHandleCount16( UINT16 count
)
737 return SetHandleCount( count
);
741 /***********************************************************************
742 * GetShortPathName (KERNEL.274)
744 WORD WINAPI
GetShortPathName16( LPCSTR longpath
, LPSTR shortpath
, WORD len
)
746 return GetShortPathNameA( longpath
, shortpath
, len
);
750 /***********************************************************************
751 * WriteOutProfiles (KERNEL.315)
753 void WINAPI
WriteOutProfiles16(void)
755 WritePrivateProfileSectionW( NULL
, NULL
, NULL
);
759 /***********************************************************************
760 * WritePrivateProfileStruct (KERNEL.406)
762 BOOL16 WINAPI
WritePrivateProfileStruct16 (LPCSTR section
, LPCSTR key
,
763 LPVOID buf
, UINT16 bufsize
, LPCSTR filename
)
765 return WritePrivateProfileStructA( section
, key
, buf
, bufsize
, filename
);
769 /***********************************************************************
770 * GetPrivateProfileStruct (KERNEL.407)
772 BOOL16 WINAPI
GetPrivateProfileStruct16(LPCSTR section
, LPCSTR key
,
773 LPVOID buf
, UINT16 len
, LPCSTR filename
)
775 return GetPrivateProfileStructA( section
, key
, buf
, len
, filename
);
779 /***********************************************************************
780 * GetCurrentDirectory (KERNEL.411)
782 UINT16 WINAPI
GetCurrentDirectory16( UINT16 buflen
, LPSTR buf
)
784 return GetCurrentDirectoryA( buflen
, buf
);
788 /***********************************************************************
789 * SetCurrentDirectory (KERNEL.412)
791 BOOL16 WINAPI
SetCurrentDirectory16( LPCSTR dir
)
793 char fulldir
[MAX_PATH
];
795 if (!GetFullPathNameA( dir
, MAX_PATH
, fulldir
, NULL
)) return FALSE
;
797 if (!SetCurrentDirectoryA( dir
)) return FALSE
;
799 if (fulldir
[0] && fulldir
[1] == ':')
801 TDB
*pTask
= GlobalLock16( GetCurrentTask() );
802 char env_var
[4] = "=A:";
804 env_var
[1] = fulldir
[0];
805 SetEnvironmentVariableA( env_var
, fulldir
);
807 /* update the directory in the TDB */
810 pTask
->curdrive
= 0x80 | (fulldir
[0] - 'A');
811 GetShortPathNameA( fulldir
+ 2, pTask
->curdir
, sizeof(pTask
->curdir
) );
818 /*************************************************************************
819 * FindFirstFile (KERNEL.413)
821 HANDLE16 WINAPI
FindFirstFile16( LPCSTR path
, WIN32_FIND_DATAA
*data
)
826 if (!(h16
= GlobalAlloc16( GMEM_MOVEABLE
, sizeof(handle
) ))) return INVALID_HANDLE_VALUE16
;
827 ptr
= GlobalLock16( h16
);
828 *ptr
= handle
= FindFirstFileA( path
, data
);
829 GlobalUnlock16( h16
);
831 if (handle
== INVALID_HANDLE_VALUE
)
834 h16
= INVALID_HANDLE_VALUE16
;
840 /*************************************************************************
841 * FindNextFile (KERNEL.414)
843 BOOL16 WINAPI
FindNextFile16( HANDLE16 handle
, WIN32_FIND_DATAA
*data
)
848 if ((handle
== INVALID_HANDLE_VALUE16
) || !(ptr
= GlobalLock16( handle
)))
850 SetLastError( ERROR_INVALID_HANDLE
);
853 ret
= FindNextFileA( *ptr
, data
);
854 GlobalUnlock16( handle
);
859 /*************************************************************************
860 * FindClose (KERNEL.415)
862 BOOL16 WINAPI
FindClose16( HANDLE16 handle
)
866 if ((handle
== INVALID_HANDLE_VALUE16
) || !(ptr
= GlobalLock16( handle
)))
868 SetLastError( ERROR_INVALID_HANDLE
);
872 GlobalUnlock16( handle
);
873 GlobalFree16( handle
);
878 /***********************************************************************
879 * WritePrivateProfileSection (KERNEL.416)
881 BOOL16 WINAPI
WritePrivateProfileSection16( LPCSTR section
,
882 LPCSTR string
, LPCSTR filename
)
884 return WritePrivateProfileSectionA( section
, string
, filename
);
888 /***********************************************************************
889 * WriteProfileSection (KERNEL.417)
891 BOOL16 WINAPI
WriteProfileSection16( LPCSTR section
, LPCSTR keys_n_values
)
893 return WritePrivateProfileSection16( section
, keys_n_values
, "win.ini");
897 /***********************************************************************
898 * GetPrivateProfileSection (KERNEL.418)
900 INT16 WINAPI
GetPrivateProfileSection16( LPCSTR section
, LPSTR buffer
,
901 UINT16 len
, LPCSTR filename
)
903 return GetPrivateProfileSectionA( section
, buffer
, len
, filename
);
907 /***********************************************************************
908 * GetProfileSection (KERNEL.419)
910 INT16 WINAPI
GetProfileSection16( LPCSTR section
, LPSTR buffer
, UINT16 len
)
912 return GetPrivateProfileSection16( section
, buffer
, len
, "win.ini" );
916 /**************************************************************************
917 * GetFileAttributes (KERNEL.420)
919 DWORD WINAPI
GetFileAttributes16( LPCSTR name
)
921 return GetFileAttributesA( name
);
925 /**************************************************************************
926 * SetFileAttributes (KERNEL.421)
928 BOOL16 WINAPI
SetFileAttributes16( LPCSTR lpFileName
, DWORD attributes
)
930 return SetFileAttributesA( lpFileName
, attributes
);
934 /***********************************************************************
935 * GetDiskFreeSpace (KERNEL.422)
937 BOOL16 WINAPI
GetDiskFreeSpace16( LPCSTR root
, LPDWORD cluster_sectors
,
938 LPDWORD sector_bytes
, LPDWORD free_clusters
,
939 LPDWORD total_clusters
)
941 return GetDiskFreeSpaceA( root
, cluster_sectors
, sector_bytes
,
942 free_clusters
, total_clusters
);
945 /***********************************************************************
946 * FileCDR (KERNEL.130)
948 FARPROC16 WINAPI
FileCDR16(FARPROC16 x
)
950 FIXME("(%p): stub\n", x
);
951 return (FARPROC16
)TRUE
;