Index: trunk/src/helpers/dosh2.c
===================================================================
--- trunk/src/helpers/dosh2.c	(revision 66)
+++ trunk/src/helpers/dosh2.c	(revision 67)
@@ -797,8 +797,7 @@
  *      -- ERROR_NOT_ENOUGH_MEMORY: malloc() failed.
  *
- *      -- ERROR_INVALID_EXE_SIGNATURE: specified file
- *              has no DOS EXE header, or it does, but
- *              the extended header is neither LX nor
- *              NE nor PE.
+ *      -- ERROR_INVALID_EXE_SIGNATURE: unknown
+ *          executable type... the given file probably
+ *          isn't even an executable.
  *
  *      -- ERROR_INVALID_PARAMETER: ppExec is NULL.
@@ -806,4 +805,23 @@
  *      plus those of DosOpen, DosSetFilePtr, and
  *      DosRead.
+ *
+ *      The following executable types are supported
+ *      (see EXECUTABLE for details):
+ *
+ *      --  Plain DOS 3.x executable without new header.
+ *
+ *      --  New Executable (NE), used by Win16 and
+ *          16-bit OS/2 and still many of today's drivers.
+ *
+ *      --  Linear Executable (LX), OS/2 2.x and above.
+ *
+ *      --  Portable Executable (PE), used by Win32.
+ *
+ *      V0.9.12 adds support for NOSTUB executables,
+ *      which are new-style executables (NE or LX)
+ *      without a leading DOS header. The executable
+ *      then starts directly with the NE or LX header.
+ *      I am not sure whether PE supports such things
+ *      as well... if so, it should be supported too.
  *
  *@@added V0.9.0 [umoeller]
@@ -812,4 +830,5 @@
  *@@changed V0.9.10 (2001-04-08) [lafaix]: added PE support
  *@@changed V0.9.10 (2001-04-08) [umoeller]: now setting ppExec only if NO_ERROR is returned
+ *@@changed V0.9.12 (2001-05-03) [umoeller]: added support for NOSTUB newstyle executables
  */
 
