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