Ignore:
Timestamp:
Feb 25, 2000, 7:19:24 PM (26 years ago)
Author:
bird
Message:

Symbol Database is implemented.
No scanning of the os2krnl file, the loaded image is now scaned to determin
which build, debug/retail and smp/uni.
And yet some more enhanchments like 16-bit logging.

Location:
trunk/src/win32k/dev16
Files:
3 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/win32k/dev16/d16init.c

    r2836 r2898  
    1 /* $Id: d16init.c,v 1.5 2000-02-21 04:45:45 bird Exp $
     1/* $Id: d16init.c,v 1.6 2000-02-25 18:15:02 bird Exp $
    22 *
    33 * d16init - init routines for both drivers.
     
    2121#define INCL_DOSERRORS
    2222#define INCL_NOPMAPI
     23
    2324
    2425/*******************************************************************************
  • trunk/src/win32k/dev16/d16strat.c

    r2877 r2898  
    1 /* $Id: d16strat.c,v 1.7 2000-02-23 20:10:19 bird Exp $
     1/* $Id: d16strat.c,v 1.8 2000-02-25 18:15:02 bird Exp $
    22 *
    33 * d16strat.c - 16-bit strategy routine, device headers, device_helper (ptr)
     
    6464};
    6565
    66 /* Note: All global variables must be initialized!  *
    67  *       Uninitialized variables ends up in DATA32. */
    68 PFN     Device_Help = NULL;
    69 ULONG   TKSSBase16  = 0;
    70 USHORT  R0FlatCS16  = 0;
    71 USHORT  R0FlatDS16  = 0;
    72 BOOL    fInitTime   = TRUE;
    7366
    7467
     
    129122{
    130123    USHORT rc;
     124
    131125    if (pRp->Category == D16_IOCTL_CAT)
    132126    {
    133127        switch (pRp->Function)
    134128        {
     129            /*
     130             * This is the IOCtl which does the R0-initiation of the device driver.
     131             * Only available at init time...
     132             */
    135133            case D16_IOCTL_RING0INIT:
    136134                if (fInitTime)
     
    142140                break;
    143141
    144             case D16_IOCTL_GETKRNLOTES:
     142            /*
     143             * This is the IOCtl collects info of the running kernel.
     144             * Only available at init time.
     145             *
     146             * Since this IOCtl is issued before R0-Init is done, we'll have to
     147             * init TKSSBase for both 16-bit and 32-bit code and be a bit carefull.
     148             */
     149            case D16_IOCTL_GETKRNLINFO:
    145150                if (fInitTime)
    146151                {
     
    151156                                          &ulLin) != NO_ERROR)
    152157                        return STATUS_DONE | STERR | ERROR_I24_INVALID_PARAMETER;
    153                     return CallGetOTEs32(ulLin);
     158                    return CallGetKernelInfo32(ulLin);
    154159                }
    155160                break;
    156161
    157             case D16_IOCTL_VERIFYPROCTAB:
     162            /*
     163             * This is the IOCtl verifies the data in the ImportTab.
     164             * Only available at init time.
     165             *
     166             * Since this IOCtl is issued before R0-Init is done, we'll have to
     167             * init TKSSBase for both 16-bit and 32-bit code and be a bit carefull.
     168             */
     169            case D16_IOCTL_VERIFYIMPORTTAB:
    158170                if (fInitTime)
    159171                {
  • trunk/src/win32k/dev16/probkrnl.c

    r2848 r2898  
    1 /* $Id: probkrnl.c,v 1.15 2000-02-21 14:53:38 bird Exp $
     1/* $Id: probkrnl.c,v 1.16 2000-02-25 18:15:02 bird Exp $
    22 *
    33 * Description:   Autoprobes the os2krnl file and os2krnl[*].sym files.
     
    3030*   Defined Constants And Macros                                               *
    3131*******************************************************************************/
    32 #ifdef DEBUGR3
    33     #if 1
    34         int printf(const char *, ...);
    35         #define dprintf(a) printf a
    36     #else
    37         #define dprintf(a)
    38     #endif
    39 #else
    40     #define dprintf(a)
    41     #define static
     32/* Disable logging when doing extracts */
     33#if defined(EXTRACT) || defined(RING0)
     34    #define NOLOGGING 1
    4235#endif
    4336
     
    7265#include "dev16.h"
    7366#include "dev1632.h"
     67#include "vprntf16.h"
     68#include "log.h"
    7469
    7570
     
    111106};
    112107
    113 unsigned long int   ulBuild          = 0;
     108unsigned short int  usBuild          = 0;
    114109unsigned short      usVerMajor       = 0;
    115110unsigned short      usVerMinor       = 0;
     111unsigned char       fSMP             = FALSE;
     112unsigned char       fDebug           = FALSE;
    116113
    117114
     
    144141};
    145142
    146 static KRNLOBJTABLE KrnlOTEs = {0};
    147 
    148 /* messages */
    149 static char szBanner[]   = "Win32k - Odin32 support driver.";
    150 static char szMsg1[]     = "\n\r    Found kernel:     ";
    151 static char szMsg1a[]    = "\n\r    Build:            ";
    152 static char szMsg2[]     = "\n\r    Found symbolfile: ";
    153 static char szMsg4[]     = "\n\r    Failed to find symbolfile!\n\r";
    154 static char szMsgfailed[]= "failed!   ";
     143/* Result from GetKernelInfo/ReadOS2Krnl. */
     144static unsigned char  cObjects = 0;
     145static POTE           paKrnlOTEs = NULL;
     146
    155147
    156148
     
    172164static int      kstrnicmp(const char *psz1, const char *psz2, int cch);
    173165static int      kstrlen(const char *psz);
     166static char *   kstrcpy(char * pszTarget, const char * pszSource);
    174167static int      kargncpy(char *pszTarget, const char *pszArg, unsigned cchMaxlen);
    175168
    176169/* Workers */
     170static int      LookupKrnlEntry(unsigned uBuild, unsigned char chType,
     171                                unsigned char fSMP, unsigned char cObjects);
    177172static int      VerifyPrologs(void);
    178 static int      ProbeSymFile(char *pszFilename);
    179 static int      VerifyKernelVer(void);
    180 static int      ReadOS2Krnl(char *pszFilename);
    181 static int      ReadOS2Krnl2(HFILE hKrnl, unsigned long  cbKrnl);
    182 static int      GetKernelOTEs(void);
     173static int      ProbeSymFile(const char *pszFilename);
     174static int      GetKernelInfo(void);
    183175
    184176/* Ouput */
     
    186178static void     ShowHexNumber(unsigned long ul);
    187179static void     ShowResult(int rc, int iSym);
     180
     181/* Others used while debugging in R3. */
     182static int      VerifyKernelVer(void);
     183static int      ReadOS2Krnl(char *pszFilename);
     184static int      ReadOS2Krnl2(HFILE hKrnl, unsigned long  cbKrnl);
     185static int      processFile(const char *pszFilename);
    188186
    189187
     
    409407
    410408/**
     409 * String copy (strcpy).
     410 * @returns   Pointer to target string.
     411 * @param     pszTarget  Target string.
     412 * @param     pszSource  Source string.
     413 * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
     414 */
     415static char * kstrcpy(char * pszTarget, register const char * pszSource)
     416{
     417    register char *psz = pszTarget;
     418
     419    while (*pszSource != '\0')
     420        *psz++ = *pszSource++;
     421
     422    return pszTarget;
     423}
     424
     425
     426
     427
     428/**
    411429 * Copy an argument to a buffer. Ie. "-K[=|:]c:\os2krnl ....". Supports quotes
    412430 * @returns   Number of chars of pszArg that has been processed.
     
    465483*   Implementation Of The Important Functions                                  *
    466484*******************************************************************************/
     485#ifndef EXTRACT
     486/**
     487 * Checks if this kernel is within the kernel symbol database.
     488 * If an entry for the kernel is found, the data is copied from the
     489 * database entry to aImportTab.
     490 * @returns   NO_ERROR on succes (0)
     491 *            1 if not found.
     492 *            Error code on error.
     493 * @param     uBuild    Build level.
     494 * @param     chType    'A' all strict
     495 *                      'H' half strict
     496 *                      'R' retail
     497 * @param     fSMP      TRUE: SMP
     498 *                      FALSE: UNI
     499 * @param     cObjects  Count of object in the running kernel.
     500 * @sketch    Loop thru the table.
     501 * @status    completely implemented.
     502 * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
     503 */
     504static int LookupKrnlEntry(unsigned uBuild, unsigned char chType, unsigned char fSMP, unsigned char cObjects)
     505{
     506    int i;
     507
     508    /*
     509     * Loop tru the DB entries until a NULL pointer is found.
     510     */
     511    for (i = 0; aKrnlSymDB[i].usBuild != 0; i++)
     512    {
     513        if (aKrnlSymDB[i].usBuild      == uBuild
     514            && aKrnlSymDB[i].chType    == chType
     515            && aKrnlSymDB[i].fSMP      == fSMP
     516            && aKrnlSymDB[i].cObjects  == cObjects)
     517        {   /* found matching entry! */
     518            int j;
     519            int rc;
     520            register PKRNLDBENTRY pEntry = &aKrnlSymDB[i];
     521
     522            dprintf(("LookUpKrnlEntry - found entry for this kernel!\n"));
     523
     524            /*
     525             * Copy symbol data from the DB to aImportTab.
     526             */
     527            for (j = 0; j < NBR_OF_KRNLIMPORTS; j++)
     528            {
     529                aImportTab[j].offObject  = pEntry->aSyms[j].offObject;
     530                aImportTab[j].iObject    = pEntry->aSyms[j].iObject;
     531                aImportTab[j].ulAddress  = paKrnlOTEs[pEntry->aSyms[j].iObject].ote_base
     532                                           + pEntry->aSyms[j].offObject;
     533                aImportTab[j].usSel      = paKrnlOTEs[pEntry->aSyms[j].iObject].ote_sel;
     534                aImportTab[j].fFound     = TRUE;
     535                dprintf(("  %-3d addr=0x%08lx off=0x%08lx  %s\n",
     536                         j, aImportTab[j].ulAddress, aImportTab[j].offObject,
     537                         aImportTab[j].achName));
     538            }
     539
     540            /* Verify prologs*/
     541            rc = VerifyPrologs();
     542
     543            /* set sym name */
     544            if (rc == 0)
     545                kstrcpy(szUsrSym, "Win32k Symbol Database");
     546            return rc;
     547        }
     548    }
     549
     550    /* not found */
     551    return 1;
     552}
     553#endif /* !EXTRACT */
    467554
    468555/**
     
    473560static int VerifyPrologs(void)
    474561{
    475 #ifndef DEBUGR3
     562#if !defined(DEBUGR3) && !defined(EXTRACT)
    476563    APIRET          rc;
    477564    HFILE           hDev0 = 0;
     
    484571    if (rc == NO_ERROR)
    485572    {
    486         rc = DosDevIOCtl("", "", D16_IOCTL_VERIFYPROCTAB, D16_IOCTL_CAT, hDev0);
     573        rc = DosDevIOCtl("", "", D16_IOCTL_VERIFYIMPORTTAB, D16_IOCTL_CAT, hDev0);
    487574        DosClose(hDev0);
    488575    }
     
    502589 * @remark    Error codes starts at -50.
    503590 */
    504 static int ProbeSymFile(char * pszFilename)
     591static int ProbeSymFile(const char * pszFilename)
    505592{
    506593    HFILE          hSym;                /* Filehandle */
     
    565652     * Verify that the number of segments is equal to the number objects in OS2KRNL.
    566653     */
    567     if (MapDef.cSegs != KrnlOTEs.cObjects)
     654    #ifndef EXTRACT
     655    if (MapDef.cSegs != cObjects)
    568656    {   /* incorrect count of segments. */
    569657        dprintf(("Segment No. verify failed\n"));
     
    571659        return -52;
    572660    }
     661    #endif /* !EXTRACT */
    573662
    574663
     
    577666     */
    578667    for (i = 0; i < NBR_OF_KRNLIMPORTS; i++)
     668    {
    579669        aImportTab[i].fFound = 0;
     670        #ifdef DEBUG
     671        aImportTab[i].offObject = 0;
     672        aImportTab[i].ulAddress = 0;
     673        aImportTab[i].usSel = 0;
     674        #endif
     675    }
    580676
    581677
     
    697793                {   /* Symbol was found */
    698794                    aImportTab[i].offObject = (SegDef.bFlags & 0x01 ? SymDef32.wSymVal : SymDef16.wSymVal);
    699                     aImportTab[i].ulAddress = aImportTab[i].offObject + KrnlOTEs.aObjects[iSeg].ote_base;
     795                    aImportTab[i].ulAddress = aImportTab[i].offObject + paKrnlOTEs[iSeg].ote_base;
    700796                    aImportTab[i].iObject   = (unsigned char)iSeg;
    701                     aImportTab[i].usSel     = KrnlOTEs.aObjects[iSeg].ote_sel;
     797                    aImportTab[i].usSel     = paKrnlOTEs[iSeg].ote_sel;
     798                    dprintf(("debug: base=%lx, size=%lx iSeg=%d\n", paKrnlOTEs[iSeg].ote_base, paKrnlOTEs[iSeg].ote_size, iSeg));
    702799
    703800                    /* Paranoia test! */
    704                     if (aImportTab[i].offObject < KrnlOTEs.aObjects[iSeg].ote_size)
     801                    #ifndef EXTRACT
     802                    if (aImportTab[i].offObject < paKrnlOTEs[iSeg].ote_size)
    705803                    {
    706804                        aImportTab[i].fFound = TRUE;
     
    712810                    else/* test failed, continue on next symbol*/
    713811                        dprintf(("Error: Paranoia test failed for %s\n", aImportTab[i].achName));;
     812                    #else
     813                    aImportTab[i].fFound = TRUE;
     814                    cLeftToFind--;
     815                    #endif /* !EXTRACT */
    714816                    break;
    715817                }
     
    740842
    741843/**
    742  * Verifies that build no, matches kernel number.
    743  * @returns   0 on equal, !0 on error.
    744  */
    745 static int VerifyKernelVer(void)
    746 {
    747     int VerMinor, VerMajor;
    748 
    749     VerMajor = ulBuild < 20000 ? 20 : 30/*?*/;
    750     VerMinor = ulBuild < 6600 ? 10 :  ulBuild < 8000 ? 11 : ulBuild < 9000 ? 30 :
    751                ulBuild < 10000 ? 40 :  ulBuild < 15000 ? 45 : 50;
    752 
    753     return VerMajor - (int)usVerMajor | VerMinor - (int)usVerMinor;
    754 }
    755 
    756 
    757 /**
    758  * Reads and verifies OS/2 kernel.
    759  * @returns   0 on success, not 0 on failure.
    760  * @param     filename   Filename of the OS/2 kernel.
    761  * @result    ulBuild is set.
    762  * @remark    This step will be eliminated by searching thru the DOSGROUP datasegment
    763  *            in the kernel memory. This segment have a string "Internal revision 9.034[smp|uni]"
    764  *            This would be much faster than reading the kernel file. It will also give us a more precise
    765  *            answer to the question! This is currently a TODO issue. !FIXME!
    766  */
    767 static int ReadOS2Krnl(char * pszFilename)
    768 {
    769     HFILE          hKrnl;
    770     unsigned long  cbKrnl;
    771     int            rc;
    772 
    773     hKrnl = fopen(pszFilename, "rb");
    774     if (hKrnl != 0)
    775     {
    776         cbKrnl = fsize(hKrnl);
    777         if (!fseek(hKrnl, 0, SEEK_SET))
    778             rc = ReadOS2Krnl2(hKrnl, cbKrnl);
    779         else
    780             rc = -2;
    781         fclose(hKrnl);
    782     }
    783     else
    784     {
    785         dprintf(("Could not open file\n"));
    786         rc = -1;
    787     }
    788     return rc;
    789 }
    790 
    791 /**
    792  * Worker function for ReadOS2Krnl
    793  * @returns   0 on success.
    794  *            errorcodes on failure. (-1 >= rc >= -14)
    795  * @param     hKrnl   Handle to the kernel file.
    796  * @param     cbKrnl  Size of the kernel file.
    797  * @author    knut st. osmundsen
    798  */
    799 static int ReadOS2Krnl2(HFILE hKrnl, unsigned long  cbKrnl)
    800 {
    801     int            i, j;
    802     int            rc = 0;
    803     char           achBuffer[KERNEL_ID_STRING_LENGTH + KERNEL_READ_SIZE];
    804     unsigned long  offLXHdr;
    805     struct e32_exe *pLXHdr;
    806 
    807 
    808     /* find bldlevel string - "@#IBM:14.020#@  IBM OS/2 Kernel - 14.020F" */
    809     if (fseek(hKrnl, 0, SEEK_SET))
    810         return -2;
    811 
    812     if (!fread(&achBuffer[KERNEL_ID_STRING_LENGTH], 1, KERNEL_READ_SIZE, hKrnl))
    813         return -3;
    814 
    815     i = KERNEL_ID_STRING_LENGTH;
    816     while (cbKrnl > 0)
    817     {
    818         if (i == KERNEL_READ_SIZE)
    819         {
    820 
    821             kmemcpy(achBuffer, &achBuffer[KERNEL_READ_SIZE], KERNEL_ID_STRING_LENGTH);
    822             if (!fread(&achBuffer[KERNEL_ID_STRING_LENGTH], 1, cbKrnl > KERNEL_READ_SIZE ? KERNEL_READ_SIZE : (int)cbKrnl, hKrnl))
    823                 return -3;
    824 
    825             i = 0;
    826         }
    827 
    828         if (kstrncmp("@#IBM:", &achBuffer[i], 6) == 0)
    829             break;
    830 
    831         /* next */
    832         i++;
    833         cbKrnl--;
    834     }
    835 
    836     if (cbKrnl == 0)
    837     {
    838         fclose(hKrnl);
    839         return -4;
    840     }
    841 
    842     /* displacement */
    843     j = 0;
    844     while (j < 6 && achBuffer[i+10+j] != '#')
    845         j++;
    846 
    847     /* verify signature */
    848     if (kstrncmp(&achBuffer[i+10+j], "#@  IBM OS/2 Kernel", 19) != 0)
    849         return -5;
    850 
    851     /* read ulBuild */
    852     ulBuild  = (char)(achBuffer[i+6] - '0') * 1000;
    853     if (achBuffer[i+7] != '.')
    854     {
    855         /* this code is for Warp5 */
    856         ulBuild *= 10;
    857         ulBuild += (char)(achBuffer[i+7] - '0') * 1000;
    858         i++;
    859         j--;
    860         if (achBuffer[i+7] != '.')
    861         {
    862             ulBuild = ulBuild * 10;
    863             ulBuild = ulBuild + (unsigned long)(achBuffer[i+7] - '0') * 1000;
    864             i++;
    865             j--;
    866         }
    867     }
    868 
    869     if (j == 0)
    870     {
    871         ulBuild += (achBuffer[i+ 8] - '0') * 10;
    872         ulBuild += (achBuffer[i+ 9] - '0') * 1;
    873     } else
    874     {
    875         if (j == 3)
    876             return -9;
    877         ulBuild += (achBuffer[i+ 8] - '0') * 100;
    878         ulBuild += (achBuffer[i+ 9] - '0') * 10;
    879         ulBuild += (achBuffer[i+10] - '0');
    880     }
    881 
    882     if (VerifyKernelVer())
    883         return -9;
    884     dprintf(("ulBuild: %d\n",ulBuild));
    885 
    886     /* get segment number */
    887     /* read-MZheader */
    888     if (fseek(hKrnl,0,SEEK_SET))
    889         return -2;
    890 
    891     if (!fread(achBuffer, 1, 0x40, hKrnl))
    892         return -3;
    893 
    894     offLXHdr = *(unsigned long int *)&achBuffer[0x3c];
    895 
    896     if (offLXHdr > 0x2000 && offLXHdr < 0x80) /* just to detect garbage */
    897         return -6;
    898 
    899     if (fseek(hKrnl, offLXHdr, SEEK_SET))
    900         return -2;
    901 
    902     if (!fread(achBuffer, 1, sizeof(struct e32_exe), hKrnl))
    903         return -3;
    904 
    905     /* check LX-magic */
    906     if (achBuffer[0] != 'L' || achBuffer[1] != 'X')
    907         return -7;
    908 
    909 #ifndef DEBUGR3
    910     /* check object count - match it with what we got from the kernel. */
    911     pLXHdr = (struct e32_exe *)achBuffer;
    912     if ((UCHAR)pLXHdr->e32_objcnt != KrnlOTEs.cObjects)
    913         return -8;
    914 
    915     if (pLXHdr->e32_objcnt < 10)
    916         return -9;
    917 
    918     /* check objects (sizes and flags(?)) */
    919     if (!fseek(hKrnl, (LONG)offLXHdr + (LONG)pLXHdr->e32_objtab, SEEK_SET))
    920     {
    921         struct o32_obj *pObj = (struct o32_obj *)achBuffer;
    922         for (i = 0; i < (int)KrnlOTEs.cObjects; i++)
    923         {
    924             if (!fread(achBuffer, 1, sizeof(OTE), hKrnl))
    925                 return -11;
    926             if (pObj->o32_size < KrnlOTEs.aObjects[i].ote_size)
    927                 return -12;
    928 
    929             #if 0 /* don't work! */
    930             if ((pObj->o32_flags & 0xffffUL) != (KrnlOTEs.aObjects[i].ote_flags & 0xffffUL))
    931                 return -14;
    932             #endif
    933         }
    934     }
    935     else
    936         return -10;
    937 #else
    938     /* Since we can't get the OTEs from the kernel when debugging in RING-3,
    939      * we'll use what we find in the kernel.
    940      */
    941 
    942     /*  object count */
    943     pLXHdr = (struct e32_exe *)achBuffer;
    944     KrnlOTEs.cObjects = (UCHAR)pLXHdr->e32_objcnt;
    945 
    946     /* get OTEs */
    947     if (!fseek(hKrnl, (LONG)offLXHdr + (LONG)pLXHdr->e32_objtab, SEEK_SET))
    948     {
    949         struct o32_obj *pObj = (struct o32_obj *)achBuffer;
    950         for (i = 0; i < (int)KrnlOTEs.cObjects; i++)
    951             if (!fread(&KrnlOTEs.aObjects[i], 1, sizeof(struct o32_obj), hKrnl))
    952                 return -11;
    953     }
    954     else
    955         return -10;
    956 #endif
    957 
    958     return 0;
    959 }
    960 
    961 
    962 /**
    963844 * Gets the os/2 kernel OTE's (object table entries).
    964845 * @returns   0 on success. Not 0 on error.
    965846 */
    966 static int   GetKernelOTEs(void)
    967 {
    968 #ifndef DEBUGR3
     847static int   GetKernelInfo(void)
     848{
     849#if !defined(DEBUGR3) && !defined(EXTRACT) /* IOCtl not available after inittime! */
     850    static KRNLINFO KrnlInfo = {0};
    969851    APIRET          rc;
    970852    HFILE           hDev0 = 0;
     
    977859    if (rc == NO_ERROR)
    978860    {
    979         rc = DosDevIOCtl(&KrnlOTEs, "", D16_IOCTL_GETKRNLOTES, D16_IOCTL_CAT, hDev0);
     861        rc = DosDevIOCtl(&KrnlInfo, "", D16_IOCTL_GETKRNLINFO, D16_IOCTL_CAT, hDev0);
     862        if (rc == NO_ERROR)
     863        {
     864            int i;
     865
     866            /* Set the exported parameters */
     867            usBuild  = KrnlInfo.usBuild;
     868            fSMP     = KrnlInfo.fSMP;
     869            fDebug   = KrnlInfo.fDebug;
     870            cObjects = KrnlInfo.cObjects;
     871            paKrnlOTEs = &KrnlInfo.aObjects[0];
     872            #ifdef DEBUG
     873            for (i = 0; i < NBR_OF_KRNLIMPORTS; i++)
     874                dprintf(("debug: no.%2d base=%lx size=%lx sel=%x\n",
     875                         i,
     876                         paKrnlOTEs[i].ote_base,
     877                         paKrnlOTEs[i].ote_size,
     878                         paKrnlOTEs[i].ote_sel));
     879            #endif
     880
     881        }
    980882        DosClose(hDev0);
    981883    }
    982884
    983885    if (rc != NO_ERROR)
    984         puts("Failed to get kernel OTEs\r\n");
     886        printf16("Failed to get kernel OTEs\r\n");
    985887
    986888    return rc;
     889
    987890#else
    988     KrnlOTEs.cObjects = 23;
    989     return 0;
     891    #ifndef EXTRACT
     892        APIRET          rc;
     893
     894        /*--------------*/
     895        /* read kernel  */
     896        /*--------------*/
     897        if (szUsrOS2Krnl[0] != '\0')
     898        {
     899            rc = ReadOS2Krnl(szUsrOS2Krnl);
     900            if (rc != 0)
     901            {
     902                puts("Warning: Invalid kernel file specified. Tries defaults.\n\r");
     903                szUsrOS2Krnl[0] = '\0';
     904                rc = ReadOS2Krnl(szOS2Krnl);
     905            }
     906        }
     907        else
     908            rc = ReadOS2Krnl(szOS2Krnl);
     909        return rc;
     910    #else
     911        return 0;
     912    #endif
    990913#endif
    991914}
    992 
    993 
    994 /**
    995  * Displays an ULONG in decimal notation using DosPutMessage
    996  * @param     n   ULONG to show.
    997  */
    998 static void ShowDecNumber(unsigned long n)
    999 {
    1000     int f = 0;
    1001     unsigned long div;
    1002     char sif;
    1003 
    1004     for (div = 1000000; div > 0; div /= 10)
    1005     {
    1006         sif = (char)(n/div);
    1007         n %= div;
    1008         if (sif != 0 || f)
    1009         {
    1010             f = 1;
    1011             sif += '0';
    1012             DosPutMessage(0, 1, &sif);
    1013         }
    1014     }
    1015 }
    1016 
    1017 
    1018 /**
    1019  * Displays an ULONG in hexadecimal notation using DosPutMessage
    1020  * @param     n   ULONG to show.
    1021  */
    1022 static void ShowHexNumber(unsigned long int n)
    1023 {
    1024     signed int div;
    1025     char sif;
    1026     DosPutMessage(0, 2, "0x");
    1027     for (div = 28; div >= 0; div -= 4)
    1028     {
    1029         sif = (char)(n >> div) & (char)0xF;
    1030         sif += (sif < 10  ? '0' : 'a' - 10);
    1031         DosPutMessage(0, 1, &sif);
    1032     }
    1033 }
    1034 
    1035915
    1036916
     
    1040920 * @param     iSym        index of .sym-file into static struct.
    1041921 */
     922#ifndef EXTRACT
    1042923static void ShowResult(int rc, int iSym)
    1043924{
    1044     int i, j;
    1045 
    1046     /* complain even if quiet on error */
     925    int i;
     926
     927    /*
     928     * Complain even if quiet on error
     929     */
    1047930    if (!fQuiet || rc != 0)
    1048931    {
    1049         puts(szBanner);
    1050 
    1051         /* kernel stuff */
    1052         puts(szMsg1);
     932        printf16("Win32k - Odin32 support driver.\n");
     933
     934        /*
     935         * kernel stuff
     936         */
    1053937        if (rc <= -50 || rc == 0)
    1054938        {
    1055             puts(szOS2Krnl);
    1056             puts(szMsg1a);
    1057             ShowDecNumber(ulBuild);
    1058             puts(" - v");
    1059             ShowDecNumber(usVerMajor);
    1060             puts(".");
    1061             ShowDecNumber(usVerMinor);
     939            #ifdef DEBUGR3
     940            printf16("    Found kernel:     %s\n", szOS2Krnl);
     941            #endif
     942            printf16("    Build:            %d - v%d.%d\n",
     943                     usBuild, usVerMajor, usVerMinor);
    1062944        }
    1063945        else
    1064             puts(szMsgfailed);
    1065 
    1066         /* functions */
     946            printf16("    Kernel probing failed with rc=%d.\n", rc);
     947
     948        /*
     949         * symbol-file
     950         */
    1067951        if (rc == 0)
     952            printf16("    Found symbolfile: %s\n",
     953                     szUsrSym[0] == '\0' ? apszSym[iSym] : szUsrSym);
     954        else
     955            printf16("    Failed to find symbolfile! rc=%d\n", rc);
     956
     957        /*
     958         * function listing
     959         */
     960        for (i = 0; i < NBR_OF_KRNLIMPORTS; i++)
    1068961        {
    1069             puts(szMsg2);
    1070             if (szUsrSym[0] == '\0')
    1071                 puts(apszSym[iSym]);
     962            printf16("  %-20s at ",aImportTab[i].achName);
     963            if (aImportTab[i].fFound)
     964                printf16("0x%08lx%s", aImportTab[i].ulAddress, (i % 2) == 0 ? "" : "\n");
    1072965            else
    1073                 puts(szUsrSym);
    1074 
    1075             for (i = 0; i < NBR_OF_KRNLIMPORTS; i++)
    1076             {
    1077                 if ((i % 2) == 0)
    1078                     puts("\n\r    ");
    1079                 else
    1080                     puts("    ");
    1081                 puts(aImportTab[i].achName);
    1082                 for (j = aImportTab[i].cchName; j < 20; j++)
    1083                     puts(" ");
    1084 
    1085                 puts(" at ");
    1086                 if (aImportTab[i].fFound)
    1087                     ShowHexNumber(aImportTab[i].ulAddress);
    1088                 else
    1089                     puts(szMsgfailed);
    1090             }
     966                printf16("failed!%s", (i % 2) == 0 ? "" : "\n");
    1091967        }
    1092         else
    1093             puts(szMsg4);
    1094         puts("\n\r");
    1095     }
    1096 
    1097     /* if error: write rc */
    1098     if (rc != 0)
    1099     {
    1100         puts("rc = ");
    1101         ShowHexNumber((unsigned long)rc);
    1102         puts("\n\r");
    1103     }
    1104 }
    1105 
     968        if (i % 2) printf16("\n");
     969    }
     970}
    1106971
    1107972
     
    11871052
    11881053    /*-----------------*/
    1189     /* get kernel OTEs */
     1054    /* get kernel info */
    11901055    /*-----------------*/
    1191     rc = GetKernelOTEs();
     1056    rc = GetKernelInfo();
    11921057    if (rc != NO_ERROR)
    11931058        return rc;
    1194 
    1195     /*--------------*/
    1196     /* read kernel  */
    1197     /*--------------*/
    1198     if (szUsrOS2Krnl[0] != '\0')
    1199     {
    1200         rc = ReadOS2Krnl(szUsrOS2Krnl);
    1201         if (rc != 0)
    1202         {
    1203             puts("Warning: Invalid kernel file specified. Tries defaults.\n\r");
    1204             szUsrOS2Krnl[0] = '\0';
    1205             rc = ReadOS2Krnl(szOS2Krnl);
    1206         }
    1207     }
    1208     else
    1209         rc = ReadOS2Krnl(szOS2Krnl);
    12101059
    12111060    /*--------------*/
     
    12241073            }
    12251074        }
    1226         if (rc != 0) /* if user sym failed or don't exists */
     1075        if (rc != 0) /* if user sym failed or don't exists. */
    12271076        {
    1228             i = 0;
    1229             while (apszSym[i] != NULL && (rc = ProbeSymFile(apszSym[i])) != 0)
    1230                 i++;
     1077            /*
     1078             * Check database - only if not a debug kernel!
     1079             * You usually have a .sym-file when using a debug kernel.
     1080             * (Currently I am not able to distinguish between half and all strict kernels...)
     1081             */
     1082            if (fDebug ||
     1083                (rc = LookupKrnlEntry((unsigned short)usBuild, 'R', fSMP, cObjects)) != 0
     1084                )
     1085            {
     1086                /* search on disk */
     1087                i = 0;
     1088                while (apszSym[i] != NULL && (rc = ProbeSymFile(apszSym[i])) != 0)
     1089                    i++;
     1090            }
    12311091        }
    12321092    }
     
    12381098    return rc;
    12391099}
    1240 
     1100#endif
    12411101
    12421102
    12431103#ifdef DEBUGR3
     1104/**
     1105 * Verifies that build no, matches kernel number.
     1106 * @returns   0 on equal, !0 on error.
     1107 */
     1108static int VerifyKernelVer(void)
     1109{
     1110    int VerMinor, VerMajor;
     1111
     1112    VerMajor = usBuild < 20000 ? 20 : 30/*?*/;
     1113    VerMinor = usBuild <  6600 ? 10 :  usBuild <  8000 ? 11 : usBuild < 9000 ? 30 :
     1114               usBuild < 10000 ? 40 :  usBuild < 15000 ? 45 : 50;
     1115
     1116    return VerMajor - (int)usVerMajor | VerMinor - (int)usVerMinor;
     1117}
     1118
     1119
     1120/**
     1121 * Reads and verifies OS/2 kernel.
     1122 * @returns   0 on success, not 0 on failure.
     1123 * @param     filename   Filename of the OS/2 kernel.
     1124 * @result    usBuild is set.
     1125 * @remark    This step will be eliminated by searching thru the DOSGROUP datasegment
     1126 *            in the kernel memory. This segment have a string "Internal revision 9.034[smp|uni]"
     1127 *            This would be much faster than reading the kernel file. It will also give us a more precise
     1128 *            answer to the question! This is currently a TODO issue. !FIXME!
     1129 */
     1130static int ReadOS2Krnl(char * pszFilename)
     1131{
     1132    HFILE          hKrnl;
     1133    unsigned long  cbKrnl;
     1134    int            rc;
     1135
     1136    hKrnl = fopen(pszFilename, "rb");
     1137    if (hKrnl != 0)
     1138    {
     1139        cbKrnl = fsize(hKrnl);
     1140        if (!fseek(hKrnl, 0, SEEK_SET))
     1141            rc = ReadOS2Krnl2(hKrnl, cbKrnl);
     1142        else
     1143            rc = -2;
     1144        fclose(hKrnl);
     1145    }
     1146    else
     1147    {
     1148        dprintf(("Could not open file\n"));
     1149        rc = -1;
     1150    }
     1151    return rc;
     1152}
     1153
     1154
     1155/**
     1156 * Worker function for ReadOS2Krnl
     1157 * @returns   0 on success.
     1158 *            errorcodes on failure. (-1 >= rc >= -14)
     1159 * @param     hKrnl   Handle to the kernel file.
     1160 * @param     cbKrnl  Size of the kernel file.
     1161 * @author    knut st. osmundsen
     1162 */
     1163static int ReadOS2Krnl2(HFILE hKrnl, unsigned long  cbKrnl)
     1164{
     1165    #if defined(DEBUGR3) || !defined(EXTRACT)
     1166    static KRNLINFO KrnlInfo = {0};
     1167    #endif
     1168    int            i, j;
     1169    int            rc = 0;
     1170    char           achBuffer[KERNEL_ID_STRING_LENGTH + KERNEL_READ_SIZE];
     1171    unsigned long  offLXHdr;
     1172    struct e32_exe *pLXHdr;
     1173
     1174
     1175    /* find bldlevel string - "@#IBM:14.020#@  IBM OS/2 Kernel - 14.020F" */
     1176    if (fseek(hKrnl, 0, SEEK_SET))
     1177        return -2;
     1178
     1179    if (!fread(&achBuffer[KERNEL_ID_STRING_LENGTH], 1, KERNEL_READ_SIZE, hKrnl))
     1180        return -3;
     1181
     1182    i = KERNEL_ID_STRING_LENGTH;
     1183    while (cbKrnl > 0)
     1184    {
     1185        if (i == KERNEL_READ_SIZE)
     1186        {
     1187
     1188            kmemcpy(achBuffer, &achBuffer[KERNEL_READ_SIZE], KERNEL_ID_STRING_LENGTH);
     1189            if (!fread(&achBuffer[KERNEL_ID_STRING_LENGTH], 1, cbKrnl > KERNEL_READ_SIZE ? KERNEL_READ_SIZE : (int)cbKrnl, hKrnl))
     1190                return -3;
     1191
     1192            i = 0;
     1193        }
     1194
     1195        if (kstrncmp("@#IBM:", &achBuffer[i], 6) == 0)
     1196            break;
     1197
     1198        /* next */
     1199        i++;
     1200        cbKrnl--;
     1201    }
     1202
     1203    if (cbKrnl == 0)
     1204    {
     1205        fclose(hKrnl);
     1206        return -4;
     1207    }
     1208
     1209    /* displacement */
     1210    j = 0;
     1211    while (j < 6 && achBuffer[i+10+j] != '#')
     1212        j++;
     1213
     1214    /* verify signature */
     1215    if (kstrncmp(&achBuffer[i+10+j], "#@  IBM OS/2 Kernel", 19) != 0)
     1216        return -5;
     1217
     1218    /* read usBuild */
     1219    usBuild  = (char)(achBuffer[i+6] - '0') * 1000;
     1220    if (achBuffer[i+7] != '.')
     1221    {
     1222        /* this code is for Warp5 */
     1223        usBuild *= 10;
     1224        usBuild += (char)(achBuffer[i+7] - '0') * 1000;
     1225        i++;
     1226        j--;
     1227        if (achBuffer[i+7] != '.')
     1228        {
     1229            usBuild = usBuild * 10;
     1230            usBuild = usBuild + (unsigned short)(achBuffer[i+7] - '0') * 1000;
     1231            i++;
     1232            j--;
     1233        }
     1234    }
     1235
     1236    if (j == 0)
     1237    {
     1238        usBuild += (achBuffer[i+ 8] - '0') * 10;
     1239        usBuild += (achBuffer[i+ 9] - '0') * 1;
     1240    }
     1241    else
     1242    {
     1243        if (j == 3)
     1244            return -9;
     1245        usBuild += (achBuffer[i+ 8] - '0') * 100;
     1246        usBuild += (achBuffer[i+ 9] - '0') * 10;
     1247        usBuild += (achBuffer[i+10] - '0');
     1248    }
     1249
     1250    if (VerifyKernelVer())
     1251        return -9;
     1252    dprintf(("usBuild: %d\n", usBuild));
     1253
     1254    /* get segment number */
     1255    /* read-MZheader */
     1256    if (fseek(hKrnl,0,SEEK_SET))
     1257        return -2;
     1258
     1259    if (!fread(achBuffer, 1, 0x40, hKrnl))
     1260        return -3;
     1261
     1262    offLXHdr = *(unsigned long int *)&achBuffer[0x3c];
     1263
     1264    if (offLXHdr > 0x2000 && offLXHdr < 0x80) /* just to detect garbage */
     1265        return -6;
     1266
     1267    if (fseek(hKrnl, offLXHdr, SEEK_SET))
     1268        return -2;
     1269
     1270    if (!fread(achBuffer, 1, sizeof(struct e32_exe), hKrnl))
     1271        return -3;
     1272
     1273    /* check LX-magic */
     1274    if (achBuffer[0] != 'L' || achBuffer[1] != 'X')
     1275        return -7;
     1276
     1277#if !defined(DEBUGR3) && !defined(EXTRACT)
     1278    /* check object count - match it with what we got from the kernel. */
     1279    pLXHdr = (struct e32_exe *)achBuffer;
     1280    if ((UCHAR)pLXHdr->e32_objcnt != cObjects)
     1281        return -8;
     1282
     1283    if (pLXHdr->e32_objcnt < 10)
     1284        return -9;
     1285
     1286    /* check objects (sizes and flags(?)) */
     1287    if (!fseek(hKrnl, (LONG)offLXHdr + (LONG)pLXHdr->e32_objtab, SEEK_SET))
     1288    {
     1289        struct o32_obj *pObj = (struct o32_obj *)achBuffer;
     1290        for (i = 0; i < (int)cObjects; i++)
     1291        {
     1292            if (!fread(achBuffer, 1, sizeof(OTE), hKrnl))
     1293                return -11;
     1294            if (pObj->o32_size < paKrnlOTEs[i].ote_size)
     1295                return -12;
     1296
     1297            #if 0 /* don't work! */
     1298            if ((pObj->o32_flags & 0xffffUL) != (paKrnlOTEs[i].ote_flags & 0xffffUL))
     1299                return -14;
     1300            #endif
     1301        }
     1302    }
     1303    else
     1304        return -10;
     1305#else
     1306    /* Since we can't get the OTEs from the kernel when debugging in RING-3,
     1307     * we'll use what we find in the kernel.
     1308     */
     1309
     1310    /*  object count */
     1311    pLXHdr = (struct e32_exe *)achBuffer;
     1312    cObjects = (UCHAR)pLXHdr->e32_objcnt;
     1313    paKrnlOTEs = &KrnlInfo.aObjects[0];
     1314
     1315    /* get OTEs */
     1316    if (!fseek(hKrnl, (LONG)offLXHdr + (LONG)pLXHdr->e32_objtab, SEEK_SET))
     1317    {
     1318        struct o32_obj *pObj = (struct o32_obj *)achBuffer;
     1319        for (i = 0; i < (int)cObjects; i++)
     1320            if (!fread(&paKrnlOTEs[i], 1, sizeof(struct o32_obj), hKrnl))
     1321                return -11;
     1322    }
     1323    else
     1324        return -10;
     1325#endif
     1326
     1327    return 0;
     1328}
     1329
     1330
     1331
    12441332/**
    12451333 * Debug - Main procedure for standalone testing.
     
    12691357    ProbeKernel(&ReqPack);
    12701358}
    1271 
    12721359#endif
    12731360
     1361
     1362#ifdef EXTRACT
     1363/**
     1364 * Dumps writes a KRNLDBENTRY struct to stderr for the given .sym-file.
     1365 * The filesnames are on this format:
     1366 *    nnnn[n]tm.SYM
     1367 * Where: n - are the build number 4 or 5 digits.
     1368 *        t - kernel type. R = retail, H = half strict, A = all strict.
     1369 *        m - UNI or SMP.  U = UNI processor kernel. S = SMP processor kernel.
     1370 * @returns   NO_ERROR on success. Untracable error code on error.
     1371 * @param     pszFilename  Pointer to read only filename of the .sym-file.
     1372 * @status    completely implemented.
     1373 * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
     1374 * @remark    Currently only retail kernels are processed. See note below.
     1375 */
     1376static int processFile(const char *pszFilename)
     1377{
     1378    APIRET   rc;
     1379    int      cch = kstrlen(pszFilename);
     1380
     1381    /* Filename check */
     1382    if (cch < 10 || cch > 11
     1383        || !(pszFilename[0] >= '0' && pszFilename[0] <= '9')
     1384        || !(pszFilename[1] >= '0' && pszFilename[1] <= '9')
     1385        || !(pszFilename[2] >= '0' && pszFilename[2] <= '9')
     1386        || !(pszFilename[3] >= '0' && pszFilename[3] <= '9')
     1387        || !(pszFilename[cch-7] >= '0' && pszFilename[cch-7] <= '9')
     1388        || !(pszFilename[cch-6] == 'A' || pszFilename[cch-6] == 'H' || pszFilename[cch-6] == 'R')
     1389        || !(pszFilename[cch-5] == 'S' || pszFilename[cch-5] == 'U')
     1390        )
     1391    {
     1392        printf16("invalid filename: %s\n", pszFilename);
     1393        return 2;
     1394    }
     1395
     1396    /** @remark
     1397     * All a/h-strict files are currently ignored.
     1398     * When a debug kernel is used we'll have to use the
     1399     * .sym-file for it. This is so because I can't distinguish
     1400     * between a all-strick and a half-strick kernel (yet).
     1401     */
     1402    if (pszFilename[cch-6] != 'R')
     1403        return 0;
     1404
     1405    /*
     1406     * Probe kernelfile
     1407     */
     1408    rc = ProbeSymFile(pszFilename);
     1409
     1410
     1411    /*
     1412     * on success dump a struct for this kernel
     1413     */
     1414    if (rc == 0)
     1415    {
     1416        int i;
     1417
     1418        printf16("    { /* %s */\n"
     1419                 "        %.*s, \'%c\', %s, %d,\n"
     1420                 "        {\n",
     1421                 pszFilename,
     1422                 cch - 6, &pszFilename[0],                       /* build number */
     1423                 pszFilename[cch - 6],                           /* Type, A=astrict, H=halfstrict, R=Retail */
     1424                 pszFilename[cch - 5] == 'S' ? "TRUE" : "FALSE", /* UNI: TRUE  SMP: FALSE */
     1425                 aImportTab[0].iObject + 1); /* ASSUMES that DOSCODE32 is the last object. */
     1426
     1427        for (i = 0; i < NBR_OF_KRNLIMPORTS; i++)
     1428        {
     1429            char *psz = aImportTab[i].achName;
     1430            printf16("            {%2d, 0x%08lx}, /* %s */\n",
     1431                     aImportTab[i].iObject,
     1432                     aImportTab[i].offObject,
     1433                     (char *)&aImportTab[i].achName[0]
     1434                     );
     1435        }
     1436        printf16("        }\n"
     1437                 "    },\n");
     1438    }
     1439    else
     1440        printf16("ProbeSymFile failed with rc=%d\n", rc);
     1441
     1442    return rc;
     1443}
     1444
     1445
     1446/**
     1447 * Extract program.
     1448 *
     1449 * This is some initial trial-and-error for creating an "database" of
     1450 * kernel entrypoints.
     1451 *
     1452 * Output to stderr the structs generated for the passed in *.sym file.
     1453 *
     1454 */
     1455int main(int argc, char **argv)
     1456{
     1457    APIRET  rc;
     1458
     1459    if (argc > 1)
     1460    {
     1461        /*
     1462         * Arguments: extract.exe <symfiles...>
     1463         */
     1464        int i;
     1465        for (i = 0; i < argc; i++)
     1466        {
     1467            rc = processFile(argv[i]);
     1468            if (rc != NO_ERROR)
     1469            {
     1470                printf16("processFile failed with rc=%d for file %s\n",
     1471                          rc, argv[i]);
     1472                return rc;
     1473            }
     1474        }
     1475    }
     1476    else
     1477    {
     1478        /*
     1479         * Arguments: extract.exe
     1480         *
     1481         * Action:    Scan current directory for *.sym files.
     1482         *
     1483         */
     1484        USHORT      usSearch = 1;
     1485        HDIR        hDir = HDIR_CREATE;
     1486        FILEFINDBUF ffb;
     1487        int         i;
     1488
     1489        printf16("/* $Id: probkrnl.c,v 1.16 2000-02-25 18:15:02 bird Exp $\n"
     1490                 "*\n"
     1491                 "* Autogenerated kernel symbol database.\n"
     1492                 "*\n"
     1493                 "* Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)\n"
     1494                 "*\n"
     1495                 "* Project Odin Software License can be found in LICENSE.TXT\n"
     1496                 "*\n"
     1497                 "*/\n");
     1498
     1499        printf16("\n"
     1500                 "#include <os2.h>\n"
     1501                 "#include \"probkrnl.h\"\n"
     1502                 "\n");
     1503
     1504        printf16("KRNLDBENTRY aKrnlSymDB[] = \n"
     1505                 "{\n");
     1506
     1507        rc = DosFindFirst("*.sym", &hDir, FILE_NORMAL,
     1508                          &ffb, sizeof(ffb),
     1509                          &usSearch, 0UL);
     1510        while (rc == NO_ERROR & usSearch > 0)
     1511        {
     1512            rc = processFile(&ffb.achName[0]);
     1513            if (rc != NO_ERROR)
     1514            {
     1515                printf16("processFile failed with rc=%d for file %s\n",
     1516                         rc, &ffb.achName[0]);
     1517                return rc;
     1518            }
     1519
     1520            /* next file */
     1521            rc = DosFindNext(hDir, &ffb, sizeof(ffb), &usSearch);
     1522        }
     1523        DosFindClose(hDir);
     1524
     1525        printf16("    { /* Terminating entry */\n"
     1526                 "        0,0,0,0,\n"
     1527                 "        {\n");
     1528        for (i = 0; i < NBR_OF_KRNLIMPORTS; i++)
     1529            printf16("            {0,0},\n");
     1530        printf16("        }\n"
     1531                 "    }\n"
     1532                 "}; /* end of aKrnlSymDB[] */\n"
     1533                 );
     1534    }
     1535
     1536
     1537    return rc;
     1538}
     1539#endif /* EXTRACT */
     1540
Note: See TracChangeset for help on using the changeset viewer.