Better handling of 16-bit native dlls when a 32-bit builtin with the
[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 /***********************************************************************
50  *           GetProfileInt   (KERNEL.57)
51  */
52 UINT16 WINAPI GetProfileInt16( LPCSTR section, LPCSTR entry, INT16 def_val )
53 {
54     return GetPrivateProfileInt16( section, entry, def_val, "win.ini" );
55 }
56
57
58 /***********************************************************************
59  *           GetProfileString   (KERNEL.58)
60  */
61 INT16 WINAPI GetProfileString16( LPCSTR section, LPCSTR entry, LPCSTR def_val,
62                                  LPSTR buffer, UINT16 len )
63 {
64     return GetPrivateProfileString16( section, entry, def_val,
65                                       buffer, len, "win.ini" );
66 }
67
68
69 /***********************************************************************
70  *           WriteProfileString   (KERNEL.59)
71  */
72 BOOL16 WINAPI WriteProfileString16( LPCSTR section, LPCSTR entry,
73                                     LPCSTR string )
74 {
75     return WritePrivateProfileString16( section, entry, string, "win.ini" );
76 }
77
78
79 /* get the search path for the current module; helper for OpenFile16 */
80 static char *get_search_path(void)
81 {
82     UINT len;
83     char *ret, *p, module[OFS_MAXPATHNAME];
84
85     module[0] = 0;
86     if (GetCurrentTask() && GetModuleFileName16( GetCurrentTask(), module, sizeof(module) ))
87     {
88         if (!(p = strrchr( module, '\\' ))) p = module;
89         *p = 0;
90     }
91
92     len = (2 +                                              /* search order: first current dir */
93            GetSystemDirectoryA( NULL, 0 ) + 1 +             /* then system dir */
94            GetWindowsDirectoryA( NULL, 0 ) + 1 +            /* then windows dir */
95            strlen( module ) + 1 +                           /* then module path */
96            GetEnvironmentVariableA( "PATH", NULL, 0 ) + 1); /* then look in PATH */
97     if (!(ret = HeapAlloc( GetProcessHeap(), 0, len ))) return NULL;
98     strcpy( ret, ".;" );
99     p = ret + 2;
100     GetSystemDirectoryA( p, ret + len - p );
101     p += strlen( p );
102     *p++ = ';';
103     GetWindowsDirectoryA( p, ret + len - p );
104     p += strlen( p );
105     *p++ = ';';
106     if (module[0])
107     {
108         strcpy( p, module );
109         p += strlen( p );
110         *p++ = ';';
111     }
112     GetEnvironmentVariableA( "PATH", p, ret + len - p );
113     return ret;
114 }
115
116 /***********************************************************************
117  *           OpenFile   (KERNEL.74)
118  *           OpenFileEx (KERNEL.360)
119  */
120 HFILE16 WINAPI OpenFile16( LPCSTR name, OFSTRUCT *ofs, UINT16 mode )
121 {
122     HFILE hFileRet;
123     HANDLE handle;
124     FILETIME filetime;
125     WORD filedatetime[2];
126     const char *p, *filename;
127
128     if (!ofs) return HFILE_ERROR;
129
130     TRACE("%s %s %s %s%s%s%s%s%s%s%s%s\n",debugstr_a(name),
131           ((mode & 0x3 )==OF_READ)?"OF_READ":
132           ((mode & 0x3 )==OF_WRITE)?"OF_WRITE":
133           ((mode & 0x3 )==OF_READWRITE)?"OF_READWRITE":"unknown",
134           ((mode & 0x70 )==OF_SHARE_COMPAT)?"OF_SHARE_COMPAT":
135           ((mode & 0x70 )==OF_SHARE_DENY_NONE)?"OF_SHARE_DENY_NONE":
136           ((mode & 0x70 )==OF_SHARE_DENY_READ)?"OF_SHARE_DENY_READ":
137           ((mode & 0x70 )==OF_SHARE_DENY_WRITE)?"OF_SHARE_DENY_WRITE":
138           ((mode & 0x70 )==OF_SHARE_EXCLUSIVE)?"OF_SHARE_EXCLUSIVE":"unknown",
139           ((mode & OF_PARSE )==OF_PARSE)?"OF_PARSE ":"",
140           ((mode & OF_DELETE )==OF_DELETE)?"OF_DELETE ":"",
141           ((mode & OF_VERIFY )==OF_VERIFY)?"OF_VERIFY ":"",
142           ((mode & OF_SEARCH )==OF_SEARCH)?"OF_SEARCH ":"",
143           ((mode & OF_CANCEL )==OF_CANCEL)?"OF_CANCEL ":"",
144           ((mode & OF_CREATE )==OF_CREATE)?"OF_CREATE ":"",
145           ((mode & OF_PROMPT )==OF_PROMPT)?"OF_PROMPT ":"",
146           ((mode & OF_EXIST )==OF_EXIST)?"OF_EXIST ":"",
147           ((mode & OF_REOPEN )==OF_REOPEN)?"OF_REOPEN ":""
148         );
149
150     if (mode & OF_PARSE)
151     {
152         OpenFile( name, ofs, mode );
153         return 0;
154     }
155
156     if (mode & OF_CREATE)
157     {
158         handle = (HANDLE)OpenFile( name, ofs, mode );
159         if (handle == (HANDLE)HFILE_ERROR) goto error;
160     }
161     else
162     {
163         ofs->cBytes = sizeof(OFSTRUCT);
164         ofs->nErrCode = 0;
165         if (mode & OF_REOPEN) name = ofs->szPathName;
166
167         if (!name) return HFILE_ERROR;
168
169         /* the watcom 10.6 IDE relies on a valid path returned in ofs->szPathName
170            Are there any cases where getting the path here is wrong?
171            Uwe Bonnes 1997 Apr 2 */
172         if (!GetFullPathNameA( name, sizeof(ofs->szPathName), ofs->szPathName, NULL )) goto error;
173
174         /* If OF_SEARCH is set, ignore the given path */
175
176         filename = name;
177         if ((mode & OF_SEARCH) && !(mode & OF_REOPEN))
178         {
179             /* First try the file name as is */
180             if (GetFileAttributesA( filename ) != INVALID_FILE_ATTRIBUTES) filename = NULL;
181             else
182             {
183                 /* Now remove the path */
184                 if (filename[0] && (filename[1] == ':')) filename += 2;
185                 if ((p = strrchr( filename, '\\' ))) filename = p + 1;
186                 if ((p = strrchr( filename, '/' ))) filename = p + 1;
187                 if (!filename[0])
188                 {
189                     SetLastError( ERROR_FILE_NOT_FOUND );
190                     goto error;
191                 }
192             }
193         }
194
195         /* Now look for the file */
196
197         if (filename)
198         {
199             BOOL found;
200             char *path = get_search_path();
201
202             if (!path) goto error;
203             found = SearchPathA( path, filename, NULL, sizeof(ofs->szPathName),
204                                  ofs->szPathName, NULL );
205             HeapFree( GetProcessHeap(), 0, path );
206             if (!found) goto error;
207         }
208
209         TRACE("found %s\n", debugstr_a(ofs->szPathName) );
210
211         if (mode & OF_DELETE)
212         {
213             if (!DeleteFileA( ofs->szPathName )) goto error;
214             TRACE("(%s): OF_DELETE return = OK\n", name);
215             return 1;
216         }
217
218         handle = (HANDLE)_lopen( ofs->szPathName, mode );
219         if (handle == INVALID_HANDLE_VALUE) goto error;
220
221         GetFileTime( handle, NULL, NULL, &filetime );
222         FileTimeToDosDateTime( &filetime, &filedatetime[0], &filedatetime[1] );
223         if ((mode & OF_VERIFY) && (mode & OF_REOPEN))
224         {
225             if (ofs->Reserved1 != filedatetime[0] || ofs->Reserved2 != filedatetime[1] )
226             {
227                 CloseHandle( handle );
228                 WARN("(%s): OF_VERIFY failed\n", name );
229                 /* FIXME: what error here? */
230                 SetLastError( ERROR_FILE_NOT_FOUND );
231                 goto error;
232             }
233         }
234         ofs->Reserved1 = filedatetime[0];
235         ofs->Reserved2 = filedatetime[1];
236     }
237
238     TRACE("(%s): OK, return = %p\n", name, handle );
239     hFileRet = Win32HandleToDosFileHandle( handle );
240     if (hFileRet == HFILE_ERROR16) goto error;
241     if (mode & OF_EXIST) _lclose16( hFileRet ); /* Return the handle, but close it first */
242     return hFileRet;
243
244 error:  /* We get here if there was an error opening the file */
245     ofs->nErrCode = GetLastError();
246     WARN("(%s): return = HFILE_ERROR error= %d\n", name,ofs->nErrCode );
247     return HFILE_ERROR16;
248 }
249
250
251 /***********************************************************************
252  *           _lclose   (KERNEL.81)
253  */
254 HFILE16 WINAPI _lclose16( HFILE16 hFile )
255 {
256     if ((hFile >= DOS_TABLE_SIZE) || !dos_handles[hFile])
257     {
258         SetLastError( ERROR_INVALID_HANDLE );
259         return HFILE_ERROR16;
260     }
261     TRACE("%d (handle32=%p)\n", hFile, dos_handles[hFile] );
262     CloseHandle( dos_handles[hFile] );
263     dos_handles[hFile] = 0;
264     return 0;
265 }
266
267 /***********************************************************************
268  *           _lcreat   (KERNEL.83)
269  */
270 HFILE16 WINAPI _lcreat16( LPCSTR path, INT16 attr )
271 {
272     return Win32HandleToDosFileHandle( (HANDLE)_lcreat( path, attr ) );
273 }
274
275 /***********************************************************************
276  *           _llseek   (KERNEL.84)
277  *
278  * FIXME:
279  *   Seeking before the start of the file should be allowed for _llseek16,
280  *   but cause subsequent I/O operations to fail (cf. interrupt list)
281  *
282  */
283 LONG WINAPI _llseek16( HFILE16 hFile, LONG lOffset, INT16 nOrigin )
284 {
285     return SetFilePointer( DosFileHandleToWin32Handle(hFile), lOffset, NULL, nOrigin );
286 }
287
288
289 /***********************************************************************
290  *           _lopen   (KERNEL.85)
291  */
292 HFILE16 WINAPI _lopen16( LPCSTR path, INT16 mode )
293 {
294     return Win32HandleToDosFileHandle( (HANDLE)_lopen( path, mode ) );
295 }
296
297
298 /***********************************************************************
299  *           _lread16   (KERNEL.82)
300  */
301 UINT16 WINAPI _lread16( HFILE16 hFile, LPVOID buffer, UINT16 count )
302 {
303     return (UINT16)_lread((HFILE)DosFileHandleToWin32Handle(hFile), buffer, (LONG)count );
304 }
305
306
307 /***********************************************************************
308  *           _lwrite   (KERNEL.86)
309  */
310 UINT16 WINAPI _lwrite16( HFILE16 hFile, LPCSTR buffer, UINT16 count )
311 {
312     return (UINT16)_hwrite( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, (LONG)count );
313 }
314
315 /***********************************************************************
316  *           _hread (KERNEL.349)
317  */
318 LONG WINAPI WIN16_hread( HFILE16 hFile, SEGPTR buffer, LONG count )
319 {
320     LONG maxlen;
321
322     TRACE("%d %08lx %ld\n", hFile, (DWORD)buffer, count );
323
324     /* Some programs pass a count larger than the allocated buffer */
325     maxlen = GetSelectorLimit16( SELECTOROF(buffer) ) - OFFSETOF(buffer) + 1;
326     if (count > maxlen) count = maxlen;
327     return _lread((HFILE)DosFileHandleToWin32Handle(hFile), MapSL(buffer), count );
328 }
329
330
331 /***********************************************************************
332  *           _lread (KERNEL.82)
333  */
334 UINT16 WINAPI WIN16_lread( HFILE16 hFile, SEGPTR buffer, UINT16 count )
335 {
336     return (UINT16)WIN16_hread( hFile, buffer, (LONG)count );
337 }
338
339
340 /***********************************************************************
341  *           GetTempDrive   (KERNEL.92)
342  * A closer look at krnl386.exe shows what the SDK doesn't mention:
343  *
344  * returns:
345  *   AL: driveletter
346  *   AH: ':'            - yes, some kernel code even does stosw with
347  *                            the returned AX.
348  *   DX: 1 for success
349  */
350 UINT WINAPI GetTempDrive( BYTE ignored )
351 {
352     WCHAR buffer[8];
353     BYTE ret;
354
355     if (GetTempPathW( 8, buffer )) ret = (BYTE)toupperW(buffer[0]);
356     else ret = 'C';
357     return MAKELONG( ret | (':' << 8), 1 );
358 }
359
360
361 /***********************************************************************
362  *           GetTempFileName   (KERNEL.97)
363  */
364 UINT16 WINAPI GetTempFileName16( BYTE drive, LPCSTR prefix, UINT16 unique,
365                                  LPSTR buffer )
366 {
367     char temppath[MAX_PATH];
368     char *prefix16 = NULL;
369     UINT16 ret;
370
371     if (!(drive & ~TF_FORCEDRIVE)) /* drive 0 means current default drive */
372     {
373         GetCurrentDirectoryA(sizeof(temppath), temppath); 
374         drive |= temppath[0];
375     }
376
377     if (drive & TF_FORCEDRIVE)
378     {
379         char    d[3];
380
381         d[0] = drive & ~TF_FORCEDRIVE;
382         d[1] = ':';
383         d[2] = '\0';
384         if (GetDriveTypeA(d) == DRIVE_NO_ROOT_DIR)
385         {
386             drive &= ~TF_FORCEDRIVE;
387             WARN("invalid drive %d specified\n", drive );
388         }
389     }
390
391     if (drive & TF_FORCEDRIVE)
392         sprintf(temppath,"%c:", drive & ~TF_FORCEDRIVE );
393     else
394         GetTempPathA( MAX_PATH, temppath );
395
396     if (prefix)
397     {
398         prefix16 = HeapAlloc(GetProcessHeap(), 0, strlen(prefix) + 2);
399         *prefix16 = '~';
400         strcpy(prefix16 + 1, prefix);
401     }
402
403     ret = GetTempFileNameA( temppath, prefix16, unique, buffer );
404
405     HeapFree(GetProcessHeap(), 0, prefix16);
406     return ret;
407 }
408
409
410 /***********************************************************************
411  *           GetPrivateProfileInt   (KERNEL.127)
412  */
413 UINT16 WINAPI GetPrivateProfileInt16( LPCSTR section, LPCSTR entry,
414                                       INT16 def_val, LPCSTR filename )
415 {
416     /* we used to have some elaborate return value limitation (<= -32768 etc.)
417      * here, but Win98SE doesn't care about this at all, so I deleted it.
418      * AFAIR versions prior to Win9x had these limits, though. */
419     return (INT16)GetPrivateProfileIntA(section,entry,def_val,filename);
420 }
421
422
423 /***********************************************************************
424  *           WritePrivateProfileString   (KERNEL.129)
425  */
426 BOOL16 WINAPI WritePrivateProfileString16( LPCSTR section, LPCSTR entry,
427                                            LPCSTR string, LPCSTR filename )
428 {
429     return WritePrivateProfileStringA(section,entry,string,filename);
430 }
431
432
433 /***********************************************************************
434  *           GetWindowsDirectory   (KERNEL.134)
435  */
436 UINT16 WINAPI GetWindowsDirectory16( LPSTR path, UINT16 count )
437 {
438     return GetWindowsDirectoryA( path, count );
439 }
440
441
442 /***********************************************************************
443  *           GetSystemDirectory   (KERNEL.135)
444  */
445 UINT16 WINAPI GetSystemDirectory16( LPSTR path, UINT16 count )
446 {
447     return GetSystemDirectoryA( path, count );
448 }
449
450
451 /***********************************************************************
452  *           GetDriveType   (KERNEL.136)
453  * This function returns the type of a drive in Win16.
454  * Note that it returns DRIVE_REMOTE for CD-ROMs, since MSCDEX uses the
455  * remote drive API. The return value DRIVE_REMOTE for CD-ROMs has been
456  * verified on Win 3.11 and Windows 95. Some programs rely on it, so don't
457  * do any pseudo-clever changes.
458  */
459 UINT16 WINAPI GetDriveType16( UINT16 drive ) /* [in] number (NOT letter) of drive */
460 {
461     UINT type;
462     WCHAR root[3];
463
464     root[0] = 'A' + drive;
465     root[1] = ':';
466     root[2] = 0;
467     type = GetDriveTypeW( root );
468     if (type == DRIVE_CDROM) type = DRIVE_REMOTE;
469     else if (type == DRIVE_NO_ROOT_DIR) type = DRIVE_UNKNOWN;
470     return type;
471 }
472
473
474 /***********************************************************************
475  *           GetProfileSectionNames   (KERNEL.142)
476  */
477 WORD WINAPI GetProfileSectionNames16(LPSTR buffer, WORD size)
478
479 {
480     return GetPrivateProfileSectionNamesA(buffer,size,"win.ini");
481 }
482
483
484 /***********************************************************************
485  *           GetPrivateProfileSectionNames   (KERNEL.143)
486  */
487 WORD WINAPI GetPrivateProfileSectionNames16( LPSTR buffer, WORD size,
488                                              LPCSTR filename )
489 {
490     return GetPrivateProfileSectionNamesA(buffer,size,filename);
491 }
492
493
494 /***********************************************************************
495  *           CreateDirectory   (KERNEL.144)
496  */
497 BOOL16 WINAPI CreateDirectory16( LPCSTR path, LPVOID dummy )
498 {
499     return CreateDirectoryA( path, NULL );
500 }
501
502
503 /***********************************************************************
504  *           RemoveDirectory   (KERNEL.145)
505  */
506 BOOL16 WINAPI RemoveDirectory16( LPCSTR path )
507 {
508     return RemoveDirectoryA( path );
509 }
510
511
512 /***********************************************************************
513  *           DeleteFile   (KERNEL.146)
514  */
515 BOOL16 WINAPI DeleteFile16( LPCSTR path )
516 {
517     return DeleteFileA( path );
518 }
519
520
521 /***********************************************************************
522  *           SetHandleCount   (KERNEL.199)
523  */
524 UINT16 WINAPI SetHandleCount16( UINT16 count )
525 {
526     return SetHandleCount( count );
527 }
528
529
530 /***********************************************************************
531  *           _hread16   (KERNEL.349)
532  */
533 LONG WINAPI _hread16( HFILE16 hFile, LPVOID buffer, LONG count)
534 {
535     return _lread( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, count );
536 }
537
538
539 /***********************************************************************
540  *           _hwrite   (KERNEL.350)
541  */
542 LONG WINAPI _hwrite16( HFILE16 hFile, LPCSTR buffer, LONG count )
543 {
544     return _hwrite( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, count );
545 }
546
547
548 /***********************************************************************
549  *           WritePrivateProfileStruct (KERNEL.406)
550  */
551 BOOL16 WINAPI WritePrivateProfileStruct16 (LPCSTR section, LPCSTR key,
552                                            LPVOID buf, UINT16 bufsize, LPCSTR filename)
553 {
554     return WritePrivateProfileStructA( section, key, buf, bufsize, filename );
555 }
556
557
558 /***********************************************************************
559  *           GetPrivateProfileStruct (KERNEL.407)
560  */
561 BOOL16 WINAPI GetPrivateProfileStruct16(LPCSTR section, LPCSTR key,
562                                         LPVOID buf, UINT16 len, LPCSTR filename)
563 {
564     return GetPrivateProfileStructA( section, key, buf, len, filename );
565 }
566
567
568 /***********************************************************************
569  *           GetCurrentDirectory   (KERNEL.411)
570  */
571 UINT16 WINAPI GetCurrentDirectory16( UINT16 buflen, LPSTR buf )
572 {
573     return GetCurrentDirectoryA( buflen, buf );
574 }
575
576
577 /***********************************************************************
578  *           SetCurrentDirectory   (KERNEL.412)
579  */
580 BOOL16 WINAPI SetCurrentDirectory16( LPCSTR dir )
581 {
582     char fulldir[MAX_PATH];
583
584     if (!GetFullPathNameA( dir, MAX_PATH, fulldir, NULL )) return FALSE;
585
586     if (!SetCurrentDirectoryA( dir )) return FALSE;
587
588     if (fulldir[0] && fulldir[1] == ':')
589     {
590         TDB *pTask = GlobalLock16( GetCurrentTask() );
591         char env_var[4] = "=A:";
592
593         env_var[1] = fulldir[0];
594         SetEnvironmentVariableA( env_var, fulldir );
595
596         /* update the directory in the TDB */
597         if (pTask)
598         {
599             pTask->curdrive = 0x80 | (fulldir[0] - 'A');
600             GetShortPathNameA( fulldir + 2, pTask->curdir, sizeof(pTask->curdir) );
601         }
602     }
603     return TRUE;
604 }
605
606
607 /*************************************************************************
608  *           FindFirstFile   (KERNEL.413)
609  */
610 HANDLE16 WINAPI FindFirstFile16( LPCSTR path, WIN32_FIND_DATAA *data )
611 {
612     HGLOBAL16 h16;
613     HANDLE handle, *ptr;
614
615     if (!(h16 = GlobalAlloc16( GMEM_MOVEABLE, sizeof(handle) ))) return INVALID_HANDLE_VALUE16;
616     ptr = GlobalLock16( h16 );
617     *ptr = handle = FindFirstFileA( path, data );
618     GlobalUnlock16( h16 );
619
620     if (handle == INVALID_HANDLE_VALUE)
621     {
622         GlobalFree16( h16 );
623         h16 = INVALID_HANDLE_VALUE16;
624     }
625     return h16;
626 }
627
628
629 /*************************************************************************
630  *           FindNextFile   (KERNEL.414)
631  */
632 BOOL16 WINAPI FindNextFile16( HANDLE16 handle, WIN32_FIND_DATAA *data )
633 {
634     HANDLE *ptr;
635     BOOL ret = FALSE;
636
637     if ((handle == INVALID_HANDLE_VALUE16) || !(ptr = GlobalLock16( handle )))
638     {
639         SetLastError( ERROR_INVALID_HANDLE );
640         return ret;
641     }
642     ret = FindNextFileA( *ptr, data );
643     GlobalUnlock16( handle );
644     return ret;
645 }
646
647
648 /*************************************************************************
649  *           FindClose   (KERNEL.415)
650  */
651 BOOL16 WINAPI FindClose16( HANDLE16 handle )
652 {
653     HANDLE *ptr;
654
655     if ((handle == INVALID_HANDLE_VALUE16) || !(ptr = GlobalLock16( handle )))
656     {
657         SetLastError( ERROR_INVALID_HANDLE );
658         return FALSE;
659     }
660     FindClose( *ptr );
661     GlobalUnlock16( handle );
662     GlobalFree16( handle );
663     return TRUE;
664 }
665
666
667 /***********************************************************************
668  *           WritePrivateProfileSection   (KERNEL.416)
669  */
670 BOOL16 WINAPI WritePrivateProfileSection16( LPCSTR section,
671                                             LPCSTR string, LPCSTR filename )
672 {
673     return WritePrivateProfileSectionA( section, string, filename );
674 }
675
676
677 /***********************************************************************
678  *           WriteProfileSection   (KERNEL.417)
679  */
680 BOOL16 WINAPI WriteProfileSection16( LPCSTR section, LPCSTR keys_n_values)
681 {
682     return WritePrivateProfileSection16( section, keys_n_values, "win.ini");
683 }
684
685
686 /***********************************************************************
687  *           GetPrivateProfileSection   (KERNEL.418)
688  */
689 INT16 WINAPI GetPrivateProfileSection16( LPCSTR section, LPSTR buffer,
690                                          UINT16 len, LPCSTR filename )
691 {
692     return GetPrivateProfileSectionA( section, buffer, len, filename );
693 }
694
695
696 /***********************************************************************
697  *           GetProfileSection   (KERNEL.419)
698  */
699 INT16 WINAPI GetProfileSection16( LPCSTR section, LPSTR buffer, UINT16 len )
700 {
701     return GetPrivateProfileSection16( section, buffer, len, "win.ini" );
702 }
703
704
705 /**************************************************************************
706  *           GetFileAttributes   (KERNEL.420)
707  */
708 DWORD WINAPI GetFileAttributes16( LPCSTR name )
709 {
710     return GetFileAttributesA( name );
711 }
712
713
714 /**************************************************************************
715  *              SetFileAttributes       (KERNEL.421)
716  */
717 BOOL16 WINAPI SetFileAttributes16( LPCSTR lpFileName, DWORD attributes )
718 {
719     return SetFileAttributesA( lpFileName, attributes );
720 }
721
722
723 /***********************************************************************
724  *           GetDiskFreeSpace   (KERNEL.422)
725  */
726 BOOL16 WINAPI GetDiskFreeSpace16( LPCSTR root, LPDWORD cluster_sectors,
727                                   LPDWORD sector_bytes, LPDWORD free_clusters,
728                                   LPDWORD total_clusters )
729 {
730     return GetDiskFreeSpaceA( root, cluster_sectors, sector_bytes,
731                                 free_clusters, total_clusters );
732 }