Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

dsocode.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: dsocode.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * This file contains the dump structure offset (dso) extension. It is 00007 * included by $(ALT_PROJECT)\dsotable.c which is generated by structo.exe 00008 * 00009 * History: 00010 * 06/17/96 GerardoB Created 00011 \***************************************************************************/ 00012 #include <stdexts.h> 00013 00014 #define DsoPrint(x) Print("%.*s", nIndent, " "); Print x 00015 00016 #define EXACT_MATCH 0xFFFF 00017 00018 int gnIndent = 0; // caller should set and restore this appropriately. 00019 00020 /***************************************************************************\ 00021 * dsoTerminateString 00022 * 00023 * This is used to "parse" the command line. It null-terminates a space 00024 * delimited string, returns its size and a pointer to the begining 00025 * of next string 00026 * 00027 * 06/17/96 Created Gerardob 00028 \***************************************************************************/ 00029 LPSTR dsoTerminateString(LPSTR psz, PDWORD pdwSize) 00030 { 00031 LPSTR pszWork = psz; 00032 00033 while (*pszWork != 0) { 00034 if (*pszWork == ' ') { 00035 *pszWork++ = 0; 00036 break; 00037 } 00038 pszWork++; 00039 } 00040 00041 *pdwSize = (DWORD)(pszWork - psz); 00042 if (*pszWork != 0) { 00043 (*pdwSize)--; 00044 } 00045 00046 while ((*pszWork != 0) && (*pszWork == ' ')) { 00047 pszWork++; 00048 } 00049 00050 return pszWork; 00051 } 00052 /***************************************************************************\ 00053 * dsoGetOffset 00054 * 00055 * If the highest order bit of psot->dwOffset is set, then the value is a 00056 * relative offset from the previous field; otherwise, it is the 00057 * actual field offset from the beginning of the structure 00058 * 00059 * 06/20/96 Created Gerardob 00060 \***************************************************************************/ 00061 UINT dsoGetOffset (PSTRUCTUREOFFSETSTABLE psot) 00062 { 00063 if (!(psot->dwOffset & 0x80000000)) { 00064 return psot->dwOffset; 00065 } else { 00066 return ((psot->dwOffset & ~0x80000000) + dsoGetOffset(psot - 1)); 00067 } 00068 } 00069 /***************************************************************************\ 00070 * dsoGetSize 00071 * 00072 * The field size is calculated by substracting its offset from the next 00073 * field's offset. If the struct has unions, several "fields" might have 00074 * the same offset, or a given table entry (i.e., a field) might have an 00075 * offset value greater than the offset value for the next entry (a union 00076 * of two structures). 00077 * 00078 * 06/26/96 Created Gerardob 00079 \***************************************************************************/ 00080 UINT dsoGetSize (PSTRUCTUREOFFSETSTABLE psot, DWORD dwOffset) 00081 { 00082 DWORD dwNextFieldOffset; 00083 00084 do { 00085 psot++; 00086 dwNextFieldOffset = dsoGetOffset(psot); 00087 } while (dwNextFieldOffset <= dwOffset); 00088 00089 return dwNextFieldOffset - dwOffset; 00090 } 00091 /***************************************************************************\ 00092 * dsoGetStruct 00093 * 00094 * 07/03/96 Created Gerardob 00095 \***************************************************************************/ 00096 PSTRUCTURESTABLE dsoGetStruct (LPSTR pszStruct, DWORD dwSize) 00097 { 00098 PSTRUCTURESTABLE pst = gst; 00099 00100 /* 00101 * If dwSize is EXACT_MATCH, we try an exact 00102 * case sensitive match 00103 */ 00104 if (dwSize == EXACT_MATCH) { 00105 while (pst->pszName != NULL) { 00106 if (!strcmp(pszStruct, pst->pszName)) { 00107 return pst; 00108 } 00109 pst++; 00110 } 00111 return NULL; 00112 } 00113 /* 00114 * Try an exact case insensitive match 00115 */ 00116 while (pst->pszName != NULL) { 00117 if (!_stricmp(pszStruct, pst->pszName)) { 00118 return pst; 00119 } 00120 pst++; 00121 } 00122 00123 /* 00124 * Partial prefix match 00125 */ 00126 pst = gst; 00127 while (pst->pszName != NULL) { 00128 if (!_strnicmp(pszStruct, pst->pszName, dwSize)) { 00129 return pst; 00130 } 00131 pst++; 00132 } 00133 00134 return NULL; 00135 00136 } 00137 /***************************************************************************\ 00138 * dsoGetField 00139 * 00140 * 07/03/96 Created Gerardob 00141 \***************************************************************************/ 00142 PSTRUCTUREOFFSETSTABLE dosGetField (PSTRUCTUREOFFSETSTABLE psot, LPSTR pszField, DWORD dwSize) 00143 { 00144 PSTRUCTUREOFFSETSTABLE psotFirst = psot; 00145 00146 /* 00147 * try an exact match 00148 */ 00149 while (psot->pszField != NULL) { 00150 if (!_stricmp(pszField, psot->pszField)) { 00151 return psot; 00152 } 00153 psot++; 00154 } 00155 00156 /* 00157 * Partial prefix match 00158 */ 00159 psot = psotFirst; 00160 while (psot->pszField != NULL) { 00161 if (!_strnicmp(pszField, psot->pszField, dwSize)) { 00162 return psot; 00163 } 00164 psot++; 00165 } 00166 return NULL; 00167 00168 } 00169 /***************************************************************************\ 00170 * Idso 00171 * 00172 * !dso StructName [FieldName] [Address] 00173 * 00174 * 06/17/96 Created Gerardob 00175 * 05/12/97 MCostea Added bit field support 00176 \***************************************************************************/ 00177 00178 #define NFIELDS 2 // per row. 00179 00180 BOOL DsoDump( 00181 DWORD opts, 00182 PSTRUCTUREOFFSETSTABLE psot, 00183 PSTRUCTURESTABLE pst, 00184 PVOID pAddress, 00185 BOOL fOneField) 00186 { 00187 DWORD dwValue, dwSize, dwMoveSize, dwBytesRead, dwOffset, dwOffsetNext, dwFieldsPerRow; 00188 DWORD *pdwValue; 00189 PSTRUCTURESTABLE pstNested; 00190 DWORD dwBuffer [20]; /* Make sure it has an even number of elemnts and at least 4*/ 00191 const DWORD *pcdwLimit = dwBuffer + (sizeof(dwBuffer) / sizeof(*dwBuffer)); 00192 PBYTE pBufferOffset; 00193 char* pTmp; 00194 int nIndent = gnIndent; /* amount to indent */ 00195 00196 int cBFStart, cBFLength; /* for printing bit field values: keeps count of field location */ 00197 int cBF; /* no of dwords this set of bit-fields spread till now */ 00198 DWORD dwMask; 00199 BOOL fBF; 00200 int cchName; /* length of field name */ 00201 00202 00203 /* 00204 * If a field name was specified, dump that field only 00205 * Otherwise, dump the whole table. 00206 */ 00207 if (fOneField) { 00208 /* 00209 * If no address available, just display the field name and offset 00210 */ 00211 dwOffset = dsoGetOffset(psot); 00212 00213 DsoPrint(("Structure %s - Size: %#lx\n", pst->pszName, pst->dwSize)); 00214 00215 /* 00216 * Try to see if the fields are not nested structures 00217 */ 00218 if (*psot->pszField >= 'A' && *psot->pszField <= 'Z') { 00219 /* 00220 * Probably the field is a nested structure 00221 */ 00222 if (pstNested = dsoGetStruct (psot->pszField, EXACT_MATCH)) { 00223 DWORD dwNestedOffset = dsoGetOffset(psot); 00224 char cmdLine[80]; 00225 DsoPrint(("\nNested at offset %03lx: ", dwNestedOffset)); 00226 if (pAddress) { 00227 sprintf(cmdLine, "%s %p", psot->pszField, (PBYTE)pAddress + dwNestedOffset); 00228 pTmp = cmdLine; 00229 } 00230 else { 00231 pTmp = psot->pszField; 00232 } 00233 return Idso(opts, pTmp); 00234 } 00235 } 00236 00237 DsoPrint(("Field: %s - Offset: %#lx\n", psot->pszField, dwOffset)); 00238 if (pAddress == NULL) { 00239 return TRUE; 00240 } 00241 00242 /* 00243 * Printing field value 00244 */ 00245 00246 /*123456789 1*/ 00247 DsoPrint(("Address Value\n")); 00248 00249 dwBytesRead = 0; 00250 dwSize = dsoGetSize(psot, dwOffset); 00251 /* 00252 * Print 4 DWORDS per row; one row per loop 00253 */ 00254 00255 do { /* while ((int)dwSize > 0) */ 00256 00257 /* 00258 * Read values for next row 00259 */ 00260 if (4 * sizeof(DWORD) >= dwSize) { 00261 dwMoveSize = dwSize; 00262 } else { 00263 dwMoveSize = 4 * sizeof(DWORD); 00264 } 00265 moveBlock(dwBuffer, (PBYTE)pAddress + dwOffset + dwBytesRead, dwMoveSize); 00266 pBufferOffset = (PBYTE)dwBuffer; 00267 00268 /* 00269 * Print the address 00270 */ 00271 DsoPrint(("%p ", (DWORD_PTR)((PBYTE)pAddress + dwOffset + dwBytesRead))); 00272 /* 00273 * Keep track of bytes read (dwBytesRead) and bytes 00274 * remaining to be read (dwSize) 00275 */ 00276 dwBytesRead += dwMoveSize; 00277 dwSize -= dwMoveSize; 00278 /* 00279 * Print the values, one dword at the time 00280 */ 00281 while (dwMoveSize >= sizeof(DWORD)) { 00282 DsoPrint(("%08lx ", *((DWORD *)pBufferOffset))); 00283 pBufferOffset += sizeof(DWORD); 00284 dwMoveSize -= sizeof(DWORD); 00285 } 00286 /* 00287 * If less than a DWORD left, zero extend and print a DWORD 00288 */ 00289 if (dwMoveSize > 0) { 00290 dwValue = 0; 00291 memcpy(&dwValue, pBufferOffset, dwMoveSize); 00292 DsoPrint(("%0*lx", dwMoveSize * 2, dwValue)); 00293 } 00294 Print("\n"); 00295 00296 } while ((int)dwSize > 0); 00297 00298 return TRUE; 00299 00300 } /* if (fOneField) */ 00301 00302 00303 /* 00304 * Printing all the fields. 00305 */ 00306 if (pAddress != NULL) { 00307 DsoPrint(("Structure %s %#lx - Size: %#lx", pst->pszName, pAddress, pst->dwSize)); 00308 } else { 00309 DsoPrint(("Structure %s - Size: %#lx", pst->pszName, pst->dwSize)); 00310 } 00311 00312 dwOffset = 0; 00313 pBufferOffset = NULL; /* Forces the local buffer to be loaded */ 00314 dwFieldsPerRow = NFIELDS; 00315 cBFStart = 0; 00316 cBF = 0; 00317 00318 /* 00319 * Loop through all fields in the table. Print one field per loop 00320 */ 00321 00322 while (psot->pszField != NULL) { 00323 /* 00324 * Print two fields per row 00325 */ 00326 if (dwFieldsPerRow == NFIELDS) { 00327 Print("\n"); 00328 dwFieldsPerRow = 1; 00329 cchName = 24 - gnIndent/NFIELDS; 00330 nIndent = gnIndent; 00331 // Print("cchName = %d\n", cchName); 00332 } else { 00333 dwFieldsPerRow++; 00334 cchName = 24 - (gnIndent + 1)/NFIELDS; 00335 nIndent = 0; 00336 // Print("cchName = %d\n", cchName); 00337 } 00338 00339 /* 00340 * -v functionality 00341 * Try to see if the fields are not nested structures 00342 * The naming convention assigns Uppercase names for them 00343 */ 00344 if (opts & OFLAG(v)) { 00345 if (*psot->pszField >= 'A' && *psot->pszField <= 'Z') { 00346 /* 00347 * Probably the field is a nested structure 00348 */ 00349 if (pstNested = dsoGetStruct (psot->pszField, EXACT_MATCH)) { 00350 DWORD dwNestedOffset = dsoGetOffset(psot); 00351 char cmdLine[80]; 00352 DsoPrint(("\nNested at offset %03lx: ", dwNestedOffset)); 00353 if (pAddress) { 00354 sprintf(cmdLine, "%s %p", psot->pszField, (PBYTE)pAddress + dwNestedOffset); 00355 pTmp = cmdLine; 00356 } 00357 else { 00358 pTmp = psot->pszField; 00359 } 00360 Idso(opts, pTmp); 00361 dwOffsetNext = dsoGetOffset(psot + 1); 00362 dwFieldsPerRow = 0; 00363 goto Continue; 00364 } 00365 } 00366 } 00367 00368 /* 00369 * If no address provided, Print field name(s) and offset(s) only 00370 */ 00371 if (pAddress == NULL) { 00372 DsoPrint(("%03lx %-*.*s", dsoGetOffset(psot), 00373 cchName, cchName, psot->pszField)); 00374 } else { 00375 /* 00376 * Printing offsets and values. 00377 * 00378 * Get the size of the value and max it to one DWORD 00379 */ 00380 dwOffsetNext = dsoGetOffset(psot + 1); 00381 if (dwOffsetNext > dwOffset) { 00382 dwSize = dwOffsetNext - dwOffset; 00383 } else { 00384 dwSize = dsoGetSize(psot, dwOffset); 00385 } 00386 if (dwSize > sizeof(DWORD)) { 00387 dwSize = sizeof(DWORD); 00388 } 00389 00390 /* 00391 * Get a pointer to the value in the local buffer 00392 * If the value is not in the buffer, load it 00393 */ 00394 pdwValue = (PDWORD)(pBufferOffset + dwOffset); 00395 if ((pdwValue < dwBuffer) || (pdwValue + dwSize > pcdwLimit)) { 00396 pBufferOffset = (PBYTE)dwBuffer - dwOffset; 00397 pdwValue = dwBuffer; 00398 00399 if (sizeof(dwBuffer) >= pst->dwSize - dwOffset) { 00400 dwMoveSize = pst->dwSize - dwOffset; 00401 } else { 00402 dwMoveSize = sizeof(dwBuffer); 00403 } 00404 moveBlock((PBYTE)dwBuffer, (PBYTE)pAddress + dwOffset, dwMoveSize); 00405 00406 } 00407 00408 /* 00409 * Copy the value and print it 00410 */ 00411 dwValue = 0; /* in case size < sizeof(DWORD) */ 00412 memcpy(&dwValue, pdwValue, dwSize); 00413 00414 /* 00415 * Deal with bit fields 00416 */ 00417 fBF = FALSE; 00418 pTmp = psot->pszField; 00419 while (*pTmp) { 00420 if (*pTmp++ == ':') { 00421 00422 fBF = TRUE; 00423 while ((*pTmp == ' ') || (*pTmp == '\t')) { /* skip white spaces */ 00424 ++pTmp; 00425 } 00426 cBFLength = *(pTmp++) - '0'; /* now get the bit size, maybe 2 digits */ 00427 if ((*pTmp >= '0') && (*pTmp <= '9')) 00428 cBFLength = cBFLength*10 + (*pTmp - '0'); 00429 00430 if (cBFStart == 0) { 00431 DsoPrint(("(%03lx) %08lx BIT FIELDS\n", dwOffset, dwValue)); 00432 dwFieldsPerRow = 1; 00433 } 00434 else if (cBFStart >= 8*sizeof(DWORD)) { /* check for multi-dword fields */ 00435 cBF ++; 00436 cBFStart %= 8*sizeof(DWORD); 00437 } 00438 00439 dwMask = (1L << cBFLength) - 1; 00440 dwMask <<= cBFStart; 00441 /* print byte offset and the bit offset inside it */ 00442 DsoPrint(("(%03lx) (%d) %-2x %-*.*s", dwOffset + cBF*sizeof(DWORD) + cBFStart/8, cBFStart & 7, 00443 (dwMask & dwValue) >> cBFStart, 00444 cchName, cchName, psot->pszField)); 00445 cBFStart += cBFLength; 00446 cBFLength = 0; 00447 break; 00448 } 00449 } 00450 if (!fBF) { 00451 int width = 8; 00452 if (dwSize == sizeof(BYTE) || ((BYTE)pdwValue & 1)) { 00453 dwValue &= 0xff; 00454 width = 2; 00455 } else if (dwSize == sizeof(WORD) || ((BYTE)pdwValue & 2)) { 00456 dwValue &= 0xffff; 00457 width = 4; 00458 } 00459 DsoPrint(("(%03lx) %*s%0*lx %-*.*s", dwOffset, 8 - width, "", width, dwValue, 00460 cchName, cchName, psot->pszField)); 00461 cBFStart = 0; 00462 cBF = 0; 00463 } 00464 00465 } /* if (pAddress == NULL) */ 00466 00467 Continue: 00468 dwOffset = dwOffsetNext; 00469 psot++; 00470 00471 } /* while (psot->pszField != NULL) */ 00472 00473 Print("\n"); 00474 return TRUE; 00475 } 00476 00477 00478 BOOL Idso(DWORD opts, LPSTR pszCmdLine) 00479 { 00480 BOOL fOneField = FALSE; 00481 DWORD dwSize; 00482 LPSTR pszField, pszAddress, pszRepeat; 00483 PSTRUCTURESTABLE pst; 00484 PSTRUCTUREOFFSETSTABLE psot; 00485 PVOID pAddress = NULL; 00486 DWORD_PTR nRepeat = 1; 00487 int nIndent = gnIndent; /* amount to indent */ 00488 00489 if (pszCmdLine == NULL) { 00490 return FALSE; 00491 } 00492 00493 /* 00494 * Find the struct table 00495 */ 00496 while (*pszCmdLine && *pszCmdLine == ' ') { 00497 *pszCmdLine++; 00498 } 00499 pszField = dsoTerminateString(pszCmdLine, &dwSize); 00500 pst = dsoGetStruct (pszCmdLine, dwSize); 00501 if (pst == NULL) { 00502 DsoPrint(("Structure not found: %s\n", pszCmdLine)); 00503 return TRUE; 00504 } 00505 00506 /* 00507 * Got a table 00508 */ 00509 psot = pst->psot; 00510 00511 /* 00512 * If there is another argument, let's assume a field name follows 00513 * first find the field: 00514 */ 00515 while (*pszField && *pszField == ' ') { 00516 *pszField++; 00517 } 00518 if (*pszField != 0) { 00519 pszAddress = dsoTerminateString(pszField, &dwSize); 00520 psot = dosGetField (psot, pszField, dwSize); 00521 while (*pszAddress && *pszAddress == ' ') { 00522 *pszAddress++; 00523 } 00524 00525 /* 00526 * If it didn't find the field and an address was provided, game over. 00527 * Otherwise, the second parameter might be the address 00528 */ 00529 if (psot == NULL) { 00530 if ((*pszAddress != 0) && (*pszAddress != '*')) { 00531 DsoPrint(("Field not found: %s. Struct: %s\n", pszField, pst->pszName)); 00532 return TRUE; 00533 } else { 00534 pszRepeat = pszAddress; 00535 pszAddress = pszField; 00536 /* 00537 * Reset psot since this argument was not a field 00538 */ 00539 psot = pst->psot; 00540 } 00541 } else { 00542 fOneField = TRUE; 00543 pszRepeat = dsoTerminateString(pszAddress, &dwSize); 00544 while (*pszRepeat && *pszRepeat == ' ') { 00545 *pszRepeat++; 00546 } 00547 } 00548 00549 /* 00550 * Get the pointer to the struct 00551 */ 00552 if (*pszAddress != 0) { 00553 pAddress = EvalExp(pszAddress); 00554 if (pAddress == NULL) { 00555 /* 00556 * EvalExp displayed the error message, so return silently 00557 */ 00558 return TRUE; 00559 } 00560 } 00561 00562 /* 00563 * Get the repeat count 00564 */ 00565 if ((*pszRepeat != 0) && (*pszRepeat == '*')) { 00566 nRepeat = (DWORD_PTR)EvalExp(pszRepeat+1); 00567 if (nRepeat == 0) { 00568 /* 00569 * EvalExp displayed the error message, so return silently 00570 */ 00571 return TRUE; 00572 } 00573 } 00574 } /* if (*pszField != 0) */ 00575 00576 while (nRepeat--) { 00577 DsoDump(opts, psot, pst, pAddress, fOneField); 00578 pAddress = (PBYTE)pAddress + pst->dwSize; 00579 } 00580 00581 return TRUE; 00582 }

Generated on Sat May 15 19:39:47 2004 for test by doxygen 1.3.7