Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

402 lines
12 KiB

  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 dosGetStruct (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. \***************************************************************************/
  143. BOOL Idso(DWORD opts, LPSTR pszCmdLine)
  144. {
  145. BOOL fOneField = FALSE;
  146. DWORD dwOptions;
  147. DWORD dwValue, dwSize, dwBytesRead, dwOffset, dwOffsetNext, dwFieldsPerRow, dwMoveSize;
  148. DWORD dwBuffer [20]; /* Make sure it has an even number of elemnts and at least 4*/
  149. const DWORD *pcdwLimit = dwBuffer + (sizeof(dwBuffer) / sizeof(*dwBuffer));
  150. DWORD *pdwValue;
  151. LPSTR pszField, pszAddress;
  152. PBYTE pBufferOffset;
  153. PSTRUCTURESTABLE pst;
  154. PSTRUCTUREOFFSETSTABLE psot;
  155. PVOID pAddress = NULL;
  156. if (pszCmdLine == NULL) {
  157. return FALSE;
  158. }
  159. /*
  160. * NULL terminate first argument and get a pointer to
  161. * second one (presumably the field name)
  162. */
  163. /*
  164. * Get the options, if any
  165. */
  166. if (*pszCmdLine == '-') {
  167. dwOptions = GetOpts(&pszCmdLine, NULL);
  168. }
  169. /*
  170. * Find the struct table
  171. */
  172. pszField = dsoTerminateString(pszCmdLine, &dwSize);
  173. pst = dosGetStruct (pszCmdLine, dwSize);
  174. if (pst == NULL) {
  175. Print("Structure not found: %s\n", pszCmdLine);
  176. return TRUE;
  177. }
  178. /*
  179. * Got a table
  180. */
  181. psot = pst->psot;
  182. /*
  183. * If there is another argument, let's assume a field name follows
  184. */
  185. if (*pszField != 0) {
  186. /*
  187. * Find the field
  188. */
  189. pszAddress = dsoTerminateString(pszField, &dwSize);
  190. psot = dosGetField (psot, pszField, dwSize);
  191. /*
  192. * If it didn't find the field and an address was provided, game over.
  193. * Otherwise, the second parameter might be the address
  194. */
  195. if (psot == NULL) {
  196. if (*pszAddress != 0) {
  197. Print("Field not found: %s. Struct: %s\n", pszField, pst->pszName);
  198. return TRUE;
  199. } else {
  200. pszAddress = pszField;
  201. /*
  202. * Reset psot since this argument was not a field
  203. */
  204. psot = pst->psot;
  205. }
  206. } else {
  207. fOneField = TRUE;
  208. }
  209. /*
  210. * Get the pointer to the struct
  211. */
  212. if (*pszAddress != 0) {
  213. pAddress = EvalExp(pszAddress);
  214. if (pAddress == NULL) {
  215. /*
  216. * EvalExp displayed the error message, so return silently
  217. */
  218. return TRUE;
  219. }
  220. }
  221. } /* if (*pszField != 0) */
  222. /*
  223. * If a field name was specified, dump that field only
  224. * Otherwise, dump the whole table.
  225. */
  226. if (fOneField) {
  227. /*
  228. * If no address available, just display the field name and offset
  229. */
  230. dwOffset = dsoGetOffset(psot);
  231. Print ("Structure %s - Size: %#lx\n", pst->pszName, pst->dwSize);
  232. Print("Field: %s - Offset: %#lx\n", psot->pszField, dwOffset);
  233. if (pAddress == NULL) {
  234. return TRUE;
  235. }
  236. /*
  237. * Printing field value
  238. */
  239. /*123456789 1*/
  240. Print("Address Value\n");
  241. dwBytesRead = 0;
  242. dwSize = dsoGetSize(psot, dwOffset);
  243. /*
  244. * Print 4 DWORDS per row; one row per loop
  245. */
  246. do { /* while ((int)dwSize > 0) */
  247. /*
  248. * Read values for next row
  249. */
  250. if (4 * sizeof(DWORD) >= dwSize) {
  251. dwMoveSize = dwSize;
  252. } else {
  253. dwMoveSize = 4 * sizeof(DWORD);
  254. }
  255. moveBlock(dwBuffer, (PBYTE)pAddress + dwOffset + dwBytesRead, dwMoveSize);
  256. pBufferOffset = (PBYTE)dwBuffer;
  257. /*
  258. * Print the address
  259. */
  260. Print("%08lx ", (DWORD)((PBYTE)pAddress + dwOffset + dwBytesRead));
  261. /*
  262. * Keep track of bytes read (dwBytesRead) and bytes
  263. * remaining to be read (dwSize)
  264. */
  265. dwBytesRead += dwMoveSize;
  266. dwSize -= dwMoveSize;
  267. /*
  268. * Print the values, one dword at the time
  269. */
  270. while (dwMoveSize >= sizeof(DWORD)) {
  271. Print("%08lx ", *((DWORD *)pBufferOffset));
  272. pBufferOffset += sizeof(DWORD);
  273. dwMoveSize -= sizeof(DWORD);
  274. }
  275. /*
  276. * If less than a DWORD left, zero extend and print a DWORD
  277. */
  278. if (dwMoveSize > 0) {
  279. dwValue = 0;
  280. memcpy(&dwValue, pBufferOffset, dwMoveSize);
  281. Print("%0*lx", dwMoveSize * 2, dwValue);
  282. }
  283. Print("\n");
  284. } while ((int)dwSize > 0);
  285. return TRUE;
  286. } /* if (fOneField) */
  287. /*
  288. * Printing all the fields.
  289. */
  290. Print ("Structure %s - Size: %#lx\n", pst->pszName, pst->dwSize);
  291. dwOffset = 0;
  292. pBufferOffset = NULL; /* Forces the local buffer to be loaded */
  293. dwFieldsPerRow = 0;
  294. /*
  295. * Loop through all fields in the table. Print one field per loop
  296. */
  297. while (psot->pszField != NULL) {
  298. /*
  299. * Print two fields per row
  300. */
  301. if (dwFieldsPerRow == 2) {
  302. Print("\n");
  303. dwFieldsPerRow = 1;
  304. } else {
  305. dwFieldsPerRow++;
  306. }
  307. /*
  308. * If no address provided, Print field name(s) and offset(s) only
  309. */
  310. if (pAddress == NULL) {
  311. Print("%03lx %-34.33s", dsoGetOffset(psot), psot->pszField);
  312. } else {
  313. /*
  314. * Printing offsets and values.
  315. *
  316. * Get the size of the value and max it to one DWORD
  317. */
  318. dwOffsetNext = dsoGetOffset(psot + 1);
  319. if (dwOffsetNext > dwOffset) {
  320. dwSize = dwOffsetNext - dwOffset;
  321. } else {
  322. dwSize = dsoGetSize(psot, dwOffset);
  323. }
  324. if (dwSize > sizeof(DWORD)) {
  325. dwSize = sizeof(DWORD);
  326. }
  327. /*
  328. * Get a pointer to the value in the local buffer
  329. * If the value is not in the buffer, load it
  330. */
  331. pdwValue = (PDWORD)(pBufferOffset + dwOffset);
  332. if ((pdwValue < dwBuffer) || (pdwValue + dwSize > pcdwLimit)) {
  333. pBufferOffset = (PBYTE)dwBuffer - dwOffset;
  334. pdwValue = dwBuffer;
  335. if (sizeof(dwBuffer) >= pst->dwSize - dwOffset) {
  336. dwMoveSize = pst->dwSize - dwOffset;
  337. } else {
  338. dwMoveSize = sizeof(dwBuffer);
  339. }
  340. moveBlock((PBYTE)dwBuffer, (PBYTE)pAddress + dwOffset, dwMoveSize);
  341. }
  342. /*
  343. * Copy the value and print it
  344. */
  345. dwValue = 0; /* in case size < sizeof(DWORD) */
  346. memcpy(&dwValue, pdwValue, dwSize);
  347. Print("(%03lx) %08lx %-24.23s", dwOffset, dwValue, psot->pszField);
  348. } /* if (pAddress == NULL) */
  349. dwOffset = dwOffsetNext;
  350. psot++;
  351. } /* while (psot->pszField != NULL) */
  352. Print("\n");
  353. return TRUE;
  354. }