@@ -870,7 +889,25 @@
                )
             {
+                ULONG ulNewHeaderOfs = 0;       // V0.9.12 (2001-05-03) [umoeller]
+                BOOL  fLoadNewHeader = FALSE;
+
                 // now check if we really have a DOS header
                 if (pExec->pDosExeHeader->usDosExeID != 0x5a4d)
-                    arc = ERROR_INVALID_EXE_SIGNATURE;
+                {
+                    // arc = ERROR_INVALID_EXE_SIGNATURE;
+
+                    // V0.9.12 (2001-05-03) [umoeller]
+                    // try loading new header directly; there are
+                    // drivers which were built with NOSTUB, and
+                    // the exe image starts out with the NE or LX
+                    // image directly
+                    fLoadNewHeader = TRUE;
+                            // ulNewHeaderOfs is 0 now
+
+                    // remove the DOS header info, since we have none
+                    // V0.9.12 (2001-05-03) [umoeller]
+                    free (pExec->pDosExeHeader);
+                    pExec->pDosExeHeader = 0;
+                }
                 else
                 {
@@ -884,129 +921,139 @@
                     else
                     {
-                        // either LX or PE or NE:
-                        // read more bytes from position specified in header
-                        CHAR    achNewHeaderType[2] = "";
-
-                        if (    (!(arc = DosSetFilePtr(hFile,
-                                                       pExec->pDosExeHeader->ulNewHeaderOfs,
-                                                       FILE_BEGIN,
-                                                       &ulLocal)))
-                                // read two chars to find out header type
-                             && (!(arc = DosRead(hFile,
-                                                 &achNewHeaderType,
-                                                 sizeof(achNewHeaderType),
-                                                 &ulBytesRead)))
-                           )
+                        // we have a new header offset:
+                        fLoadNewHeader = TRUE;
+                        ulNewHeaderOfs = pExec->pDosExeHeader->ulNewHeaderOfs;
+                    }
+                }
+
+                if (fLoadNewHeader)
+                {
+                    // either LX or PE or NE:
+                    // read in new header...
+                    // ulNewHeaderOfs is now either 0 (if no DOS header
+                    // was found) or pDosExeHeader->ulNewHeaderOfs
+                    // V0.9.12 (2001-05-03) [umoeller]
+                    CHAR    achNewHeaderType[2] = "";
+
+                    if (    (!(arc = DosSetFilePtr(hFile,
+                                                   ulNewHeaderOfs,
+                                                   FILE_BEGIN,
+                                                   &ulLocal)))
+                            // read two chars to find out header type
+                         && (!(arc = DosRead(hFile,
+                                             &achNewHeaderType,
+                                             sizeof(achNewHeaderType),
+                                             &ulBytesRead)))
+                       )
+                    {
+                        PBYTE   pbCheckOS = NULL;
+
+                        // reset file ptr
+                        DosSetFilePtr(hFile,
+                                      ulNewHeaderOfs,
+                                      FILE_BEGIN,
+                                      &ulLocal);
+
+                        if (memcmp(achNewHeaderType, "NE", 2) == 0)
                         {
-                            PBYTE   pbCheckOS = NULL;
-
-                            // reset file ptr
-                            DosSetFilePtr(hFile,
-                                          pExec->pDosExeHeader->ulNewHeaderOfs,
-                                          FILE_BEGIN,
-                                          &ulLocal);
-
-                            if (memcmp(achNewHeaderType, "NE", 2) == 0)
+                            // New Executable:
+                            pExec->ulExeFormat = EXEFORMAT_NE;
+                            // allocate NE header
+                            pExec->pNEHeader = (PNEHEADER)malloc(sizeof(NEHEADER));
+                            if (!(pExec->pNEHeader))
+                                arc = ERROR_NOT_ENOUGH_MEMORY;
+                            else
+                                // read in NE header
+                                if (!(arc = DosRead(hFile,
+                                                    pExec->pNEHeader,
+                                                    sizeof(NEHEADER),
+                                                    &(pExec->cbNEHeader))))
+                                    if (pExec->cbNEHeader == sizeof(NEHEADER))
+                                        pbCheckOS = &(pExec->pNEHeader->bTargetOS);
+                        }
+                        else if (   (memcmp(achNewHeaderType, "LX", 2) == 0)
+                                 || (memcmp(achNewHeaderType, "LE", 2) == 0)
+                                            // this is used by SMARTDRV.EXE
+                                )
+                        {
+                            // OS/2 Linear Executable:
+                            pExec->ulExeFormat = EXEFORMAT_LX;
+                            // allocate LX header
+                            pExec->pLXHeader = (PLXHEADER)malloc(sizeof(LXHEADER));
+                            if (!(pExec->pLXHeader))
+                                arc = ERROR_NOT_ENOUGH_MEMORY;
+                            else
+                                // read in LX header
+                                if (!(arc = DosRead(hFile,
+                                                    pExec->pLXHeader,
+                                                    sizeof(LXHEADER),
+                                                    &(pExec->cbLXHeader))))
+                                    if (pExec->cbLXHeader == sizeof(LXHEADER))
+                                        pbCheckOS = (PBYTE)(&(pExec->pLXHeader->usTargetOS));
+                        }
+                        else if (memcmp(achNewHeaderType, "PE", 2) == 0)
+                        {
+                            PEHEADER PEHeader = {0};
+
+                            pExec->ulExeFormat = EXEFORMAT_PE;
+                            pExec->ulOS = EXEOS_WIN32;
+                            pExec->f32Bits = TRUE;
+
+                            // V0.9.10 (2001-04-08) [lafaix]
+                            // read in standard PE header
+                            if (!(arc = DosRead(hFile,
+                                                &PEHeader,
+                                                24,
+                                                &ulBytesRead)))
                             {
-                                // New Executable:
-                                pExec->ulExeFormat = EXEFORMAT_NE;
-                                // allocate NE header
-                                pExec->pNEHeader = (PNEHEADER)malloc(sizeof(NEHEADER));
-                                if (!(pExec->pNEHeader))
+                                // allocate PE header
+                                pExec->pPEHeader = (PPEHEADER)malloc(24 + PEHeader.usHeaderSize);
+                                if (!(pExec->pPEHeader))
                                     arc = ERROR_NOT_ENOUGH_MEMORY;
                                 else
-                                    // read in NE header
+                                {
+                                    // copy standard PE header
+                                    memcpy(pExec->pPEHeader,
+                                           &PEHeader,
+                                           24);
+
+                                    // read in optional PE header
                                     if (!(arc = DosRead(hFile,
-                                                        pExec->pNEHeader,
-                                                        sizeof(NEHEADER),
-                                                        &(pExec->cbNEHeader))))
-                                        if (pExec->cbNEHeader == sizeof(NEHEADER))
-                                            pbCheckOS = &(pExec->pNEHeader->bTargetOS);
-                            }
-                            else if (   (memcmp(achNewHeaderType, "LX", 2) == 0)
-                                     || (memcmp(achNewHeaderType, "LE", 2) == 0)
-                                                // this is used by SMARTDRV.EXE
-                                    )
-                            {
-                                // OS/2 Linear Executable:
-                                pExec->ulExeFormat = EXEFORMAT_LX;
-                                // allocate LX header
-                                pExec->pLXHeader = (PLXHEADER)malloc(sizeof(LXHEADER));
-                                if (!(pExec->pLXHeader))
-                                    arc = ERROR_NOT_ENOUGH_MEMORY;
-                                else
-                                    // read in LX header
-                                    if (!(arc = DosRead(hFile,
-                                                        pExec->pLXHeader,
-                                                        sizeof(LXHEADER),
-                                                        &(pExec->cbLXHeader))))
-                                        if (pExec->cbLXHeader == sizeof(LXHEADER))
-                                            pbCheckOS = (PBYTE)(&(pExec->pLXHeader->usTargetOS));
-                            }
-                            else if (memcmp(achNewHeaderType, "PE", 2) == 0)
-                            {
-                                PEHEADER PEHeader = {0};
-
-                                pExec->ulExeFormat = EXEFORMAT_PE;
-                                pExec->ulOS = EXEOS_WIN32;
-                                pExec->f32Bits = TRUE;
-
-                                // V0.9.10 (2001-04-08) [lafaix]
-                                // read in standard PE header
-                                if (!(arc = DosRead(hFile,
-                                                    &PEHeader,
-                                                    24,
-                                                    &ulBytesRead)))
-                                {
-                                    // allocate PE header
-                                    pExec->pPEHeader = (PPEHEADER)malloc(24 + PEHeader.usHeaderSize);
-                                    if (!(pExec->pPEHeader))
-                                        arc = ERROR_NOT_ENOUGH_MEMORY;
-                                    else
-                                    {
-                                        // copy standard PE header
-                                        memcpy(pExec->pPEHeader,
-                                               &PEHeader,
-                                               24);
-
-                                        // read in optional PE header
-                                        if (!(arc = DosRead(hFile,
-                                                            &(pExec->pPEHeader->usReserved3),
-                                                            PEHeader.usHeaderSize,
-                                                            &(pExec->cbPEHeader))))
-                                            pExec->cbPEHeader += 24;
-                                    }
+                                                        &(pExec->pPEHeader->usReserved3),
+                                                        PEHeader.usHeaderSize,
+                                                        &(pExec->cbPEHeader))))
+                                        pExec->cbPEHeader += 24;
                                 }
                             }
-                            else
-                                // strange type:
-                                arc = ERROR_INVALID_EXE_SIGNATURE;
-
-                            if (pbCheckOS)
-                                // BYTE to check for operating system
-                                // (NE and LX):
-                                switch (*pbCheckOS)
-                                {
-                                    case NEOS_OS2:
-                                        pExec->ulOS = EXEOS_OS2;
-                                        if (pExec->ulExeFormat == EXEFORMAT_LX)
-                                            pExec->f32Bits = TRUE;
-                                    break;
-
-                                    case NEOS_WIN16:
-                                        pExec->ulOS = EXEOS_WIN16;
-                                    break;
-
-                                    case NEOS_DOS4:
-                                        pExec->ulOS = EXEOS_DOS4;
-                                    break;
-
-                                    case NEOS_WIN386:
-                                        pExec->ulOS = EXEOS_WIN386;
+                        }
+                        else
+                            // strange type:
+                            arc = ERROR_INVALID_EXE_SIGNATURE;
+
+                        if (pbCheckOS)
+                            // BYTE to check for operating system
+                            // (NE and LX):
+                            switch (*pbCheckOS)
+                            {
+                                case NEOS_OS2:
+                                    pExec->ulOS = EXEOS_OS2;
+                                    if (pExec->ulExeFormat == EXEFORMAT_LX)
                                         pExec->f32Bits = TRUE;
-                                    break;
-                                }
-                        } // end if (!(arc = DosSetFilePtr(hFile,
-                    }
+                                break;
+
+                                case NEOS_WIN16:
+                                    pExec->ulOS = EXEOS_WIN16;
+                                break;
+
+                                case NEOS_DOS4:
+                                    pExec->ulOS = EXEOS_DOS4;
+                                break;
+
+                                case NEOS_WIN386:
+                                    pExec->ulOS = EXEOS_WIN386;
+                                    pExec->f32Bits = TRUE;
+                                break;
+                            }
+                    } // end if (!(arc = DosSetFilePtr(hFile,
                 }
             } // end if (!(arc = DosSetFilePtr(hFile,
