Commit 768008fa authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

- got rid of FILE_Dup2 export from kernel32

- move all dos handle related code into dlls/kernel32
parent 53145d96
......@@ -46,11 +46,39 @@
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.@)
*
* Check the result of an Asynchronous data transfer from a file.
......@@ -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);
......
......@@ -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)
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment