- 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);
|
WINE_DEFAULT_DEBUG_CHANNEL(file);
|
||||||
|
|
||||||
|
HANDLE dos_handles[DOS_TABLE_SIZE];
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* Operations on file handles *
|
* 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.@)
|
* 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 );
|
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 *
|
* Operations on file names *
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
|
@ -62,6 +62,21 @@ LONG WINAPI _hwrite16( HFILE16 hFile, LPCSTR buffer, LONG count )
|
||||||
return _hwrite( (HFILE)DosFileHandleToWin32Handle(hFile), buffer, 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)
|
* _lcreat (KERNEL.83)
|
||||||
|
|
|
@ -1147,7 +1147,6 @@
|
||||||
@ cdecl DOSMEM_GetBlock(long ptr)
|
@ cdecl DOSMEM_GetBlock(long ptr)
|
||||||
@ cdecl DOSMEM_Init(long)
|
@ cdecl DOSMEM_Init(long)
|
||||||
@ cdecl DOSMEM_ResizeBlock(ptr long long)
|
@ cdecl DOSMEM_ResizeBlock(ptr long long)
|
||||||
@ cdecl FILE_Dup2(long long)
|
|
||||||
@ cdecl LOCAL_Alloc(long long long)
|
@ cdecl LOCAL_Alloc(long long long)
|
||||||
@ cdecl LOCAL_Compact(long long long)
|
@ cdecl LOCAL_Compact(long long long)
|
||||||
@ cdecl LOCAL_CountFree(long)
|
@ cdecl LOCAL_CountFree(long)
|
||||||
|
|
|
@ -3737,6 +3737,44 @@ static void INT21_ParseFileNameIntoFCB( CONTEXT86 *context )
|
||||||
SET_SI( context, context->Esi + (int)s - (int)filename );
|
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
|
* DOSVM_Int21Handler
|
||||||
*
|
*
|
||||||
|
@ -4517,8 +4555,7 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
|
||||||
case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */
|
case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */
|
||||||
TRACE( "FORCEDUP - FORCE DUPLICATE FILE HANDLE %d to %d\n",
|
TRACE( "FORCEDUP - FORCE DUPLICATE FILE HANDLE %d to %d\n",
|
||||||
BX_reg(context), CX_reg(context) );
|
BX_reg(context), CX_reg(context) );
|
||||||
|
if (!INT21_Dup2(BX_reg(context), CX_reg(context)))
|
||||||
if (FILE_Dup2( BX_reg(context), CX_reg(context) ) == HFILE_ERROR16)
|
|
||||||
bSetDOSExtendedError = TRUE;
|
bSetDOSExtendedError = TRUE;
|
||||||
else
|
else
|
||||||
RESET_CFLAG(context);
|
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')
|
#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;
|
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)
|
* FILE_ReadWriteApc (internal)
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue