2 * File handling functions
4 * Copyright 1993 John Burton
5 * Copyright 1996 Alexandre Julliard
12 #include <sys/errno.h>
18 #include "directory.h"
30 /***********************************************************************
33 * Set the DOS error code from errno.
35 void FILE_SetDosError(void)
40 DOS_ERROR( ER_ShareViolation
, EC_Temporary
, SA_Retry
, EL_Disk
);
43 DOS_ERROR( ER_InvalidHandle
, EC_ProgramError
, SA_Abort
, EL_Disk
);
46 DOS_ERROR( ER_DiskFull
, EC_MediaError
, SA_Abort
, EL_Disk
);
51 DOS_ERROR( ER_WriteProtected
, EC_AccessDenied
, SA_Abort
, EL_Disk
);
54 DOS_ERROR( ER_LockViolation
, EC_AccessDenied
, SA_Abort
, EL_Disk
);
57 DOS_ERROR( ER_FileNotFound
, EC_NotFound
, SA_Abort
, EL_Disk
);
60 DOS_ERROR( ER_CanNotMakeDir
, EC_AccessDenied
, SA_Abort
, EL_Unknown
);
64 DOS_ERROR( ER_NoMoreFiles
, EC_MediaError
, SA_Abort
, EL_Unknown
);
67 DOS_ERROR( ER_FileExists
, EC_Exists
, SA_Abort
, EL_Disk
);
70 perror( "int21: unknown errno" );
71 DOS_ERROR( ER_GeneralFailure
, EC_SystemFailure
, SA_Abort
, EL_Unknown
);
77 /***********************************************************************
78 * FILE_AllocTaskHandle
80 * Allocate a DOS file handle for the current task.
82 static HFILE
FILE_AllocTaskHandle( int handle
)
84 PDB
*pdb
= (PDB
*)GlobalLock( GetCurrentPDB() );
90 fprintf(stderr
,"FILE_MakeTaskHandle: internal error, no current PDB.\n");
93 fp
= files
= PTR_SEG_TO_LIN( pdb
->fileHandlesPtr
);
94 for (i
= pdb
->nbFiles
; (i
> 0) && (*fp
!= 0xff); i
--, fp
++);
95 if (!i
|| (handle
>= 0xff)) /* No more handles */
97 DOS_ERROR( ER_TooManyOpenFiles
, EC_ProgramError
, SA_Abort
, EL_Disk
);
101 return (HFILE
)(fp
- files
);
105 /***********************************************************************
106 * FILE_FreeTaskHandle
108 * Free a DOS file handle for the current task.
110 static void FILE_FreeTaskHandle( HFILE handle
)
112 PDB
*pdb
= (PDB
*)GlobalLock( GetCurrentPDB() );
117 fprintf(stderr
,"FILE_FreeTaskHandle: internal error, no current PDB.\n");
120 files
= PTR_SEG_TO_LIN( pdb
->fileHandlesPtr
);
121 if ((handle
<0) || (handle
>= (INT
)pdb
->nbFiles
) || (files
[handle
] == 0xff))
123 fprintf( stderr
, "FILE_FreeTaskHandle: invalid file handle %d\n",
127 files
[handle
] = 0xff;
131 /***********************************************************************
134 * Return the Unix file handle associated to a DOS file handle.
136 int FILE_GetUnixHandle( HFILE handle
)
138 PDB
*pdb
= (PDB
*)GlobalLock( GetCurrentPDB() );
143 fprintf(stderr
,"FILE_GetUnixHandle: internal error, no current PDB.\n");
146 files
= PTR_SEG_TO_LIN( pdb
->fileHandlesPtr
);
147 if ((handle
<0) || (handle
>= (INT
)pdb
->nbFiles
) || (files
[handle
] == 0xff))
149 DOS_ERROR( ER_InvalidHandle
, EC_ProgramError
, SA_Abort
, EL_Disk
);
152 return (int)files
[handle
];
156 /***********************************************************************
159 * Close all open files of a given PDB. Used on task termination.
161 void FILE_CloseAllFiles( HANDLE hPDB
)
165 PDB
*pdb
= (PDB
*)GlobalLock( hPDB
);
168 files
= PTR_SEG_TO_LIN( pdb
->fileHandlesPtr
);
169 for (count
= pdb
->nbFiles
; count
> 0; count
--, files
++)
173 close( (int)*files
);
180 /***********************************************************************
183 int FILE_Open( LPCSTR path
, int mode
)
185 const char *unixName
;
188 dprintf_file(stddeb
, "FILE_Open: '%s' %04x\n", path
, mode
);
189 if ((unixName
= DOSFS_IsDevice( path
)) != NULL
)
191 dprintf_file( stddeb
, "FILE_Open: opening device '%s'\n", unixName
);
192 if (!unixName
[0]) /* Non-existing device */
194 DOS_ERROR( ER_FileNotFound
, EC_NotFound
, SA_Abort
, EL_Disk
);
197 handle
= open( unixName
, mode
);
201 if (!(unixName
= DOSFS_GetUnixFileName( path
, TRUE
))) return -1;
203 if ((handle
= open( unixName
, mode
)) == -1)
205 if (Options
.allowReadOnly
&& (mode
== O_RDWR
))
207 if ((handle
= open( unixName
, O_RDONLY
)) != -1)
208 fprintf( stderr
, "Warning: could not open %s for writing, opening read-only.\n", unixName
);
212 if (handle
== -1) FILE_SetDosError();
217 /***********************************************************************
220 int FILE_Create( LPCSTR path
, int mode
, int unique
)
222 const char *unixName
;
225 dprintf_file(stddeb
, "FILE_Create: '%s' %04x %d\n", path
, mode
, unique
);
227 if ((unixName
= DOSFS_IsDevice( path
)) != NULL
)
229 dprintf_file(stddeb
, "FILE_Create: creating device '%s'!\n", unixName
);
230 DOS_ERROR( ER_AccessDenied
, EC_NotFound
, SA_Abort
, EL_Disk
);
234 if (!(unixName
= DOSFS_GetUnixFileName( path
, FALSE
))) return -1;
235 if ((handle
= open( unixName
,
236 O_CREAT
| O_TRUNC
| O_RDWR
| (unique
? O_EXCL
: 0),
243 /***********************************************************************
246 int FILE_Unlink( LPCSTR path
)
248 const char *unixName
;
250 dprintf_file(stddeb
, "FILE_Unlink: '%s'\n", path
);
252 if ((unixName
= DOSFS_IsDevice( path
)) != NULL
)
254 dprintf_file(stddeb
, "FILE_Unlink: removing device '%s'!\n", unixName
);
255 DOS_ERROR( ER_FileNotFound
, EC_NotFound
, SA_Abort
, EL_Disk
);
259 if (!(unixName
= DOSFS_GetUnixFileName( path
, TRUE
))) return 0;
260 if (unlink( unixName
) == -1)
269 /***********************************************************************
272 * Stat a Unix path name. Return 1 if OK.
274 int FILE_Stat( LPCSTR unixName
, BYTE
*pattr
, DWORD
*psize
,
275 WORD
*pdate
, WORD
*ptime
)
279 if (stat( unixName
, &st
) == -1)
284 if (pattr
) *pattr
= FA_ARCHIVE
| (S_ISDIR(st
.st_mode
) ? FA_DIRECTORY
: 0);
285 if (psize
) *psize
= st
.st_size
;
286 DOSFS_ToDosDateTime( &st
.st_mtime
, pdate
, ptime
);
291 /***********************************************************************
294 * Stat a DOS handle. Return 1 if OK.
296 int FILE_Fstat( HFILE hFile
, BYTE
*pattr
, DWORD
*psize
,
297 WORD
*pdate
, WORD
*ptime
)
302 if ((handle
= FILE_GetUnixHandle( hFile
)) == -1) return 0;
303 if (fstat( handle
, &st
) == -1)
308 if (pattr
) *pattr
= FA_ARCHIVE
| (S_ISDIR(st
.st_mode
) ? FA_DIRECTORY
: 0);
309 if (psize
) *psize
= st
.st_size
;
310 DOSFS_ToDosDateTime( &st
.st_mtime
, pdate
, ptime
);
315 /***********************************************************************
318 int FILE_MakeDir( LPCSTR path
)
320 const char *unixName
;
322 dprintf_file(stddeb
, "FILE_MakeDir: '%s'\n", path
);
324 if ((unixName
= DOSFS_IsDevice( path
)) != NULL
)
326 dprintf_file(stddeb
, "FILE_MakeDir: device '%s'!\n", unixName
);
327 DOS_ERROR( ER_AccessDenied
, EC_AccessDenied
, SA_Abort
, EL_Disk
);
330 if (!(unixName
= DOSFS_GetUnixFileName( path
, TRUE
))) return 0;
331 if ((mkdir( unixName
, 0777 ) == -1) && (errno
!= EEXIST
))
340 /***********************************************************************
343 int FILE_RemoveDir( LPCSTR path
)
345 const char *unixName
;
347 dprintf_file(stddeb
, "FILE_RemoveDir: '%s'\n", path
);
349 if ((unixName
= DOSFS_IsDevice( path
)) != NULL
)
351 dprintf_file(stddeb
, "FILE_RemoveDir: device '%s'!\n", unixName
);
352 DOS_ERROR( ER_FileNotFound
, EC_NotFound
, SA_Abort
, EL_Disk
);
355 if (!(unixName
= DOSFS_GetUnixFileName( path
, TRUE
))) return 0;
356 if (rmdir( unixName
) == -1)
365 /***********************************************************************
368 * dup() function for DOS handles.
370 HFILE
FILE_Dup( HFILE hFile
)
372 int handle
, newhandle
;
375 if ((handle
= FILE_GetUnixHandle( hFile
)) == -1) return HFILE_ERROR
;
376 if ((newhandle
= dup(handle
)) == -1)
381 if ((dosHandle
= FILE_AllocTaskHandle( newhandle
)) == HFILE_ERROR
)
387 /***********************************************************************
390 * dup2() function for DOS handles.
392 HFILE
FILE_Dup2( HFILE hFile1
, HFILE hFile2
)
394 PDB
*pdb
= (PDB
*)GlobalLock( GetCurrentPDB() );
396 int handle
, newhandle
;
398 if ((handle
= FILE_GetUnixHandle( hFile1
)) == -1) return HFILE_ERROR
;
399 if ((hFile2
< 0) || (hFile2
>= (INT
)pdb
->nbFiles
))
401 DOS_ERROR( ER_InvalidHandle
, EC_ProgramError
, SA_Abort
, EL_Disk
);
405 if ((newhandle
= dup(handle
)) == -1)
410 if (newhandle
>= 0xff)
412 DOS_ERROR( ER_TooManyOpenFiles
, EC_ProgramError
, SA_Abort
, EL_Disk
);
416 files
= PTR_SEG_TO_LIN( pdb
->fileHandlesPtr
);
417 if (files
[hFile2
] != 0xff) close( files
[hFile2
] );
418 files
[hFile2
] = (BYTE
)newhandle
;
423 /***********************************************************************
426 * Implementation of API function OpenFile(). Returns a Unix file handle.
428 int FILE_OpenFile( LPCSTR name
, OFSTRUCT
*ofs
, UINT mode
)
430 const char *unixName
, *dosName
;
432 int handle
, len
, i
, unixMode
;
435 ofs
->cBytes
= sizeof(OFSTRUCT
);
437 if (mode
& OF_REOPEN
) name
= ofs
->szPathName
;
438 dprintf_file( stddeb
, "Openfile: %s %04x\n", name
, mode
);
440 /* OF_PARSE simply fills the structure */
444 if (!(dosName
= DOSFS_GetDosTrueName( name
, FALSE
)))
446 ofs
->nErrCode
= DOS_ExtendedError
;
449 lstrcpyn( ofs
->szPathName
, dosName
, sizeof(ofs
->szPathName
) );
450 ofs
->fFixedDisk
= (GetDriveType( dosName
[0]-'A' ) != DRIVE_REMOVABLE
);
454 /* OF_CREATE is completely different from all other options, so
457 if (mode
& OF_CREATE
)
459 if ((unixName
= DOSFS_GetUnixFileName( name
, FALSE
)) == NULL
)
461 ofs
->nErrCode
= DOS_ExtendedError
;
464 dprintf_file( stddeb
, "OpenFile: creating '%s'\n", unixName
);
465 handle
= open( unixName
, O_TRUNC
| O_RDWR
| O_CREAT
, 0666 );
469 ofs
->nErrCode
= DOS_ExtendedError
;
472 lstrcpyn( ofs
->szPathName
, DOSFS_GetDosTrueName( name
, FALSE
),
473 sizeof(ofs
->szPathName
) );
477 /* Now look for the file */
479 /* First try the current directory */
481 lstrcpyn( ofs
->szPathName
, name
, sizeof(ofs
->szPathName
) );
482 if ((unixName
= DOSFS_GetUnixFileName( ofs
->szPathName
, TRUE
)) != NULL
)
485 /* Now try some different paths if none was specified */
487 if ((mode
& OF_SEARCH
) && !(mode
& OF_REOPEN
))
489 if (name
[1] == ':') name
+= 2;
490 if ((p
= strrchr( name
, '\\' ))) name
= p
+ 1;
491 if ((p
= strrchr( name
, '/' ))) name
= p
+ 1;
492 if (!name
[0]) goto not_found
;
496 if ((name
[1] == ':') || strchr( name
, '/' ) || strchr( name
, '\\' ))
500 if ((len
= sizeof(ofs
->szPathName
) - strlen(name
) - 1) < 0) goto not_found
;
502 /* Try the Windows directory */
504 GetWindowsDirectory( ofs
->szPathName
, len
);
505 strcat( ofs
->szPathName
, "\\" );
506 strcat( ofs
->szPathName
, name
);
507 if ((unixName
= DOSFS_GetUnixFileName( ofs
->szPathName
, TRUE
)) != NULL
)
510 /* Try the Windows system directory */
512 GetSystemDirectory( ofs
->szPathName
, len
);
513 strcat( ofs
->szPathName
, "\\" );
514 strcat( ofs
->szPathName
, name
);
515 if ((unixName
= DOSFS_GetUnixFileName( ofs
->szPathName
, TRUE
)) != NULL
)
518 /* Try the path of the current executable */
520 if (GetCurrentTask())
522 GetModuleFileName( GetCurrentTask(), ofs
->szPathName
, len
);
523 if ((p
= strrchr( ofs
->szPathName
, '\\' )))
525 strcpy( p
+ 1, name
);
526 if ((unixName
= DOSFS_GetUnixFileName( ofs
->szPathName
, TRUE
)))
531 /* Try all directories in path */
535 if (!DIR_GetDosPath( i
, ofs
->szPathName
, len
)) break;
536 strcat( ofs
->szPathName
, "\\" );
537 strcat( ofs
->szPathName
, name
);
538 if ((unixName
= DOSFS_GetUnixFileName( ofs
->szPathName
, TRUE
)) != NULL
)
543 dprintf_file( stddeb
, "OpenFile: '%s' not found\n", name
);
544 DOS_ERROR( ER_FileNotFound
, EC_NotFound
, SA_Abort
, EL_Disk
);
545 ofs
->nErrCode
= ER_FileNotFound
;
549 dprintf_file( stddeb
, "OpenFile: found '%s'\n", unixName
);
550 lstrcpyn( ofs
->szPathName
, DOSFS_GetDosTrueName( ofs
->szPathName
, FALSE
),
551 sizeof(ofs
->szPathName
) );
553 if (mode
& OF_PARSE
) return 0;
555 if (mode
& OF_DELETE
)
557 if (unlink( unixName
) == -1) goto not_found
;
564 unixMode
= O_WRONLY
; break;
566 unixMode
= O_RDWR
; break;
569 unixMode
= O_RDONLY
; break;
572 if ((handle
= open( unixName
, unixMode
)) == -1)
574 if (Options
.allowReadOnly
&& (unixMode
== O_RDWR
))
576 if ((handle
= open( unixName
, O_RDONLY
)) != -1)
577 fprintf( stderr
, "Warning: could not open %s for writing, opening read-only.\n", unixName
);
580 if (handle
== -1) goto not_found
;
582 if (fstat( handle
, &st
) != -1)
584 if ((mode
& OF_VERIFY
) && (mode
& OF_REOPEN
))
586 if (memcmp( ofs
->reserved
, &st
.st_mtime
, sizeof(ofs
->reserved
) ))
589 memcpy( ofs
->reserved
, &st
.st_mtime
, sizeof(ofs
->reserved
) );
592 if (mode
& OF_EXIST
) close( handle
);
598 /***********************************************************************
599 * GetTempFileName (KERNEL.97)
601 INT
GetTempFileName( BYTE drive
, LPCSTR prefix
, UINT unique
, LPSTR buffer
)
604 UINT num
= unique
? (unique
& 0xffff) : time(NULL
) & 0xffff;
607 if (drive
& TF_FORCEDRIVE
)
609 sprintf( buffer
, "%c:", drive
& ~TF_FORCEDRIVE
);
613 DIR_GetTempDosDir( buffer
, 132 ); /* buffer must be at least 144 */
614 strcat( buffer
, "\\" );
617 p
= buffer
+ strlen(buffer
);
618 for (i
= 3; (i
> 0) && (*prefix
); i
--) *p
++ = *prefix
++;
619 sprintf( p
, "%04x.tmp", num
);
623 lstrcpyn( buffer
, DOSFS_GetDosTrueName( buffer
, FALSE
), 144 );
624 dprintf_file( stddeb
, "GetTempFileName: returning %s\n", buffer
);
628 /* Now try to create it */
632 if ((handle
= FILE_Create( buffer
, 0666, TRUE
)) != -1)
633 { /* We created it */
634 dprintf_file( stddeb
, "GetTempFileName: created %s\n", buffer
);
638 if (DOS_ExtendedError
!= ER_FileExists
) break; /* No need to go on */
640 sprintf( p
, "%04x.tmp", num
);
641 } while (num
!= (unique
& 0xffff));
643 lstrcpyn( buffer
, DOSFS_GetDosTrueName( buffer
, FALSE
), 144 );
644 dprintf_file( stddeb
, "GetTempFileName: returning %s\n", buffer
);
649 /***********************************************************************
650 * OpenFile (KERNEL.74)
652 HFILE
OpenFile( LPCSTR name
, OFSTRUCT
*ofs
, UINT mode
)
657 if ((unixHandle
= FILE_OpenFile( name
, ofs
, mode
)) == -1)
659 if ((handle
= FILE_AllocTaskHandle( unixHandle
)) == HFILE_ERROR
)
661 ofs
->nErrCode
= DOS_ExtendedError
;
662 if (unixHandle
) close( unixHandle
);
664 if (!unixHandle
) FILE_FreeTaskHandle( handle
);
669 /***********************************************************************
670 * _lclose (KERNEL.81)
672 HFILE
_lclose( HFILE hFile
)
676 dprintf_file( stddeb
, "_lclose: handle %d\n", hFile
);
678 if ((handle
= FILE_GetUnixHandle( hFile
)) == -1) return HFILE_ERROR
;
681 fprintf( stderr
, "_lclose: internal error: closing handle %d\n", handle
);
684 FILE_FreeTaskHandle( hFile
);
690 /***********************************************************************
693 INT
_lread( HFILE hFile
, LPSTR buffer
, WORD count
)
695 return (INT
)_hread( hFile
, buffer
, (LONG
)count
);
699 /***********************************************************************
700 * _lcreat (KERNEL.83)
702 INT
_lcreat( LPCSTR path
, INT attr
)
704 int unixHandle
, mode
;
707 dprintf_file( stddeb
, "_lcreat: %s %02x\n", path
, attr
);
708 mode
= (attr
& 1) ? 0444 : 0666;
709 if ((unixHandle
= FILE_Create( path
, mode
, FALSE
)) == -1)
711 if ((handle
= FILE_AllocTaskHandle( unixHandle
)) == HFILE_ERROR
)
717 /***********************************************************************
718 * _lcreat_uniq (Not a Windows API)
720 INT
_lcreat_uniq( LPCSTR path
, INT attr
)
722 int unixHandle
, mode
;
725 dprintf_file( stddeb
, "_lcreat: %s %02x\n", path
, attr
);
726 mode
= (attr
& 1) ? 0444 : 0666;
727 if ((unixHandle
= FILE_Create( path
, mode
, TRUE
)) == -1)
729 if ((handle
= FILE_AllocTaskHandle( unixHandle
)) == HFILE_ERROR
)
735 /***********************************************************************
736 * _llseek (KERNEL.84)
738 LONG
_llseek( HFILE hFile
, LONG lOffset
, INT nOrigin
)
740 int handle
, origin
, result
;
742 dprintf_file( stddeb
, "_llseek: handle %d, offset %ld, origin %d\n",
743 hFile
, lOffset
, nOrigin
);
745 if ((handle
= FILE_GetUnixHandle( hFile
)) == -1) return HFILE_ERROR
;
748 case 1: origin
= SEEK_CUR
; break;
749 case 2: origin
= SEEK_END
; break;
750 default: origin
= SEEK_SET
; break;
753 if ((result
= lseek( handle
, lOffset
, origin
)) == -1) FILE_SetDosError();
754 return (result
== -1) ? HFILE_ERROR
: result
;
758 /***********************************************************************
761 HFILE
_lopen( LPCSTR path
, INT mode
)
767 dprintf_file(stddeb
, "_lopen('%s',%04x)\n", path
, mode
);
772 unixMode
= O_WRONLY
| O_TRUNC
;
782 if ((unixHandle
= FILE_Open( path
, unixMode
)) == -1) return HFILE_ERROR
;
783 if ((handle
= FILE_AllocTaskHandle( unixHandle
)) == HFILE_ERROR
)
789 /***********************************************************************
790 * _lwrite (KERNEL.86)
792 INT
_lwrite( HFILE hFile
, LPCSTR buffer
, WORD count
)
794 return (INT
)_hwrite( hFile
, buffer
, (LONG
)count
);
798 /***********************************************************************
799 * _hread (KERNEL.349)
801 LONG
_hread( HFILE hFile
, LPSTR buffer
, LONG count
)
806 dprintf_file( stddeb
, "_hread: %d %p %ld\n", hFile
, buffer
, count
);
808 if ((handle
= FILE_GetUnixHandle( hFile
)) == -1) return HFILE_ERROR
;
809 if (!count
) return 0;
810 if ((result
= read( handle
, buffer
, count
)) == -1) FILE_SetDosError();
811 return (result
== -1) ? HFILE_ERROR
: result
;
815 /***********************************************************************
816 * _hwrite (KERNEL.350)
818 LONG
_hwrite( HFILE hFile
, LPCSTR buffer
, LONG count
)
823 dprintf_file( stddeb
, "_hwrite: %d %p %ld\n", hFile
, buffer
, count
);
825 if ((handle
= FILE_GetUnixHandle( hFile
)) == -1) return HFILE_ERROR
;
827 if (count
== 0) /* Expand or truncate at current position */
828 result
= ftruncate( handle
, lseek( handle
, 0, SEEK_CUR
) );
830 result
= write( handle
, buffer
, count
);
832 if (result
== -1) FILE_SetDosError();
833 return (result
== -1) ? HFILE_ERROR
: result
;
837 /***********************************************************************
838 * SetHandleCount (KERNEL.199)
840 WORD
SetHandleCount( WORD count
)
842 HANDLE hPDB
= GetCurrentPDB();
843 PDB
*pdb
= (PDB
*)GlobalLock( hPDB
);
844 BYTE
*files
= PTR_SEG_TO_LIN( pdb
->fileHandlesPtr
);
847 dprintf_file( stddeb
, "SetHandleCount(%d)\n", count
);
849 if (count
< 20) count
= 20; /* No point in going below 20 */
850 else if (count
> 254) count
= 254;
852 /* If shrinking the table, make sure all extra file handles are closed */
853 if (count
< pdb
->nbFiles
)
855 for (i
= count
; i
< pdb
->nbFiles
; i
++)
856 if (files
[i
] != 0xff) /* File open */
858 DOS_ERROR( ER_TooManyOpenFiles
, EC_ProgramError
,
866 if (pdb
->nbFiles
> 20)
868 memcpy( pdb
->fileHandles
, files
, 20 );
870 GlobalFree( pdb
->fileHandlesPtr
);
871 pdb
->fileHandlesPtr
= pdb
->fileHandles
;
873 GlobalFree( GlobalHandle( SELECTOROF(pdb
->fileHandlesPtr
) ));
874 pdb
->fileHandlesPtr
= (SEGPTR
)MAKELONG( 0x18,
875 GlobalHandleToSel( hPDB
) );
880 else /* More than 20, need a new file handles table */
883 HANDLE newhandle
= GlobalAlloc( GMEM_MOVEABLE
, count
);
886 DOS_ERROR( ER_OutOfMemory
, EC_OutOfResource
, SA_Abort
, EL_Memory
);
889 newfiles
= (BYTE
*)GlobalLock( newhandle
);
890 if (count
> pdb
->nbFiles
)
892 memcpy( newfiles
, files
, pdb
->nbFiles
);
893 memset( newfiles
+ pdb
->nbFiles
, 0xff, count
- pdb
->nbFiles
);
895 else memcpy( newfiles
, files
, count
);
897 if (pdb
->nbFiles
> 20) GlobalFree( pdb
->fileHandlesPtr
);
899 if (pdb
->nbFiles
> 20)
900 GlobalFree( GlobalHandle( SELECTOROF(pdb
->fileHandlesPtr
) ));
902 pdb
->fileHandlesPtr
= WIN16_GlobalLock( newhandle
);
903 pdb
->nbFiles
= count
;