00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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;
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00054
00055
00056
00057
00058
00059
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
00071
00072
00073
00074
00075
00076
00077
00078
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
00093
00094
00095
00096 PSTRUCTURESTABLE
dsoGetStruct (LPSTR pszStruct, DWORD dwSize)
00097 {
00098 PSTRUCTURESTABLE pst = gst;
00099
00100
00101
00102
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
00115
00116
while (pst->pszName !=
NULL) {
00117
if (!_stricmp(pszStruct, pst->pszName)) {
00118
return pst;
00119 }
00120 pst++;
00121 }
00122
00123
00124
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
00139
00140
00141
00142 PSTRUCTUREOFFSETSTABLE
dosGetField (PSTRUCTUREOFFSETSTABLE psot, LPSTR pszField, DWORD dwSize)
00143 {
00144 PSTRUCTUREOFFSETSTABLE psotFirst = psot;
00145
00146
00147
00148
00149
while (psot->pszField !=
NULL) {
00150
if (!_stricmp(pszField, psot->pszField)) {
00151
return psot;
00152 }
00153 psot++;
00154 }
00155
00156
00157
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
00171
00172
00173
00174
00175
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];
00191
const DWORD *pcdwLimit = dwBuffer + (
sizeof(dwBuffer) /
sizeof(*dwBuffer));
00192
PBYTE pBufferOffset;
00193
char* pTmp;
00194
int nIndent =
gnIndent;
00195
00196
int cBFStart, cBFLength;
00197
int cBF;
00198
DWORD dwMask;
00199
BOOL fBF;
00200
int cchName;
00201
00202
00203
00204
00205
00206
00207
if (fOneField) {
00208
00209
00210
00211 dwOffset =
dsoGetOffset(psot);
00212
00213
DsoPrint((
"Structure %s - Size: %#lx\n", pst->pszName, pst->dwSize));
00214
00215
00216
00217
00218
if (*psot->pszField >=
'A' && *psot->pszField <=
'Z') {
00219
00220
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
00244
00245
00246
00247
DsoPrint((
"Address Value\n"));
00248
00249 dwBytesRead = 0;
00250 dwSize =
dsoGetSize(psot, dwOffset);
00251
00252
00253
00254
00255
do {
00256
00257
00258
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
00270
00271
DsoPrint((
"%p ", (DWORD_PTR)((
PBYTE)pAddress + dwOffset + dwBytesRead)));
00272
00273
00274
00275
00276 dwBytesRead += dwMoveSize;
00277 dwSize -= dwMoveSize;
00278
00279
00280
00281
while (dwMoveSize >=
sizeof(
DWORD)) {
00282
DsoPrint((
"%08lx ", *((
DWORD *)pBufferOffset)));
00283 pBufferOffset +=
sizeof(
DWORD);
00284 dwMoveSize -=
sizeof(
DWORD);
00285 }
00286
00287
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 }
00301
00302
00303
00304
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;
00314 dwFieldsPerRow =
NFIELDS;
00315 cBFStart = 0;
00316 cBF = 0;
00317
00318
00319
00320
00321
00322
while (psot->pszField !=
NULL) {
00323
00324
00325
00326
if (dwFieldsPerRow ==
NFIELDS) {
00327 Print(
"\n");
00328 dwFieldsPerRow = 1;
00329 cchName = 24 -
gnIndent/
NFIELDS;
00330 nIndent =
gnIndent;
00331
00332 }
else {
00333 dwFieldsPerRow++;
00334 cchName = 24 - (
gnIndent + 1)/
NFIELDS;
00335 nIndent = 0;
00336
00337 }
00338
00339
00340
00341
00342
00343
00344
if (opts & OFLAG(v)) {
00345
if (*psot->pszField >=
'A' && *psot->pszField <=
'Z') {
00346
00347
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
00370
00371
if (pAddress ==
NULL) {
00372
DsoPrint((
"%03lx %-*.*s",
dsoGetOffset(psot),
00373 cchName, cchName, psot->pszField));
00374 }
else {
00375
00376
00377
00378
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
00392
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
00410
00411 dwValue = 0;
00412 memcpy(&dwValue, pdwValue, dwSize);
00413
00414
00415
00416
00417 fBF =
FALSE;
00418 pTmp = psot->pszField;
00419
while (*pTmp) {
00420
if (*pTmp++ ==
':') {
00421
00422 fBF =
TRUE;
00423
while ((*pTmp ==
' ') || (*pTmp ==
'\t')) {
00424 ++pTmp;
00425 }
00426 cBFLength = *(pTmp++) -
'0';
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)) {
00435 cBF ++;
00436 cBFStart %= 8*
sizeof(
DWORD);
00437 }
00438
00439 dwMask = (1
L << cBFLength) - 1;
00440 dwMask <<= cBFStart;
00441
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 }
00466
00467 Continue:
00468 dwOffset = dwOffsetNext;
00469 psot++;
00470
00471 }
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;
00488
00489
if (pszCmdLine ==
NULL) {
00490
return FALSE;
00491 }
00492
00493
00494
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
00508
00509 psot = pst->psot;
00510
00511
00512
00513
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
00527
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
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
00551
00552
if (*pszAddress != 0) {
00553 pAddress = EvalExp(pszAddress);
00554
if (pAddress ==
NULL) {
00555
00556
00557
00558
return TRUE;
00559 }
00560 }
00561
00562
00563
00564
00565
if ((*pszRepeat != 0) && (*pszRepeat ==
'*')) {
00566 nRepeat = (DWORD_PTR)EvalExp(pszRepeat+1);
00567
if (nRepeat == 0) {
00568
00569
00570
00571
return TRUE;
00572 }
00573 }
00574 }
00575
00576
while (nRepeat--) {
00577
DsoDump(opts, psot, pst, pAddress, fOneField);
00578 pAddress = (
PBYTE)pAddress + pst->dwSize;
00579 }
00580
00581
return TRUE;
00582 }