@@ -1273,4 +1320,5 @@
  *@@changed V0.9.10 (2001-04-10) [lafaix]: added Win16 and Win386 support
  *@@changed V0.9.10 (2001-04-13) [lafaix]: removed 127 characters limit
+ *@@changed V0.9.12 (2001-05-03) [umoeller]: adjusted for new NOSTUB support
  */
 
@@ -1291,4 +1339,10 @@
         int i;
 
+        ULONG ulNewHeaderOfs = 0;       // V0.9.12 (2001-05-03) [umoeller]
+
+        if (pExec->pDosExeHeader)
+            // executable has DOS stub: V0.9.12 (2001-05-03) [umoeller]
+            ulNewHeaderOfs = pExec->pDosExeHeader->ulNewHeaderOfs;
+
         if (pExec->ulExeFormat == EXEFORMAT_LX)
         {
@@ -1298,6 +1352,6 @@
             if (cModules)
             {
-                ULONG cb = sizeof(FSYSMODULE) * cModules; // V0.9.9 (2001-04-03) [umoeller]
-                ULONG ulDummy;
+                ULONG   cb = sizeof(FSYSMODULE) * cModules; // V0.9.9 (2001-04-03) [umoeller]
+                ULONG   ulDummy;
 
                 paModules = (PFSYSMODULE)malloc(cb);
@@ -1309,5 +1363,5 @@
                 ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
                                           pExec->pLXHeader->ulImportModTblOfs
-                                            + pExec->pDosExeHeader->ulNewHeaderOfs,
+                                            + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
                                           FILE_BEGIN,
                                           &ulDummy));
