~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/krnl386.exe16/file.c

Version: ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 "winternl.h"
 39 #include "wine/winbase16.h"
 40 #include "kernel16_private.h"
 41 #include "wine/unicode.h"
 42 #include "wine/debug.h"
 43 
 44 WINE_DEFAULT_DEBUG_CHANNEL(file);
 45 
 46 #define DOS_TABLE_SIZE 256
 47 
 48 static HANDLE dos_handles[DOS_TABLE_SIZE];
 49 
 50 /***********************************************************************
 51  *           FILE_InitProcessDosHandles
 52  *
 53  * Allocates the default DOS handles for a process. Called either by
 54  * Win32HandleToDosFileHandle below or by the DOSVM stuff.
 55  */
 56 static void FILE_InitProcessDosHandles( void )
 57 {
 58     static BOOL init_done /* = FALSE */;
 59     HANDLE cp = GetCurrentProcess();
 60 
 61     if (init_done) return;
 62     init_done = TRUE;
 63     DuplicateHandle(cp, GetStdHandle(STD_INPUT_HANDLE), cp, &dos_handles[0],
 64                     0, TRUE, DUPLICATE_SAME_ACCESS);
 65     DuplicateHandle(cp, GetStdHandle(STD_OUTPUT_HANDLE), cp, &dos_handles[1],
 66                     0, TRUE, DUPLICATE_SAME_ACCESS);
 67     DuplicateHandle(cp, GetStdHandle(STD_ERROR_HANDLE), cp, &dos_handles[2],
 68                     0, TRUE, DUPLICATE_SAME_ACCESS);
 69     DuplicateHandle(cp, GetStdHandle(STD_ERROR_HANDLE), cp, &dos_handles[3],
 70                     0, TRUE, DUPLICATE_SAME_ACCESS);
 71     DuplicateHandle(cp, GetStdHandle(STD_ERROR_HANDLE), cp, &dos_handles[4],
 72                     0, TRUE, DUPLICATE_SAME_ACCESS);
 73 }
 74 
 75 /***********************************************************************
 76  *           DosFileHandleToWin32Handle   (KERNEL32.20)
 77  *
 78  * Return the Win32 handle for a DOS handle.
 79  *
 80  * Note: this is not exactly right, since on Win95 the Win32 handles
 81  *       are on top of DOS handles and we do it the other way
 82  *       around. Should be good enough though.
 83  */
 84 HANDLE WINAPI DosFileHandleToWin32Handle( HFILE handle )
 85 {
 86     HFILE16 hfile = (HFILE16)handle;
 87     if (hfile < 5) FILE_InitProcessDosHandles();
 88     if ((hfile >= DOS_TABLE_SIZE) || !dos_handles[hfile])
 89     {
 90         SetLastError( ERROR_INVALID_HANDLE );
 91         return INVALID_HANDLE_VALUE;
 92     }
 93     return dos_handles[hfile];
 94 }
 95 
 96 /***********************************************************************
 97  *           Win32HandleToDosFileHandle   (KERNEL32.21)
 98  *
 99  * Allocate a DOS handle for a Win32 handle. The Win32 handle is no
100  * longer valid after this function (even on failure).
101  *
102  * Note: this is not exactly right, since on Win95 the Win32 handles
103  *       are on top of DOS handles and we do it the other way
104  *       around. Should be good enough though.
105  */
106 HFILE WINAPI Win32HandleToDosFileHandle( HANDLE handle )
107 {
108     int i;
109 
110     if (!handle || (handle == INVALID_HANDLE_VALUE))
111         return HFILE_ERROR;
112 
113     FILE_InitProcessDosHandles();
114     for (i = 0; i < DOS_TABLE_SIZE; i++)
115         if (!dos_handles[i])
116         {
117             dos_handles[i] = handle;
118             TRACE("Got %d for h32 %p\n", i, handle );
119             return (HFILE)i;
120         }
121     CloseHandle( handle );
122     SetLastError( ERROR_TOO_MANY_OPEN_FILES );
123     return HFILE_ERROR;
124 }
125 
126 /***********************************************************************
127  *           DisposeLZ32Handle   (KERNEL32.22)
128  *
129  * Note: this is not entirely correct, we should only close the
130  *       32-bit handle and not the 16-bit one, but we cannot do
131  *       this because of the way our DOS handles are implemented.
132  *       It shouldn't break anything though.
133  */
134 void WINAPI DisposeLZ32Handle( HANDLE handle )
135 {
136     int i;
137 
138     if (!handle || (handle == INVALID_HANDLE_VALUE)) return;
139 
140     for (i = 5; i < DOS_TABLE_SIZE; i++)
141         if (dos_handles[i] == handle)
142         {
143             dos_handles[i] = 0;
144             CloseHandle( handle );
145             break;
146         }
147 }
148 
149 /***********************************************************************
150  *           GetProfileInt   (KERNEL.57)
151  */
152 UINT16 WINAPI GetProfileInt16( LPCSTR section, LPCSTR entry, INT16 def_val )
153 {
154     return GetPrivateProfileInt16( section, entry, def_val, "win.ini" );
155 }
156 
157 
158 /***********************************************************************
159  *           GetProfileString   (KERNEL.58)
160  */
161 INT16 WINAPI GetProfileString16( LPCSTR section, LPCSTR entry, LPCSTR def_val,
162                                  LPSTR buffer, UINT16 len )
163 {
164     return GetPrivateProfileString16( section, entry, def_val,
165                                       buffer, len, "win.ini" );
166 }
167 
168 
169 /***********************************************************************
170  *           WriteProfileString   (KERNEL.59)
171  */
172 BOOL16 WINAPI WriteProfileString16( LPCSTR section, LPCSTR entry,
173                                     LPCSTR string )
174 {
175     return WritePrivateProfileString16( section, entry, string, "win.ini" );
176 }
177 
178 
179 /* get the search path for the current module; helper for OpenFile16 */
180 static char *get_search_path(void)
181 {
182     UINT len;
183     char *ret, *p, module[OFS_MAXPATHNAME];
184 
185     module[0] = 0;
186     if (GetCurrentTask() && GetModuleFileName16( GetCurrentTask(), module, sizeof(module) ))
187     {
188         if (!(p = strrchr( module, '\\' ))) p = module;
189         *p = 0;
190     }
191 
192     len = (2 +                                              /* search order: first current dir */
193            GetSystemDirectory16( NULL, 0 ) + 1 +            /* then system dir */
194            GetWindowsDirectoryA( NULL, 0 ) + 1 +            /* then windows dir */
195            strlen( module ) + 1 +                           /* then module path */
196            GetEnvironmentVariableA( "PATH", NULL, 0 ) + 1); /* then look in PATH */
197     if (!(ret = HeapAlloc( GetProcessHeap(), 0, len ))) return NULL;
198     strcpy( ret, ".;" );
199     p = ret + 2;
200     GetSystemDirectory16( p, ret + len - p );
201     p += strlen( p );
202     *p++ = ';';
203     GetWindowsDirectoryA( p, ret + len - p );
204     p += strlen( p );
205     *p++ = ';';
206     if (module[0])
207     {
208         strcpy( p, module );
209         p += strlen( p );
210         *p++ = ';';
211     }
212     GetEnvironmentVariableA( "PATH", p, ret + len - p );
213     return ret;
214 }
215 
216 /***********************************************************************
217  *           OpenFile   (KERNEL.74)
218  *           OpenFileEx (KERNEL.360)
219  */
220 HFILE16 WINAPI OpenFile16( LPCSTR name, OFSTRUCT *ofs, UINT16 mode )
221 {
222     HFILE hFileRet;
223     HANDLE handle;
224     FILETIME filetime;
225     WORD filedatetime[2];
226     const char *p, *filename;
227 
228     if (!ofs) return HFILE_ERROR;
229 
230     TRACE("%s %s %s %s%s%s%s%s%s%s%s%s\n",debugstr_a(name),
231           ((mode & 0x3 )==OF_READ)?"OF_READ":
232           ((mode & 0x3 )==OF_WRITE)?"OF_WRITE":
233           ((mode & 0x3 )==OF_READWRITE)?"OF_READWRITE":"unknown",
234           ((mode & 0x70 )==OF_SHARE_COMPAT)?"OF_SHARE_COMPAT":
235           ((mode & 0x70 )==OF_SHARE_DENY_NONE)?"OF_SHARE_DENY_NONE":
236           ((mode & 0x70 )==OF_SHARE_DENY_READ)?"OF_SHARE_DENY_READ":
237           ((mode & 0x70 )==OF_SHARE_DENY_WRITE)?"OF_SHARE_DENY_WRITE":
238           ((mode & 0x70 )==OF_SHARE_EXCLUSIVE)?"OF_SHARE_EXCLUSIVE":"unknown",
239           ((mode & OF_PARSE )==OF_PARSE)?"OF_PARSE ":"",
240           ((mode & OF_DELETE )==OF_DELETE)?"OF_DELETE ":"",
241           ((mode & OF_VERIFY )==OF_VERIFY)?"OF_VERIFY ":"",
242           ((mode & OF_SEARCH )==OF_SEARCH)?"OF_SEARCH ":"",
243           ((mode & OF_CANCEL )==OF_CANCEL)?"OF_CANCEL ":"",
244           ((mode & OF_CREATE )==OF_CREATE)?"OF_CREATE ":"",
245           ((mode & OF_PROMPT )==OF_PROMPT)?"OF_PROMPT ":"",
246           ((mode & OF_EXIST )==OF_EXIST)?"OF_EXIST ":"",
247           ((mode & OF_REOPEN )==OF_REOPEN)?"OF_REOPEN ":""
248         );
249 
250     if (mode & OF_PARSE)
251     {
252         OpenFile( name, ofs, mode );
253         return 0;
254     }
255 
256     if (mode & OF_CREATE)
257     {
258         handle = (HANDLE)OpenFile( name, ofs, mode );
259         if (handle == (HANDLE)HFILE_ERROR) goto error;
260     }
261     else
262     {
263         ofs->cBytes = sizeof(OFSTRUCT);
264         ofs->nErrCode = 0;
265         if (mode & OF_REOPEN) name = ofs->szPathName;
266 
267         if (!name) return HFILE_ERROR;
268 
269         /* the watcom 10.6 IDE relies on a valid path returned in ofs->szPathName
270            Are there any cases where getting the path here is wrong?
271            Uwe Bonnes 1997 Apr 2 */
272         if (!GetFullPathNameA( name, sizeof(ofs->szPathName), ofs->szPathName, NULL )) goto error;
273 
274         /* If OF_SEARCH is set, ignore the given path */
275 
276         filename = name;
277         if ((mode & OF_SEARCH) && !(mode & OF_REOPEN))
278         {
279             /* First try the file name as is */
280             if (GetFileAttributesA( filename ) != INVALID_FILE_ATTRIBUTES) filename = NULL;
281             else
282             {
283                 /* Now remove the path */
284                 if (filename[0] && (filename[1] == ':')) filename += 2;
285                 if ((p = strrchr( filename, '\\' ))) filename = p + 1;
286                 if ((p = strrchr( filename, '/' ))) filename = p + 1;
287                 if (!filename[0])
288                 {
289                     SetLastError( ERROR_FILE_NOT_FOUND );
290                     goto error;
291                 }
292             }
293         }
294 
295         /* Now look for the file */
296 
297         if (filename)
298         {
299             BOOL found;
300             char *path = get_search_path();
301 
302             if (!path) goto error;
303             found = SearchPathA( path, filename, NULL, sizeof(ofs->szPathName),
304                                  ofs->szPathName, NULL );
305             HeapFree( GetProcessHeap(), 0, path );
306             if (!found) goto error;
307         }
308 
309         TRACE("found %s\n", debugstr_a(ofs->szPathName) );
310 
311         if (mode & OF_DELETE)
312         {
313             if (!DeleteFileA( ofs->szPathName )) goto error;
314             TRACE("(%s): OF_DELETE return = OK\n", name);
315             return 1;
316         }
317 
318         handle = (HANDLE)_lopen( ofs->szPathName, mode );
319         if (handle == INVALID_HANDLE_VALUE) goto error;
320 
321         GetFileTime( handle, NULL, NULL, &filetime );
322         FileTimeToDosDateTime( &filetime, &filedatetime[0], &filedatetime[1] );
323         if ((mode & OF_VERIFY) && (mode & OF_REOPEN))
324         {
325             if (ofs->Reserved1 != filedatetime[0] || ofs->Reserved2 != filedatetime[1] )
326             {
327                 CloseHandle( handle );
328                 WARN("(%s): OF_VERIFY failed\n", name );
329                 /* FIXME: what error here? */
330                 SetLastError( ERROR_FILE_NOT_FOUND );
331                 goto error;
332             }
333         }
334         ofs->Reserved1 = filedatetime[0];
335         ofs->Reserved2 = filedatetime[1];
336     }
337 
338     TRACE("(%s): OK, return = %p\n", name, handle );
339     hFileRet = Win32HandleToDosFileHandle( handle );
340     if (hFileRet == HFILE_ERROR16) goto error;
341     if (mode & OF_EXIST) _lclose16( hFileRet ); /* Return the handle, but close it first */
342     return hFileRet;
343 
344 error:  /* We get here if there was an error opening the file */
345     ofs->nErrCode = GetLastError();
346     WARN("(%s): return = HFILE_ERROR error= %d\n", name,ofs->nErrCode );
347     return HFILE_ERROR16;
348 }
349 
350 
351 /***********************************************************************
352  *           _lclose   (KERNEL.81)
353  */
354 HFILE16 WINAPI _lclose16( HFILE16 hFile )
355 {
356     if ((hFile >= DOS_TABLE_SIZE) || !dos_handles[hFile])
357     {
358         SetLastError( ERROR_INVALID_HANDLE );
359         return HFILE_ERROR16;
360     }
361     TRACE("%d (handle32=%p)\n", hFile, dos_handles[hFile] );
362     CloseHandle( dos_handles[hFile] );
363     dos_handles[hFile] = 0;
364     return 0;
365 }
366 
367 /***********************************************************************
368  *           _lcreat   (KERNEL.83)
369  */
370 HFILE16 WINAPI _lcreat16( LPCSTR path, INT16 attr )
371 {
372     return Win32HandleToDosFileHandle( (HANDLE)_lcreat( path, attr ) );
373 }
374 
375 /***********************************************************************
376  *           _llseek   (KERNEL.84)
377  *
378  * FIXME:
379  *   Seeking before the start of the file should be allowed for _llseek16,
380  *   but cause subsequent I/O operations to fail (cf. interrupt list)
381  *
382  */
383 LONG WINAPI _llseek16( HFILE16 hFile, LONG lOffset, INT16 nOrigin )
384 {
385     return SetFilePointer( DosFileHandleToWin32Handle(hFile), lOffset, NULL, nOrigin );
386 }
387 
388 
389 /***********************************************************************
390  *           _lopen   (KERNEL.85)
391  */
392 HFILE16 WINAPI _lopen16( LPCSTR path, INT16 mode )
393 {
394     return Win32HandleToDosFileHandle( (HANDLE)_lopen( path, mode ) );
395 }
396 
397 
398 /***********************************************************************
399  *           _lread16   (KERNEL.82)
400  */
401 UINT16 WINAPI _lread16( HFILE16 hFile, LPVOID buffer, UINT16 count )
402 {
403     return (UINT16)_lread((HFILE)DosFileHandleToWin32Handle(hFile), buffer, (LONG)count );
404 }
405 
406 
407 /***********************************************************************
408  *           _lwrite   (KERNEL.86)
409  */
410 UINT16 WINAPI _lwrite16( HFILE16 hFile, LPCSTR buffer, UINT16 count )
411 {
412     return (UINT16)_hwrite( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, (LONG)count );
413 }
414 
415 /***********************************************************************
416  *           _hread (KERNEL.349)
417  */
418 LONG WINAPI WIN16_hread( HFILE16 hFile, SEGPTR buffer, LONG count )
419 {
420     LONG maxlen;
421 
422     TRACE("%d %08x %d\n", hFile, (DWORD)buffer, count );
423 
424     /* Some programs pass a count larger than the allocated buffer */
425     maxlen = GetSelectorLimit16( SELECTOROF(buffer) ) - OFFSETOF(buffer) + 1;
426     if (count > maxlen) count = maxlen;
427     return _lread((HFILE)DosFileHandleToWin32Handle(hFile), MapSL(buffer), count );
428 }
429 
430 
431 /***********************************************************************
432  *           _lread (KERNEL.82)
433  */
434 UINT16 WINAPI WIN16_lread( HFILE16 hFile, SEGPTR buffer, UINT16 count )
435 {
436     return (UINT16)WIN16_hread( hFile, buffer, (LONG)count );
437 }
438 
439 
440 /***********************************************************************
441  *           _hwrite   (KERNEL.350)
442  */
443 LONG WINAPI _hwrite16( HFILE16 hFile, LPCSTR buffer, LONG count )
444 {
445     return _hwrite( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, count );
446 }
447 
448 
449 /***********************************************************************
450  *           GetTempDrive   (KERNEL.92)
451  * A closer look at krnl386.exe shows what the SDK doesn't mention:
452  *
453  * returns:
454  *   AL: driveletter
455  *   AH: ':'            - yes, some kernel code even does stosw with
456  *                            the returned AX.
457  *   DX: 1 for success
458  */
459 UINT WINAPI GetTempDrive( BYTE ignored )
460 {
461     WCHAR buffer[8];
462     BYTE ret;
463 
464     if (GetTempPathW( 8, buffer )) ret = (BYTE)toupperW(buffer[0]);
465     else ret = 'C';
466     return MAKELONG( ret | (':' << 8), 1 );
467 }
468 
469 
470 /***********************************************************************
471  *           GetTempFileName   (KERNEL.97)
472  */
473 UINT16 WINAPI GetTempFileName16( BYTE drive, LPCSTR prefix, UINT16 unique,
474                                  LPSTR buffer )
475 {
476     char temppath[MAX_PATH];
477     char *prefix16 = NULL;
478     UINT16 ret;
479 
480     if (!(drive & ~TF_FORCEDRIVE)) /* drive 0 means current default drive */
481     {
482         GetCurrentDirectoryA(sizeof(temppath), temppath); 
483         drive |= temppath[0];
484     }
485 
486     if (drive & TF_FORCEDRIVE)
487     {
488         char    d[3];
489 
490         d[0] = drive & ~TF_FORCEDRIVE;
491         d[1] = ':';
492         d[2] = '\0';
493         if (GetDriveTypeA(d) == DRIVE_NO_ROOT_DIR)
494         {
495             drive &= ~TF_FORCEDRIVE;
496             WARN("invalid drive %d specified\n", drive );
497         }
498     }
499 
500     if (drive & TF_FORCEDRIVE)
501         sprintf(temppath,"%c:", drive & ~TF_FORCEDRIVE );
502     else
503         GetTempPathA( MAX_PATH, temppath );
504 
505     if (prefix)
506     {
507         prefix16 = HeapAlloc(GetProcessHeap(), 0, strlen(prefix) + 2);
508         *prefix16 = '~';
509         strcpy(prefix16 + 1, prefix);
510     }
511 
512     ret = GetTempFileNameA( temppath, prefix16, unique, buffer );
513 
514     HeapFree(GetProcessHeap(), 0, prefix16);
515     return ret;
516 }
517 
518 
519 /***********************************************************************
520  *           GetPrivateProfileInt   (KERNEL.127)
521  */
522 UINT16 WINAPI GetPrivateProfileInt16( LPCSTR section, LPCSTR entry,
523                                       INT16 def_val, LPCSTR filename )
524 {
525     /* we used to have some elaborate return value limitation (<= -32768 etc.)
526      * here, but Win98SE doesn't care about this at all, so I deleted it.
527      * AFAIR versions prior to Win9x had these limits, though. */
528     return (INT16)GetPrivateProfileIntA(section,entry,def_val,filename);
529 }
530 
531 
532 /***********************************************************************
533  *           GetPrivateProfileString   (KERNEL.128)
534  */
535 INT16 WINAPI GetPrivateProfileString16( LPCSTR section, LPCSTR entry,
536                                         LPCSTR def_val, LPSTR buffer,
537                                         UINT16 len, LPCSTR filename )
538 {
539     if (!section)
540     {
541         if (buffer && len) buffer[0] = 0;
542         return 0;
543     }
544     if (!entry)
545     {
546         /* We have to return the list of keys in the section but without the values
547          * so we need to massage the results of GetPrivateProfileSectionA.
548          */
549         UINT ret, oldlen = len, size = min( len, 1024 );
550         LPSTR data, src;
551 
552         for (;;)
553         {
554             if (!(data = HeapAlloc(GetProcessHeap(), 0, size ))) return 0;
555             ret = GetPrivateProfileSectionA( section, data, size, filename );
556             if (!ret)
557             {
558                 HeapFree( GetProcessHeap(), 0, data );
559                 return GetPrivateProfileStringA( section, entry, def_val, buffer, len, filename );
560             }
561             if (ret != size - 2) break;
562             /* overflow, try again */
563             size *= 2;
564             HeapFree( GetProcessHeap(), 0, data );
565         }
566 
567         src = data;
568         while (len && *src)
569         {
570             char *p = strchr( src, '=' );
571 
572             if (!p) p = src + strlen(src);
573             if (p - src < len)
574             {
575                 memcpy( buffer, src, p - src );
576                 buffer += p - src;
577                 *buffer++ = 0;
578                 len -= (p - src) + 1;
579                 src += strlen(src) + 1;
580             }
581             else  /* overflow */
582             {
583                 memcpy( buffer, src, len );
584                 buffer += len;
585                 len = 0;
586             }
587         }
588         HeapFree( GetProcessHeap(), 0, data );
589 
590         if (len)
591         {
592             *buffer = 0;
593             return oldlen - len;
594         }
595         if (oldlen > 2)
596         {
597             buffer[-2] = 0;
598             buffer[-1] = 0;
599             return oldlen - 2;
600         }
601         return 0;
602     }
603     return GetPrivateProfileStringA( section, entry, def_val, buffer, len, filename );
604 }
605 
606 
607 /***********************************************************************
608  *           WritePrivateProfileString   (KERNEL.129)
609  */
610 BOOL16 WINAPI WritePrivateProfileString16( LPCSTR section, LPCSTR entry,
611                                            LPCSTR string, LPCSTR filename )
612 {
613     return WritePrivateProfileStringA(section,entry,string,filename);
614 }
615 
616 
617 /***********************************************************************
618  *           GetWindowsDirectory   (KERNEL.134)
619  */
620 UINT16 WINAPI GetWindowsDirectory16( LPSTR path, UINT16 count )
621 {
622     return GetWindowsDirectoryA( path, count );
623 }
624 
625 
626 /***********************************************************************
627  *           GetSystemDirectory   (KERNEL.135)
628  */
629 UINT16 WINAPI GetSystemDirectory16( LPSTR path, UINT16 count )
630 {
631     static const char system16[] = "\\SYSTEM";
632     char windir[MAX_PATH];
633     UINT16 len;
634 
635     len = GetWindowsDirectory16(windir, sizeof(windir) - sizeof(system16) + 1) + sizeof(system16);
636     if (count >= len)
637     {
638         lstrcpyA(path, windir);
639         lstrcatA(path, system16);
640         len--;  /* space for the terminating zero is not included on success */
641     }
642     return len;
643 }
644 
645 
646 /***********************************************************************
647  *           GetDriveType   (KERNEL.136)
648  * Get the type of a drive in Win16.
649  *
650  * RETURNS
651  *  The type of the Drive. For a list see GetDriveTypeW from kernel32.
652  *
653  * NOTES
654  *  Note that it returns DRIVE_REMOTE for CD-ROMs, since MSCDEX uses the
655  *  remote drive API. The return value DRIVE_REMOTE for CD-ROMs has been
656  *  verified on Win 3.11 and Windows 95. Some programs rely on it, so don't
657  *  do any pseudo-clever changes.
658  */
659 UINT16 WINAPI GetDriveType16( UINT16 drive ) /* [in] number (NOT letter) of drive */
660 {
661     UINT type;
662     WCHAR root[3];
663 
664     root[0] = 'A' + drive;
665     root[1] = ':';
666     root[2] = 0;
667     type = GetDriveTypeW( root );
668     if (type == DRIVE_CDROM) type = DRIVE_REMOTE;
669     else if (type == DRIVE_NO_ROOT_DIR) type = DRIVE_UNKNOWN;
670     return type;
671 }
672 
673 
674 /***********************************************************************
675  *           GetProfileSectionNames   (KERNEL.142)
676  */
677 WORD WINAPI GetProfileSectionNames16(LPSTR buffer, WORD size)
678 
679 {
680     return GetPrivateProfileSectionNamesA(buffer,size,"win.ini");
681 }
682 
683 
684 /***********************************************************************
685  *           GetPrivateProfileSectionNames   (KERNEL.143)
686  */
687 WORD WINAPI GetPrivateProfileSectionNames16( LPSTR buffer, WORD size,
688                                              LPCSTR filename )
689 {
690     return GetPrivateProfileSectionNamesA(buffer,size,filename);
691 }
692 
693 
694 /***********************************************************************
695  *           CreateDirectory   (KERNEL.144)
696  */
697 BOOL16 WINAPI CreateDirectory16( LPCSTR path, LPVOID dummy )
698 {
699     return CreateDirectoryA( path, NULL );
700 }
701 
702 
703 /***********************************************************************
704  *           RemoveDirectory   (KERNEL.145)
705  */
706 BOOL16 WINAPI RemoveDirectory16( LPCSTR path )
707 {
708     return RemoveDirectoryA( path );
709 }
710 
711 
712 /***********************************************************************
713  *           DeleteFile   (KERNEL.146)
714  */
715 BOOL16 WINAPI DeleteFile16( LPCSTR path )
716 {
717     return DeleteFileA( path );
718 }
719 
720 
721 /***********************************************************************
722  *           SetHandleCount   (KERNEL.199)
723  */
724 UINT16 WINAPI SetHandleCount16( UINT16 count )
725 {
726     return SetHandleCount( count );
727 }
728 
729 
730 /***********************************************************************
731  *           GetShortPathName   (KERNEL.274)
732  */
733 WORD WINAPI GetShortPathName16( LPCSTR longpath, LPSTR shortpath, WORD len )
734 {
735     return GetShortPathNameA( longpath, shortpath, len );
736 }
737 
738 
739 /***********************************************************************
740  *           WriteOutProfiles   (KERNEL.315)
741  */
742 void WINAPI WriteOutProfiles16(void)
743 {
744     WritePrivateProfileSectionW( NULL, NULL, NULL );
745 }
746 
747 
748 /***********************************************************************
749  *           WritePrivateProfileStruct (KERNEL.406)
750  */
751 BOOL16 WINAPI WritePrivateProfileStruct16 (LPCSTR section, LPCSTR key,
752                                            LPVOID buf, UINT16 bufsize, LPCSTR filename)
753 {
754     return WritePrivateProfileStructA( section, key, buf, bufsize, filename );
755 }
756 
757 
758 /***********************************************************************
759  *           GetPrivateProfileStruct (KERNEL.407)
760  */
761 BOOL16 WINAPI GetPrivateProfileStruct16(LPCSTR section, LPCSTR key,
762                                         LPVOID buf, UINT16 len, LPCSTR filename)
763 {
764     return GetPrivateProfileStructA( section, key, buf, len, filename );
765 }
766 
767 
768 /***********************************************************************
769  *           GetCurrentDirectory   (KERNEL.411)
770  */
771 UINT16 WINAPI GetCurrentDirectory16( UINT16 buflen, LPSTR buf )
772 {
773     return GetCurrentDirectoryA( buflen, buf );
774 }
775 
776 
777 /***********************************************************************
778  *           SetCurrentDirectory   (KERNEL.412)
779  */
780 BOOL16 WINAPI SetCurrentDirectory16( LPCSTR dir )
781 {
782     char fulldir[MAX_PATH];
783 
784     if (!GetFullPathNameA( dir, MAX_PATH, fulldir, NULL )) return FALSE;
785 
786     if (!SetCurrentDirectoryA( dir )) return FALSE;
787 
788     if (fulldir[0] && fulldir[1] == ':')
789     {
790         TDB *pTask = GlobalLock16( GetCurrentTask() );
791         char env_var[4] = "=A:";
792 
793         env_var[1] = fulldir[0];
794         SetEnvironmentVariableA( env_var, fulldir );
795 
796         /* update the directory in the TDB */
797         if (pTask)
798         {
799             pTask->curdrive = 0x80 | (fulldir[0] - 'A');
800             GetShortPathNameA( fulldir + 2, pTask->curdir, sizeof(pTask->curdir) );
801         }
802     }
803     return TRUE;
804 }
805 
806 
807 /*************************************************************************
808  *           FindFirstFile   (KERNEL.413)
809  */
810 HANDLE16 WINAPI FindFirstFile16( LPCSTR path, WIN32_FIND_DATAA *data )
811 {
812     HGLOBAL16 h16;
813     HANDLE handle, *ptr;
814 
815     if (!(h16 = GlobalAlloc16( GMEM_MOVEABLE, sizeof(handle) ))) return INVALID_HANDLE_VALUE16;
816     ptr = GlobalLock16( h16 );
817     *ptr = handle = FindFirstFileA( path, data );
818     GlobalUnlock16( h16 );
819 
820     if (handle == INVALID_HANDLE_VALUE)
821     {
822         GlobalFree16( h16 );
823         h16 = INVALID_HANDLE_VALUE16;
824     }
825     return h16;
826 }
827 
828 
829 /*************************************************************************
830  *           FindNextFile   (KERNEL.414)
831  */
832 BOOL16 WINAPI FindNextFile16( HANDLE16 handle, WIN32_FIND_DATAA *data )
833 {
834     HANDLE *ptr;
835     BOOL ret = FALSE;
836 
837     if ((handle == INVALID_HANDLE_VALUE16) || !(ptr = GlobalLock16( handle )))
838     {
839         SetLastError( ERROR_INVALID_HANDLE );
840         return ret;
841     }
842     ret = FindNextFileA( *ptr, data );
843     GlobalUnlock16( handle );
844     return ret;
845 }
846 
847 
848 /*************************************************************************
849  *           FindClose   (KERNEL.415)
850  */
851 BOOL16 WINAPI FindClose16( HANDLE16 handle )
852 {
853     HANDLE *ptr;
854 
855     if ((handle == INVALID_HANDLE_VALUE16) || !(ptr = GlobalLock16( handle )))
856     {
857         SetLastError( ERROR_INVALID_HANDLE );
858         return FALSE;
859     }
860     FindClose( *ptr );
861     GlobalUnlock16( handle );
862     GlobalFree16( handle );
863     return TRUE;
864 }
865 
866 
867 /***********************************************************************
868  *           WritePrivateProfileSection   (KERNEL.416)
869  */
870 BOOL16 WINAPI WritePrivateProfileSection16( LPCSTR section,
871                                             LPCSTR string, LPCSTR filename )
872 {
873     return WritePrivateProfileSectionA( section, string, filename );
874 }
875 
876 
877 /***********************************************************************
878  *           WriteProfileSection   (KERNEL.417)
879  */
880 BOOL16 WINAPI WriteProfileSection16( LPCSTR section, LPCSTR keys_n_values)
881 {
882     return WritePrivateProfileSection16( section, keys_n_values, "win.ini");
883 }
884 
885 
886 /***********************************************************************
887  *           GetPrivateProfileSection   (KERNEL.418)
888  */
889 INT16 WINAPI GetPrivateProfileSection16( LPCSTR section, LPSTR buffer,
890                                          UINT16 len, LPCSTR filename )
891 {
892     return GetPrivateProfileSectionA( section, buffer, len, filename );
893 }
894 
895 
896 /***********************************************************************
897  *           GetProfileSection   (KERNEL.419)
898  */
899 INT16 WINAPI GetProfileSection16( LPCSTR section, LPSTR buffer, UINT16 len )
900 {
901     return GetPrivateProfileSection16( section, buffer, len, "win.ini" );
902 }
903 
904 
905 /**************************************************************************
906  *           GetFileAttributes   (KERNEL.420)
907  */
908 DWORD WINAPI GetFileAttributes16( LPCSTR name )
909 {
910     return GetFileAttributesA( name );
911 }
912 
913 
914 /**************************************************************************
915  *              SetFileAttributes       (KERNEL.421)
916  */
917 BOOL16 WINAPI SetFileAttributes16( LPCSTR lpFileName, DWORD attributes )
918 {
919     return SetFileAttributesA( lpFileName, attributes );
920 }
921 
922 
923 /***********************************************************************
924  *           GetDiskFreeSpace   (KERNEL.422)
925  */
926 BOOL16 WINAPI GetDiskFreeSpace16( LPCSTR root, LPDWORD cluster_sectors,
927                                   LPDWORD sector_bytes, LPDWORD free_clusters,
928                                   LPDWORD total_clusters )
929 {
930     return GetDiskFreeSpaceA( root, cluster_sectors, sector_bytes,
931                                 free_clusters, total_clusters );
932 }
933 
934 /***********************************************************************
935  *      FileCDR (KERNEL.130)
936  */
937 FARPROC16 WINAPI FileCDR16(FARPROC16 x)
938 {
939     FIXME("(%p): stub\n", x);
940     return (FARPROC16)TRUE;
941 }
942 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.