From 768008fa20098948460df12e14a94f82d793a29f Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Wed, 14 Jan 2004 04:34:20 +0000 Subject: [PATCH] - got rid of FILE_Dup2 export from kernel32 - move all dos handle related code into dlls/kernel32 --- dlls/kernel/file.c | 105 ++++++++++++++++++++++++++++ dlls/kernel/file16.c | 15 ++++ dlls/kernel/kernel32.spec | 1 - dlls/winedos/int21.c | 41 ++++++++++- files/file.c | 141 -------------------------------------- 5 files changed, 159 insertions(+), 144 deletions(-) diff --git a/dlls/kernel/file.c b/dlls/kernel/file.c index 6767b94d3ba..701d39bfd80 100644 --- a/dlls/kernel/file.c +++ b/dlls/kernel/file.c @@ -46,10 +46,38 @@ WINE_DEFAULT_DEBUG_CHANNEL(file); +HANDLE dos_handles[DOS_TABLE_SIZE]; + /************************************************************************** * Operations on file handles * **************************************************************************/ +/*********************************************************************** + * FILE_InitProcessDosHandles + * + * Allocates the default DOS handles for a process. Called either by + * Win32HandleToDosFileHandle below or by the DOSVM stuff. + */ +static void FILE_InitProcessDosHandles( void ) +{ + static BOOL init_done /* = FALSE */; + HANDLE cp = GetCurrentProcess(); + + if (init_done) return; + init_done = TRUE; + DuplicateHandle(cp, GetStdHandle(STD_INPUT_HANDLE), cp, &dos_handles[0], + 0, TRUE, DUPLICATE_SAME_ACCESS); + DuplicateHandle(cp, GetStdHandle(STD_OUTPUT_HANDLE), cp, &dos_handles[1], + 0, TRUE, DUPLICATE_SAME_ACCESS); + DuplicateHandle(cp, GetStdHandle(STD_ERROR_HANDLE), cp, &dos_handles[2], + 0, TRUE, DUPLICATE_SAME_ACCESS); + DuplicateHandle(cp, GetStdHandle(STD_ERROR_HANDLE), cp, &dos_handles[3], + 0, TRUE, DUPLICATE_SAME_ACCESS); + DuplicateHandle(cp, GetStdHandle(STD_ERROR_HANDLE), cp, &dos_handles[4], + 0, TRUE, DUPLICATE_SAME_ACCESS); +} + + /*********************************************************************** * GetOverlappedResult (KERNEL32.@) * @@ -420,6 +448,83 @@ BOOL WINAPI UnlockFileEx( HANDLE hFile, DWORD reserved, DWORD count_low, DWORD c return UnlockFile( hFile, overlapped->Offset, overlapped->OffsetHigh, count_low, count_high ); } + +/*********************************************************************** + * Win32HandleToDosFileHandle (KERNEL32.21) + * + * Allocate a DOS handle for a Win32 handle. The Win32 handle is no + * longer valid after this function (even on failure). + * + * Note: this is not exactly right, since on Win95 the Win32 handles + * are on top of DOS handles and we do it the other way + * around. Should be good enough though. + */ +HFILE WINAPI Win32HandleToDosFileHandle( HANDLE handle ) +{ + int i; + + if (!handle || (handle == INVALID_HANDLE_VALUE)) + return HFILE_ERROR; + + FILE_InitProcessDosHandles(); + for (i = 0; i < DOS_TABLE_SIZE; i++) + if (!dos_handles[i]) + { + dos_handles[i] = handle; + TRACE("Got %d for h32 %p\n", i, handle ); + return (HFILE)i; + } + CloseHandle( handle ); + SetLastError( ERROR_TOO_MANY_OPEN_FILES ); + return HFILE_ERROR; +} + + +/*********************************************************************** + * DosFileHandleToWin32Handle (KERNEL32.20) + * + * Return the Win32 handle for a DOS handle. + * + * Note: this is not exactly right, since on Win95 the Win32 handles + * are on top of DOS handles and we do it the other way + * around. Should be good enough though. + */ +HANDLE WINAPI DosFileHandleToWin32Handle( HFILE handle ) +{ + HFILE16 hfile = (HFILE16)handle; + if (hfile < 5) FILE_InitProcessDosHandles(); + if ((hfile >= DOS_TABLE_SIZE) || !dos_handles[hfile]) + { + SetLastError( ERROR_INVALID_HANDLE ); + return INVALID_HANDLE_VALUE; + } + return dos_handles[hfile]; +} + + +/*********************************************************************** + * DisposeLZ32Handle (KERNEL32.22) + * + * Note: this is not entirely correct, we should only close the + * 32-bit handle and not the 16-bit one, but we cannot do + * this because of the way our DOS handles are implemented. + * It shouldn't break anything though. + */ +void WINAPI DisposeLZ32Handle( HANDLE handle ) +{ + int i; + + if (!handle || (handle == INVALID_HANDLE_VALUE)) return; + + for (i = 5; i < DOS_TABLE_SIZE; i++) + if (dos_handles[i] == handle) + { + dos_handles[i] = 0; + CloseHandle( handle ); + break; + } +} + /************************************************************************** * Operations on file names * **************************************************************************/ diff --git a/dlls/kernel/file16.c b/dlls/kernel/file16.c index c034b4a71c1..e6704e1b5bc 100644 --- a/dlls/kernel/file16.c +++ b/dlls/kernel/file16.c @@ -62,6 +62,21 @@ LONG WINAPI _hwrite16( HFILE16 hFile, LPCSTR buffer, LONG count ) return _hwrite( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, count ); } +/*********************************************************************** + * _lclose (KERNEL.81) + */ +HFILE16 WINAPI _lclose16( HFILE16 hFile ) +{ + if ((hFile >= DOS_TABLE_SIZE) || !dos_handles[hFile]) + { + SetLastError( ERROR_INVALID_HANDLE ); + return HFILE_ERROR16; + } + TRACE("%d (handle32=%p)\n", hFile, dos_handles[hFile] ); + CloseHandle( dos_handles[hFile] ); + dos_handles[hFile] = 0; + return 0; +} /*********************************************************************** * _lcreat (KERNEL.83) diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec index 5d6dcff7557..59a347fbdfc 100644 --- a/dlls/kernel/kernel32.spec +++ b/dlls/kernel/kernel32.spec @@ -1147,7 +1147,6 @@ @ cdecl DOSMEM_GetBlock(long ptr) @ cdecl DOSMEM_Init(long) @ cdecl DOSMEM_ResizeBlock(ptr long long) -@ cdecl FILE_Dup2(long long) @ cdecl LOCAL_Alloc(long long long) @ cdecl LOCAL_Compact(long long long) @ cdecl LOCAL_CountFree(long) diff --git a/dlls/winedos/int21.c b/dlls/winedos/int21.c index dd0d016d5b5..4f7a9e36ed6 100644 --- a/dlls/winedos/int21.c +++ b/dlls/winedos/int21.c @@ -3737,6 +3737,44 @@ static void INT21_ParseFileNameIntoFCB( CONTEXT86 *context ) SET_SI( context, context->Esi + (int)s - (int)filename ); } +static BOOL INT21_Dup2(HFILE16 hFile1, HFILE16 hFile2) +{ + HFILE16 res = HFILE_ERROR16; + HANDLE handle, new_handle; +#define DOS_TABLE_SIZE 256 + DWORD map[DOS_TABLE_SIZE / 32]; + int i; + + handle = DosFileHandleToWin32Handle(hFile1); + if (handle == INVALID_HANDLE_VALUE) + return FALSE; + + _lclose16(hFile2); + /* now loop to allocate the same one... */ + memset(map, 0, sizeof(map)); + for (i = 0; i < DOS_TABLE_SIZE; i++) + { + if (!DuplicateHandle(GetCurrentProcess(), handle, + GetCurrentProcess(), &new_handle, + 0, FALSE, DUPLICATE_SAME_ACCESS)) + { + res = HFILE_ERROR16; + break; + } + res = Win32HandleToDosFileHandle(new_handle); + if (res == HFILE_ERROR16 || res == hFile2) break; + map[res / 32] |= 1 << (res % 32); + } + /* clean up the allocated slots */ + for (i = 0; i < DOS_TABLE_SIZE; i++) + { + if (map[i / 32] & (1 << (i % 32))) + _lclose16((HFILE16)i); + } + return res == hFile2; +} + + /*********************************************************************** * DOSVM_Int21Handler * @@ -4517,8 +4555,7 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */ TRACE( "FORCEDUP - FORCE DUPLICATE FILE HANDLE %d to %d\n", BX_reg(context), CX_reg(context) ); - - if (FILE_Dup2( BX_reg(context), CX_reg(context) ) == HFILE_ERROR16) + if (!INT21_Dup2(BX_reg(context), CX_reg(context))) bSetDOSExtendedError = TRUE; else RESET_CFLAG(context); diff --git a/files/file.c b/files/file.c index 4857181d059..ff3cf60b862 100644 --- a/files/file.c +++ b/files/file.c @@ -84,7 +84,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(file); #define IS_OPTION_TRUE(ch) ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1') -HANDLE dos_handles[DOS_TABLE_SIZE]; mode_t FILE_umask; /*********************************************************************** @@ -1162,146 +1161,6 @@ HFILE WINAPI OpenFile( LPCSTR name, OFSTRUCT *ofs, UINT mode ) } -/*********************************************************************** - * FILE_InitProcessDosHandles - * - * Allocates the default DOS handles for a process. Called either by - * Win32HandleToDosFileHandle below or by the DOSVM stuff. - */ -static void FILE_InitProcessDosHandles( void ) -{ - HANDLE cp = GetCurrentProcess(); - DuplicateHandle(cp, GetStdHandle(STD_INPUT_HANDLE), cp, &dos_handles[0], - 0, TRUE, DUPLICATE_SAME_ACCESS); - DuplicateHandle(cp, GetStdHandle(STD_OUTPUT_HANDLE), cp, &dos_handles[1], - 0, TRUE, DUPLICATE_SAME_ACCESS); - DuplicateHandle(cp, GetStdHandle(STD_ERROR_HANDLE), cp, &dos_handles[2], - 0, TRUE, DUPLICATE_SAME_ACCESS); - DuplicateHandle(cp, GetStdHandle(STD_ERROR_HANDLE), cp, &dos_handles[3], - 0, TRUE, DUPLICATE_SAME_ACCESS); - DuplicateHandle(cp, GetStdHandle(STD_ERROR_HANDLE), cp, &dos_handles[4], - 0, TRUE, DUPLICATE_SAME_ACCESS); -} - -/*********************************************************************** - * Win32HandleToDosFileHandle (KERNEL32.21) - * - * Allocate a DOS handle for a Win32 handle. The Win32 handle is no - * longer valid after this function (even on failure). - * - * Note: this is not exactly right, since on Win95 the Win32 handles - * are on top of DOS handles and we do it the other way - * around. Should be good enough though. - */ -HFILE WINAPI Win32HandleToDosFileHandle( HANDLE handle ) -{ - int i; - - if (!handle || (handle == INVALID_HANDLE_VALUE)) - return HFILE_ERROR; - - for (i = 5; i < DOS_TABLE_SIZE; i++) - if (!dos_handles[i]) - { - dos_handles[i] = handle; - TRACE("Got %d for h32 %p\n", i, handle ); - return (HFILE)i; - } - CloseHandle( handle ); - SetLastError( ERROR_TOO_MANY_OPEN_FILES ); - return HFILE_ERROR; -} - - -/*********************************************************************** - * DosFileHandleToWin32Handle (KERNEL32.20) - * - * Return the Win32 handle for a DOS handle. - * - * Note: this is not exactly right, since on Win95 the Win32 handles - * are on top of DOS handles and we do it the other way - * around. Should be good enough though. - */ -HANDLE WINAPI DosFileHandleToWin32Handle( HFILE handle ) -{ - HFILE16 hfile = (HFILE16)handle; - if (hfile < 5 && !dos_handles[hfile]) FILE_InitProcessDosHandles(); - if ((hfile >= DOS_TABLE_SIZE) || !dos_handles[hfile]) - { - SetLastError( ERROR_INVALID_HANDLE ); - return INVALID_HANDLE_VALUE; - } - return dos_handles[hfile]; -} - - -/*********************************************************************** - * DisposeLZ32Handle (KERNEL32.22) - * - * Note: this is not entirely correct, we should only close the - * 32-bit handle and not the 16-bit one, but we cannot do - * this because of the way our DOS handles are implemented. - * It shouldn't break anything though. - */ -void WINAPI DisposeLZ32Handle( HANDLE handle ) -{ - int i; - - if (!handle || (handle == INVALID_HANDLE_VALUE)) return; - - for (i = 5; i < DOS_TABLE_SIZE; i++) - if (dos_handles[i] == handle) - { - dos_handles[i] = 0; - CloseHandle( handle ); - break; - } -} - - -/*********************************************************************** - * FILE_Dup2 - * - * dup2() function for DOS handles. - */ -HFILE16 FILE_Dup2( HFILE16 hFile1, HFILE16 hFile2 ) -{ - HANDLE new_handle; - - if (hFile1 < 5 && !dos_handles[hFile1]) FILE_InitProcessDosHandles(); - - if ((hFile1 >= DOS_TABLE_SIZE) || (hFile2 >= DOS_TABLE_SIZE) || !dos_handles[hFile1]) - { - SetLastError( ERROR_INVALID_HANDLE ); - return HFILE_ERROR16; - } - if (!DuplicateHandle( GetCurrentProcess(), dos_handles[hFile1], - GetCurrentProcess(), &new_handle, - 0, FALSE, DUPLICATE_SAME_ACCESS )) - return HFILE_ERROR16; - if (dos_handles[hFile2]) CloseHandle( dos_handles[hFile2] ); - dos_handles[hFile2] = new_handle; - return hFile2; -} - - -/*********************************************************************** - * _lclose (KERNEL.81) - */ -HFILE16 WINAPI _lclose16( HFILE16 hFile ) -{ - if ((hFile >= DOS_TABLE_SIZE) || !dos_handles[hFile]) - { - SetLastError( ERROR_INVALID_HANDLE ); - return HFILE_ERROR16; - } - TRACE("%d (handle32=%p)\n", hFile, dos_handles[hFile] ); - CloseHandle( dos_handles[hFile] ); - dos_handles[hFile] = 0; - return 0; -} - - /****************************************************************** * FILE_ReadWriteApc (internal) *