@@ -1360,5 +1414,5 @@
                     ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
                                               pExec->pNEHeader->usModRefTblOfs
-                                                + pExec->pDosExeHeader->ulNewHeaderOfs
+                                                + ulNewHeaderOfs // V0.9.12 (2001-05-03) [umoeller]
                                                 + sizeof(usOfs) * i,
                                               FILE_BEGIN,
@@ -1369,5 +1423,5 @@
                     ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
                                               pExec->pNEHeader->usImportTblOfs
-                                                + pExec->pDosExeHeader->ulNewHeaderOfs
+                                                + ulNewHeaderOfs // V0.9.12 (2001-05-03) [umoeller]
                                                 + usOfs,
                                               FILE_BEGIN,
@@ -1384,5 +1438,5 @@
                 } // end for
             }
-        }
+        } // end NE
         else
             ENSURE_FAIL(ERROR_INVALID_EXE_SIGNATURE); // V0.9.9 (2001-04-03) [umoeller]
@@ -1426,4 +1480,5 @@
  *@@changed V0.9.9 (2001-04-03) [umoeller]: added tons of error checking, changed prototype to return APIRET
  *@@changed V0.9.9 (2001-04-05) [lafaix]: rewritten error checking code
+ *@@changed V0.9.12 (2001-05-03) [umoeller]: adjusted for new NOSTUB support
  */
 
@@ -1437,7 +1492,13 @@
     int    i;
 
+    ULONG ulNewHeaderOfs = 0; // V0.9.12 (2001-05-03) [umoeller]
+
+    if (pExec->pDosExeHeader)
+        // executable has DOS stub: V0.9.12 (2001-05-03) [umoeller]
+        ulNewHeaderOfs = pExec->pDosExeHeader->ulNewHeaderOfs;
+
     ENSURE(DosSetFilePtr(pExec->hfExe,
                          pExec->pLXHeader->ulEntryTblOfs
-                           + pExec->pDosExeHeader->ulNewHeaderOfs,
+                           + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
                          FILE_BEGIN,
                          &ulDummy));
@@ -1659,4 +1720,5 @@
  *@@changed V0.9.9 (2001-04-03) [umoeller]: added tons of error checking, changed prototype to return APIRET
  *@@changed V0.9.9 (2001-04-05) [lafaix]: rewritten error checking code
+ *@@changed V0.9.12 (2001-05-03) [umoeller]: adjusted for new NOSTUB support
  */
 
@@ -1670,7 +1732,13 @@
     int    i;
 
+    ULONG ulNewHeaderOfs = 0;
+
+    if (pExec->pDosExeHeader)
+        // executable has DOS stub: V0.9.12 (2001-05-03) [umoeller]
+        ulNewHeaderOfs = pExec->pDosExeHeader->ulNewHeaderOfs;
+
     ENSURE(DosSetFilePtr(pExec->hfExe,
                          pExec->pNEHeader->usEntryTblOfs
-                           + pExec->pDosExeHeader->ulNewHeaderOfs,
+                           + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
                          FILE_BEGIN,
                          &ulDummy));
