winedos: implement job file table
Markus Amsler
markus.amsler at oribi.org
Fri Oct 15 09:29:47 CDT 2004
This patch depends on the dos file seperation patch[1].
Tested with [2], [3].
Changelog:
* Implement job file table
[1] http://www.winehq.org/hypermail/wine-patches/2004/10/0173.html
[2] http://oribi.org/linux/wine/win16tests/
[3] http://oribi.org/linux/wine/dostests/
-------------- next part --------------
diff -ur dlls/winedos_filesep/dosexe.h dlls/winedos/dosexe.h
--- dlls/winedos_filesep/dosexe.h 2004-10-12 11:36:58.000000000 +0200
+++ dlls/winedos/dosexe.h 2004-10-14 20:48:15.000000000 +0200
@@ -92,6 +92,21 @@
extern struct DPMI_segments *DOSVM_dpmi_segments;
extern HANDLE sft_handles[SFT_TABLE_SIZE]; /* some kind of a system file table */
+/* DOS file attributes */
+#define ATTR_STDIN 0x0001
+#define ATTR_STDOUT 0x0002
+#define ATTR_NUL 0x0004
+#define ATTR_CLOCK 0x0008
+#define ATTR_FASTCON 0x0010
+#define ATTR_RAW 0x0020
+#define ATTR_NOTEOF 0x0040
+#define ATTR_DEVICE 0x0080
+#define ATTR_REMOVABLE 0x0800
+#define ATTR_NONIBM 0x2000 /* block devices */
+#define ATTR_UNTILBUSY 0x2000 /* char devices */
+#define ATTR_IOCTL 0x4000
+#define ATTR_CHAR 0x8000
+
#if defined(linux) && defined(__i386__) && defined(HAVE_SYS_VM86_H)
# define MZ_SUPPORTED
#endif /* linux-i386 */
@@ -230,6 +245,10 @@
extern UINT WINAPI FILE_SetHandleCount( UINT count );
extern void WINAPI FILE_DisposeLZ32Handle( HANDLE handle );
extern HFILE WINAPI FILE_Close( HFILE hFile );
+extern HFILE FILE_Dup(HFILE handle);
+extern BOOL FILE_Dup2(BYTE dos_from, BYTE dos_to);
+extern BOOL FILE_IsSTDIO(HFILE handle);
+extern WORD FILE_CountFreeHandles();
/* fpu.c */
extern void WINAPI DOSVM_Int34Handler(CONTEXT86*);
diff -ur dlls/winedos_filesep/file.c dlls/winedos/file.c
--- dlls/winedos_filesep/file.c 2004-10-12 17:28:38.000000000 +0200
+++ dlls/winedos/file.c 2004-10-15 15:48:01.000000000 +0200
@@ -3,6 +3,7 @@
*
* Copyright 1993 John Burton
* Copyright 1996, 2004 Alexandre Julliard
+ * Copyright 2004 Markus Amsler
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,6 +22,13 @@
/* FIXME: move some of the int21 code in here */
+/*
+ * Some introduction:
+ * DOS file handles are indices in the job file table (JFT).
+ * Values in the JFT are indices in the system file table (SFT).
+ * In an SFT entry is stored all info to access the file on disk. Here it's a win32 file handle.
+ */
+
#include <stdarg.h>
#include <stdio.h>
@@ -28,12 +36,179 @@
#include "winbase.h"
#include "dosexe.h"
#include "wine/debug.h"
+#include "wine/winbase16.h"
-WINE_DEFAULT_DEBUG_CHANNEL(file);
+WINE_DEFAULT_DEBUG_CHANNEL(dosmem);
/* some kind of a system file table */
HANDLE sft_handles[SFT_TABLE_SIZE];
+#define JFT_AUX 0x00
+#define JFT_STDIO 0x01
+#define JFT_PRN 0x02
+#define JFT_INVALID 0xff
+
+/* the first 3 are default handles for STDIO, AUX, PRN */
+#define SFT_START 0x03
+
+/*
+ * FIXME: From Win16 there's no context, so I can't use CTX_SEG_OFF_TO_LIN.
+ * Will this work in any case?
+ */
+#define MY_SEG_OFF_TO_LIN(seg,off) \
+ (DOSVM_IsWin16 () ? wine_ldt_get_ptr((seg),(off)): PTR_REAL_TO_LIN((seg),(off)))
+
+/***********************************************************************
+ * FILE_GetPSP
+ */
+PDB16* FILE_GetPSP( void ){
+ WORD psp_seg;
+ if (DOSVM_IsWin16())
+ psp_seg = LOWORD (GetCurrentPDB16());
+ else
+ psp_seg = DOSVM_psp;
+
+ return (PDB16*) MY_SEG_OFF_TO_LIN (psp_seg, 0);
+}
+
+/***********************************************************************
+ * FILE_GetJFT
+ *
+ * Gets the start and the size of the current JFT.
+ *
+ */
+LPVOID FILE_GetJFT( WORD *size ){
+ PDB16* psp;
+ LPVOID ret;
+
+ psp = FILE_GetPSP();
+
+ *size = psp->nbFiles;
+ if (*size > 20)
+ ret = (LPVOID) MY_SEG_OFF_TO_LIN (SELECTOROF (psp->fileHandlesPtr), OFFSETOF (psp->fileHandlesPtr));
+ else
+ ret = (LPVOID) psp->fileHandles;
+
+ return ret;
+}
+
+
+#if 0
+/******************************************************************
+ * FILE_DumpJFT
+ *
+ * For debuging only
+ *
+ */
+void FILE_DumpJFT()
+{
+ BYTE *jft; WORD jft_size;
+ jft = FILE_GetJFT (&jft_size);
+ int i;
+
+ TRACE ("jft start=%p size=%d", jft, jft_size);
+ for (i=0; i<jft_size; i++){
+ if(!(i%16)) TRACE ("\n%3d-%3d ", i, i+15);
+ TRACE ("%02x ", jft[i]);
+ }
+ TRACE ("\n");
+
+ TRACE ("sft start=%p ", sft_handles);
+ for (i=0; i<16; i++){
+ if(!(i%16)) TRACE ("\n%3d-%3d ", i, i+15);
+ TRACE ("%p ", sft_handles[i]);
+ }
+ TRACE ("\n");
+
+}
+#endif
+
+
+/******************************************************************
+ * FILE_CountFreeHandles
+ *
+ * Retunrs the number of slots available in the JFT
+ *
+ */
+WORD FILE_CountFreeHandles()
+{
+ BYTE *jft; WORD jft_size;
+ jft = FILE_GetJFT (&jft_size);
+ int i;
+ WORD count = 0;
+
+ for (i = 0; i < jft_size; i++)
+ if (jft[i] == JFT_INVALID)
+ count++;
+
+ return count;
+}
+
+
+/******************************************************************
+ * FILE_HandleDosToJFT
+ *
+ * Returns the JFTHandle from a dos handle.
+ *
+ */
+static const BYTE FILE_HandleDosToJFT(HFILE handle)
+{
+ BYTE *jft; WORD jft_size;
+
+ jft = FILE_GetJFT (&jft_size);
+ if (handle > jft_size || handle < 0 || handle > 255){
+ return JFT_INVALID;
+ }
+
+ return jft[handle];
+}
+
+
+/******************************************************************
+ * FILE_IsSTDIO
+ *
+ * retunrs special properties of file like stdin, stderr, readonly, ..
+ */
+BOOL FILE_IsSTDIO(HFILE handle)
+{
+ return FILE_HandleDosToJFT (handle) == JFT_STDIO;
+}
+
+/******************************************************************
+ * FILE_HandleJFTToDos
+ *
+ * returns the first DosHandle found for this jfthandle
+ * If the jfthandle is not found, a new dos handle will be created
+ */
+static const HFILE FILE_HandleJFTToDos(BYTE jfthandle)
+{
+ BYTE *jft; WORD jft_size;
+ int first_free = -1;
+ int i;
+
+ jft = FILE_GetJFT (&jft_size);
+
+ for (i=0; i<jft_size; i++){
+ if (jft[i] == JFT_INVALID && first_free == -1){
+ first_free = i;
+ }
+ if (jft[i] == jfthandle){
+ return i;
+ }
+ }
+
+ if (first_free==-1){
+ /* out of dos handles */
+ SetLastError (ERROR_TOO_MANY_OPEN_FILES);
+ return HFILE_ERROR;
+ }
+
+ /* jft_handle not found, create a new dos handle */
+ jft[first_free] = jfthandle;
+ return first_free;
+}
+
+
/***********************************************************************
* FILE_InitProcessDosHandles
*
@@ -44,17 +219,17 @@
{
static BOOL init_done /* = FALSE */;
HANDLE cp = GetCurrentProcess();
+
if (init_done) return;
init_done = TRUE;
- DuplicateHandle(cp, GetStdHandle(STD_INPUT_HANDLE), cp, &sft_handles[0],
- 0, TRUE, DUPLICATE_SAME_ACCESS);
- DuplicateHandle(cp, GetStdHandle(STD_OUTPUT_HANDLE), cp, &sft_handles[1],
- 0, TRUE, DUPLICATE_SAME_ACCESS);
- DuplicateHandle(cp, GetStdHandle(STD_ERROR_HANDLE), cp, &sft_handles[2],
+
+ /* Initialize the sft */
+ /* FIXME: stdaux and stdprn are currently redirected to stderror */
+ DuplicateHandle(cp, GetStdHandle(STD_ERROR_HANDLE), cp, &sft_handles[JFT_AUX],
0, TRUE, DUPLICATE_SAME_ACCESS);
- DuplicateHandle(cp, GetStdHandle(STD_ERROR_HANDLE), cp, &sft_handles[3],
+ DuplicateHandle(cp, GetStdHandle(STD_OUTPUT_HANDLE), cp, &sft_handles[JFT_STDIO],
0, TRUE, DUPLICATE_SAME_ACCESS);
- DuplicateHandle(cp, GetStdHandle(STD_ERROR_HANDLE), cp, &sft_handles[4],
+ DuplicateHandle(cp, GetStdHandle(STD_ERROR_HANDLE), cp, &sft_handles[JFT_PRN],
0, TRUE, DUPLICATE_SAME_ACCESS);
}
@@ -73,20 +248,21 @@
HFILE WINAPI FILE_HandleWin32ToDos( HANDLE handle )
{
int i;
-
if (!handle || (handle == INVALID_HANDLE_VALUE))
return HFILE_ERROR;
FILE_InitProcessDosHandles();
- for (i = 0; i < SFT_TABLE_SIZE; i++)
+ for (i = SFT_START; i < SFT_TABLE_SIZE; i++)
if (!sft_handles[i])
{
sft_handles[i] = handle;
+ i = FILE_HandleJFTToDos(i);
TRACE("Got %d for h32 %p\n", i, handle );
- return (HFILE)i;
+ return i;
}
- CloseHandle( handle );
- SetLastError( ERROR_TOO_MANY_OPEN_FILES );
+
+ CloseHandle (handle);
+ SetLastError (ERROR_TOO_MANY_OPEN_FILES);
return HFILE_ERROR;
}
@@ -103,26 +279,83 @@
*/
HANDLE WINAPI FILE_HandleDosToWin32( HFILE handle )
{
- HFILE hfile = handle;
+ BYTE jfth;
- if (hfile < 5) FILE_InitProcessDosHandles();
- if ((hfile >= SFT_TABLE_SIZE) || !sft_handles[hfile])
- {
- SetLastError( ERROR_INVALID_HANDLE );
+ jfth = FILE_HandleDosToJFT (handle);
+ if (jfth == JFT_INVALID){
+ SetLastError (ERROR_INVALID_HANDLE);
return INVALID_HANDLE_VALUE;
}
- return sft_handles[hfile];
+ return sft_handles[jfth];
}
/*************************************************************************
* FILE_SetHandleCount (WINEDOS.@)
*
- * Note: Same behaviour as KERNEL32.DosSetHandleCount.
+ * Note: The maximum handle count is 255 the minimum 20.
+ * Win16 never shrinks the handle count.
+ * On DOS the maximum different files that can be opened is
+ * also restricted by the SFT size which is normally 20.
+ * Here it's 255, but shouldn't break anything.
*/
UINT WINAPI FILE_SetHandleCount( UINT count )
{
- return min( 256, count );
+ BYTE *jft_old; WORD jft_size;
+ BYTE *jft;
+ WORD seg;
+ PDB16* psp;
+ LPSTR ptr;
+ int i;
+
+ psp = FILE_GetPSP();
+ jft_old = FILE_GetJFT (&jft_size);
+
+ TRACE("(%d)\n", count);
+ /*
+ * The allocation strategy is pretty simple:
+ * We allocte just once 256 handles and never reallocate it.
+ * Shrinking is done by setting the handlecount only.
+ */
+ /* force the limits */
+ if (count < 20) count=20;
+ if (count > 255) count=255;
+
+ /* don't ask my why, but on win16 JFT never shrinks */
+ if (DOSVM_IsWin16() && count <= jft_size)
+ return jft_size;
+
+ /* FIXME: what should happen with open files? */
+ for (i = count; i < psp->nbFiles; i++)
+ FILE_Close (i);
+
+ psp->nbFiles = count;
+ jft = MY_SEG_OFF_TO_LIN (SELECTOROF (psp->fileHandlesPtr), OFFSETOF (psp->fileHandlesPtr));
+
+ if( count > 20 && (psp->fileHandlesPtr == 0 || jft_old == jft) ){
+ if (DOSVM_IsWin16()){
+ seg = LOWORD (GlobalDOSAlloc16 (256));
+ psp->fileHandlesPtr = MAKESEGPTR (seg, 0);
+ }else{
+ ptr = DOSMEM_GetBlock (256, &seg);
+ psp->fileHandlesPtr = MAKESEGPTR (seg, 0);
+ }
+ jft = FILE_GetJFT (&jft_size);
+ /* initialize the new jft */
+ memcpy (jft, jft_old, 20);
+ memset (jft+20, JFT_INVALID, 236);
+
+ if (DOSVM_IsWin16()){
+ /*
+ * Win16 stores the selector of the extended JFT in fileHandles[0..1].
+ * No idea why.
+ */
+ psp->fileHandles[0] = seg;
+ psp->fileHandles[1] = (seg & 0xff00) >> 8;
+ }
+ }
+
+ return count;
}
@@ -144,8 +377,7 @@
for (i = 5; i < SFT_TABLE_SIZE; i++)
if (sft_handles[i] == handle)
{
- sft_handles[i] = 0;
- CloseHandle( handle );
+ FILE_Close (FILE_HandleJFTToDos (i));
break;
}
}
@@ -156,15 +388,98 @@
*
* Closes a dos handle.
*/
-HFILE WINAPI FILE_Close( HFILE hFile )
+HFILE WINAPI FILE_Close( HFILE handle )
{
- if ((hFile >= SFT_TABLE_SIZE) || !sft_handles[hFile])
- {
- SetLastError( ERROR_INVALID_HANDLE );
- return HFILE_ERROR16;
- }
- TRACE("%d (handle32=%p)\n", hFile, sft_handles[hFile] );
- CloseHandle( sft_handles[hFile] );
- sft_handles[hFile] = 0;
+ BYTE *jft; WORD jft_size;
+ int i;
+ BOOL result;
+ BOOL is_last = TRUE;
+ int jfth = FILE_HandleDosToJFT (handle);
+
+ jft = FILE_GetJFT (&jft_size);
+
+ if (jfth == JFT_INVALID){
+ SetLastError (ERROR_INVALID_HANDLE);
+ return HFILE_ERROR;
+ }
+
+ /* mark dos handle as invalid */
+ jft[handle] = JFT_INVALID;
+
+ /* Only close the real handle if it's the last one */
+ for (i=0; i<jft_size; i++)
+ if (jft[i] == jfth)
+ is_last = FALSE;
+
+ if (is_last){
+ result = CloseHandle (sft_handles[jfth]);
+ sft_handles[jfth] = 0;
+ if(!result){
+ SetLastError (ERROR_INVALID_HANDLE);
+ return HFILE_ERROR;
+ }
+ }
+
+ TRACE("%d (handle32=%p)\n", handle, sft_handles[jfth] );
+
return 0;
}
+
+
+/******************************************************************
+ * FILE_Dup2
+ *
+ * Force Duplication of Dos Handle.
+ *
+ */
+BOOL FILE_Dup2(BYTE dos_from, BYTE dos_to)
+{
+ BYTE *jft; WORD jft_size;
+ jft = FILE_GetJFT (&jft_size);
+
+ TRACE ("(%d, %d)\n", dos_from, dos_to);
+
+ int jfth = FILE_HandleDosToJFT (dos_from);
+ if (dos_to > jft_size || jfth == JFT_INVALID){
+ SetLastError (ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ FILE_Close (dos_to);
+ jft[dos_to] = jfth;
+ return TRUE;
+}
+
+
+/******************************************************************
+ * FILE_Dup
+ *
+ * Duplication of Dos Handle, takes the first free slot.
+ *
+ */
+HFILE FILE_Dup(HFILE handle)
+{
+ BYTE *jft; WORD jft_size;
+ int jfth = FILE_HandleDosToJFT (handle);
+ int i;
+
+ jft = FILE_GetJFT (&jft_size);
+
+ TRACE ("(%d)\n", handle);
+
+ if (jfth == JFT_INVALID){
+ SetLastError (ERROR_INVALID_HANDLE);
+ return HFILE_ERROR;
+ }
+
+ for (i=0; i<jft_size; i++){
+ if (jft[i] == JFT_INVALID){
+ jft[i] = jfth;
+ return i;
+ }
+ }
+
+ /* out of dos handles */
+ SetLastError (ERROR_TOO_MANY_OPEN_FILES);
+ return HFILE_ERROR;
+}
diff -ur dlls/winedos_filesep/int21.c dlls/winedos/int21.c
--- dlls/winedos_filesep/int21.c 2004-10-12 11:35:46.000000000 +0200
+++ dlls/winedos/int21.c 2004-10-15 11:50:38.000000000 +0200
@@ -954,6 +954,12 @@
"create flags=%04x, file=%s.\n",
AH_reg(context), dosAction, dosAccessShare, CX_reg(context), pathA );
+ /* DOS Handles available ? */
+ if (FILE_CountFreeHandles() == 0){
+ SetLastError( ERROR_TOO_MANY_OPEN_FILES );
+ return FALSE;
+ }
+
/*
* Application tried to create/open a file whose name
* ends with a backslash. This is not allowed.
@@ -2762,22 +2768,13 @@
TRACE( "IOCTL - GET DEVICE INFORMATION - %d\n", BX_reg(context) );
if (S_ISCHR(st.st_mode))
{
- /*
- * Returns attribute word in DX:
- * Bit 14 - Device driver can process IOCTL requests.
- * Bit 13 - Output until busy supported.
- * Bit 11 - Driver supports OPEN/CLOSE calls.
- * Bit 8 - Unknown.
- * Bit 7 - Set (indicates device).
- * Bit 6 - EOF on input.
- * Bit 5 - Raw (binary) mode.
- * Bit 4 - Device is special (uses int29).
- * Bit 3 - Clock device.
- * Bit 2 - NUL device.
- * Bit 1 - Standard output.
- * Bit 0 - Standard input.
- */
- SET_DX( context, 0x80c0 /* FIXME */ );
+ /* Returns attribute word in DX. */
+ WORD ret = ATTR_CHAR | ATTR_DEVICE | ATTR_NOTEOF;
+ if (FILE_IsSTDIO(BX_reg(context)))
+ ret |= ATTR_STDIN | ATTR_STDOUT | ATTR_FASTCON;
+ if (st.st_dev == 0x0301) /* FIXME: is this check for /dev/null correct? */
+ ret |= ATTR_NUL;
+ SET_DX( context, ret );
}
else
{
@@ -4051,44 +4048,6 @@
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 = FILE_HandleDosToWin32(hFile1);
- if (handle == INVALID_HANDLE_VALUE)
- return FALSE;
-
- FILE_Close(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 = FILE_HandleWin32ToDos(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)))
- FILE_Close((HFILE16)i);
- }
- return res == hFile2;
-}
-
-
/***********************************************************************
* DOSVM_Int21Handler
*
@@ -4767,9 +4726,8 @@
BX_reg(context), CX_reg(context) );
{
BYTE *ptr = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
-
- if (!DOSVM_IsWin16() &&
- (BX_reg(context) == 1 || BX_reg(context) == 2))
+ HFILE handle = BX_reg(context);
+ if (!DOSVM_IsWin16() && FILE_IsSTDIO (handle) )
{
int i;
for(i=0; i<CX_reg(context); i++)
@@ -4846,16 +4804,7 @@
case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */
TRACE( "DUPLICATE FILE HANDLE %d\n", BX_reg(context) );
{
- HANDLE handle32;
- HFILE handle16 = HFILE_ERROR;
-
- if (DuplicateHandle( GetCurrentProcess(),
- FILE_HandleDosToWin32(BX_reg(context)),
- GetCurrentProcess(),
- &handle32,
- 0, TRUE, DUPLICATE_SAME_ACCESS ))
- handle16 = FILE_HandleWin32ToDos(handle32);
-
+ HFILE handle16 = FILE_Dup (BX_reg (context));
if (handle16 == HFILE_ERROR)
bSetDOSExtendedError = TRUE;
else
@@ -4869,7 +4818,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 (!INT21_Dup2(BX_reg(context), CX_reg(context)))
+ if (!FILE_Dup2(BX_reg(context), CX_reg(context)))
bSetDOSExtendedError = TRUE;
else
RESET_CFLAG(context);
diff -ur dlls/winedos_filesep/module.c dlls/winedos/module.c
--- dlls/winedos_filesep/module.c 2004-10-12 10:49:11.000000000 +0200
+++ dlls/winedos/module.c 2004-10-15 13:47:01.000000000 +0200
@@ -124,6 +124,13 @@
psp->savedint24 = DOSVM_GetRMHandler(0x24);
psp->parentPSP=par;
psp->environment=env;
+ psp->nbFiles=20;
+ psp->fileHandles[0] = 1;
+ psp->fileHandles[1] = 1;
+ psp->fileHandles[2] = 1;
+ psp->fileHandles[3] = 0;
+ psp->fileHandles[4] = 2;
+ memset(psp->fileHandles + 5, 0xff, 15);
/* FIXME: more PSP stuff */
}
@@ -680,6 +687,8 @@
/* free process's associated memory
* FIXME: walk memory and deallocate all blocks owned by process */
DOSMEM_FreeBlock( PTR_REAL_TO_LIN(psp->environment,0) );
+ if (SELECTOROF(psp->fileHandlesPtr))
+ DOSMEM_FreeBlock( PTR_REAL_TO_LIN(SELECTOROF(psp->fileHandlesPtr),0) );
DOSMEM_FreeBlock( PTR_REAL_TO_LIN(DOSVM_psp,0) );
/* switch to parent's PSP */
DOSVM_psp = parpsp;
diff -ur dlls/kernel_filesep/task.c dlls/kernel/task.c
--- dlls/kernel_filesep/task.c 2004-05-01 07:25:08.000000000 +0200
+++ dlls/kernel/task.c 2004-10-15 14:37:52.000000000 +0200
@@ -316,7 +316,13 @@
pTask->pdb.fileHandlesPtr =
MAKESEGPTR( GlobalHandleToSel16(pTask->hPDB), (int)&((PDB16 *)0)->fileHandles );
pTask->pdb.hFileHandles = 0;
- memset( pTask->pdb.fileHandles, 0xff, sizeof(pTask->pdb.fileHandles) );
+ /* init the job file table */
+ pTask->pdb.fileHandles[0] = 1;
+ pTask->pdb.fileHandles[1] = 1;
+ pTask->pdb.fileHandles[2] = 1;
+ pTask->pdb.fileHandles[3] = 0;
+ pTask->pdb.fileHandles[4] = 2;
+ memset( pTask->pdb.fileHandles + 5, 0xff, 15);
/* FIXME: should we make a copy of the environment? */
pTask->pdb.environment = SELECTOROF(GetDOSEnvironment16());
pTask->pdb.nbFiles = 20;
More information about the wine-patches
mailing list