Hmm I don't remember that one, it may have gotten lost in the vacation backlog. Could you please resend?
and by the way, this one got lost too A+
Name: ntkrnl_37 ChangeLog: - got rid of FILE_Dup2 export from kernel32 - move all dos handle related code into dlls/kernel32 License: X11 GenDate: 2003/12/07 10:38:48 UTC ModifiedFiles: dlls/kernel/kernel32.spec dlls/kernel/file.c dlls/kernel/file16.c dlls/winedos/int21.c files/file.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/kernel/kernel32.spec,v retrieving revision 1.120 diff -u -u -r1.120 kernel32.spec --- dlls/kernel/kernel32.spec 25 Nov 2003 01:51:07 -0000 1.120 +++ dlls/kernel/kernel32.spec 7 Dec 2003 09:31:21 -0000 @@ -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) Index: dlls/kernel/file.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/kernel/file.c,v retrieving revision 1.4 diff -u -u -r1.4 file.c --- dlls/kernel/file.c 5 Sep 2003 23:08:37 -0000 1.4 +++ dlls/kernel/file.c 7 Dec 2003 10:38:30 -0000 @@ -222,7 +222,6 @@ return (HFILE)CreateFileA( path, access, sharing, NULL, OPEN_EXISTING, 0, 0 ); }
- /*********************************************************************** * _lread (KERNEL32.@) */ @@ -450,3 +449,110 @@ SetLastError(ERROR_UNABLE_TO_MOVE_REPLACEMENT); return FALSE; } + +HANDLE dos_handles[DOS_TABLE_SIZE]; +/*********************************************************************** + * 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); +} + +/*********************************************************************** + * 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; + } +} + + + + + Index: dlls/kernel/file16.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/kernel/file16.c,v retrieving revision 1.4 diff -u -u -r1.4 file16.c --- dlls/kernel/file16.c 15 Nov 2003 00:13:21 -0000 1.4 +++ dlls/kernel/file16.c 7 Dec 2003 10:31:48 -0000 @@ -62,6 +62,21 @@ 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) Index: dlls/winedos/int21.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/winedos/int21.c,v retrieving revision 1.51 diff -u -u -r1.51 int21.c --- dlls/winedos/int21.c 26 Nov 2003 22:29:30 -0000 1.51 +++ dlls/winedos/int21.c 7 Dec 2003 10:35:38 -0000 @@ -3737,6 +3801,44 @@ SET_SI( context, context->Esi + (int)s - (int)filename ); }
+static BOOL INT21_Dup2(HFILE16 hFile1, HFILE16 hFile2) +{ + HFILE16 res; + 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 +4619,7 @@ 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); Index: files/file.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/files/file.c,v retrieving revision 1.195 diff -u -u -r1.195 file.c --- files/file.c 2 Dec 2003 04:48:16 -0000 1.195 +++ files/file.c 7 Dec 2003 10:30:34 -0000 @@ -84,7 +84,6 @@
#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;
/*********************************************************************** @@ -1277,146 +1276,6 @@ HFILE WINAPI OpenFile( LPCSTR name, OFSTRUCT *ofs, UINT mode ) { return FILE_DoOpenFile( name, ofs, mode, TRUE ); -} - - -/*********************************************************************** - * 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; }