@@ -1849,4 +1917,5 @@
  *@@changed V0.9.9 (2001-04-05) [lafaix]: rewritten error checking code
  *@@changed V0.9.10 (2001-04-10) [lafaix]: added Win16 and Win386 support
+ *@@changed V0.9.12 (2001-05-03) [umoeller]: adjusted for new NOSTUB support
  */
 
@@ -1868,4 +1937,10 @@
         ULONG ulDummy;
 
+        ULONG ulNewHeaderOfs = 0; // V0.9.12 (2001-05-03) [umoeller]
+
+        if (pExec->pDosExeHeader)
+            // executable has DOS stub: V0.9.12 (2001-05-03) [umoeller]
+            ulNewHeaderOfs = pExec->pDosExeHeader->ulNewHeaderOfs;
+
         if (pExec->ulExeFormat == EXEFORMAT_LX)
         {
@@ -1898,5 +1973,5 @@
                 ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
                                           pExec->pLXHeader->ulResdNameTblOfs
-                                            + pExec->pDosExeHeader->ulNewHeaderOfs,
+                                            + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
                                           FILE_BEGIN,
                                           &ulDummy));
@@ -1946,5 +2021,5 @@
                 ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
                                           pExec->pNEHeader->usResdNameTblOfs
-                                            + pExec->pDosExeHeader->ulNewHeaderOfs,
+                                            + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
                                           FILE_BEGIN,
                                           &ulDummy));
@@ -2018,4 +2093,5 @@
  *@@changed V0.9.9 (2001-04-03) [umoeller]: added tons of error checking, changed prototype to return APIRET
  *@@changed V0.9.10 (2001-04-10) [lafaix]: added Win16 and Win386 support
+ *@@changed V0.9.12 (2001-05-03) [umoeller]: adjusted for new NOSTUB support
  */
 
@@ -2034,4 +2110,10 @@
         ULONG           cResources = 0;
         PFSYSRESOURCE   paResources = NULL;
+
+        ULONG           ulNewHeaderOfs = 0; // V0.9.12 (2001-05-03) [umoeller]
+
+        if (pExec->pDosExeHeader)
+            // executable has DOS stub: V0.9.12 (2001-05-03) [umoeller]
+            ulNewHeaderOfs = pExec->pDosExeHeader->ulNewHeaderOfs;
 
         if (pExec->ulExeFormat == EXEFORMAT_LX)
@@ -2075,5 +2157,5 @@
                 ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
                                           pExec->pLXHeader->ulResTblOfs
-                                            + pExec->pDosExeHeader->ulNewHeaderOfs,
+                                            + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
                                           FILE_BEGIN,
                                           &ulDummy));
@@ -2095,5 +2177,5 @@
                 {
                     ULONG ulOfsThis =   pExec->pLXHeader->ulObjTblOfs
-                                      + pExec->pDosExeHeader->ulNewHeaderOfs
+                                      + ulNewHeaderOfs // V0.9.12 (2001-05-03) [umoeller]
                                       + (   sizeof(ot)
                                           * (paResources[i].ulFlag - 1));
@@ -2155,5 +2237,5 @@
                     ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
                                               pExec->pNEHeader->usResTblOfs
-                                                + pExec->pDosExeHeader->ulNewHeaderOfs,
+                                                + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
                                               FILE_BEGIN,
                                               &ulDummy));
@@ -2172,5 +2254,5 @@
                     {
                         ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
-                                                  pExec->pDosExeHeader->ulNewHeaderOfs
+                                                  ulNewHeaderOfs // V0.9.12 (2001-05-03) [umoeller]
                                                     + pExec->pNEHeader->usSegTblOfs
                                                     + (sizeof(ns)
@@ -2200,5 +2282,5 @@
                 ENSURE(DosSetFilePtr(pExec->hfExe,
                                      pExec->pNEHeader->usResTblOfs
-                                       + pExec->pDosExeHeader->ulNewHeaderOfs,
+                                       + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
                                      FILE_BEGIN,
                                      &ulDummy));
@@ -2254,5 +2336,5 @@
                     ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
                                               pExec->pNEHeader->usResTblOfs
-                                                + pExec->pDosExeHeader->ulNewHeaderOfs,
+                                                + ulNewHeaderOfs,
                                               FILE_BEGIN,
                                               &ulDummy));
