Ignore:
Timestamp:
Apr 4, 2001, 4:39:06 PM (24 years ago)
Author:
umoeller
Message:

Misc changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/helpers/dosh2.c

    r52 r54  
    255255    BOOL  brc = FALSE;
    256256    PSZ   pSource = pszSource,
    257           pTarget = pszTarget,
    258           pszInvalid = (fIsFAT)
    259                             ? "*<>|+=:;,\"/\\[] "  // invalid characters in FAT
    260                             : "*<>|:\"/\\"; // invalid characters in IFS's
     257          pTarget = pszTarget;
     258
     259    const char *pcszInvalid = (fIsFAT)
     260                                   ? "*<>|+=:;,\"/\\[] "  // invalid characters in FAT
     261                                   : "*<>|:\"/\\"; // invalid characters in IFS's
    261262
    262263    for (ul = 0; ul < cbSource; ul++)
     
    277278        }
    278279        // and replace invalid characters
    279         if (strchr(pszInvalid, *pSource) == NULL)
     280        if (strchr(pcszInvalid, *pSource) == NULL)
    280281            *pTarget = *pSource;
    281282        else
     
    322323 *      one will change the current drive
    323324 *      also, if one is specified.
     325 *
     326 *@@changed V0.9.9 (2001-04-04) [umoeller]: this returned an error even if none occured, fixed
    324327 */
    325328
    326329APIRET doshSetCurrentDir(const char *pcszDir)
    327330{
    328     if (pcszDir)
     331    APIRET  arc = NO_ERROR;
     332    if (!pcszDir)
     333        return (ERROR_INVALID_PARAMETER);
    329334    {
    330335        if (*pcszDir != 0)
     
    333338                // drive given:
    334339                CHAR    cDrive = toupper(*(pcszDir));
    335                 APIRET  arc;
    336340                // change drive
    337341                arc = DosSetDefaultDisk( (ULONG)(cDrive - 'A' + 1) );
    338342                        // 1 = A:, 2 = B:, ...
    339                 if (arc != NO_ERROR)
    340                     return (arc);
    341343            }
    342344
    343         return (DosSetCurrentDir((PSZ)pcszDir));
     345        arc = DosSetCurrentDir((PSZ)pcszDir);
    344346    }
    345     return (ERROR_INVALID_PARAMETER);
     347
     348    return (arc);       // V0.9.9 (2001-04-04) [umoeller]
    346349}
    347350
     
    775778 *      and a pointer to a new EXECUTABLE structure
    776779 *      is stored in *ppExec. Consider this pointer a
    777  *      handle and pass it to doshExecClose when the
    778  *      executable is no longer needed to free
    779  *      resources.
     780 *      handle and pass it to doshExecClose to clean
     781 *      up.
    780782 *
    781783 *      If NO_ERROR is returned, all the fields through
     
    784786 *      call to doshExecQueryBldLevel.
    785787 *
     788 *      NOTE: If NO_ERROR is returned, the executable
     789 *      file has been opened by this function. It will
     790 *      only be closed when you call doshExecClose.
     791 *
    786792 *      If errors occur, this function returns the
    787793 *      following error codes:
     794 *
    788795 *      -- ERROR_NOT_ENOUGH_MEMORY: malloc() failed.
     796 *
    789797 *      -- ERROR_INVALID_EXE_SIGNATURE: specified file
    790  *              has no DOS EXE header.
     798 *              has no DOS EXE header, or it does, but
     799 *              the extended header is neither LX nor
     800 *              NE nor PE.
     801 *
    791802 *      -- ERROR_INVALID_PARAMETER: ppExec is NULL.
    792803 *
     
    802813                    PEXECUTABLE* ppExec)
    803814{
     815    APIRET  arc = NO_ERROR;
     816
    804817    ULONG   ulAction = 0;
    805818    HFILE   hFile;
    806     APIRET  arc = DosOpen((PSZ)pcszExecutable,
    807                           &hFile,
    808                           &ulAction,                      // out: action taken
    809                           0,                              // in: new file (ignored for read-mode)
    810                           0,                              // in: new file attribs (ignored)
    811                           // open-flags
    812                           OPEN_ACTION_FAIL_IF_NEW
    813                              | OPEN_ACTION_OPEN_IF_EXISTS,
    814                           // open-mode
    815                           OPEN_FLAGS_FAIL_ON_ERROR        // report errors to caller
    816                              | OPEN_FLAGS_SEQUENTIAL
    817                              | OPEN_FLAGS_NOINHERIT
    818                              | OPEN_SHARE_DENYNONE
    819                              | OPEN_ACCESS_READONLY,      // read-only mode
    820                           NULL);                          // no EAs
    821 
    822     if (arc == NO_ERROR)
     819
     820    if (!ppExec)
     821        return (ERROR_INVALID_PARAMETER);
     822
     823    *ppExec = (PEXECUTABLE)malloc(sizeof(EXECUTABLE));
     824    if (!(*ppExec))
     825        return (ERROR_NOT_ENOUGH_MEMORY);
     826
     827    memset((*ppExec), 0, sizeof(EXECUTABLE));
     828
     829    if (!(arc = DosOpen((PSZ)pcszExecutable,
     830                        &hFile,
     831                        &ulAction,                      // out: action taken
     832                        0,                              // in: new file (ignored for read-mode)
     833                        0,                              // in: new file attribs (ignored)
     834                        // open-flags
     835                        OPEN_ACTION_FAIL_IF_NEW
     836                           | OPEN_ACTION_OPEN_IF_EXISTS,
     837                        // open-mode
     838                        OPEN_FLAGS_FAIL_ON_ERROR        // report errors to caller
     839                           | OPEN_FLAGS_SEQUENTIAL
     840                           | OPEN_FLAGS_NOINHERIT
     841                           | OPEN_SHARE_DENYNONE
     842                           | OPEN_ACCESS_READONLY,      // read-only mode
     843                        NULL)))                         // no EAs
    823844    {
    824845        // file opened successfully:
    825         // create EXECUTABLE structure
    826 
    827         if (ppExec)
    828         {
    829             *ppExec = (PEXECUTABLE)malloc(sizeof(EXECUTABLE));
    830             if (*ppExec)
     846
     847        ULONG           ulLocal = 0;
     848
     849        // read old DOS EXE header
     850        (*ppExec)->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER));
     851        if (!((*ppExec)->pDosExeHeader))
     852            arc = ERROR_NOT_ENOUGH_MEMORY;
     853        else
     854        {
     855            ULONG   ulBytesRead = 0;
     856
     857            if (    (!(arc = DosSetFilePtr(hFile,
     858                                           0L,
     859                                           FILE_BEGIN,
     860                                           &ulLocal)))      // out: new offset
     861                 && (!(arc = DosRead(hFile,
     862                                     (*ppExec)->pDosExeHeader,
     863                                     sizeof(DOSEXEHEADER),
     864                                     &((*ppExec)->cbDosExeHeader))))
     865               )
    831866            {
    832                 ULONG           ulLocal = 0;
    833 
    834                 memset((*ppExec), 0, sizeof(EXECUTABLE));
    835 
    836                 // read old DOS EXE header
    837                 (*ppExec)->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER));
    838                 if ((*ppExec)->pDosExeHeader == NULL)
    839                     arc = ERROR_NOT_ENOUGH_MEMORY;
     867                // now check if we really have a DOS header
     868                if ((*ppExec)->pDosExeHeader->usDosExeID != 0x5a4d)
     869                    arc = ERROR_INVALID_EXE_SIGNATURE;
    840870                else
    841871                {
    842                     ULONG   ulBytesRead = 0;
    843                     arc = DosSetFilePtr(hFile,
    844                                         0L,
    845                                         FILE_BEGIN,
    846                                         &ulLocal);      // out: new offset
    847                     arc = DosRead(hFile,
    848                                   (*ppExec)->pDosExeHeader,
    849                                   sizeof(DOSEXEHEADER),
    850                                   &((*ppExec)->cbDosExeHeader));
    851                     // now check if we really have a DOS header
    852                     if ((*ppExec)->pDosExeHeader->usDosExeID != 0x5a4d)
    853                         arc = ERROR_INVALID_EXE_SIGNATURE;
     872                    // we have a DOS header:
     873                    if ((*ppExec)->pDosExeHeader->usRelocTableOfs < 0x40)
     874                    {
     875                        // neither LX nor PE nor NE:
     876                        (*ppExec)->ulOS = EXEOS_DOS3;
     877                        (*ppExec)->ulExeFormat = EXEFORMAT_OLDDOS;
     878                    }
    854879                    else
    855880                    {
    856                         // we have a DOS header:
    857                         if ((*ppExec)->pDosExeHeader->usRelocTableOfs < 0x40)
     881                        // either LX or PE or NE:
     882                        // read more bytes from position specified in header
     883                        CHAR    achNewHeaderType[2] = "";
     884
     885                        if (    (!(arc = DosSetFilePtr(hFile,
     886                                                       (*ppExec)->pDosExeHeader->ulNewHeaderOfs,
     887                                                       FILE_BEGIN,
     888                                                       &ulLocal)))
     889                                // read two chars to find out header type
     890                             && (!(arc = DosRead(hFile,
     891                                                 &achNewHeaderType,
     892                                                 sizeof(achNewHeaderType),
     893                                                 &ulBytesRead)))
     894                           )
    858895                        {
    859                             // not LX or PE or NE:
    860                             (*ppExec)->ulOS = EXEOS_DOS3;
    861                             (*ppExec)->ulExeFormat = EXEFORMAT_OLDDOS;
    862                         }
    863                         else
    864                         {
    865                             // either LX or PE or NE:
    866                             // read more bytes from position
    867                             // specified in header
    868                             arc = DosSetFilePtr(hFile,
    869                                                 (*ppExec)->pDosExeHeader->ulNewHeaderOfs,
    870                                                 FILE_BEGIN,
    871                                                 &ulLocal);
    872 
    873                             if (arc == NO_ERROR)
     896                            PBYTE   pbCheckOS = NULL;
     897
     898                            // reset file ptr
     899                            DosSetFilePtr(hFile,
     900                                          (*ppExec)->pDosExeHeader->ulNewHeaderOfs,
     901                                          FILE_BEGIN,
     902                                          &ulLocal);
     903
     904                            if (memcmp(achNewHeaderType, "NE", 2) == 0)
    874905                            {
    875                                 PBYTE   pbCheckOS = NULL;
    876 
    877                                 // read two chars to find out header type
    878                                 CHAR    achNewHeaderType[2] = "";
    879                                 arc = DosRead(hFile,
    880                                               &achNewHeaderType,
    881                                               sizeof(achNewHeaderType),
    882                                               &ulBytesRead);
    883                                 // reset file ptr
    884                                 DosSetFilePtr(hFile,
    885                                               (*ppExec)->pDosExeHeader->ulNewHeaderOfs,
    886                                               FILE_BEGIN,
    887                                               &ulLocal);
    888 
    889                                 if (memcmp(achNewHeaderType, "NE", 2) == 0)
     906                                // New Executable:
     907                                (*ppExec)->ulExeFormat = EXEFORMAT_NE;
     908                                // allocate NE header
     909                                (*ppExec)->pNEHeader = (PNEHEADER)malloc(sizeof(NEHEADER));
     910                                if (!((*ppExec)->pNEHeader))
     911                                    arc = ERROR_NOT_ENOUGH_MEMORY;
     912                                else
     913                                    // read in NE header
     914                                    if (!(arc = DosRead(hFile,
     915                                                        (*ppExec)->pNEHeader,
     916                                                        sizeof(NEHEADER),
     917                                                        &((*ppExec)->cbNEHeader))))
     918                                        if ((*ppExec)->cbNEHeader == sizeof(NEHEADER))
     919                                            pbCheckOS = &((*ppExec)->pNEHeader->bTargetOS);
     920                            }
     921                            else if (   (memcmp(achNewHeaderType, "LX", 2) == 0)
     922                                     || (memcmp(achNewHeaderType, "LE", 2) == 0)
     923                                                // this is used by SMARTDRV.EXE
     924                                    )
     925                            {
     926                                // OS/2 Linear Executable:
     927                                (*ppExec)->ulExeFormat = EXEFORMAT_LX;
     928                                // allocate LX header
     929                                (*ppExec)->pLXHeader = (PLXHEADER)malloc(sizeof(LXHEADER));
     930                                if (!((*ppExec)->pLXHeader))
     931                                    arc = ERROR_NOT_ENOUGH_MEMORY;
     932                                else
     933                                    // read in LX header
     934                                    if (!(arc = DosRead(hFile,
     935                                                        (*ppExec)->pLXHeader,
     936                                                        sizeof(LXHEADER),
     937                                                        &((*ppExec)->cbLXHeader))))
     938                                        if ((*ppExec)->cbLXHeader == sizeof(LXHEADER))
     939                                            pbCheckOS = (PBYTE)(&((*ppExec)->pLXHeader->usTargetOS));
     940                            }
     941                            else if (memcmp(achNewHeaderType, "PE", 2) == 0)
     942                            {
     943                                (*ppExec)->ulExeFormat = EXEFORMAT_PE;
     944                                (*ppExec)->ulOS = EXEOS_WIN32;
     945                                (*ppExec)->f32Bits = TRUE;
     946
     947                                // can't parse this yet
     948                            }
     949                            else
     950                                // strange type:
     951                                arc = ERROR_INVALID_EXE_SIGNATURE;
     952
     953                            if (pbCheckOS)
     954                                // BYTE to check for operating system
     955                                // (NE and LX):
     956                                switch (*pbCheckOS)
    890957                                {
    891                                     // New Executable:
    892                                     (*ppExec)->ulExeFormat = EXEFORMAT_NE;
    893                                     // read NE header
    894                                     (*ppExec)->pNEHeader = (PNEHEADER)malloc(sizeof(NEHEADER));
    895                                     DosRead(hFile,
    896                                             (*ppExec)->pNEHeader,
    897                                             sizeof(NEHEADER),
    898                                             &((*ppExec)->cbNEHeader));
    899                                     if ((*ppExec)->cbNEHeader == sizeof(NEHEADER))
    900                                         pbCheckOS = &((*ppExec)->pNEHeader->bTargetOS);
     958                                    case NEOS_OS2:
     959                                        (*ppExec)->ulOS = EXEOS_OS2;
     960                                        if ((*ppExec)->ulExeFormat == EXEFORMAT_LX)
     961                                            (*ppExec)->f32Bits = TRUE;
     962                                    break;
     963
     964                                    case NEOS_WIN16:
     965                                        (*ppExec)->ulOS = EXEOS_WIN16;
     966                                    break;
     967
     968                                    case NEOS_DOS4:
     969                                        (*ppExec)->ulOS = EXEOS_DOS4;
     970                                    break;
     971
     972                                    case NEOS_WIN386:
     973                                        (*ppExec)->ulOS = EXEOS_WIN386;
     974                                        (*ppExec)->f32Bits = TRUE;
     975                                    break;
    901976                                }
    902                                 else if (   (memcmp(achNewHeaderType, "LX", 2) == 0)
    903                                          || (memcmp(achNewHeaderType, "LE", 2) == 0)
    904                                                     // this is used by SMARTDRV.EXE
    905                                         )
    906                                 {
    907                                     // OS/2 Linear Executable:
    908                                     (*ppExec)->ulExeFormat = EXEFORMAT_LX;
    909                                     // read LX header
    910                                     (*ppExec)->pLXHeader = (PLXHEADER)malloc(sizeof(LXHEADER));
    911                                     DosRead(hFile,
    912                                             (*ppExec)->pLXHeader,
    913                                             sizeof(LXHEADER),
    914                                             &((*ppExec)->cbLXHeader));
    915                                     if ((*ppExec)->cbLXHeader == sizeof(LXHEADER))
    916                                         pbCheckOS = (PBYTE)(&((*ppExec)->pLXHeader->usTargetOS));
    917                                 }
    918                                 else if (memcmp(achNewHeaderType, "PE", 2) == 0)
    919                                 {
    920                                     (*ppExec)->ulExeFormat = EXEFORMAT_PE;
    921                                     (*ppExec)->ulOS = EXEOS_WIN32;
    922                                     (*ppExec)->f32Bits = TRUE;
    923                                 }
    924                                 else
    925                                     arc = ERROR_INVALID_EXE_SIGNATURE;
    926 
    927                                 if (pbCheckOS)
    928                                     // BYTE to check for operating system
    929                                     // (NE and LX):
    930                                     switch (*pbCheckOS)
    931                                     {
    932                                         case NEOS_OS2:
    933                                             (*ppExec)->ulOS = EXEOS_OS2;
    934                                             if ((*ppExec)->ulExeFormat == EXEFORMAT_LX)
    935                                                 (*ppExec)->f32Bits = TRUE;
    936                                         break;
    937                                         case NEOS_WIN16:
    938                                             (*ppExec)->ulOS = EXEOS_WIN16;
    939                                         break;
    940                                         case NEOS_DOS4:
    941                                             (*ppExec)->ulOS = EXEOS_DOS4;
    942                                         break;
    943                                         case NEOS_WIN386:
    944                                             (*ppExec)->ulOS = EXEOS_WIN386;
    945                                             (*ppExec)->f32Bits = TRUE;
    946                                         break;
    947                                     }
    948                             }
    949                         }
     977                        } // end if (!(arc = DosSetFilePtr(hFile,
    950978                    }
    951 
    952                     // store exec's HFILE
    953                     (*ppExec)->hfExe = hFile;
    954979                }
    955 
    956                 if (arc != NO_ERROR)
    957                     // error: clean up
    958                     doshExecClose(*ppExec);
    959 
    960             } // end if (*ppExec)
    961             else
    962                 arc = ERROR_NOT_ENOUGH_MEMORY;
    963         } // end if (ppExec)
    964         else
    965             arc = ERROR_INVALID_PARAMETER;
    966     } // end if (arc == NO_ERROR)
     980            } // end if (!(arc = DosSetFilePtr(hFile,
     981        } // end if (*ppExec)->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER));
     982
     983        // store exec's HFILE
     984        (*ppExec)->hfExe = hFile;
     985    } // end if (!(arc = DosOpen((PSZ)pcszExecutable,
     986
     987    if (arc != NO_ERROR)
     988        // error: clean up
     989        doshExecClose(*ppExec);
    967990
    968991    return (arc);
     
    9991022            free(pExec->pszInfo);
    10001023
    1001         DosClose(pExec->hfExe);
     1024        if (pExec->hfExe)
     1025            arc = DosClose(pExec->hfExe);
    10021026
    10031027        free(pExec);
     
    10481072 *
    10491073 *      This returns the following errors:
     1074 *
    10501075 *      -- ERROR_INVALID_PARAMETER: pExec invalid
     1076 *
    10511077 *      -- ERROR_INVALID_EXE_SIGNATURE (191): pExec is not in LX or NE format
     1078 *
    10521079 *      -- ERROR_INVALID_DATA (13): non-resident name table not found.
     1080 *
    10531081 *      -- ERROR_NOT_ENOUGH_MEMORY: malloc() failed.
    10541082 *
     
    10581086 *@@changed V0.9.0 (99-10-22) [umoeller]: NE format now supported
    10591087 *@@changed V0.9.1 (99-12-06): fixed memory leak
     1088 *@@changed V0.9.9 (2001-04-04) [umoeller]: added more error checking
    10601089 */
    10611090
     
    10631092{
    10641093    APIRET      arc = NO_ERROR;
    1065     PSZ         pszNameTable = NULL;
    1066     ULONG       ulNRNTOfs = 0;
    1067 
    1068     do
     1094
     1095    if (!pExec)
     1096        arc = ERROR_INVALID_PARAMETER;
     1097    else
    10691098    {
    1070         ULONG       ulLocal = 0,
    1071                     ulBytesRead = 0;
    1072         PSZ         pStartOfAuthor = NULL;
    1073 
    1074         if (pExec == NULL)
    1075         {
    1076             arc = ERROR_INVALID_PARAMETER;
    1077             break;
    1078         }
     1099        ULONG       ulNRNTOfs = 0;
    10791100
    10801101        if (pExec->ulExeFormat == EXEFORMAT_LX)
     
    10831104            // check if we have a non-resident name table
    10841105            if (pExec->pLXHeader == NULL)
    1085             {
    10861106                arc = ERROR_INVALID_DATA;
    1087                 break;
    1088             }
    1089             if (pExec->pLXHeader->ulNonResdNameTblOfs == 0)
    1090             {
     1107            else if (pExec->pLXHeader->ulNonResdNameTblOfs == 0)
    10911108                arc = ERROR_INVALID_DATA;
    1092                 break;
    1093             }
    1094 
    1095             ulNRNTOfs = pExec->pLXHeader->ulNonResdNameTblOfs;
     1109            else
     1110                ulNRNTOfs = pExec->pLXHeader->ulNonResdNameTblOfs;
    10961111        }
    10971112        else if (pExec->ulExeFormat == EXEFORMAT_NE)
     
    11001115            // check if we have a non-resident name table
    11011116            if (pExec->pNEHeader == NULL)
    1102             {
    11031117                arc = ERROR_INVALID_DATA;
    1104                 break;
    1105             }
    1106             if (pExec->pNEHeader->ulNonResdTblOfs == 0)
    1107             {
     1118            else if (pExec->pNEHeader->ulNonResdTblOfs == 0)
    11081119                arc = ERROR_INVALID_DATA;
    1109                 break;
    1110             }
    1111 
    1112             ulNRNTOfs = pExec->pNEHeader->ulNonResdTblOfs;
     1120            else
     1121                ulNRNTOfs = pExec->pNEHeader->ulNonResdTblOfs;
    11131122        }
    11141123        else
    1115         {
    11161124            // neither LX nor NE: stop
    11171125            arc = ERROR_INVALID_EXE_SIGNATURE;
    1118             break;
     1126
     1127        if (    (!arc)
     1128             && (ulNRNTOfs)
     1129           )
     1130        {
     1131            ULONG       ulLocal = 0,
     1132                        ulBytesRead = 0;
     1133
     1134            // move EXE file pointer to offset of non-resident name table
     1135            // (from LX header)
     1136            if (!(arc = DosSetFilePtr(pExec->hfExe,     // file is still open
     1137                                      ulNRNTOfs,      // ofs determined above
     1138                                      FILE_BEGIN,
     1139                                      &ulLocal)))
     1140            {
     1141                // allocate memory as necessary
     1142                PSZ pszNameTable = (PSZ)malloc(2001); // should suffice, because each entry
     1143                                                      // may only be 255 bytes in length
     1144                if (!pszNameTable)
     1145                    arc = ERROR_NOT_ENOUGH_MEMORY;
     1146                else
     1147                {
     1148                    if (!(arc = DosRead(pExec->hfExe,
     1149                                        pszNameTable,
     1150                                        2000,
     1151                                        &ulBytesRead)))
     1152                    {
     1153                        if (*pszNameTable == 0)
     1154                            // first byte (length byte) is null:
     1155                            arc = ERROR_INVALID_DATA;
     1156                        else
     1157                        {
     1158                            // now copy the string, which is in Pascal format
     1159                            pExec->pszDescription = (PSZ)malloc((*pszNameTable) + 1);    // addt'l null byte
     1160                            if (!pExec->pszDescription)
     1161                                arc = ERROR_NOT_ENOUGH_MEMORY;
     1162                            else
     1163                            {
     1164                                const char  *pStartOfAuthor = 0,
     1165                                            *pStartOfVendor = 0;
     1166
     1167                                memcpy(pExec->pszDescription,
     1168                                       pszNameTable + 1,        // skip length byte
     1169                                       *pszNameTable);          // length byte
     1170                                // terminate string
     1171                                *(pExec->pszDescription + (*pszNameTable)) = 0;
     1172
     1173                                // now parse the damn thing:
     1174                                // @#VENDOR:VERSION#@ DESCRIPTION
     1175                                // but skip the first byte, which has the string length
     1176                                pStartOfVendor = strstr(pExec->pszDescription,
     1177                                                        "@#");
     1178                                if (pStartOfVendor)
     1179                                {
     1180                                    const char *pStartOfInfo = strstr(pStartOfVendor + 2,
     1181                                                                      "#@");
     1182                                    if (pStartOfInfo)
     1183                                    {
     1184                                        PSZ pEndOfVendor = strchr(pStartOfVendor + 2,
     1185                                                                  ':');
     1186                                        if (pEndOfVendor)
     1187                                        {
     1188                                            pExec->pszVendor = strhSubstr(pStartOfVendor + 2,
     1189                                                                          pEndOfVendor);
     1190                                            pExec->pszVersion = strhSubstr(pEndOfVendor + 1,
     1191                                                                           pStartOfInfo);
     1192                                            // skip "@#" in info string
     1193                                            pStartOfInfo += 2;
     1194                                            // skip leading spaces in info string
     1195                                            while (*pStartOfInfo == ' ')
     1196                                                pStartOfInfo++;
     1197                                            if (*pStartOfInfo)  // V0.9.9 (2001-04-04) [umoeller]
     1198                                                // and copy until end of string
     1199                                                pExec->pszInfo = strdup(pStartOfInfo);
     1200                                        }
     1201                                    }
     1202                                }
     1203                            }
     1204                        }
     1205                    }
     1206
     1207                    free(pszNameTable);
     1208                } // end if PSZ pszNameTable = (PSZ)malloc(2001);
     1209            }
    11191210        }
    1120 
    1121         if (ulNRNTOfs == 0)
    1122         {
    1123             // shouldn't happen
    1124             arc = ERROR_INVALID_DATA;
    1125             break;
    1126         }
    1127 
    1128         // move EXE file pointer to offset of non-resident name table
    1129         // (from LX header)
    1130         arc = DosSetFilePtr(pExec->hfExe,     // file is still open
    1131                             ulNRNTOfs,      // ofs determined above
    1132                             FILE_BEGIN,
    1133                             &ulLocal);
    1134         if (arc != NO_ERROR)
    1135             break;
    1136 
    1137         // allocate memory as necessary
    1138         pszNameTable = (PSZ)malloc(2001); // should suffice, because each entry
    1139                                     // may only be 255 bytes in length
    1140         if (pszNameTable)
    1141         {
    1142             arc = DosRead(pExec->hfExe,
    1143                           pszNameTable,
    1144                           2000,
    1145                           &ulBytesRead);
    1146             if (arc != NO_ERROR)
    1147                 break;
    1148             if (*pszNameTable == 0)
     1211    } // end if (!pExec)
     1212
     1213    return (arc);
     1214}
     1215
     1216/*
     1217 *@@ doshExecQueryImportedModules:
     1218 *      returns an array of FSYSMODULE structure describing all
     1219 *      imported modules.
     1220 *
     1221 *      *pcModules receives the # of items in the array (not the
     1222 *      array size!).  Use doshFreeImportedModules to clean up.
     1223 *
     1224 *      This returns a standard OS/2 error code, which might be
     1225 *      any of the codes returned by DosSetFilePtr and DosRead.
     1226 *      In addition, this may return:
     1227 *
     1228 *      --  ERROR_NOT_ENOUGH_MEMORY
     1229 *
     1230 *      --  ERROR_INVALID_EXE_SIGNATURE: exe is in a format other
     1231 *          than LX or NE, which is not understood by this function.
     1232 *
     1233 *      Even if NO_ERROR is returned, the array pointer might still
     1234 *      be NULL if the module contains no such data.
     1235 *
     1236 *@@added V0.9.9 (2001-03-11) [lafaix]
     1237 *@@changed V0.9.9 (2001-04-03) [umoeller]: added tons of error checking, changed prototype to return APIRET
     1238 */
     1239
     1240APIRET doshExecQueryImportedModules(PEXECUTABLE pExec,
     1241                                    PFSYSMODULE *ppaModules,    // out: modules array
     1242                                    PULONG pcModules)           // out: array item count
     1243{
     1244    APIRET      arc = NO_ERROR;
     1245
     1246    if (    (pExec)
     1247         && (pExec->ulOS == EXEOS_OS2)
     1248       )
     1249    {
     1250        ULONG       cModules = 0;
     1251        PFSYSMODULE paModules = NULL;
     1252        int i;
     1253
     1254        if (pExec->ulExeFormat == EXEFORMAT_LX)
     1255        {
     1256            // 32-bit OS/2 executable:
     1257            if (cModules = pExec->pLXHeader->ulImportModTblCnt)
    11491258            {
    1150                 // first byte (length byte) is null:
    1151                 arc = ERROR_INVALID_DATA;
    1152                 free (pszNameTable);        // fixed V0.9.1 (99-12-06)
    1153                 break;
    1154             }
    1155 
    1156             // now copy the string, which is in Pascal format
    1157             pExec->pszDescription = (PSZ)malloc((*pszNameTable) + 1);    // addt'l null byte
    1158             memcpy(pExec->pszDescription,
    1159                    pszNameTable + 1,        // skip length byte
    1160                    *pszNameTable);          // length byte
    1161             // terminate string
    1162             *(pExec->pszDescription + (*pszNameTable)) = 0;
    1163 
    1164             // _Pmpf(("pszDescription: %s", pExec->pszDescription));
    1165 
    1166             // now parse the damn thing:
    1167             // @#AUTHOR:VERSION#@ DESCRIPTION
    1168             // but skip the first byte, which has the string length
    1169             pStartOfAuthor = strstr(pExec->pszDescription, "@#");
    1170             if (pStartOfAuthor)
    1171             {
    1172                 PSZ pStartOfInfo = strstr(pStartOfAuthor + 2, "#@");
    1173                 // _Pmpf(("Testing"));
    1174                 if (pStartOfInfo)
     1259                ULONG cb = sizeof(FSYSMODULE) * cModules; // V0.9.9 (2001-04-03) [umoeller]
     1260
     1261                paModules = (PFSYSMODULE)malloc(cb);
     1262                if (!paModules)
     1263                    arc = ERROR_NOT_ENOUGH_MEMORY; // V0.9.9 (2001-04-03) [umoeller]
     1264                else
    11751265                {
    1176                     PSZ pEndOfAuthor = strchr(pStartOfAuthor + 2, ':');
    1177                     // _Pmpf(("pStartOfinfo: %s", pStartOfInfo));
    1178                     if (pEndOfAuthor)
     1266                    ULONG ulDummy;
     1267
     1268                    memset(paModules, 0, cb);   // V0.9.9 (2001-04-03) [umoeller]
     1269
     1270                    // V0.9.9 (2001-04-03) [umoeller]:
     1271                    // Martin, I added error checking to all the below
     1272                    // Dos* calls. You can't just read around a file
     1273                    // and assume it will always be valid... especially
     1274                    // if you fill dynamically allocated memory.
     1275
     1276                    if (!(arc = DosSetFilePtr(pExec->hfExe,
     1277                                              pExec->pLXHeader->ulImportModTblOfs
     1278                                                + pExec->pDosExeHeader->ulNewHeaderOfs,
     1279                                              FILE_BEGIN,
     1280                                              &ulDummy)))
    11791281                    {
    1180                         // _Pmpf(("pEndOfAuthor: %s", pEndOfAuthor));
    1181                         pExec->pszVendor = strhSubstr(pStartOfAuthor + 2, pEndOfAuthor);
    1182                         pExec->pszVersion = strhSubstr(pEndOfAuthor + 1, pStartOfInfo);
    1183                         // skip "@#" in info string
    1184                         pStartOfInfo += 2;
    1185                         // skip leading spaces in info string
    1186                         while (*pStartOfInfo == ' ')
    1187                             pStartOfInfo++;
    1188                         // and copy until end of string
    1189                         pExec->pszInfo = strdup(pStartOfInfo);
     1282                        for (i = 0; i < cModules; i++)
     1283                        {
     1284                             BYTE bLen = 0;
     1285
     1286                             // reading the length of the module name
     1287                             if (!(arc = DosRead(pExec->hfExe,
     1288                                                 &bLen,
     1289                                                 1,
     1290                                                 &ulDummy)))
     1291                             {
     1292                                 // At most 127 bytes
     1293                                 bLen &= 0x7F;
     1294
     1295                                 // reading the module name
     1296                                 if (!(arc = DosRead(pExec->hfExe,
     1297                                                     paModules[i].achModuleName,
     1298                                                     bLen,
     1299                                                     &ulDummy)))
     1300                                    // module names are not null terminated, so we must
     1301                                    // do it now
     1302                                    paModules[i].achModuleName[bLen] = 0;
     1303                            }
     1304
     1305                            if (arc)
     1306                                break; // V0.9.9 (2001-04-03) [umoeller]
     1307
     1308                        } // end for
    11901309                    }
    11911310                }
    11921311            }
    1193 
    1194             free(pszNameTable);
    1195         }
    1196         else
    1197             arc = ERROR_NOT_ENOUGH_MEMORY;
    1198     } while (FALSE);
    1199 
    1200 
    1201     return (arc);
    1202 }
    1203 
    1204 /*
    1205  *@@ doshExecQueryImportedModules:
    1206  *      returns an array of FSYSMODULE structure describing all
    1207  *      imported modules.
    1208  *
    1209  *      *pcModules receives the # of items in the array (not the
    1210  *      array size!).  Use doshFreeImportedModules to clean up.
    1211  *
    1212  *@@added V0.9.9 (2001-03-11) [lafaix]
    1213  */
    1214 
    1215 PFSYSMODULE doshExecQueryImportedModules(PEXECUTABLE pExec,
    1216                                          PULONG pcModules)
    1217 {
    1218     ULONG       cModules = 0;
    1219     PFSYSMODULE paModules = NULL;
    1220     int i;
    1221 
    1222     if (pExec)
    1223     {
    1224         if (pExec->ulOS == EXEOS_OS2)
    1225         {
    1226             ULONG ulDummy;
    1227 
    1228             if (pExec->ulExeFormat == EXEFORMAT_LX)
     1312        } // end LX
     1313        else if (pExec->ulExeFormat == EXEFORMAT_NE)
     1314        {
     1315            // 16-bit OS/2 executable:
     1316            if (cModules = pExec->pNEHeader->usModuleTblEntries)
    12291317            {
    1230                 // It's a 32bit OS/2 executable
    1231                 cModules = pExec->pLXHeader->ulImportModTblCnt;
    1232 
    1233                 if (cModules)
     1318                ULONG cb = sizeof(FSYSMODULE) * cModules;
     1319
     1320                paModules = (PFSYSMODULE)malloc(cb);
     1321                if (!paModules)
     1322                    arc = ERROR_NOT_ENOUGH_MEMORY;  // V0.9.9 (2001-04-03) [umoeller]
     1323                else
    12341324                {
    1235                     BYTE bLen;
    1236 
    1237                     paModules = (PFSYSMODULE)malloc(sizeof(FSYSMODULE) * cModules);
    1238 
    1239                     DosSetFilePtr(pExec->hfExe,
    1240                                   pExec->pLXHeader->ulImportModTblOfs
    1241                                     + pExec->pDosExeHeader->ulNewHeaderOfs,
    1242                                   FILE_BEGIN,
    1243                                   &ulDummy);
    1244 
    1245                     for (i = 0; i < cModules; i++)
    1246                     {
    1247                          // reading the length of the module name
    1248                          DosRead(pExec->hfExe,
    1249                                  &bLen,
    1250                                  1,
    1251                                  &ulDummy);
    1252 
    1253                          // At most 127 bytes
    1254                          bLen &= 0x7F;
    1255 
    1256                          // reading the module name
    1257                          DosRead(pExec->hfExe,
    1258                                  paModules[i].achModuleName,
    1259                                  bLen,
    1260                                  &ulDummy);
    1261 
    1262                          // modules name are not null terminated, so we must
    1263                          // do it now
    1264                          paModules[i].achModuleName[bLen] = 0;
    1265                     }
    1266                 }
    1267             }
    1268             else
    1269             if (pExec->ulExeFormat == EXEFORMAT_NE)
    1270             {
    1271                 // It's a 16bit OS/2 executable
    1272                 cModules = pExec->pNEHeader->usModuleTblEntries;
    1273 
    1274                 if (cModules)
    1275                 {
    1276                     BYTE bLen;
    1277 
    1278                     paModules = (PFSYSMODULE)malloc(sizeof(FSYSMODULE) * cModules);
     1325                    memset(paModules, 0, cb);   // V0.9.9 (2001-04-03) [umoeller]
    12791326
    12801327                    for (i = 0; i < cModules; i ++)
    12811328                    {
     1329                        BYTE bLen;
    12821330                        USHORT usOfs;
     1331                        ULONG ulDummy;
    12831332
    12841333                        // the module reference table contains offsets
     
    12871336                        // then we read the name in the import table
    12881337
    1289                         DosSetFilePtr(pExec->hfExe,
    1290                                       pExec->pNEHeader->usModRefTblOfs
    1291                                         + pExec->pDosExeHeader->ulNewHeaderOfs
    1292                                         + sizeof(usOfs) * i,
    1293                                       FILE_BEGIN,
    1294                                       &ulDummy);
    1295 
    1296                         DosRead(pExec->hfExe,
    1297                                 &usOfs,
    1298                                 2,
    1299                                 &ulDummy);
    1300 
    1301                         DosSetFilePtr(pExec->hfExe,
    1302                                       pExec->pNEHeader->usImportTblOfs
    1303                                         + pExec->pDosExeHeader->ulNewHeaderOfs
    1304                                         + usOfs,
    1305                                       FILE_BEGIN,
    1306                                       &ulDummy);
    1307 
    1308                         DosRead(pExec->hfExe,
    1309                                 &bLen,
    1310                                 1,
    1311                                 &ulDummy);
    1312 
    1313                         bLen &= 0x7F;
    1314 
    1315                         DosRead(pExec->hfExe,
    1316                                 paModules[i].achModuleName,
    1317                                 bLen,
    1318                                 &ulDummy);
    1319 
    1320                         paModules[i].achModuleName[bLen] = 0;
    1321                     }
    1322 
     1338                        if (    (!(arc = DosSetFilePtr(pExec->hfExe,
     1339                                                       pExec->pNEHeader->usModRefTblOfs
     1340                                                         + pExec->pDosExeHeader->ulNewHeaderOfs
     1341                                                         + sizeof(usOfs) * i,
     1342                                                       FILE_BEGIN,
     1343                                                       &ulDummy)))
     1344                             && (!(arc = DosRead(pExec->hfExe,
     1345                                                 &usOfs,
     1346                                                 2,
     1347                                                 &ulDummy)))
     1348                             && (!(arc = DosSetFilePtr(pExec->hfExe,
     1349                                                       pExec->pNEHeader->usImportTblOfs
     1350                                                         + pExec->pDosExeHeader->ulNewHeaderOfs
     1351                                                         + usOfs,
     1352                                                       FILE_BEGIN,
     1353                                                       &ulDummy)))
     1354                             && (!(arc = DosRead(pExec->hfExe,
     1355                                                 &bLen,
     1356                                                 1,
     1357                                                 &ulDummy)))
     1358                            )
     1359                        {
     1360                            bLen &= 0x7F;
     1361
     1362                            if (!(arc = DosRead(pExec->hfExe,
     1363                                                paModules[i].achModuleName,
     1364                                                bLen,
     1365                                                &ulDummy)))
     1366                                paModules[i].achModuleName[bLen] = 0;
     1367                        }
     1368
     1369                        if (arc)
     1370                            break;  // V0.9.9 (2001-04-03) [umoeller]
     1371                    } // end for
    13231372                }
    13241373            }
    1325 
     1374        }
     1375        else
     1376            arc = ERROR_INVALID_EXE_SIGNATURE; // V0.9.9 (2001-04-03) [umoeller]
     1377
     1378        if (arc)
     1379        {
     1380            // if we had an error above, clean up
     1381            if (paModules)
     1382                free(paModules);
     1383        }
     1384        else
     1385        {
     1386            // no error: output data
     1387            *ppaModules = paModules;
    13261388            *pcModules = cModules;
    13271389        }
    13281390    }
    1329 
    1330     return (paModules);
     1391    else
     1392        arc = ERROR_INVALID_EXE_SIGNATURE; // V0.9.9 (2001-04-03) [umoeller]
     1393
     1394    return (arc);
    13311395}
    13321396
     
    13401404APIRET doshExecFreeImportedModules(PFSYSMODULE paModules)
    13411405{
    1342     free(paModules);
     1406    if (paModules)          // V0.9.9 (2001-04-04) [umoeller]
     1407        free(paModules);
    13431408    return (NO_ERROR);
    13441409}
     
    13481413 *      returns the number of exported entries in the entry table.
    13491414 *
     1415 *      If paFunctions is not NULL, then successive entries are
     1416 *      filled with the found type and ordinal values.
     1417 *
     1418 *@@added V0.9.9 (2001-03-30) [lafaix]
     1419 *@@changed V0.9.9 (2001-04-03) [umoeller]: added tons of error checking, changed prototype to return APIRET
     1420 */
     1421
     1422APIRET ScanLXEntryTable(PEXECUTABLE pExec,
     1423                        PFSYSFUNCTION paFunctions,
     1424                        PULONG pcEntries)        // out: entry table entry count; ptr can be NULL
     1425{
     1426    APIRET arc = NO_ERROR;
     1427
     1428    ULONG  ulDummy;
     1429
     1430    if (!(arc = DosSetFilePtr(pExec->hfExe,
     1431                              pExec->pLXHeader->ulEntryTblOfs
     1432                                + pExec->pDosExeHeader->ulNewHeaderOfs,
     1433                              FILE_BEGIN,
     1434                              &ulDummy)))
     1435    {
     1436        USHORT usOrdinal = 1,
     1437               usCurrent = 0;
     1438        int    i;
     1439
     1440        while (!arc)            // V0.9.9 (2001-04-03) [umoeller]
     1441        {
     1442            BYTE   bCnt,
     1443                   bType,
     1444                   bFlag;
     1445
     1446            if (!(arc = DosRead(pExec->hfExe,
     1447                                &bCnt,
     1448                                1,
     1449                                &ulDummy)))
     1450            {
     1451                if (bCnt == 0)
     1452                    // end of the entry table
     1453                    break;
     1454
     1455                if (!(arc = DosRead(pExec->hfExe,
     1456                                    &bType,
     1457                                    1,
     1458                                    &ulDummy)))
     1459                {
     1460                    switch (bType & 0x7F)
     1461                    {
     1462                        /*
     1463                         * unused entries
     1464                         *
     1465                         */
     1466
     1467                        case 0:
     1468                           usOrdinal += bCnt;
     1469                        break;
     1470
     1471                        /*
     1472                         * 16-bit entries
     1473                         *
     1474                         * the bundle type is followed by the object number
     1475                         * and by bCnt bFlag+usOffset entries
     1476                         *
     1477                         */
     1478
     1479                        case 1:
     1480                            if (!(arc = DosSetFilePtr(pExec->hfExe,
     1481                                                      sizeof(USHORT),
     1482                                                      FILE_CURRENT,
     1483                                                      &ulDummy)))
     1484                            {
     1485                                for (i = 0; i < bCnt; i ++)
     1486                                {
     1487                                    if (!(arc = DosRead(pExec->hfExe,
     1488                                                        &bFlag,
     1489                                                        1,
     1490                                                        &ulDummy)))
     1491                                    {
     1492                                        if (bFlag & 0x01)
     1493                                        {
     1494                                            if (paFunctions)
     1495                                            {
     1496                                                paFunctions[usCurrent].ulOrdinal = usOrdinal;
     1497                                                paFunctions[usCurrent].ulType = 1;
     1498                                                paFunctions[usCurrent].achFunctionName[0] = 0;
     1499                                            }
     1500                                            usCurrent++;
     1501                                        }
     1502
     1503                                        usOrdinal++;
     1504
     1505                                        arc = DosSetFilePtr(pExec->hfExe,
     1506                                                            sizeof(USHORT),
     1507                                                            FILE_CURRENT,
     1508                                                            &ulDummy);
     1509                                    }
     1510
     1511                                    if (arc)
     1512                                        break; // V0.9.9 (2001-04-03) [umoeller]
     1513
     1514                                } // end for
     1515                            }
     1516                        break;
     1517
     1518                        /*
     1519                         * 286 call gate entries
     1520                         *
     1521                         * the bundle type is followed by the object number
     1522                         * and by bCnt bFlag+usOffset+usCallGate entries
     1523                         *
     1524                         */
     1525
     1526                        case 2:
     1527                            if (!(arc = DosSetFilePtr(pExec->hfExe,
     1528                                                      sizeof(USHORT),
     1529                                                      FILE_CURRENT,
     1530                                                      &ulDummy)))
     1531                            {
     1532                                for (i = 0; i < bCnt; i ++)
     1533                                {
     1534                                    if (!(arc = DosRead(pExec->hfExe,
     1535                                                        &bFlag,
     1536                                                        1,
     1537                                                        &ulDummy)))
     1538                                    {
     1539                                        if (bFlag & 0x01)
     1540                                        {
     1541                                            if (paFunctions)
     1542                                            {
     1543                                                paFunctions[usCurrent].ulOrdinal = usOrdinal;
     1544                                                paFunctions[usCurrent].ulType = 2;
     1545                                                paFunctions[usCurrent].achFunctionName[0] = 0;
     1546                                            }
     1547                                            usCurrent++;
     1548                                        }
     1549
     1550                                        usOrdinal++;
     1551
     1552                                        arc = DosSetFilePtr(pExec->hfExe,
     1553                                                            sizeof(USHORT) + sizeof(USHORT),
     1554                                                            FILE_CURRENT,
     1555                                                            &ulDummy);
     1556                                    }
     1557
     1558                                    if (arc)
     1559                                        break; // V0.9.9 (2001-04-03) [umoeller]
     1560
     1561                                } // end for
     1562                            }
     1563                        break;
     1564
     1565                        /*
     1566                         * 32-bit entries
     1567                         *
     1568                         * the bundle type is followed by the object number
     1569                         * and by bCnt bFlag+ulOffset entries
     1570                         *
     1571                         */
     1572
     1573                        case 3:
     1574                            if (!(arc = DosSetFilePtr(pExec->hfExe,
     1575                                                      sizeof(USHORT),
     1576                                                      FILE_CURRENT,
     1577                                                      &ulDummy)))
     1578                            {
     1579                                for (i = 0; i < bCnt; i ++)
     1580                                {
     1581                                    if (!(arc = DosRead(pExec->hfExe,
     1582                                                        &bFlag,
     1583                                                        1,
     1584                                                        &ulDummy)))
     1585                                    {
     1586                                        if (bFlag & 0x01)
     1587                                        {
     1588                                            if (paFunctions)
     1589                                            {
     1590                                                paFunctions[usCurrent].ulOrdinal = usOrdinal;
     1591                                                paFunctions[usCurrent].ulType = 3;
     1592                                                paFunctions[usCurrent].achFunctionName[0] = 0;
     1593                                            }
     1594                                            usCurrent++;
     1595                                        }
     1596
     1597                                        usOrdinal++;
     1598
     1599                                        arc = DosSetFilePtr(pExec->hfExe,
     1600                                                            sizeof(ULONG),
     1601                                                            FILE_CURRENT,
     1602                                                            &ulDummy);
     1603                                    }
     1604
     1605                                    if (arc)
     1606                                        break; // V0.9.9 (2001-04-03) [umoeller]
     1607                                } // end for
     1608                            }
     1609                        break;
     1610
     1611                        /*
     1612                         * forwarder entries
     1613                         *
     1614                         * the bundle type is followed by a reserved word
     1615                         * and by bCnt bFlag+usModOrd+ulOffsOrdNum entries
     1616                         *
     1617                         */
     1618
     1619                        case 4:
     1620                            if (!(arc = DosSetFilePtr(pExec->hfExe,
     1621                                                      sizeof(USHORT),
     1622                                                      FILE_CURRENT,
     1623                                                      &ulDummy)))
     1624                            {
     1625                                for (i = 0; i < bCnt; i ++)
     1626                                {
     1627                                    if (!(arc = DosSetFilePtr(pExec->hfExe,
     1628                                                              sizeof(BYTE) + sizeof(USHORT) + sizeof(ULONG),
     1629                                                              FILE_CURRENT,
     1630                                                              &ulDummy)))
     1631                                    {
     1632                                        if (paFunctions)
     1633                                        {
     1634                                            paFunctions[usCurrent].ulOrdinal = usOrdinal;
     1635                                            paFunctions[usCurrent].ulType = 4;
     1636                                            paFunctions[usCurrent].achFunctionName[0] = 0;
     1637                                        }
     1638                                        usCurrent++;
     1639
     1640                                        usOrdinal++;
     1641                                    }
     1642
     1643                                    if (arc)
     1644                                        break; // V0.9.9 (2001-04-03) [umoeller]
     1645                                } // end for
     1646                            }
     1647                        break;
     1648
     1649                        /*
     1650                         * unknown bundle type
     1651                         *
     1652                         * we don't know how to handle this bundle, so we must
     1653                         * stop parsing the entry table here (as we don't know the
     1654                         * bundle size); if paFunctions is not null, we fill it with
     1655                         * informative data
     1656                         */
     1657
     1658                        default:
     1659                            if (paFunctions)
     1660                            {
     1661                                paFunctions[usCurrent].ulOrdinal = usOrdinal;
     1662                                paFunctions[usCurrent].ulType = bType;
     1663                                sprintf(paFunctions[usCurrent].achFunctionName,
     1664                                        "Unknown bundle type encountered (%d).  Aborting entry table scan.",
     1665                                        bType);
     1666
     1667                                arc = ERROR_INVALID_LIST_FORMAT;
     1668                                    // whatever
     1669                                    // V0.9.9 (2001-04-03) [umoeller]
     1670                            }
     1671
     1672                            usCurrent++;
     1673                    } // end switch (bType & 0x7F)
     1674                }
     1675            }
     1676        } // end while (!arc)
     1677
     1678        if (!arc)
     1679            if (pcEntries)
     1680                *pcEntries = usCurrent;
     1681    }
     1682
     1683    return (arc);
     1684}
     1685
     1686/*
     1687 *@@ ScanNEEntryTable:
     1688 *      returns the number of exported entries in the entry table.
     1689 *
    13501690 *      if paFunctions is not NULL, then successive entries are
    13511691 *      filled with the found type and ordinal values.
    13521692 *
    13531693 *@@added V0.9.9 (2001-03-30) [lafaix]
    1354  */
    1355 
    1356 ULONG ScanLXEntryTable(PEXECUTABLE pExec,
    1357                        PFSYSFUNCTION paFunctions)
    1358 {
    1359     USHORT usOrdinal = 1,
    1360            usCurrent = 0;
     1694 *@@changed V0.9.9 (2001-04-03) [umoeller]: added tons of error checking, changed prototype to return APIRET
     1695 */
     1696
     1697APIRET ScanNEEntryTable(PEXECUTABLE pExec,
     1698                        PFSYSFUNCTION paFunctions,
     1699                        PULONG pcEntries)        // out: entry table entry count; ptr can be NULL
     1700{
     1701    APIRET arc = NO_ERROR;
    13611702    ULONG  ulDummy;
    1362     int    i;
    1363 
    1364     DosSetFilePtr(pExec->hfExe,
    1365                   pExec->pLXHeader->ulEntryTblOfs
    1366                     + pExec->pDosExeHeader->ulNewHeaderOfs,
    1367                   FILE_BEGIN,
    1368                   &ulDummy);
    1369 
    1370     while (TRUE)
     1703
     1704    if (!(arc = DosSetFilePtr(pExec->hfExe,
     1705                              pExec->pNEHeader->usEntryTblOfs
     1706                                + pExec->pDosExeHeader->ulNewHeaderOfs,
     1707                              FILE_BEGIN,
     1708                              &ulDummy)))
    13711709    {
    1372         BYTE   bCnt,
    1373                bType,
    1374                bFlag;
    1375 
    1376         DosRead(pExec->hfExe,
    1377                 &bCnt,
    1378                 1,
    1379                 &ulDummy);
    1380 
    1381         if (bCnt == 0)
    1382             // end of the entry table
    1383             break;
    1384 
    1385         DosRead(pExec->hfExe,
    1386                 &bType,
    1387                 1,
    1388                 &ulDummy);
    1389 
    1390         switch (bType & 0x7F)
    1391         {
    1392             /*
    1393              * unused entries
    1394              *
    1395              */
    1396 
    1397             case 0:
    1398                usOrdinal += bCnt;
    1399             break;
    1400 
    1401             /*
    1402              * 16-bit entries
    1403              *
    1404              * the bundle type is followed by the object number
    1405              * and by bCnt bFlag+usOffset entries
    1406              *
    1407              */
    1408 
    1409             case 1:
    1410                 DosSetFilePtr(pExec->hfExe,
    1411                               sizeof(USHORT),
    1412                               FILE_CURRENT,
    1413                               &ulDummy);
    1414 
    1415                 for (i = 0; i < bCnt; i ++)
     1710        USHORT usOrdinal = 1,
     1711               usCurrent = 0;
     1712        int    i;
     1713
     1714        while (!arc)        // V0.9.9 (2001-04-03) [umoeller]
     1715        {
     1716            BYTE bCnt,
     1717                 bType,
     1718                 bFlag;
     1719
     1720            if (!(arc = DosRead(pExec->hfExe,
     1721                                &bCnt,
     1722                                1,
     1723                                &ulDummy)))
     1724            {
     1725                if (bCnt == 0)
     1726                    // end of the entry table
     1727                    break;
     1728
     1729                if (!(arc = DosRead(pExec->hfExe,
     1730                                    &bType,
     1731                                    1,
     1732                                    &ulDummy)))
    14161733                {
    1417                     DosRead(pExec->hfExe,
    1418                             &bFlag,
    1419                             1,
    1420                             &ulDummy);
    1421 
    1422                     if (bFlag & 0x01)
     1734                    for (i = 0; i < bCnt; i++)
    14231735                    {
    1424                         if (paFunctions)
     1736                        if (!(arc = DosRead(pExec->hfExe,
     1737                                            &bFlag,
     1738                                            1,
     1739                                            &ulDummy)))
    14251740                        {
    1426                             paFunctions[usCurrent].ulOrdinal = usOrdinal;
    1427                             paFunctions[usCurrent].ulType = 1;
    1428                             paFunctions[usCurrent].achFunctionName[0] = 0;
     1741                            if (bFlag & 0x01)
     1742                            {
     1743                                if (paFunctions)
     1744                                {
     1745                                    paFunctions[usCurrent].ulOrdinal = usOrdinal;
     1746                                    paFunctions[usCurrent].ulType = 1; // 16-bit entry
     1747                                    paFunctions[usCurrent].achFunctionName[0] = 0;
     1748                                }
     1749                                usCurrent++;
     1750                            }
     1751
     1752                            usOrdinal++;
     1753
     1754                            if (bType == 0xFF)
     1755                                // moveable segment
     1756                                arc = DosSetFilePtr(pExec->hfExe,
     1757                                                    5,
     1758                                                    FILE_CURRENT,
     1759                                                    &ulDummy);
     1760                            else
     1761                                // fixed segment
     1762                                arc = DosSetFilePtr(pExec->hfExe,
     1763                                                    2,
     1764                                                    FILE_CURRENT,
     1765                                                    &ulDummy);
    14291766                        }
    1430                         usCurrent++;
    1431                     }
    1432 
    1433                     usOrdinal++;
    1434 
    1435                     DosSetFilePtr(pExec->hfExe,
    1436                                   sizeof(USHORT),
    1437                                   FILE_CURRENT,
    1438                                   &ulDummy);
     1767
     1768                        if (arc)
     1769                            break; // V0.9.9 (2001-04-03) [umoeller]
     1770
     1771                    } // end for
    14391772                }
    1440             break;
    1441 
    1442             /*
    1443              * 286 call gate entries
    1444              *
    1445              * the bundle type is followed by the object number
    1446              * and by bCnt bFlag+usOffset+usCallGate entries
    1447              *
    1448              */
    1449 
    1450             case 2:
    1451                 DosSetFilePtr(pExec->hfExe,
    1452                               sizeof(USHORT),
    1453                               FILE_CURRENT,
    1454                               &ulDummy);
    1455 
    1456                 for (i = 0; i < bCnt; i ++)
    1457                 {
    1458                     DosRead(pExec->hfExe,
    1459                             &bFlag,
    1460                             1,
    1461                             &ulDummy);
    1462 
    1463                     if (bFlag & 0x01)
    1464                     {
    1465                         if (paFunctions)
    1466                         {
    1467                             paFunctions[usCurrent].ulOrdinal = usOrdinal;
    1468                             paFunctions[usCurrent].ulType = 2;
    1469                             paFunctions[usCurrent].achFunctionName[0] = 0;
    1470                         }
    1471                         usCurrent++;
    1472                     }
    1473 
    1474                     usOrdinal++;
    1475 
    1476                 DosSetFilePtr(pExec->hfExe,
    1477                               sizeof(USHORT) + sizeof(USHORT),
    1478                               FILE_CURRENT,
    1479                               &ulDummy);
    1480                 }
    1481             break;
    1482 
    1483             /*
    1484              * 32-bit entries
    1485              *
    1486              * the bundle type is followed by the object number
    1487              * and by bCnt bFlag+ulOffset entries
    1488              *
    1489              */
    1490 
    1491             case 3:
    1492                 DosSetFilePtr(pExec->hfExe,
    1493                               sizeof(USHORT),
    1494                               FILE_CURRENT,
    1495                               &ulDummy);
    1496 
    1497                 for (i = 0; i < bCnt; i ++)
    1498                 {
    1499                     DosRead(pExec->hfExe,
    1500                             &bFlag,
    1501                             1,
    1502                             &ulDummy);
    1503 
    1504                     if (bFlag & 0x01)
    1505                     {
    1506                         if (paFunctions)
    1507                         {
    1508                             paFunctions[usCurrent].ulOrdinal = usOrdinal;
    1509                             paFunctions[usCurrent].ulType = 3;
    1510                             paFunctions[usCurrent].achFunctionName[0] = 0;
    1511                         }
    1512                         usCurrent++;
    1513                     }
    1514 
    1515                     usOrdinal++;
    1516 
    1517                     DosSetFilePtr(pExec->hfExe,
    1518                                   sizeof(ULONG),
    1519                                   FILE_CURRENT,
    1520                                   &ulDummy);
    1521                 }
    1522             break;
    1523 
    1524             /*
    1525              * forwarder entries
    1526              *
    1527              * the bundle type is followed by a reserved word
    1528              * and by bCnt bFlag+usModOrd+ulOffsOrdNum entries
    1529              *
    1530              */
    1531 
    1532             case 4:
    1533                 DosSetFilePtr(pExec->hfExe,
    1534                               sizeof(USHORT),
    1535                               FILE_CURRENT,
    1536                               &ulDummy);
    1537 
    1538                 for (i = 0; i < bCnt; i ++)
    1539                 {
    1540                     DosSetFilePtr(pExec->hfExe,
    1541                                   sizeof(BYTE) + sizeof(USHORT) + sizeof(ULONG),
    1542                                   FILE_CURRENT,
    1543                                   &ulDummy);
    1544 
    1545                     if (paFunctions)
    1546                     {
    1547                         paFunctions[usCurrent].ulOrdinal = usOrdinal;
    1548                         paFunctions[usCurrent].ulType = 4;
    1549                         paFunctions[usCurrent].achFunctionName[0] = 0;
    1550                     }
    1551                     usCurrent++;
    1552 
    1553                     usOrdinal++;
    1554                 }
    1555             break;
    1556         }
    1557     } // end while (TRUE)
    1558 
    1559     return (usCurrent);
    1560 }
    1561 
    1562 /*
    1563  *@@ ScanNEEntryTable:
    1564  *      returns the number of exported entries in the entry table.
    1565  *
    1566  *      if paFunctions is not NULL, then successive entries are
    1567  *      filled with the found type and ordinal values.
    1568  *
    1569  *@@added V0.9.9 (2001-03-30) [lafaix]
    1570  */
    1571 
    1572 ULONG ScanNEEntryTable(PEXECUTABLE pExec,
    1573                        PFSYSFUNCTION paFunctions)
    1574 {
    1575     USHORT usOrdinal = 1,
    1576            usCurrent = 0;
    1577     ULONG  ulDummy;
    1578     int    i;
    1579 
    1580     DosSetFilePtr(pExec->hfExe,
    1581                   pExec->pNEHeader->usEntryTblOfs
    1582                     + pExec->pDosExeHeader->ulNewHeaderOfs,
    1583                   FILE_BEGIN,
    1584                   &ulDummy);
    1585 
    1586     while (TRUE)
    1587     {
    1588         BYTE bCnt,
    1589              bType,
    1590              bFlag;
    1591 
    1592         DosRead(pExec->hfExe,
    1593                 &bCnt,
    1594                 1,
    1595                 &ulDummy);
    1596 
    1597         if (bCnt == 0)
    1598             // end of the entry table
    1599             break;
    1600 
    1601         DosRead(pExec->hfExe,
    1602                 &bType,
    1603                 1,
    1604                 &ulDummy);
    1605 
    1606         for (i = 0; i < bCnt; i++)
    1607         {
    1608             DosRead(pExec->hfExe,
    1609                     &bFlag,
    1610                     1,
    1611                     &ulDummy);
    1612 
    1613             if (bFlag & 0x01)
    1614             {
    1615                 if (paFunctions)
    1616                 {
    1617                     paFunctions[usCurrent].ulOrdinal = usOrdinal;
    1618                     paFunctions[usCurrent].ulType = 1; // 16-bit entry
    1619                     paFunctions[usCurrent].achFunctionName[0] = 0;
    1620                 }
    1621                 usCurrent++;
    16221773            }
    1623 
    1624             usOrdinal++;
    1625 
    1626             if (bType == 0xFF)
    1627                 // moveable segment
    1628                 DosSetFilePtr(pExec->hfExe,
    1629                               5,
    1630                               FILE_CURRENT,
    1631                               &ulDummy);
    1632             else
    1633                 // fixed segment
    1634                 DosSetFilePtr(pExec->hfExe,
    1635                               2,
    1636                               FILE_CURRENT,
    1637                               &ulDummy);
    1638         }
    1639     } // end while (TRUE)
    1640 
    1641     return (usCurrent);
     1774        } // end while (!arc)
     1775
     1776        if (!arc)
     1777            if (pcEntries)
     1778                *pcEntries = usCurrent;
     1779    }
     1780
     1781    return (arc);
     1782}
     1783
     1784/*
     1785 *@@ Compare:
     1786 *      binary search helper
     1787 *
     1788 *@@added V0.9.9 (2001-04-01) [lafaix]
     1789 */
     1790
     1791int Compare(const void *key,
     1792            const void *element)
     1793{
     1794    USHORT        usOrdinal = *((PUSHORT) key);
     1795    PFSYSFUNCTION pFunction = (PFSYSFUNCTION)element;
     1796
     1797    if (usOrdinal > pFunction->ulOrdinal)
     1798        return (1);
     1799    else if (usOrdinal < pFunction->ulOrdinal)
     1800        return (-1);
     1801    else
     1802        return (0);
    16421803}
    16431804
     
    16511812 *
    16521813 *@@added V0.9.9 (2001-03-30) [lafaix]
    1653  */
    1654 
    1655 VOID ScanNameTable(PEXECUTABLE pExec,
    1656                    ULONG cFunctions,
    1657                    PFSYSFUNCTION paFunctions)
    1658 {
    1659     USHORT usOrdinal;
    1660     ULONG  ulDummy;
    1661 
    1662     while (TRUE)
     1814 *@@changed V0.9.9 (2001-04-02) [lafaix]: the first entry is special
     1815 *@@changed V0.9.9 (2001-04-03) [umoeller]: added tons of error checking, changed prototype to return APIRET
     1816 */
     1817
     1818APIRET ScanNameTable(PEXECUTABLE pExec,
     1819                     ULONG cFunctions,
     1820                     PFSYSFUNCTION paFunctions)
     1821{
     1822    APIRET  arc = NO_ERROR;
     1823    ULONG   ulDummy;
     1824
     1825    USHORT        usOrdinal;
     1826    PFSYSFUNCTION pFunction;
     1827    BOOL          bFirst = TRUE;
     1828
     1829    while (!arc)        // V0.9.9 (2001-04-03) [umoeller]
    16631830    {
    16641831        BYTE   bLen;
    1665         CHAR   achName[128];
     1832        CHAR   achName[256];
    16661833        int    i;
    16671834
    1668         DosRead(pExec->hfExe,
    1669                 &bLen,
    1670                 1,
    1671                 &ulDummy);
    1672 
    1673         if (bLen == 0)
    1674             // end of the name table
    1675             break;
    1676 
    1677         bLen &= 0x7F;
    1678 
    1679         DosRead(pExec->hfExe,
    1680                 &achName,
    1681                 bLen,
    1682                 &ulDummy);
    1683         achName[bLen] = 0;
    1684 
    1685         DosRead(pExec->hfExe,
    1686                 &usOrdinal,
    1687                 sizeof(USHORT),
    1688                 &ulDummy);
    1689 
    1690         for (i = 0; i < cFunctions; i++)
    1691         {
    1692             if (paFunctions[i].ulOrdinal == usOrdinal)
     1835        if (!(arc = DosRead(pExec->hfExe,
     1836                            &bLen,
     1837                            1,
     1838                            &ulDummy)))
     1839        {
     1840            if (bLen == 0)
     1841                // end of the name table
     1842                break;
     1843
     1844            // the LX docs says that len is limited to 127 (the 8th bit being
     1845            // reserved for future use); but does this applies to 16bits
     1846            // tables too?
     1847            // in any case, we must skip the first entry (module name in the
     1848            // resident name table, and module description in non-resident
     1849            // name table)
     1850            if (bFirst)
     1851                bFirst = FALSE;
     1852            else
     1853                bLen &= 0x7F;
     1854
     1855            if (!(arc = DosRead(pExec->hfExe,
     1856                                &achName,
     1857                                bLen,
     1858                                &ulDummy)))
    16931859            {
    1694                 memcpy(paFunctions[i].achFunctionName,
    1695                        achName,
    1696                        bLen+1);
    1697                 break;
     1860                achName[bLen] = 0;
     1861
     1862                if (!(arc = DosRead(pExec->hfExe,
     1863                                    &usOrdinal,
     1864                                    sizeof(USHORT),
     1865                                    &ulDummy)))
     1866                {
     1867                    if ((pFunction = bsearch(&usOrdinal,
     1868                                             paFunctions,
     1869                                             cFunctions,
     1870                                             sizeof(FSYSFUNCTION),
     1871                                             Compare)))
     1872                    {
     1873                        memcpy(pFunction->achFunctionName,
     1874                               achName,
     1875                               bLen+1);
     1876                    }
     1877                }
    16981878            }
    16991879        }
    17001880    }
     1881
     1882    return (arc);
    17011883}
    17021884
     
    17121894 *      functions.  Empty export entries are _not_ included.
    17131895 *
     1896 *      This returns a standard OS/2 error code, which might be
     1897 *      any of the codes returned by DosSetFilePtr and DosRead.
     1898 *      In addition, this may return:
     1899 *
     1900 *      --  ERROR_NOT_ENOUGH_MEMORY
     1901 *
     1902 *      --  ERROR_INVALID_EXE_SIGNATURE: exe is in a format other
     1903 *          than LX or NE, which is not understood by this function.
     1904 *
     1905 *      --  If ERROR_INVALID_LIST_FORMAT is returned, the format of an
     1906 *          export entry wasn't understood here.
     1907 *
     1908 *      Even if NO_ERROR is returned, the array pointer might still
     1909 *      be NULL if the module contains no such data.
     1910 *
    17141911 *@@added V0.9.9 (2001-03-11) [lafaix]
    1715  */
    1716 
    1717 PFSYSFUNCTION doshExecQueryExportedFunctions(PEXECUTABLE pExec,
    1718                                              PULONG pcFunctions)
    1719 {
    1720     ULONG         cFunctions = 0;
    1721     PFSYSFUNCTION paFunctions = NULL;
    1722 
    1723     if (pExec)
     1912 *@@changed V0.9.9 (2001-04-03) [umoeller]: added tons of error checking, changed prototype to return APIRET
     1913 */
     1914
     1915APIRET doshExecQueryExportedFunctions(PEXECUTABLE pExec,
     1916                                      PFSYSFUNCTION *ppaFunctions,  // out: functions array
     1917                                      PULONG pcFunctions)           // out: array item count
     1918{
     1919    APIRET arc = NO_ERROR;
     1920
     1921    if (    (pExec)
     1922         && (pExec->ulOS == EXEOS_OS2)
     1923       )
    17241924    {
    1725         if (pExec->ulOS == EXEOS_OS2)
    1726         {
    1727             ULONG ulDummy;
    1728 
    1729             if (pExec->ulExeFormat == EXEFORMAT_LX)
     1925        ULONG         cFunctions = 0;
     1926        PFSYSFUNCTION paFunctions = NULL;
     1927
     1928        ULONG ulDummy;
     1929
     1930        if (pExec->ulExeFormat == EXEFORMAT_LX)
     1931        {
     1932            // It's a 32bit OS/2 executable
     1933
     1934            // the number of exported entry points is not stored
     1935            // in the executable header; we have to count them in
     1936            // the entry table
     1937
     1938            if (!(arc = ScanLXEntryTable(pExec,
     1939                                         NULL,
     1940                                         &cFunctions)))
    17301941            {
    1731                 // It's a 32bit OS/2 executable
    1732 
    1733                 // the number of exported entry points is not stored
    1734                 // in the executable header; we have to count them in
    1735                 // the entry table
    1736 
    1737                 cFunctions = ScanLXEntryTable(pExec, NULL);
    1738 
    17391942                // we now have the number of exported entries; let us
    17401943                // build them
     
    17421945                if (cFunctions)
    17431946                {
    1744                     paFunctions = (PFSYSFUNCTION)malloc(sizeof(FSYSFUNCTION) * cFunctions);
    1745 
    1746                     // we rescan the entry table (the cost is not as bad
    1747                     // as it may seem, due to disk caching)
    1748 
    1749                     ScanLXEntryTable(pExec, paFunctions);
    1750 
    1751                     // we now scan the resident name table entries
    1752                     DosSetFilePtr(pExec->hfExe,
    1753                                   pExec->pLXHeader->ulResdNameTblOfs
    1754                                     + pExec->pDosExeHeader->ulNewHeaderOfs,
    1755                                   FILE_BEGIN,
    1756                                   &ulDummy);
    1757 
    1758                     ScanNameTable(pExec, cFunctions, paFunctions);
    1759 
    1760                     // we now scan the non-resident name table entries,
    1761                     // whose offset is _from the begining of the file_
    1762                     DosSetFilePtr(pExec->hfExe,
    1763                                   pExec->pLXHeader->ulNonResdNameTblOfs,
    1764                                   FILE_BEGIN,
    1765                                   &ulDummy);
    1766 
    1767                     ScanNameTable(pExec, cFunctions, paFunctions);
     1947                    ULONG cb = sizeof(FSYSFUNCTION) * cFunctions;
     1948
     1949                    paFunctions = (PFSYSFUNCTION)malloc(cb);
     1950                    if (!paFunctions)
     1951                        arc = ERROR_NOT_ENOUGH_MEMORY;  // V0.9.9 (2001-04-03) [umoeller]
     1952                    else
     1953                    {
     1954                        // we rescan the entry table (the cost is not as bad
     1955                        // as it may seem, due to disk caching)
     1956
     1957                        if (    (!(arc = ScanLXEntryTable(pExec, paFunctions, NULL)))
     1958                                // we now scan the resident name table entries
     1959                             && (!(arc = DosSetFilePtr(pExec->hfExe,
     1960                                                       pExec->pLXHeader->ulResdNameTblOfs
     1961                                                         + pExec->pDosExeHeader->ulNewHeaderOfs,
     1962                                                       FILE_BEGIN,
     1963                                                       &ulDummy)))
     1964                             && (!(arc = ScanNameTable(pExec, cFunctions, paFunctions)))
     1965                                // we now scan the non-resident name table entries,
     1966                                // whose offset is _from the begining of the file_
     1967                             && (!(arc = DosSetFilePtr(pExec->hfExe,
     1968                                                       pExec->pLXHeader->ulNonResdNameTblOfs,
     1969                                                       FILE_BEGIN,
     1970                                                       &ulDummy)))
     1971                           )
     1972                        {
     1973                            arc = ScanNameTable(pExec, cFunctions, paFunctions);
     1974                        }
     1975                    }
    17681976                } // end if (cFunctions)
    17691977            }
    1770             else
    1771             if (pExec->ulExeFormat == EXEFORMAT_NE)
     1978        }
     1979        else if (pExec->ulExeFormat == EXEFORMAT_NE)
     1980        {
     1981            // It's a 16bit OS/2 executable
     1982
     1983            // here too the number of exported entry points
     1984            // is not stored in the executable header; we
     1985            // have to count them in the entry table
     1986
     1987            if (!(arc = ScanNEEntryTable(pExec,
     1988                                         NULL,
     1989                                         &cFunctions)))
    17721990            {
    1773                 // It's a 16bit OS/2 executable
    1774 
    1775                 // here too the number of exported entry points
    1776                 // is not stored in the executable header; we
    1777                 // have to count them in the entry table
    1778 
    1779                 cFunctions = ScanNEEntryTable(pExec, NULL);
    1780 
    17811991                // we now have the number of exported entries; let us
    17821992                // build them
     
    17881998
    17891999                    paFunctions = (PFSYSFUNCTION)malloc(sizeof(FSYSFUNCTION) * cFunctions);
    1790 
    1791                     // we rescan the entry table (the cost is not as bad
    1792                     // as it may seem, due to disk caching)
    1793 
    1794                     ScanNEEntryTable(pExec, paFunctions);
    1795 
    1796                     // we now scan the resident name table entries
    1797                     DosSetFilePtr(pExec->hfExe,
    1798                                   pExec->pNEHeader->usResdNameTblOfs
    1799                                     + pExec->pDosExeHeader->ulNewHeaderOfs,
    1800                                   FILE_BEGIN,
    1801                                   &ulDummy);
    1802 
    1803                     ScanNameTable(pExec, cFunctions, paFunctions);
    1804 
    1805                     // we now scan the non-resident name table entries,
    1806                     // whose offset is _from the begining of the file_
    1807                     DosSetFilePtr(pExec->hfExe,
    1808                                   pExec->pNEHeader->ulNonResdTblOfs,
    1809                                   FILE_BEGIN,
    1810                                   &ulDummy);
    1811 
    1812                     ScanNameTable(pExec, cFunctions, paFunctions);
     2000                    if (!paFunctions)
     2001                        arc = ERROR_NOT_ENOUGH_MEMORY;
     2002                    else
     2003                    {
     2004                        // we rescan the entry table (the cost is not as bad
     2005                        // as it may seem, due to disk caching)
     2006
     2007                        if (    (!(arc = ScanNEEntryTable(pExec, paFunctions, NULL)))
     2008                                // we now scan the resident name table entries
     2009                             && (!(arc = DosSetFilePtr(pExec->hfExe,
     2010                                                       pExec->pNEHeader->usResdNameTblOfs
     2011                                                         + pExec->pDosExeHeader->ulNewHeaderOfs,
     2012                                                       FILE_BEGIN,
     2013                                                       &ulDummy)))
     2014                             && (!(arc = ScanNameTable(pExec, cFunctions, paFunctions)))
     2015                                // we now scan the non-resident name table entries,
     2016                                // whose offset is _from the begining of the file_
     2017                             && (!(arc = DosSetFilePtr(pExec->hfExe,
     2018                                                       pExec->pNEHeader->ulNonResdTblOfs,
     2019                                                       FILE_BEGIN,
     2020                                                       &ulDummy)))
     2021                           )
     2022                        {
     2023                             arc = ScanNameTable(pExec, cFunctions, paFunctions);
     2024                        }
     2025                    }
    18132026                }
    18142027            }
    1815 
     2028        }
     2029        else
     2030            arc = ERROR_INVALID_EXE_SIGNATURE; // V0.9.9 (2001-04-03) [umoeller]
     2031
     2032        if (arc) // V0.9.9 (2001-04-03) [umoeller]
     2033        {
     2034            // if we had an error above, clean up
     2035            if (paFunctions)
     2036                free(paFunctions);
     2037        }
     2038        else
     2039        {
     2040            // no error: output data
     2041            *ppaFunctions = paFunctions;
    18162042            *pcFunctions = cFunctions;
    18172043        }
    18182044    }
    1819 
    1820     return (paFunctions);
     2045    else
     2046        arc = ERROR_INVALID_EXE_SIGNATURE; // V0.9.9 (2001-04-03) [umoeller]
     2047
     2048    return (arc);
    18212049}
    18222050
     
    18302058APIRET doshExecFreeExportedFunctions(PFSYSFUNCTION paFunctions)
    18312059{
    1832     free(paFunctions);
     2060    if (paFunctions)       // V0.9.9 (2001-04-04) [umoeller]
     2061        free(paFunctions);
    18332062    return (NO_ERROR);
    18342063}
     
    18422071 *      (not the array size!). Use doshExecFreeResources to clean up.
    18432072 *
     2073 *      This returns a standard OS/2 error code, which might be
     2074 *      any of the codes returned by DosSetFilePtr and DosRead.
     2075 *      In addition, this may return:
     2076 *
     2077 *      --  ERROR_NOT_ENOUGH_MEMORY
     2078 *
     2079 *      --  ERROR_INVALID_EXE_SIGNATURE: exe is in a format other
     2080 *          than LX or NE, which is not understood by this function.
     2081 *
     2082 *      Even if NO_ERROR is returned, the array pointer might still
     2083 *      be NULL if the module contains no such data.
     2084 *
    18442085 *@@added V0.9.7 (2000-12-18) [lafaix]
    1845  */
    1846 
    1847 PFSYSRESOURCE doshExecQueryResources(PEXECUTABLE pExec, PULONG pcResources)
    1848 {
    1849     ULONG         cResources = 0;
    1850     PFSYSRESOURCE paResources = NULL;
    1851     int i;
    1852 
    1853     if (pExec)
     2086 *@@changed V0.9.9 (2001-04-03) [umoeller]: added tons of error checking, changed prototype to return APIRET
     2087 */
     2088
     2089APIRET doshExecQueryResources(PEXECUTABLE pExec,     // in: executable from doshExecOpen
     2090                              PFSYSRESOURCE *ppaResources,   // out: res's array
     2091                              PULONG pcResources)    // out: array item count
     2092{
     2093    APIRET          arc = NO_ERROR;
     2094
     2095    if (    (pExec)
     2096         && (pExec->ulOS == EXEOS_OS2)
     2097       )
    18542098    {
    1855         if (pExec->ulOS == EXEOS_OS2)
    1856         {
    1857             ULONG ulDummy;
    1858 
    1859             if (pExec->ulExeFormat == EXEFORMAT_LX)
     2099        ULONG           cResources = 0;
     2100        PFSYSRESOURCE   paResources = NULL;
     2101
     2102        if (pExec->ulExeFormat == EXEFORMAT_LX)
     2103        {
     2104            // 32-bit OS/2 executable:
     2105            if (cResources = pExec->pLXHeader->ulResTblCnt)
    18602106            {
    1861                 // It's a 32bit OS/2 executable
    1862                 cResources = pExec->pLXHeader->ulResTblCnt;
    1863 
    1864                 if (cResources)
     2107                ULONG cb = sizeof(FSYSRESOURCE) * cResources;
     2108                paResources = (PFSYSRESOURCE)malloc(cb);
     2109                if (!paResources)
     2110                    arc = ERROR_NOT_ENOUGH_MEMORY;
     2111                else
    18652112                {
    1866                     struct rsrc32               /* Resource Table Entry */
     2113                    ULONG ulDummy;
     2114
     2115                    memset(paResources, 0, cb); // V0.9.9 (2001-04-03) [umoeller]
     2116
     2117                    // V0.9.9 (2001-04-03) [umoeller]:
     2118                    // Martin, I added error checking to all the below
     2119                    // Dos* calls. You can't just read around a file
     2120                    // and assume it will always be valid... especially
     2121                    // if you fill dynamically allocated memory.
     2122                    if (!(arc = DosSetFilePtr(pExec->hfExe,
     2123                                              pExec->pLXHeader->ulResTblOfs
     2124                                                + pExec->pDosExeHeader->ulNewHeaderOfs,
     2125                                              FILE_BEGIN,
     2126                                              &ulDummy)))
    18672127                    {
    1868                         unsigned short  type;   /* Resource type */
    1869                         unsigned short  name;   /* Resource name */
    1870                         unsigned long   cb;     /* Resource size */
    1871                         unsigned short  obj;    /* Object number */
    1872                         unsigned long   offset; /* Offset within object */
    1873                     } rs;
    1874 
    1875                     struct o32_obj                    /* Flat .EXE object table entry */
     2128                        int i;
     2129
     2130                        // V0.9.9 (2001-04-03) [umoeller]:
     2131                        // Besides, packing was missing.
     2132                        #pragma pack(1)     // V0.9.9 (2001-04-02) [umoeller]
     2133                        struct rsrc32               /* Resource Table Entry */
     2134                        {
     2135                            unsigned short  type;   /* Resource type */
     2136                            unsigned short  name;   /* Resource name */
     2137                            unsigned long   cb;     /* Resource size */
     2138                            unsigned short  obj;    /* Object number */
     2139                            unsigned long   offset; /* Offset within object */
     2140                        } rs;
     2141
     2142                        struct o32_obj                    /* Flat .EXE object table entry */
     2143                        {
     2144                            unsigned long   o32_size;     /* Object virtual size */
     2145                            unsigned long   o32_base;     /* Object base virtual address */
     2146                            unsigned long   o32_flags;    /* Attribute flags */
     2147                            unsigned long   o32_pagemap;  /* Object page map index */
     2148                            unsigned long   o32_mapsize;  /* Number of entries in object page map */
     2149                            unsigned long   o32_reserved; /* Reserved */
     2150                        } ot;
     2151                        #pragma pack() // V0.9.9 (2001-04-03) [umoeller]
     2152
     2153                        for (i = 0; i < cResources; i++)
     2154                        {
     2155                            arc = DosRead(pExec->hfExe,
     2156                                          &rs,
     2157                                          14,
     2158                                          &ulDummy);
     2159                            if (arc)
     2160                                break;      // V0.9.9 (2001-04-03) [umoeller]
     2161                            else
     2162                            {
     2163                                paResources[i].ulID = rs.name;
     2164                                paResources[i].ulType = rs.type;
     2165                                paResources[i].ulSize = rs.cb;
     2166                                paResources[i].ulFlag = rs.obj; // Temp storage for Object
     2167                                                                // number.  Will be filled
     2168                                                                // with resource flag
     2169                                                                // later.
     2170                            }
     2171                        }
     2172
     2173                        if (!arc)       // V0.9.9 (2001-04-03) [umoeller]
     2174                        {
     2175                            for (i = 0; i < cResources; i++)
     2176                            {
     2177                                ULONG ulOfsThis
     2178                                    =   pExec->pLXHeader->ulObjTblOfs
     2179                                      + pExec->pDosExeHeader->ulNewHeaderOfs
     2180                                      + (   sizeof(ot)
     2181                                          * (paResources[i].ulFlag - 1));
     2182
     2183                                if (!(arc = DosSetFilePtr(pExec->hfExe,
     2184                                                          ulOfsThis,
     2185                                                          FILE_BEGIN,
     2186                                                          &ulDummy)))
     2187                                {
     2188                                    if (!(arc = DosRead(pExec->hfExe,
     2189                                                        &ot,
     2190                                                        sizeof(ot),
     2191                                                        &ulDummy)))
     2192                                    {
     2193                                        paResources[i].ulFlag  = ((ot.o32_flags & OBJWRITE)
     2194                                                                        ? 0
     2195                                                                        : RNPURE);
     2196                                        paResources[i].ulFlag |= ((ot.o32_flags & OBJDISCARD)
     2197                                                                        ? 4096
     2198                                                                        : 0);
     2199                                        paResources[i].ulFlag |= ((ot.o32_flags & OBJSHARED)
     2200                                                                        ? RNMOVE
     2201                                                                        : 0);
     2202                                        paResources[i].ulFlag |= ((ot.o32_flags & OBJPRELOAD)
     2203                                                                        ? RNPRELOAD
     2204                                                                        : 0);
     2205                                    }
     2206                                }
     2207
     2208                                if (arc)
     2209                                    break; // V0.9.9 (2001-04-03) [umoeller]
     2210                            } // end for
     2211                        }
     2212                    } // end if !DosSetFilePtr(pExec->hfExe,
     2213                } // end if paResources = (PFSYSRESOURCE)malloc(sizeof(FSYSRESOURCE) * cResources);
     2214            } // end if (cResources)
     2215        } // end if (pExec->ulExeFormat == EXEFORMAT_LX)
     2216        else if (pExec->ulExeFormat == EXEFORMAT_NE)
     2217        {
     2218            // 16-bit OS/2 executable:
     2219            if (cResources = pExec->pNEHeader->usResSegmCount)
     2220            {
     2221                #pragma pack(1)     // V0.9.9 (2001-04-02) [umoeller]
     2222                struct {unsigned short type; unsigned short name;} rti;
     2223                struct new_seg                          /* New .EXE segment table entry */
     2224                {
     2225                    unsigned short      ns_sector;      /* File sector of start of segment */
     2226                    unsigned short      ns_cbseg;       /* Number of bytes in file */
     2227                    unsigned short      ns_flags;       /* Attribute flags */
     2228                    unsigned short      ns_minalloc;    /* Minimum allocation in bytes */
     2229                } ns;
     2230                #pragma pack()
     2231
     2232                ULONG cb = sizeof(FSYSRESOURCE) * cResources;
     2233
     2234                paResources = (PFSYSRESOURCE)malloc(cb);
     2235                if (!paResources)
     2236                    arc = ERROR_NOT_ENOUGH_MEMORY;
     2237                else
     2238                {
     2239                    ULONG ulDummy;
     2240
     2241                    memset(paResources, 0, cb);     // V0.9.9 (2001-04-03) [umoeller]
     2242
     2243                    // we first read the resources IDs and types
     2244                    if (!(arc = DosSetFilePtr(pExec->hfExe,
     2245                                              pExec->pNEHeader->usResTblOfs
     2246                                                 + pExec->pDosExeHeader->ulNewHeaderOfs,
     2247                                              FILE_BEGIN,
     2248                                              &ulDummy)))
    18762249                    {
    1877                         unsigned long   o32_size;     /* Object virtual size */
    1878                         unsigned long   o32_base;     /* Object base virtual address */
    1879                         unsigned long   o32_flags;    /* Attribute flags */
    1880                         unsigned long   o32_pagemap;  /* Object page map index */
    1881                         unsigned long   o32_mapsize;  /* Number of entries in object page map */
    1882                         unsigned long   o32_reserved; /* Reserved */
    1883                     } ot;
    1884 
    1885                     paResources = (PFSYSRESOURCE)malloc(sizeof(FSYSRESOURCE) * cResources);
    1886 
    1887                     DosSetFilePtr(pExec->hfExe,
    1888                                   pExec->pLXHeader->ulResTblOfs
    1889                                     + pExec->pDosExeHeader->ulNewHeaderOfs,
    1890                                   FILE_BEGIN,
    1891                                   &ulDummy);
    1892 
    1893                     for (i = 0; i < cResources; i++)
    1894                     {
    1895                         DosRead(pExec->hfExe, &rs, 14, &ulDummy);
    1896                         paResources[i].ulID = rs.name;
    1897                         paResources[i].ulType = rs.type;
    1898                         paResources[i].ulSize = rs.cb;
    1899                         paResources[i].ulFlag = rs.obj; // Temp storage for Object
    1900                                                         // number.  Will be filled
    1901                                                         // with resource flag
    1902                                                         // later.
    1903                     }
    1904 
    1905                     for (i = 0; i < cResources; i++)
    1906                     {
    1907                         DosSetFilePtr(pExec->hfExe,
    1908                                       pExec->pLXHeader->ulObjTblOfs
    1909                                         + pExec->pDosExeHeader->ulNewHeaderOfs
    1910                                         + (   sizeof(ot)
    1911                                             * (paResources[i].ulFlag - 1)),
    1912                                       FILE_BEGIN,
    1913                                       &ulDummy);
    1914                         DosRead(pExec->hfExe, &ot, sizeof(ot), &ulDummy);
    1915 
    1916                         paResources[i].ulFlag  = (ot.o32_flags & OBJWRITE) ? 0 : RNPURE;
    1917                         paResources[i].ulFlag |= (ot.o32_flags & OBJDISCARD) ? 4096 : 0;
    1918                         paResources[i].ulFlag |= (ot.o32_flags & OBJSHARED) ? RNMOVE : 0;
    1919                         paResources[i].ulFlag |= (ot.o32_flags & OBJPRELOAD) ? RNPRELOAD : 0;
    1920                     }
    1921                 }
    1922             }
    1923             else
    1924             if (pExec->ulExeFormat == EXEFORMAT_NE)
    1925             {
    1926                // It's a 16bit OS/2 executable
    1927                cResources = pExec->pNEHeader->usResSegmCount;
    1928 
    1929                if (cResources)
    1930                {
    1931                    struct {unsigned short type; unsigned short name;} rti;
    1932                    struct new_seg                          /* New .EXE segment table entry */
    1933                    {
    1934                        unsigned short      ns_sector;      /* File sector of start of segment */
    1935                        unsigned short      ns_cbseg;       /* Number of bytes in file */
    1936                        unsigned short      ns_flags;       /* Attribute flags */
    1937                        unsigned short      ns_minalloc;    /* Minimum allocation in bytes */
    1938                    } ns;
    1939 
    1940                    paResources = (PFSYSRESOURCE)malloc(sizeof(FSYSRESOURCE) * cResources);
    1941 
    1942                    // We first read the resources IDs and types
    1943                    DosSetFilePtr(pExec->hfExe,
    1944                                  pExec->pNEHeader->usResTblOfs
    1945                                     + pExec->pDosExeHeader->ulNewHeaderOfs,
    1946                                  FILE_BEGIN,
    1947                                  &ulDummy);
    1948 
    1949                    for (i = 0; i < cResources; i++)
    1950                    {
    1951                        DosRead(pExec->hfExe, &rti, sizeof(rti), &ulDummy);
    1952                        paResources[i].ulID = rti.name;
    1953                        paResources[i].ulType = rti.type;
    1954                    }
    1955 
    1956                    // And we then read their sizes and flags
    1957                    for (i = 0; i < cResources; i++)
    1958                    {
    1959                        DosSetFilePtr(pExec->hfExe,
    1960                                      pExec->pDosExeHeader->ulNewHeaderOfs
    1961                                             + pExec->pNEHeader->usSegTblOfs
    1962                                             + (sizeof(ns)
    1963                                                 * (  pExec->pNEHeader->usSegTblEntries
    1964                                                    - pExec->pNEHeader->usResSegmCount
    1965                                                    + i)),
    1966                                      FILE_BEGIN,
    1967                                      &ulDummy);
    1968                        DosRead(pExec->hfExe, &ns, sizeof(ns), &ulDummy);
    1969 
    1970                        paResources[i].ulSize = ns.ns_cbseg;
    1971 
    1972                        paResources[i].ulFlag  = (ns.ns_flags & OBJPRELOAD) ? RNPRELOAD : 0;
    1973                        paResources[i].ulFlag |= (ns.ns_flags & OBJSHARED) ? RNPURE : 0;
    1974                        paResources[i].ulFlag |= (ns.ns_flags & OBJDISCARD) ? RNMOVE : 0;
    1975                        paResources[i].ulFlag |= (ns.ns_flags & OBJDISCARD) ? 4096 : 0;
    1976                    }
    1977                }
    1978             }
    1979 
     2250                        int i;
     2251
     2252                        for (i = 0; i < cResources; i++)
     2253                        {
     2254                            arc = DosRead(pExec->hfExe, &rti, sizeof(rti), &ulDummy);
     2255                            if (arc)
     2256                                break;
     2257                            else
     2258                            {
     2259                                paResources[i].ulID = rti.name;
     2260                                paResources[i].ulType = rti.type;
     2261                            }
     2262                        }
     2263
     2264                        if (!arc)
     2265                        {
     2266                            // we then read their sizes and flags
     2267                            for (i = 0; i < cResources; i++)
     2268                            {
     2269                                if (!(arc = DosSetFilePtr(pExec->hfExe,
     2270                                                          pExec->pDosExeHeader->ulNewHeaderOfs
     2271                                                                 + pExec->pNEHeader->usSegTblOfs
     2272                                                                 + (sizeof(ns)
     2273                                                                     * (  pExec->pNEHeader->usSegTblEntries
     2274                                                                        - pExec->pNEHeader->usResSegmCount
     2275                                                                        + i)),
     2276                                                          FILE_BEGIN,
     2277                                                          &ulDummy)))
     2278                                {
     2279                                    if (!(arc = DosRead(pExec->hfExe,
     2280                                                        &ns,
     2281                                                        sizeof(ns),
     2282                                                        &ulDummy)))
     2283                                    {
     2284                                        paResources[i].ulSize = ns.ns_cbseg;
     2285
     2286                                        paResources[i].ulFlag  = (ns.ns_flags & OBJPRELOAD) ? RNPRELOAD : 0;
     2287                                        paResources[i].ulFlag |= (ns.ns_flags & OBJSHARED) ? RNPURE : 0;
     2288                                        paResources[i].ulFlag |= (ns.ns_flags & OBJDISCARD) ? RNMOVE : 0;
     2289                                        paResources[i].ulFlag |= (ns.ns_flags & OBJDISCARD) ? 4096 : 0;
     2290                                    }
     2291                                }
     2292
     2293                                if (arc)
     2294                                    break; // V0.9.9 (2001-04-04) [umoeller]
     2295                            } // end for
     2296                        }
     2297                    } // end if !arc = DosSetFilePtr(pExec->hfExe,
     2298                } // end if paResources = (PFSYSRESOURCE)malloc(sizeof(FSYSRESOURCE) * cResources);
     2299            } // end if (cResources)
     2300        } // end else if (pExec->ulExeFormat == EXEFORMAT_NE)
     2301        else
     2302            arc = ERROR_INVALID_EXE_SIGNATURE; // V0.9.9 (2001-04-03) [umoeller]
     2303
     2304        if (arc) // V0.9.9 (2001-04-03) [umoeller]
     2305        {
     2306            // if we had an error above, clean up
     2307            if (paResources)
     2308                free(paResources);
     2309        }
     2310        else
     2311        {
     2312            // no error: output data
     2313            *ppaResources = paResources;
    19802314            *pcResources = cResources;
    19812315        }
    19822316    }
    1983 
    1984     return (paResources);
     2317    else
     2318        arc = ERROR_INVALID_EXE_SIGNATURE; // V0.9.9 (2001-04-03) [umoeller]
     2319
     2320    return (arc);
    19852321}
    19862322
     
    19942330APIRET doshExecFreeResources(PFSYSRESOURCE paResources)
    19952331{
    1996     free(paResources);
     2332    if (paResources)        // V0.9.9 (2001-04-04) [umoeller]
     2333        free(paResources);
    19972334    return (NO_ERROR);
    19982335}
     
    20382375 *
    20392376 *@@added V0.9.0 [umoeller]
     2377 *@@changed V0.9.9 (2001-04-04) [umoeller]: added more error checking
    20402378 */
    20412379
     
    20462384                      USHORT sector)
    20472385{
    2048     UINT   arc;
    2049     HFILE  dh = 0;
    2050     char   dn[256];
    2051     // char   ms[256];
    2052 
    2053     sprintf( dn, "%u:", disk );
    2054     arc = DosPhysicalDisk(INFO_GETIOCTLHANDLE, &dh, 2, dn, 3);
    2055 
    2056     if (arc)
    2057         // error:
    2058         return (arc);
    2059     else
     2386    APIRET  arc;
     2387    HFILE   dh = 0;
     2388    char    dn[256];
     2389
     2390    sprintf(dn, "%u:", disk);
     2391    if (!(arc = DosPhysicalDisk(INFO_GETIOCTLHANDLE, &dh, 2, dn, 3)))
    20602392    {
    20612393        TRACKLAYOUT DiskIOParm;
     
    20762408                          buff       , IOCtlDataLength, &IOCtlDataLength);
    20772409
    2078         if(arc)
    2079         {
    2080             // error:
    2081             DosPhysicalDisk(INFO_FREEIOCTLHANDLE, 0, 0, &dh, 2);
    2082             return (arc);
    2083         }
    2084 
    20852410        DosPhysicalDisk(INFO_FREEIOCTLHANDLE, 0, 0, &dh, 2);
    20862411    }
    2087     return (NO_ERROR);
     2412
     2413    return (arc);
    20882414}
    20892415
     
    22212547 */
    22222548
    2223 char* doshType2FSName(unsigned char bFSType)  // in: FS type
     2549const char* doshType2FSName(unsigned char bFSType)  // in: FS type
    22242550{
    22252551    PSZ zFSName = NULL;
     
    24592785static USHORT GetCyl(USHORT rBeginSecCyl)
    24602786{
    2461     return ((rBeginSecCyl & 0x00C0) << 2) +
    2462         ((rBeginSecCyl & 0xFF00) >> 8);
     2787    return (   (rBeginSecCyl & 0x00C0) << 2)
     2788             + ((rBeginSecCyl & 0xFF00) >> 8);
    24632789}
    24642790
     
    25572883                            UINT iDisk)          // in: system's physical disk count
    25582884{
    2559     APIRET          arc = NO_ERROR;
    2560     MBR_INFO        MBoot;      // Master Boot
    2561     SYS_INFO        MName[32];  // Name Space from Boot Manager
    2562     USHORT          i;
    2563 
    2564     memset(&MName, 0, sizeof(MName));
    2565 
    2566     if (BmInfo)
     2885    APIRET  arc = NO_ERROR;
     2886
     2887    if (!BmInfo)
     2888        arc = ERROR_INVALID_PARAMETER;
     2889    else
    25672890    {
     2891        SYS_INFO        MName[32];  // Name Space from Boot Manager
     2892        memset(&MName, 0, sizeof(MName));
     2893
    25682894        // read boot manager name table
    2569         if ((arc = doshReadSector(BmDisk, &MName, BmInfo->bBeginHead,
    2570                                   GetCyl(BmInfo->rBeginSecCyl),
    2571                                   GetSec(BmInfo->rBeginSecCyl) + 3)))
    2572             return (arc);
    2573     }
    2574 
    2575     // read master boot record
    2576     if ((arc = doshReadSector(iDisk, &MBoot, 0, 0, 1)))
    2577         return (arc);
    2578 
    2579     for (i = 0;
    2580          i < 4;     // there can be only four primary partitions
    2581          i++)
    2582     {
    2583         // skip unused partition, BootManager or Extended partition
    2584         if (    (MBoot.sPrtnInfo[i].bFileSysCode)  // skip unused
    2585             &&  (MBoot.sPrtnInfo[i].bFileSysCode != PAR_BOOTMANAGER) // skip boot manager
    2586             &&  (MBoot.sPrtnInfo[i].bFileSysCode != PAR_EXTENDED) // skip extended
    2587            )
    2588         {
    2589             BOOL fBootable = (  (BmInfo)
    2590                              && (MName[(iDisk-1) * 4 + i].bootable & 0x01)
    2591                              );
    2592             // store this partition
    2593             if ((arc = AppendPartition(pppiFirst,
    2594                                        pppiThis,
    2595                                        posCount,
    2596                                        iDisk,
    2597                                        (fBootable)
    2598                                          ? (char*)&MName[(iDisk - 1) * 4 + i].name
    2599                                          : "",
    2600                                        *pcLetter,
    2601                                        MBoot.sPrtnInfo[i].bFileSysCode,
    2602                                        TRUE,        // primary
    2603                                        fBootable,
    2604                                        MBoot.sPrtnInfo[i].lTotalSects)))
    2605                 return (arc);
     2895        if (!(arc = doshReadSector(BmDisk,
     2896                                   &MName,
     2897                                   BmInfo->bBeginHead,
     2898                                   GetCyl(BmInfo->rBeginSecCyl),
     2899                                   GetSec(BmInfo->rBeginSecCyl) + 3)))
     2900        {
     2901            MBR_INFO        MBoot;      // Master Boot
     2902            USHORT          i;
     2903
     2904            // read master boot record of this disk
     2905            if (!(arc = doshReadSector(iDisk, &MBoot, 0, 0, 1)))
     2906            {
     2907                for (i = 0;
     2908                     i < 4;     // there can be only four primary partitions
     2909                     i++)
     2910                {
     2911                    // skip unused partition, BootManager or Extended partition
     2912                    if (    (MBoot.sPrtnInfo[i].bFileSysCode)  // skip unused
     2913                        &&  (MBoot.sPrtnInfo[i].bFileSysCode != PAR_BOOTMANAGER) // skip boot manager
     2914                        &&  (MBoot.sPrtnInfo[i].bFileSysCode != PAR_EXTENDED) // skip extended
     2915                       )
     2916                    {
     2917                        BOOL fBootable = (  (BmInfo)
     2918                                         && (MName[(iDisk-1) * 4 + i].bootable & 0x01)
     2919                                         );
     2920                        // store this partition
     2921                        if ((arc = AppendPartition(pppiFirst,
     2922                                                   pppiThis,
     2923                                                   posCount,
     2924                                                   iDisk,
     2925                                                   (fBootable)
     2926                                                     ? (char*)&MName[(iDisk - 1) * 4 + i].name
     2927                                                     : "",
     2928                                                   *pcLetter,
     2929                                                   MBoot.sPrtnInfo[i].bFileSysCode,
     2930                                                   TRUE,        // primary
     2931                                                   fBootable,
     2932                                                   MBoot.sPrtnInfo[i].lTotalSects)))
     2933                            return (arc);
     2934                    }
     2935                }
     2936            }
    26062937        }
    26072938    }
    2608     return (NO_ERROR);
     2939
     2940    return (arc);
    26092941}
    26102942
     
    26342966    USHORT          i;
    26352967
    2636     if ((arc = doshReadSector(PrDisk, &MBoot, PrInfo->bBeginHead,
     2968    if ((arc = doshReadSector(PrDisk,
     2969                              &MBoot,
     2970                              PrInfo->bBeginHead,
    26372971                              GetCyl(PrInfo->rBeginSecCyl),
    26382972                              GetSec(PrInfo->rBeginSecCyl))))
     
    26923026                return (arc);
    26933027        }
    2694 
    2695         /* // if BootManager installed and partition is bootable
    2696         if (BmInfo)
    2697         {
    2698             if (MBoot.sBmNames[i].bootable & 0x01)
    2699             {
    2700             }
    2701         }
    2702 
    2703         // if BootManager not installed
    2704         else
    2705         {
    2706             if (arc = AppendPartition(pppiFirst,
    2707                                       pppiThis,
    2708                                       posCount,
    2709                                       PrDisk,
    2710                                       "",
    2711                                       *pcLetter,
    2712                                       MBoot.sPrtnInfo[i].bFileSysCode,
    2713                                       FALSE,
    2714                                       MBoot.sPrtnInfo[i].lTotalSects))
    2715                 return (arc);
    2716         } */
    27173028    }
    27183029
     
    27953106 *      If an error != NO_ERROR is returned, *pusContext
    27963107 *      will be set to one of the following:
     3108 *
    27973109 *      --  1: boot manager not found
     3110 *
    27983111 *      --  2: primary partitions error
     3112 *
    27993113 *      --  3: secondary partitions error
    28003114 *
     
    28323146    // on each disk, read primary partitions
    28333147    for (i = 1; i <= cDisks; i++)
     3148    {
    28343149        if ((arc = GetPrimaryPartitions(&pPartitionInfos,
    28353150                                        &ppiTemp,
     
    28433158            return (arc);
    28443159        }
     3160    }
    28453161
    28463162    if (usBmDisk)
     
    28503166        // with logical drives
    28513167        for (i = 1; i <= cDisks; i++)
     3168        {
    28523169            if ((arc = GetExtendedPartition(&pPartitionInfos,
    28533170                                            &ppiTemp,
     
    28563173                                            &BmInfo,
    28573174                                            i)))
    2858         {
    2859             *pusContext = 3;
    2860             return (arc);
     3175            {
     3176                *pusContext = 3;
     3177                return (arc);
     3178            }
    28613179        }
    28623180    }
Note: See TracChangeset for help on using the changeset viewer.