Changeset 2898 for trunk/src/win32k/dev16
- Timestamp:
- Feb 25, 2000, 7:19:24 PM (26 years ago)
- 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:45bird Exp $1 /* $Id: d16init.c,v 1.6 2000-02-25 18:15:02 bird Exp $ 2 2 * 3 3 * d16init - init routines for both drivers. … … 21 21 #define INCL_DOSERRORS 22 22 #define INCL_NOPMAPI 23 23 24 24 25 /******************************************************************************* -
trunk/src/win32k/dev16/d16strat.c
r2877 r2898 1 /* $Id: d16strat.c,v 1. 7 2000-02-23 20:10:19bird Exp $1 /* $Id: d16strat.c,v 1.8 2000-02-25 18:15:02 bird Exp $ 2 2 * 3 3 * d16strat.c - 16-bit strategy routine, device headers, device_helper (ptr) … … 64 64 }; 65 65 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;73 66 74 67 … … 129 122 { 130 123 USHORT rc; 124 131 125 if (pRp->Category == D16_IOCTL_CAT) 132 126 { 133 127 switch (pRp->Function) 134 128 { 129 /* 130 * This is the IOCtl which does the R0-initiation of the device driver. 131 * Only available at init time... 132 */ 135 133 case D16_IOCTL_RING0INIT: 136 134 if (fInitTime) … … 142 140 break; 143 141 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: 145 150 if (fInitTime) 146 151 { … … 151 156 &ulLin) != NO_ERROR) 152 157 return STATUS_DONE | STERR | ERROR_I24_INVALID_PARAMETER; 153 return CallGet OTEs32(ulLin);158 return CallGetKernelInfo32(ulLin); 154 159 } 155 160 break; 156 161 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: 158 170 if (fInitTime) 159 171 { -
trunk/src/win32k/dev16/probkrnl.c
r2848 r2898 1 /* $Id: probkrnl.c,v 1.1 5 2000-02-21 14:53:38bird Exp $1 /* $Id: probkrnl.c,v 1.16 2000-02-25 18:15:02 bird Exp $ 2 2 * 3 3 * Description: Autoprobes the os2krnl file and os2krnl[*].sym files. … … 30 30 * Defined Constants And Macros * 31 31 *******************************************************************************/ 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 42 35 #endif 43 36 … … 72 65 #include "dev16.h" 73 66 #include "dev1632.h" 67 #include "vprntf16.h" 68 #include "log.h" 74 69 75 70 … … 111 106 }; 112 107 113 unsigned long int ulBuild = 0;108 unsigned short int usBuild = 0; 114 109 unsigned short usVerMajor = 0; 115 110 unsigned short usVerMinor = 0; 111 unsigned char fSMP = FALSE; 112 unsigned char fDebug = FALSE; 116 113 117 114 … … 144 141 }; 145 142 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. */ 144 static unsigned char cObjects = 0; 145 static POTE paKrnlOTEs = NULL; 146 155 147 156 148 … … 172 164 static int kstrnicmp(const char *psz1, const char *psz2, int cch); 173 165 static int kstrlen(const char *psz); 166 static char * kstrcpy(char * pszTarget, const char * pszSource); 174 167 static int kargncpy(char *pszTarget, const char *pszArg, unsigned cchMaxlen); 175 168 176 169 /* Workers */ 170 static int LookupKrnlEntry(unsigned uBuild, unsigned char chType, 171 unsigned char fSMP, unsigned char cObjects); 177 172 static 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); 173 static int ProbeSymFile(const char *pszFilename); 174 static int GetKernelInfo(void); 183 175 184 176 /* Ouput */ … … 186 178 static void ShowHexNumber(unsigned long ul); 187 179 static void ShowResult(int rc, int iSym); 180 181 /* Others used while debugging in R3. */ 182 static int VerifyKernelVer(void); 183 static int ReadOS2Krnl(char *pszFilename); 184 static int ReadOS2Krnl2(HFILE hKrnl, unsigned long cbKrnl); 185 static int processFile(const char *pszFilename); 188 186 189 187 … … 409 407 410 408 /** 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 */ 415 static 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 /** 411 429 * Copy an argument to a buffer. Ie. "-K[=|:]c:\os2krnl ....". Supports quotes 412 430 * @returns Number of chars of pszArg that has been processed. … … 465 483 * Implementation Of The Important Functions * 466 484 *******************************************************************************/ 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 */ 504 static 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 */ 467 554 468 555 /** … … 473 560 static int VerifyPrologs(void) 474 561 { 475 #if ndef DEBUGR3562 #if !defined(DEBUGR3) && !defined(EXTRACT) 476 563 APIRET rc; 477 564 HFILE hDev0 = 0; … … 484 571 if (rc == NO_ERROR) 485 572 { 486 rc = DosDevIOCtl("", "", D16_IOCTL_VERIFY PROCTAB, D16_IOCTL_CAT, hDev0);573 rc = DosDevIOCtl("", "", D16_IOCTL_VERIFYIMPORTTAB, D16_IOCTL_CAT, hDev0); 487 574 DosClose(hDev0); 488 575 } … … 502 589 * @remark Error codes starts at -50. 503 590 */ 504 static int ProbeSymFile(c har * pszFilename)591 static int ProbeSymFile(const char * pszFilename) 505 592 { 506 593 HFILE hSym; /* Filehandle */ … … 565 652 * Verify that the number of segments is equal to the number objects in OS2KRNL. 566 653 */ 567 if (MapDef.cSegs != KrnlOTEs.cObjects) 654 #ifndef EXTRACT 655 if (MapDef.cSegs != cObjects) 568 656 { /* incorrect count of segments. */ 569 657 dprintf(("Segment No. verify failed\n")); … … 571 659 return -52; 572 660 } 661 #endif /* !EXTRACT */ 573 662 574 663 … … 577 666 */ 578 667 for (i = 0; i < NBR_OF_KRNLIMPORTS; i++) 668 { 579 669 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 } 580 676 581 677 … … 697 793 { /* Symbol was found */ 698 794 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; 700 796 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)); 702 799 703 800 /* Paranoia test! */ 704 if (aImportTab[i].offObject < KrnlOTEs.aObjects[iSeg].ote_size) 801 #ifndef EXTRACT 802 if (aImportTab[i].offObject < paKrnlOTEs[iSeg].ote_size) 705 803 { 706 804 aImportTab[i].fFound = TRUE; … … 712 810 else/* test failed, continue on next symbol*/ 713 811 dprintf(("Error: Paranoia test failed for %s\n", aImportTab[i].achName));; 812 #else 813 aImportTab[i].fFound = TRUE; 814 cLeftToFind--; 815 #endif /* !EXTRACT */ 714 816 break; 715 817 } … … 740 842 741 843 /** 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 datasegment763 * 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 precise765 * 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 else780 rc = -2;781 fclose(hKrnl);782 }783 else784 {785 dprintf(("Could not open file\n"));786 rc = -1;787 }788 return rc;789 }790 791 /**792 * Worker function for ReadOS2Krnl793 * @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. osmundsen798 */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 } else874 {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 DEBUGR3910 /* 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 #endif933 }934 }935 else936 return -10;937 #else938 /* 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 else955 return -10;956 #endif957 958 return 0;959 }960 961 962 /**963 844 * Gets the os/2 kernel OTE's (object table entries). 964 845 * @returns 0 on success. Not 0 on error. 965 846 */ 966 static int GetKernelOTEs(void) 967 { 968 #ifndef DEBUGR3 847 static int GetKernelInfo(void) 848 { 849 #if !defined(DEBUGR3) && !defined(EXTRACT) /* IOCtl not available after inittime! */ 850 static KRNLINFO KrnlInfo = {0}; 969 851 APIRET rc; 970 852 HFILE hDev0 = 0; … … 977 859 if (rc == NO_ERROR) 978 860 { 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 } 980 882 DosClose(hDev0); 981 883 } 982 884 983 885 if (rc != NO_ERROR) 984 p uts("Failed to get kernel OTEs\r\n");886 printf16("Failed to get kernel OTEs\r\n"); 985 887 986 888 return rc; 889 987 890 #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 990 913 #endif 991 914 } 992 993 994 /**995 * Displays an ULONG in decimal notation using DosPutMessage996 * @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 DosPutMessage1020 * @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 1035 915 1036 916 … … 1040 920 * @param iSym index of .sym-file into static struct. 1041 921 */ 922 #ifndef EXTRACT 1042 923 static void ShowResult(int rc, int iSym) 1043 924 { 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 */ 1047 930 if (!fQuiet || rc != 0) 1048 931 { 1049 puts(szBanner); 1050 1051 /* kernel stuff */ 1052 puts(szMsg1); 932 printf16("Win32k - Odin32 support driver.\n"); 933 934 /* 935 * kernel stuff 936 */ 1053 937 if (rc <= -50 || rc == 0) 1054 938 { 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); 1062 944 } 1063 945 else 1064 puts(szMsgfailed); 1065 1066 /* functions */ 946 printf16(" Kernel probing failed with rc=%d.\n", rc); 947 948 /* 949 * symbol-file 950 */ 1067 951 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++) 1068 961 { 1069 p uts(szMsg2);1070 if ( szUsrSym[0] == '\0')1071 p uts(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"); 1072 965 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"); 1091 967 } 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 } 1106 971 1107 972 … … 1187 1052 1188 1053 /*-----------------*/ 1189 /* get kernel OTEs*/1054 /* get kernel info */ 1190 1055 /*-----------------*/ 1191 rc = GetKernel OTEs();1056 rc = GetKernelInfo(); 1192 1057 if (rc != NO_ERROR) 1193 1058 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 else1209 rc = ReadOS2Krnl(szOS2Krnl);1210 1059 1211 1060 /*--------------*/ … … 1224 1073 } 1225 1074 } 1226 if (rc != 0) /* if user sym failed or don't exists */1075 if (rc != 0) /* if user sym failed or don't exists. */ 1227 1076 { 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 } 1231 1091 } 1232 1092 } … … 1238 1098 return rc; 1239 1099 } 1240 1100 #endif 1241 1101 1242 1102 1243 1103 #ifdef DEBUGR3 1104 /** 1105 * Verifies that build no, matches kernel number. 1106 * @returns 0 on equal, !0 on error. 1107 */ 1108 static 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 */ 1130 static 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 */ 1163 static 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 1244 1332 /** 1245 1333 * Debug - Main procedure for standalone testing. … … 1269 1357 ProbeKernel(&ReqPack); 1270 1358 } 1271 1272 1359 #endif 1273 1360 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 */ 1376 static 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 */ 1455 int 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.