- got rid of FILE_Dup2 export from kernel32
- move all dos handle related code into dlls/kernel32
This commit is contained in:
parent
53145d96f6
commit
768008fa20
|
@ -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 *
|
||||
**************************************************************************/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
141
files/file.c
141
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)
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue