Source code of Windows XP (NT5)
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.

559 lines
16 KiB

  1. /*** binfmt.c - Binary Data Format services
  2. *
  3. * This module contains format services for converting binary data into format
  4. * text strings according to the format record.
  5. *
  6. * Copyright (c) 1995,1996 Microsoft Corporation
  7. * Author: Michael Tsang (MikeTs)
  8. * Created 11/06/95
  9. *
  10. * MODIFICATION HISTORY
  11. */
  12. #ifdef __UNASM
  13. #pragma warning (disable: 4001)
  14. #include "basedef.h"
  15. #define USE_CRUNTIME
  16. #include "binfmt.h"
  17. typedef int (*PFNFMT)(char *, PFMTHDR, BYTE *, DWORD *);
  18. //Local function prototypes
  19. int FormatNum(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset);
  20. int FormatEnum(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset);
  21. int FormatBits(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset);
  22. int FormatString(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset);
  23. int GetData(BYTE bUnitSize, BYTE *pb, DWORD dwOffset, DWORD *pdwData);
  24. int PrintData(char *pszBuffer, BYTE bUnitSize, DWORD dwData, BOOL fPadSpace);
  25. char szDefSep[] = SZ_SEP_SPACE;
  26. char szDefOffsetFmt[] = SZ_FMT_WORDOFFSET;
  27. PFNFMT FmtFuncTable[] =
  28. {
  29. FormatNum, //0: FMT_NUMBER
  30. FormatEnum, //1: FMT_ENUM
  31. FormatBits, //2: FMT_BITS
  32. FormatString, //3: FMT_STRING
  33. };
  34. #define NUM_FMT_FUNCS (sizeof(FmtFuncTable)/sizeof(PFNFMT))
  35. #ifdef FPRINTF
  36. /***EP BinFPrintf - Binary fprintf
  37. *
  38. * ENTRY
  39. * pfile -> output file
  40. * pszBuffer -> buffer to hold the formatted string
  41. * (if NULL, use internal buffer)
  42. * pfmt -> format record array
  43. * pb -> binary data buffer
  44. * pdwOffset -> offset to binary data buffer (if NULL, use internal)
  45. * pszOffsetFormat -> offset format string (can be NULL)
  46. *
  47. * EXIT-SUCCESS
  48. * returns FERR_NONE
  49. * EXIT-FAILURE
  50. * returns negative error code
  51. */
  52. int BinFPrintf(FILE *pfile, char *pszBuffer, PFMT pfmt, BYTE *pb,
  53. DWORD *pdwOffset, char *pszOffsetFormat)
  54. {
  55. TRACENAME("BINFPRINTF")
  56. int rc = FERR_NONE;
  57. DWORD dwOffset = 0, dwOldOffset;
  58. DWORD dwData;
  59. char szBuff[256];
  60. char *psz = pszBuffer? pszBuffer: szBuff;
  61. DWORD *pdw = pdwOffset? pdwOffset: &dwOffset;
  62. ENTER(4, ("BinFPrintf(pszBuff=%lx,pfmt=%lx,pdwOffset=%lx,Offset=%lx)\n",
  63. pszBuffer, pfmt, pdwOffset, pdwOffset? *pdwOffset: 0));
  64. if (pfmt != NULL)
  65. {
  66. BYTE i, j;
  67. for (i = 0; pfmt[i].pfmtType != NULL; ++i)
  68. {
  69. if (pfmt[i].pszLabel != NULL)
  70. {
  71. if (pszOffsetFormat != NULL)
  72. {
  73. FPRINTF(pfile, pszOffsetFormat,
  74. *pdw, pfmt[i].pfmtType->bUnitSize);
  75. if (pfmt[i].pfmtType->dwfFormat & FMTF_NO_RAW_DATA)
  76. {
  77. FPRINTF(pfile, " ");
  78. }
  79. else
  80. {
  81. if (GetData(pfmt[i].pfmtType->bUnitSize, pb, *pdw,
  82. &dwData) == FERR_NONE)
  83. {
  84. PrintData(psz, pfmt[i].pfmtType->bUnitSize, dwData,
  85. TRUE);
  86. FPRINTF(pfile, psz);
  87. }
  88. for (j = 1; j < pfmt[i].pfmtType->bUnitCnt; ++j)
  89. {
  90. if (GetData(pfmt[i].pfmtType->bUnitSize, pb,
  91. *pdw + j*pfmt[i].pfmtType->bUnitSize,
  92. &dwData) == FERR_NONE)
  93. {
  94. FPRINTF(pfile, ",");
  95. PrintData(psz, pfmt[i].pfmtType->bUnitSize,
  96. dwData, FALSE);
  97. FPRINTF(pfile, psz);
  98. }
  99. }
  100. }
  101. }
  102. if (pfmt[i].pszLabel[0] != '\0')
  103. FPRINTF(pfile, ";%s", pfmt[i].pszLabel);
  104. else
  105. FPRINTF(pfile, "\n");
  106. }
  107. dwOldOffset = *pdw;
  108. if ((pfmt[i].pszLabel != NULL) && (pfmt[i].pszLabel[0] == '\0'))
  109. {
  110. *pdw += pfmt[i].pfmtType->bUnitCnt*pfmt[i].pfmtType->bUnitSize;
  111. }
  112. else
  113. {
  114. if (pfmt[i].pszLabel == NULL)
  115. FPRINTF(pfile, ",");
  116. rc = BinSprintf(psz, pfmt[i].pfmtType, pb, pdw);
  117. if (rc == FERR_NONE)
  118. {
  119. char *psz1, *psz2;
  120. BOOL fSpace = FALSE, fInQuote = FALSE, fInString = FALSE;
  121. for (psz1 = psz2 = psz; *psz2 != '\0'; ++psz2)
  122. {
  123. if (*psz2 == '"')
  124. {
  125. fSpace = FALSE;
  126. fInString = ~fInString;
  127. *psz1 = *psz2;
  128. psz1++;
  129. }
  130. else if (*psz2 == '\'')
  131. {
  132. fSpace = FALSE;
  133. fInQuote = ~fInQuote;
  134. *psz1 = *psz2;
  135. psz1++;
  136. }
  137. else if (*psz2 == ' ')
  138. {
  139. if (!fSpace && !fInString && !fInQuote &&
  140. (psz1 != psz))
  141. {
  142. *psz1 = ',';
  143. psz1++;
  144. }
  145. else if (fInString || fInQuote)
  146. {
  147. *psz1 = *psz2;
  148. psz1++;
  149. }
  150. fSpace = TRUE;
  151. }
  152. else
  153. {
  154. fSpace = FALSE;
  155. *psz1 = *psz2;
  156. psz1++;
  157. }
  158. }
  159. if ((psz1 > psz) && (*(psz1 - 1) == ','))
  160. *(psz1 - 1) = '\0';
  161. else if ((psz1 > psz) && (*(psz1 - 1) == '\n') &&
  162. (*(psz1 - 2) == ','))
  163. {
  164. *(psz1 - 2) = '\n';
  165. *(psz1 - 1) = '\0';
  166. }
  167. else
  168. *psz1 = '\0';
  169. FPRINTF(pfile, psz);
  170. }
  171. }
  172. if (pfmt[i].lpfn != NULL)
  173. (*pfmt[i].lpfn)(pfile, pb, dwOldOffset);
  174. }
  175. }
  176. EXIT(4, ("BinFPrintf=%d (Offset=%lx,Buff=%s)\n",
  177. rc, *pdwOffset, pszBuffer));
  178. return rc;
  179. } //BinFPrintf
  180. #endif //ifdef FPRINTF
  181. /***EP BinSprintf - Binary sprintf
  182. *
  183. * ENTRY
  184. * pszBuffer -> buffer to hold the formatted string
  185. * pfmt -> format record
  186. * pb -> binary data buffer
  187. * pdwOffset -> offset to binary data buffer
  188. *
  189. * EXIT-SUCCESS
  190. * returns FERR_NONE
  191. * EXIT-FAILURE
  192. * returns negative error code
  193. */
  194. int BinSprintf(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset)
  195. {
  196. TRACENAME("BINSPRINTF")
  197. int rc = FERR_NONE;
  198. ENTER(4, ("BinSprintf(fmt=%d,Offset=%lx)\n", pfmt->bFmtType, *pdwOffset));
  199. if (pfmt->bFmtType >= NUM_FMT_FUNCS)
  200. rc = FERR_INVALID_FORMAT;
  201. else
  202. {
  203. int i;
  204. BYTE j;
  205. DWORD dwData;
  206. *pszBuffer = '\0';
  207. for (i = 0; (rc == FERR_NONE) && (i < pfmt->iRepeatCnt); ++i)
  208. {
  209. if (pfmt->dwfFormat & FMTF_PRINT_OFFSET)
  210. {
  211. SPRINTF(pszBuffer,
  212. pfmt->pszOffsetFmt? pfmt->pszOffsetFmt: szDefOffsetFmt,
  213. *pdwOffset);
  214. }
  215. if (!(pfmt->dwfFormat & FMTF_NO_PRINT_DATA) &&
  216. (GetData(pfmt->bUnitSize, pb, *pdwOffset, &dwData) ==
  217. FERR_NONE))
  218. {
  219. PrintData(pszBuffer, pfmt->bUnitSize, dwData, FALSE);
  220. STRCAT(pszBuffer, ";");
  221. }
  222. if (pfmt->pszLabel)
  223. STRCAT(pszBuffer, pfmt->pszLabel);
  224. for (j = 0; (rc == FERR_NONE) && (j < pfmt->bUnitCnt); ++j)
  225. {
  226. rc = (*FmtFuncTable[pfmt->bFmtType])
  227. (&pszBuffer[STRLEN(pszBuffer)], pfmt, pb, pdwOffset);
  228. if (rc == FERR_NONE)
  229. {
  230. if (!(pfmt->dwfFormat & FMTF_NO_SEP))
  231. {
  232. STRCAT(pszBuffer,
  233. pfmt->pszFieldSep? pfmt->pszFieldSep: szDefSep);
  234. }
  235. if (!(pfmt->dwfFormat & FMTF_NO_INC_OFFSET))
  236. *pdwOffset += pfmt->bUnitSize;
  237. }
  238. }
  239. if ((rc == FERR_NONE) && !(pfmt->dwfFormat & FMTF_NO_EOL))
  240. {
  241. STRCAT(pszBuffer, "\n");
  242. }
  243. }
  244. }
  245. EXIT(4, ("BinSprintf=%d (Offset=%lx,Buff=%s)\n",
  246. rc, *pdwOffset, pszBuffer));
  247. return rc;
  248. } //BinSprintf
  249. /***LP FormatNum - Format numbers
  250. *
  251. * ENTRY
  252. * pszBuffer -> buffer to hold formatted string
  253. * pfmt -> format record
  254. * pb -> binary data buffer
  255. * pdwOffset -> offset to binary data buffer
  256. *
  257. * EXIT-SUCCESS
  258. * returns FERR_NONE
  259. * EXIT-FAILURE
  260. * returns negative error code
  261. */
  262. int FormatNum(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset)
  263. {
  264. TRACENAME("FORMATNUM")
  265. int rc;
  266. PFMTNUM pfmtNum = (PFMTNUM)pfmt;
  267. DWORD dwData;
  268. ENTER(5, ("FormatNum(Offset=%lx)\n", *pdwOffset));
  269. if ((rc = GetData(pfmt->bUnitSize, pb, *pdwOffset, &dwData)) == FERR_NONE)
  270. {
  271. dwData &= pfmtNum->dwMask;
  272. dwData >>= pfmtNum->bShiftCnt;
  273. SPRINTF(&pszBuffer[STRLEN(pszBuffer)], pfmtNum->pszNumFmt, dwData);
  274. }
  275. EXIT(5, ("FormatNum=%d (Offset=%lx,Buff=%s)\n",
  276. rc, *pdwOffset, pszBuffer));
  277. return rc;
  278. } //FormatNum
  279. /***LP FormatEnum - Format enumerated values
  280. *
  281. * ENTRY
  282. * pszBuffer -> buffer to hold formatted string
  283. * pfmt -> format record
  284. * pb -> binary data buffer
  285. * pdwOffset -> offset to binary data buffer
  286. *
  287. * EXIT-SUCCESS
  288. * returns FERR_NONE
  289. * EXIT-FAILURE
  290. * returns negative error code
  291. */
  292. int FormatEnum(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset)
  293. {
  294. TRACENAME("FORMATENUM")
  295. int rc = FERR_NONE;
  296. PFMTENUM pfmtEnum = (PFMTENUM)pfmt;
  297. DWORD dwData;
  298. ENTER(5, ("FormatEnum(Offset=%lx)\n", *pdwOffset));
  299. if ((rc = GetData(pfmt->bUnitSize, pb, *pdwOffset, &dwData)) == FERR_NONE)
  300. {
  301. dwData &= pfmtEnum->dwMask;
  302. dwData >>= pfmtEnum->bShiftCnt;
  303. if ((dwData < pfmtEnum->dwStartEnum) || (dwData > pfmtEnum->dwEndEnum))
  304. STRCAT(pszBuffer, pfmtEnum->pszOutOfRange);
  305. else
  306. {
  307. dwData -= pfmtEnum->dwStartEnum;
  308. STRCAT(pszBuffer, pfmtEnum->ppszEnumNames[dwData]);
  309. }
  310. }
  311. EXIT(5, ("FormatEnum=%d (Offset=%lx,Buff=%s)\n",
  312. rc, *pdwOffset, pszBuffer));
  313. return rc;
  314. } //FormatEnum
  315. /***LP FormatBits - Format bit values
  316. *
  317. * ENTRY
  318. * pszBuffer -> buffer to hold formatted string
  319. * pfmt -> format record
  320. * pb -> binary data buffer
  321. * pdwOffset -> offset to binary data buffer
  322. *
  323. * EXIT-SUCCESS
  324. * returns FERR_NONE
  325. * EXIT-FAILURE
  326. * returns negative error code
  327. */
  328. int FormatBits(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset)
  329. {
  330. TRACENAME("FORMATBITS")
  331. int rc = FERR_NONE;
  332. PFMTBITS pfmtBits = (PFMTBITS)pfmt;
  333. DWORD dwData;
  334. ENTER(5, ("FormatBits(Offset=%lx)\n", *pdwOffset));
  335. if ((rc = GetData(pfmt->bUnitSize, pb, *pdwOffset, &dwData)) == FERR_NONE)
  336. {
  337. int i, j;
  338. DWORD dw;
  339. for (i = 31, j = 0; i >= 0; --i)
  340. {
  341. dw = 1L << i;
  342. if (pfmtBits->dwMask & dw)
  343. {
  344. if (dwData & dw)
  345. {
  346. if ((pfmtBits->ppszOnNames != NULL) &&
  347. (pfmtBits->ppszOnNames[j] != NULL))
  348. {
  349. STRCAT(pszBuffer, pfmtBits->ppszOnNames[j]);
  350. }
  351. }
  352. else
  353. {
  354. if ((pfmtBits->ppszOffNames != NULL) &&
  355. (pfmtBits->ppszOffNames[j] != NULL))
  356. {
  357. STRCAT(pszBuffer, pfmtBits->ppszOffNames[j]);
  358. }
  359. }
  360. if (!(pfmt->dwfFormat & FMTF_NO_SEP))
  361. {
  362. STRCAT(pszBuffer,
  363. pfmt->pszFieldSep? pfmt->pszFieldSep: szDefSep);
  364. }
  365. j++;
  366. }
  367. }
  368. }
  369. EXIT(5, ("FormatBits=%d (Offset=%lx,Buff=%s)\n",
  370. rc, *pdwOffset, pszBuffer));
  371. return rc;
  372. } //FormatBits
  373. /***LP FormatString - Format string data
  374. *
  375. * ENTRY
  376. * pszBuffer -> buffer to hold formatted string
  377. * pfmt -> format record
  378. * pb -> binary data buffer
  379. * pdwOffset -> offset to binary data buffer
  380. *
  381. * EXIT-SUCCESS
  382. * returns FERR_NONE
  383. * EXIT-FAILURE
  384. * returns negative error code
  385. */
  386. int FormatString(char *pszBuffer, PFMTHDR pfmt, BYTE *pb, DWORD *pdwOffset)
  387. {
  388. TRACENAME("FORMATSTRING")
  389. int rc = FERR_NONE;
  390. ENTER(5, ("FormatString(Offset=%lx)\n", *pdwOffset));
  391. pb += *pdwOffset;
  392. if (pfmt->dwfFormat & FMTF_STR_ASCIIZ)
  393. {
  394. pszBuffer[0] = '"';
  395. STRCPY(pszBuffer + 1, (char *)pb);
  396. pszBuffer[STRLEN(pszBuffer)] = '"';
  397. if ((pfmt->bUnitSize == 0) && !(pfmt->dwfFormat & FMTF_NO_INC_OFFSET))
  398. *pdwOffset += STRLEN((char *)pb) + 3;
  399. }
  400. else if (pfmt->bUnitSize != 0)
  401. {
  402. if (isalnum(*pb) || (*pb == ' '))
  403. {
  404. pszBuffer[0] = '\'';
  405. STRCPYN(pszBuffer + 1, (char *)pb, pfmt->bUnitSize);
  406. pszBuffer[pfmt->bUnitSize + 1] = '\'';
  407. pszBuffer[pfmt->bUnitSize + 2] = '\0';
  408. }
  409. else
  410. {
  411. rc = PrintData(pszBuffer, pfmt->bUnitSize, *((PDWORD)pb), FALSE);
  412. }
  413. }
  414. EXIT(5, ("FormatString=%d (Offset=%lx,Buff=%s)\n",
  415. rc, *pdwOffset, pszBuffer));
  416. return rc;
  417. } //FormatString
  418. /***LP GetData - Get data of appropriate size from the binary buffer
  419. *
  420. * ENTRY
  421. * bUnitSize - size of data unit
  422. * pb -> data buffer
  423. * dwOffset - offset into data buffer
  424. * pdwData -> to hold data
  425. *
  426. * EXIT-SUCCESS
  427. * returns FERR_NONE
  428. * EXIT-FAILURE
  429. * returns negative error code
  430. */
  431. int GetData(BYTE bUnitSize, BYTE *pb, DWORD dwOffset, DWORD *pdwData)
  432. {
  433. TRACENAME("GETDATA")
  434. int rc = FERR_NONE;
  435. ENTER(6, ("GetData(UnitSize=%d,Data=%lx,Offset=%lx)\n",
  436. bUnitSize, *(DWORD *)pb, dwOffset));
  437. pb += dwOffset;
  438. switch (bUnitSize)
  439. {
  440. case UNIT_BYTE:
  441. *pdwData = (DWORD)(*pb);
  442. break;
  443. case UNIT_WORD:
  444. *pdwData = (DWORD)(*((WORD *)pb));
  445. break;
  446. case UNIT_DWORD:
  447. *pdwData = *(DWORD *)pb;
  448. break;
  449. default:
  450. rc = FERR_INVALID_UNITSIZE;
  451. }
  452. EXIT(6, ("GetData=%d (Data=%lx)\n", rc, *pdwData));
  453. return rc;
  454. } //GetData
  455. /***LP PrintData - Print data value according to its size
  456. *
  457. * ENTRY
  458. * pszBuffer -> buffer to hold formatted string
  459. * bUnitSize - size of data unit
  460. * dwData - number
  461. * fPadSpace - if TRUE pad space to 8 chars
  462. *
  463. * EXIT-SUCCESS
  464. * returns FERR_NONE
  465. * EXIT-FAILURE
  466. * returns negative error code
  467. */
  468. int PrintData(char *pszBuffer, BYTE bUnitSize, DWORD dwData, BOOL fPadSpace)
  469. {
  470. TRACENAME("PRINTDATA")
  471. int rc = FERR_NONE;
  472. ENTER(6, ("PrintData(UnitSize=%d,Data=%lx)\n", bUnitSize, dwData));
  473. switch (bUnitSize)
  474. {
  475. case UNIT_BYTE:
  476. SPRINTF(pszBuffer, "%02x", (BYTE)dwData);
  477. if (fPadSpace)
  478. STRCAT(pszBuffer, " ");
  479. break;
  480. case UNIT_WORD:
  481. SPRINTF(pszBuffer, "%04x", (WORD)dwData);
  482. if (fPadSpace)
  483. STRCAT(pszBuffer, " ");
  484. break;
  485. case UNIT_DWORD:
  486. SPRINTF(pszBuffer, "%08lx", dwData);
  487. break;
  488. default:
  489. rc = FERR_INVALID_UNITSIZE;
  490. }
  491. EXIT(6, ("PrintData=%d (Buff=%s)\n", rc, pszBuffer));
  492. return rc;
  493. } //PrintData
  494. #endif //ifdef __UNASM