Added wine_ldt_is_system() to replace the IS_SELECTOR_SYSTEM macro,
[wine] / dlls / kernel / file16.c
1 /*
2  * File handling functions
3  *
4  * Copyright 1993 John Burton
5  * Copyright 1996 Alexandre Julliard
6  *
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.
11  *
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.
16  *
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * TODO:
22  *    Fix the CopyFileEx methods to implement the "extended" functionality.
23  *    Right now, they simply call the CopyFile method.
24  */
25
26 #include "config.h"
27 #include "wine/port.h"
28
29 #include <stdarg.h>
30 #include <stdio.h>
31 #include <assert.h>
32
33 #define NONAMELESSUNION
34 #define NONAMELESSSTRUCT
35 #include "winerror.h"
36 #include "windef.h"
37 #include "winbase.h"
38 #include "winreg.h"
39 #include "winternl.h"
40 #include "wine/winbase16.h"
41 #include "wine/server.h"
42 #include "kernel_private.h"
43 #include "wine/unicode.h"
44 #include "wine/debug.h"
45
46 WINE_DEFAULT_DEBUG_CHANNEL(file);
47
48 /***********************************************************************
49  *           _hread16   (KERNEL.349)
50  */
51 LONG WINAPI _hread16( HFILE16 hFile, LPVOID buffer, LONG count)
52 {
53     return _lread( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, count );
54 }
55
56
57 /***********************************************************************
58  *           _hwrite   (KERNEL.350)
59  */
60 LONG WINAPI _hwrite16( HFILE16 hFile, LPCSTR buffer, LONG count )
61 {
62     return _hwrite( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, count );
63 }
64
65
66 /***********************************************************************
67  *           _lcreat   (KERNEL.83)
68  */
69 HFILE16 WINAPI _lcreat16( LPCSTR path, INT16 attr )
70 {
71     return Win32HandleToDosFileHandle( (HANDLE)_lcreat( path, attr ) );
72 }
73
74 /***********************************************************************
75  *           _llseek   (KERNEL.84)
76  *
77  * FIXME:
78  *   Seeking before the start of the file should be allowed for _llseek16,
79  *   but cause subsequent I/O operations to fail (cf. interrupt list)
80  *
81  */
82 LONG WINAPI _llseek16( HFILE16 hFile, LONG lOffset, INT16 nOrigin )
83 {
84     return SetFilePointer( DosFileHandleToWin32Handle(hFile), lOffset, NULL, nOrigin );
85 }
86
87
88 /***********************************************************************
89  *           _lopen   (KERNEL.85)
90  */
91 HFILE16 WINAPI _lopen16( LPCSTR path, INT16 mode )
92 {
93     return Win32HandleToDosFileHandle( (HANDLE)_lopen( path, mode ) );
94 }
95
96
97 /***********************************************************************
98  *           _lread16   (KERNEL.82)
99  */
100 UINT16 WINAPI _lread16( HFILE16 hFile, LPVOID buffer, UINT16 count )
101 {
102     return (UINT16)_lread((HFILE)DosFileHandleToWin32Handle(hFile), buffer, (LONG)count );
103 }
104
105
106 /***********************************************************************
107  *           _lwrite   (KERNEL.86)
108  */
109 UINT16 WINAPI _lwrite16( HFILE16 hFile, LPCSTR buffer, UINT16 count )
110 {
111     return (UINT16)_hwrite( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, (LONG)count );
112 }
113
114 /***********************************************************************
115  *           _hread (KERNEL.349)
116  */
117 LONG WINAPI WIN16_hread( HFILE16 hFile, SEGPTR buffer, LONG count )
118 {
119     LONG maxlen;
120
121     TRACE("%d %08lx %ld\n", hFile, (DWORD)buffer, count );
122
123     /* Some programs pass a count larger than the allocated buffer */
124     maxlen = GetSelectorLimit16( SELECTOROF(buffer) ) - OFFSETOF(buffer) + 1;
125     if (count > maxlen) count = maxlen;
126     return _lread((HFILE)DosFileHandleToWin32Handle(hFile), MapSL(buffer), count );
127 }
128
129
130 /***********************************************************************
131  *           _lread (KERNEL.82)
132  */
133 UINT16 WINAPI WIN16_lread( HFILE16 hFile, SEGPTR buffer, UINT16 count )
134 {
135     return (UINT16)WIN16_hread( hFile, buffer, (LONG)count );
136 }
137
138
139 /***********************************************************************
140  *           DeleteFile   (KERNEL.146)
141  */
142 BOOL16 WINAPI DeleteFile16( LPCSTR path )
143 {
144     return DeleteFileA( path );
145 }
146
147 /**************************************************************************
148  *           GetFileAttributes   (KERNEL.420)
149  */
150 DWORD WINAPI GetFileAttributes16( LPCSTR name )
151 {
152     return GetFileAttributesA( name );
153 }
154
155
156 /***********************************************************************
157  *           GetTempFileName   (KERNEL.97)
158  */
159 UINT16 WINAPI GetTempFileName16( BYTE drive, LPCSTR prefix, UINT16 unique,
160                                  LPSTR buffer )
161 {
162     char temppath[MAX_PATH];
163     char *prefix16 = NULL;
164     UINT16 ret;
165
166     if (!(drive & ~TF_FORCEDRIVE)) /* drive 0 means current default drive */
167     {
168         GetCurrentDirectoryA(sizeof(temppath), temppath); 
169         drive |= temppath[0];
170     }
171
172     if (drive & TF_FORCEDRIVE)
173     {
174         char    d[3];
175
176         d[0] = drive & ~TF_FORCEDRIVE;
177         d[1] = ':';
178         d[2] = '\0';
179         if (GetDriveTypeA(d) == DRIVE_NO_ROOT_DIR)
180         {
181             drive &= ~TF_FORCEDRIVE;
182             WARN("invalid drive %d specified\n", drive );
183         }
184     }
185
186     if (drive & TF_FORCEDRIVE)
187         sprintf(temppath,"%c:", drive & ~TF_FORCEDRIVE );
188     else
189         GetTempPathA( MAX_PATH, temppath );
190
191     if (prefix)
192     {
193         prefix16 = HeapAlloc(GetProcessHeap(), 0, strlen(prefix) + 2);
194         *prefix16 = '~';
195         strcpy(prefix16 + 1, prefix);
196     }
197
198     ret = GetTempFileNameA( temppath, prefix16, unique, buffer );
199
200     if (prefix16) HeapFree(GetProcessHeap(), 0, prefix16);
201     return ret;
202 }
203
204 /**************************************************************************
205  *              SetFileAttributes       (KERNEL.421)
206  */
207 BOOL16 WINAPI SetFileAttributes16( LPCSTR lpFileName, DWORD attributes )
208 {
209     return SetFileAttributesA( lpFileName, attributes );
210 }
211
212
213 /***********************************************************************
214  *           SetHandleCount   (KERNEL.199)
215  */
216 UINT16 WINAPI SetHandleCount16( UINT16 count )
217 {
218     return SetHandleCount( count );
219 }
220
221
222 /*************************************************************************
223  *           FindFirstFile   (KERNEL.413)
224  */
225 HANDLE16 WINAPI FindFirstFile16( LPCSTR path, WIN32_FIND_DATAA *data )
226 {
227     HGLOBAL16 h16;
228     HANDLE handle, *ptr;
229
230     if (!(h16 = GlobalAlloc16( GMEM_MOVEABLE, sizeof(handle) ))) return INVALID_HANDLE_VALUE16;
231     ptr = GlobalLock16( h16 );
232     *ptr = handle = FindFirstFileA( path, data );
233     GlobalUnlock16( h16 );
234
235     if (handle == INVALID_HANDLE_VALUE)
236     {
237         GlobalFree16( h16 );
238         h16 = INVALID_HANDLE_VALUE16;
239     }
240     return h16;
241 }
242
243
244 /*************************************************************************
245  *           FindNextFile   (KERNEL.414)
246  */
247 BOOL16 WINAPI FindNextFile16( HANDLE16 handle, WIN32_FIND_DATAA *data )
248 {
249     HANDLE *ptr;
250     BOOL ret = FALSE;
251
252     if ((handle == INVALID_HANDLE_VALUE16) || !(ptr = GlobalLock16( handle )))
253     {
254         SetLastError( ERROR_INVALID_HANDLE );
255         return ret;
256     }
257     ret = FindNextFileA( *ptr, data );
258     GlobalUnlock16( handle );
259     return ret;
260 }
261
262
263 /*************************************************************************
264  *           FindClose   (KERNEL.415)
265  */
266 BOOL16 WINAPI FindClose16( HANDLE16 handle )
267 {
268     HANDLE *ptr;
269
270     if ((handle == INVALID_HANDLE_VALUE16) || !(ptr = GlobalLock16( handle )))
271     {
272         SetLastError( ERROR_INVALID_HANDLE );
273         return FALSE;
274     }
275     FindClose( *ptr );
276     GlobalUnlock16( handle );
277     GlobalFree16( handle );
278     return TRUE;
279 }