dsocode.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 14k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /****************************** Module Header ******************************
  2. * Module Name: dsocode.c
  3. *
  4. * Copyright (c) 1985-96, Microsoft Corporation
  5. *
  6. * This file contains the dump structure offset (dso) extension. It is
  7. *  included by $(ALT_PROJECT)dsotable.c which is generated by structo.exe
  8. *
  9. * History:
  10. * 06/17/96 GerardoB Created
  11. ***************************************************************************/
  12. #include <stdexts.h>
  13. /***************************************************************************
  14. * dsoTerminateString
  15. *
  16. * This is used to "parse" the command line. It null-terminates a space
  17. *  delimited string, returns its size and a pointer to the begining
  18. *  of next string
  19. *
  20. * 06/17/96 Created Gerardob
  21. ***************************************************************************/
  22. LPSTR dsoTerminateString(LPSTR psz, PDWORD pdwSize)
  23. {
  24.     LPSTR pszWork = psz;
  25.     while (*pszWork != 0) {
  26.         if (*pszWork == ' ') {
  27.             *pszWork++ = 0;
  28.             break;
  29.         }
  30.         pszWork++;
  31.     }
  32.     *pdwSize = (DWORD)(pszWork - psz);
  33.     if (*pszWork != 0) {
  34.         (*pdwSize)--;
  35.     }
  36.     while ((*pszWork != 0) && (*pszWork == ' ')) {
  37.         pszWork++;
  38.     }
  39.     return pszWork;
  40. }
  41. /***************************************************************************
  42. * dsoGetOffset
  43. *
  44. * If the highest order bit of psot->dwOffset is set, then the value is a
  45. *  relative offset from the previous field; otherwise, it is the
  46. *  actual field offset from the beginnig of the structure
  47. *
  48. * 06/20/96 Created Gerardob
  49. ***************************************************************************/
  50. UINT dsoGetOffset (PSTRUCTUREOFFSETSTABLE psot)
  51. {
  52.     if (!(psot->dwOffset & 0x80000000)) {
  53.         return psot->dwOffset;
  54.     } else {
  55.         return ((psot->dwOffset & ~0x80000000) + dsoGetOffset(psot - 1));
  56.     }
  57. }
  58. /***************************************************************************
  59. * dsoGetSize
  60. *
  61. * The field size is calculated by substracting its offset from the next
  62. *  field's offset. If the struct has unions, several "fields" might have
  63. *  the same offset, or a given table entry (i.e., a field) might have an
  64. *  offset value greater than the offset value for the next entry (a union
  65. *  of two structures).
  66. *
  67. * 06/26/96 Created Gerardob
  68. ***************************************************************************/
  69. UINT dsoGetSize (PSTRUCTUREOFFSETSTABLE psot, DWORD dwOffset)
  70. {
  71.     DWORD dwNextFieldOffset;
  72.     do {
  73.         psot++;
  74.         dwNextFieldOffset = dsoGetOffset(psot);
  75.     } while (dwNextFieldOffset <= dwOffset);
  76.     return dwNextFieldOffset - dwOffset;
  77. }
  78. /***************************************************************************
  79. * dsoGetStruct
  80. *
  81. * 07/03/96 Created Gerardob
  82. ***************************************************************************/
  83. PSTRUCTURESTABLE dsoGetStruct (LPSTR pszStruct, DWORD dwSize)
  84. {
  85.     PSTRUCTURESTABLE pst = gst;
  86.     /*
  87.      * try an exact match
  88.      */
  89.     while (pst->pszName != NULL) {
  90.         if (!_stricmp(pszStruct, pst->pszName)) {
  91.             return pst;
  92.         }
  93.         pst++;
  94.     }
  95.     /*
  96.      * Partial prefix match
  97.      */
  98.     pst = gst;
  99.     while (pst->pszName != NULL) {
  100.         if (!_strnicmp(pszStruct, pst->pszName, dwSize)) {
  101.             return pst;
  102.         }
  103.         pst++;
  104.     }
  105.     return NULL;
  106. }
  107. /***************************************************************************
  108. * dsoGetField
  109. *
  110. * 07/03/96 Created Gerardob
  111. ***************************************************************************/
  112. PSTRUCTUREOFFSETSTABLE dosGetField (PSTRUCTUREOFFSETSTABLE psot, LPSTR pszField, DWORD dwSize)
  113. {
  114.     PSTRUCTUREOFFSETSTABLE psotFirst = psot;
  115.     /*
  116.      * try an exact match
  117.      */
  118.     while (psot->pszField != NULL) {
  119.         if (!_stricmp(pszField, psot->pszField)) {
  120.             return psot;
  121.         }
  122.         psot++;
  123.     }
  124.     /*
  125.      * Partial prefix match
  126.      */
  127.     psot = psotFirst;
  128.     while (psot->pszField != NULL) {
  129.         if (!_strnicmp(pszField, psot->pszField, dwSize)) {
  130.             return psot;
  131.         }
  132.         psot++;
  133.     }
  134.     return NULL;
  135. }
  136. /***************************************************************************
  137. * Idso
  138. *
  139. * !dso StructName [FieldName] [Address]
  140. *
  141. * 06/17/96 Created Gerardob
  142. * 05/12/97 MCostea Added bit field support
  143. ***************************************************************************/
  144. BOOL Idso(DWORD opts, LPSTR pszCmdLine)
  145. {
  146.     BOOL fOneField = FALSE;
  147.     DWORD dwOptions;
  148.     DWORD dwValue, dwSize, dwBytesRead, dwOffset, dwOffsetNext, dwFieldsPerRow, dwMoveSize;
  149.     DWORD dwBuffer [20];  /* Make sure it has an even number of elemnts and at least 4*/
  150.     const DWORD *pcdwLimit = dwBuffer + (sizeof(dwBuffer) / sizeof(*dwBuffer));
  151.     DWORD *pdwValue;
  152.     LPSTR pszField, pszAddress;
  153.     PBYTE pBufferOffset;
  154.     PSTRUCTURESTABLE pst;
  155.     PSTRUCTUREOFFSETSTABLE psot;
  156.     PVOID pAddress = NULL;
  157.     int   cBFStart, cBFLength;   /* for printing bit field values: keeps count of field location */
  158.     char* pTmp;
  159.     DWORD dwMask;
  160.     BOOL  fBF;
  161.     int   cBF;                    /* no of dwords this set of bit-fields spread till now */
  162.     UNREFERENCED_PARAMETER(opts);
  163.     if (pszCmdLine == NULL) {
  164.         return FALSE;
  165.     }
  166.     /*
  167.      * NULL terminate first argument and get a pointer to
  168.      *  second one (presumably the field name)
  169.      */
  170.     // did the user ask us to dump the list of structure names we understand ?
  171.     if ( opts & OFLAG(l))
  172.     {
  173.         int iStruct;
  174.         Print( "Structures known:n" );
  175.         
  176.         for ( iStruct = 0; gst[iStruct].pszName != NULL; iStruct ++ )
  177.         {
  178.             Print( "    " );
  179.             Print( gst[iStruct].pszName );
  180.             Print( "n" );
  181.         }
  182.         return TRUE;
  183.     }
  184.     
  185.     /*
  186.      * Find the struct table
  187.      */
  188.     pszField = dsoTerminateString(pszCmdLine, &dwSize);
  189.     pst = dsoGetStruct (pszCmdLine, dwSize);
  190.     if (pst == NULL) {
  191.         Print("Structure not found: %sn", pszCmdLine);
  192.         return TRUE;
  193.     }
  194.     /*
  195.      * Got a table
  196.      */
  197.     psot = pst->psot;
  198.     /*
  199.      * If there is another argument, let's assume a field name follows
  200.      */
  201.     if (*pszField != 0) {
  202.         /*
  203.          * Find the field
  204.          */
  205.         pszAddress = dsoTerminateString(pszField, &dwSize);
  206.         psot = dosGetField (psot, pszField, dwSize);
  207.         /*
  208.          * If it didn't find the field and an address was provided, game over.
  209.          * Otherwise, the second parameter might be the address
  210.          */
  211.         if (psot == NULL) {
  212.             if (*pszAddress != 0) {
  213.                 Print("Field not found: %s. Struct: %sn", pszField, pst->pszName);
  214.                 return TRUE;
  215.             } else {
  216.                 pszAddress = pszField;
  217.                 /*
  218.                  * Reset psot since this argument was not a field
  219.                  */
  220.                 psot = pst->psot;
  221.             }
  222.         } else {
  223.             fOneField = TRUE;
  224.         }
  225.         /*
  226.          * Get the pointer to the struct
  227.          */
  228.         if (*pszAddress != 0) {
  229.             pAddress = EvalExp(pszAddress);
  230.             if (pAddress == NULL) {
  231.                 /*
  232.                  * EvalExp displayed the error message, so return silently
  233.                  */
  234.                 return TRUE;
  235.             }
  236.         }
  237.     } /* if (*pszField != 0) */
  238.     /*
  239.      * If a field name was specified, dump that field only
  240.      * Otherwise, dump the whole table.
  241.      */
  242.     if (fOneField) {
  243.         /*
  244.          * If no address available, just display the field name and offset
  245.          */
  246.         dwOffset = dsoGetOffset(psot);
  247.         Print ("Structure %s - Size: %#lxn", pst->pszName, pst->dwSize);
  248.         Print("Field: %s - Offset: %#lxn", psot->pszField, dwOffset);
  249.         if (pAddress == NULL) {
  250.             return TRUE;
  251.         }
  252.         /*
  253.          * Printing field value
  254.          */
  255.         /*123456789 1*/
  256.         Print("Address   Valuen");
  257.         dwBytesRead = 0;
  258.         dwSize = dsoGetSize(psot, dwOffset);
  259.         /*
  260.          * Print 4 DWORDS per row; one row per loop
  261.          */
  262.         do { /* while ((int)dwSize > 0) */
  263.             /*
  264.              * Read values for next row
  265.              */
  266.             if (4 * sizeof(DWORD) >= dwSize) {
  267.                 dwMoveSize = dwSize;
  268.             } else {
  269.                 dwMoveSize = 4 * sizeof(DWORD);
  270.             }
  271.             moveBlock(dwBuffer, (PBYTE)pAddress + dwOffset + dwBytesRead, dwMoveSize);
  272.             pBufferOffset = (PBYTE)dwBuffer;
  273.             /*
  274.              * Print the address
  275.              */
  276.             Print("%08lx  ", (DWORD_PTR)((PBYTE)pAddress + dwOffset + dwBytesRead));
  277.             /*
  278.              * Keep track of bytes read (dwBytesRead) and bytes
  279.              *  remaining to be read (dwSize)
  280.              */
  281.             dwBytesRead += dwMoveSize;
  282.             dwSize -= dwMoveSize;
  283.             /*
  284.              * Print the values, one dword at the time
  285.              */
  286.             while (dwMoveSize >= sizeof(DWORD)) {
  287.                 Print("%08lx ", *((DWORD *)pBufferOffset));
  288.                 pBufferOffset += sizeof(DWORD);
  289.                 dwMoveSize -= sizeof(DWORD);
  290.             }
  291.             /*
  292.              * If less than a DWORD left, zero extend and print a DWORD
  293.              */
  294.             if (dwMoveSize > 0) {
  295.                 dwValue = 0;
  296.                 memcpy(&dwValue, pBufferOffset, dwMoveSize);
  297.                 Print("%0*lx", dwMoveSize * 2, dwValue);
  298.             }
  299.             Print("n");
  300.         } while ((int)dwSize > 0);
  301.         return TRUE;
  302.     } /* if (fOneField) */
  303.     /*
  304.      * Printing all the fields.
  305.      */
  306.     if (pAddress != NULL) {
  307.         Print ("Structure %s %#lx - Size: %#lxn", pst->pszName, pAddress, pst->dwSize);
  308.     } else {
  309.         Print ("Structure %s - Size: %#lxn", pst->pszName, pst->dwSize);
  310.     }
  311.     dwOffset = 0;
  312.     pBufferOffset = NULL; /* Forces the local buffer to be loaded */
  313.     dwFieldsPerRow = 0;
  314.     cBFStart = 0;
  315.     cBF = 0;
  316.     /*
  317.      * Loop through all fields in the table. Print one field per loop
  318.      */
  319.     while (psot->pszField != NULL) {
  320.         /*
  321.          * Print two fields per row
  322.          */
  323.         if (dwFieldsPerRow == 2) {
  324.             Print("n");
  325.             dwFieldsPerRow = 1;
  326.         } else {
  327.             dwFieldsPerRow++;
  328.         }
  329.         /*
  330.          * If no address provided, Print field name(s) and offset(s) only
  331.          */
  332.         if (pAddress == NULL) {
  333.             Print("%03lx %-33.32s", dsoGetOffset(psot), psot->pszField);
  334.         } else {
  335.             /*
  336.              * Printing offsets and values.
  337.              *
  338.              * Get the size of the value and max it to one DWORD
  339.              */
  340.             dwOffsetNext = dsoGetOffset(psot + 1);
  341.             if (dwOffsetNext > dwOffset) {
  342.                 dwSize = dwOffsetNext - dwOffset;
  343.             } else {
  344.                 dwSize = dsoGetSize(psot, dwOffset);
  345.             }
  346.             if (dwSize > sizeof(DWORD)) {
  347.                 dwSize = sizeof(DWORD);
  348.             }
  349.             /*
  350.              * Get a pointer to the value in the local buffer
  351.              * If the value is not in the buffer, load it
  352.              */
  353.             pdwValue = (PDWORD)(pBufferOffset + dwOffset);
  354.             if ((pdwValue < dwBuffer) || (pdwValue + dwSize > pcdwLimit)) {
  355.                 pBufferOffset = (PBYTE)dwBuffer - dwOffset;
  356.                 pdwValue = dwBuffer;
  357.                 if (sizeof(dwBuffer) >= pst->dwSize - dwOffset) {
  358.                     dwMoveSize = pst->dwSize - dwOffset;
  359.                 } else {
  360.                     dwMoveSize = sizeof(dwBuffer);
  361.                 }
  362.                 moveBlock((PBYTE)dwBuffer, (PBYTE)pAddress + dwOffset, dwMoveSize);
  363.             }
  364.             /*
  365.              * Copy the value and print it
  366.              */
  367.             dwValue = 0; /* in case size < sizeof(DWORD) */
  368.             memcpy(&dwValue, pdwValue, dwSize);
  369.             /*
  370.              * Deal with bit fields
  371.              */
  372.             fBF = FALSE;
  373.             pTmp = psot->pszField;
  374.             while (*pTmp) {
  375.                 if (*pTmp++ == ':') {
  376.                     fBF = TRUE;
  377.                     while ((*pTmp == ' ') || (*pTmp == 't')) {     /* skip white spaces */
  378.                         ++pTmp;
  379.                     }
  380.                     cBFLength = *(pTmp++) - '0';      /* now get the bit size, maybe 2 digits */
  381.                     if ((*pTmp >= '0') && (*pTmp <= '9'))
  382.                         cBFLength = cBFLength*10 + (*pTmp - '0');
  383.                     if (cBFStart == 0) {
  384.                         Print("(%03lx) %08lx BIT FIELDSn", dwOffset, dwValue);
  385.                         dwFieldsPerRow = 1;
  386.                     }
  387.                     else if (cBFStart >= 8*sizeof(DWORD)) {   /* check for multi-dword fields */
  388.                         cBF ++;
  389.                         cBFStart %= 8*sizeof(DWORD);
  390.                     }
  391.                     dwMask = (1L << cBFLength) - 1;
  392.                     dwMask <<= cBFStart;
  393.                     /* print byte offset and the bit offset inside it */
  394.                     Print("(%03lx) (%d)   %-2x %-23.22s", dwOffset + cBF*sizeof(DWORD) + cBFStart/8, cBFStart & 7,
  395.                            (dwMask & dwValue) >> cBFStart,
  396.                                          psot->pszField);
  397.                     cBFStart += cBFLength;
  398.                     cBFLength = 0;
  399.                     break;
  400.                 }
  401.             }
  402.             if (!fBF) {
  403.                 Print("(%03lx) %08lx %-23.22s", dwOffset, dwValue, psot->pszField);
  404.                 cBFStart = 0;
  405.                 cBF = 0;
  406.             }
  407.         } /* if (pAddress == NULL) */
  408.         dwOffset = dwOffsetNext;
  409.         psot++;
  410.     } /* while (psot->pszField != NULL) */
  411.     Print("n");
  412.     return TRUE;
  413. }