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.

773 lines
22 KiB

  1. /*++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. read.c
  5. Abstract:
  6. This module implements primitives used for reading the database.
  7. Author:
  8. dmunsil created sometime in 1999
  9. Revision History:
  10. several people contributed (vadimb, clupu, ...)
  11. --*/
  12. #include "sdbp.h"
  13. #if defined(KERNEL_MODE) && defined(ALLOC_PRAGMA)
  14. #pragma alloc_text(PAGE, SdbpGetTagHeadSize)
  15. #pragma alloc_text(PAGE, SdbReadBYTETag)
  16. #pragma alloc_text(PAGE, SdbReadWORDTag)
  17. #pragma alloc_text(PAGE, SdbReadDWORDTag)
  18. #pragma alloc_text(PAGE, SdbReadQWORDTag)
  19. #pragma alloc_text(PAGE, SdbReadBYTETagRef)
  20. #pragma alloc_text(PAGE, SdbReadWORDTagRef)
  21. #pragma alloc_text(PAGE, SdbReadDWORDTagRef)
  22. #pragma alloc_text(PAGE, SdbReadQWORDTagRef)
  23. #pragma alloc_text(PAGE, SdbGetTagDataSize)
  24. #pragma alloc_text(PAGE, SdbpGetTagRefDataSize)
  25. #pragma alloc_text(PAGE, SdbpReadTagData)
  26. #pragma alloc_text(PAGE, SdbReadStringTagRef)
  27. #pragma alloc_text(PAGE, SdbpReadBinaryTagRef)
  28. #pragma alloc_text(PAGE, SdbpGetMappedTagData)
  29. #pragma alloc_text(PAGE, SdbpGetStringRefLength)
  30. #pragma alloc_text(PAGE, SdbpReadStringRef)
  31. #pragma alloc_text(PAGE, SdbReadStringTag)
  32. #pragma alloc_text(PAGE, SdbGetStringTagPtr)
  33. #pragma alloc_text(PAGE, SdbpReadStringFromTable)
  34. #pragma alloc_text(PAGE, SdbpGetMappedStringFromTable)
  35. #pragma alloc_text(PAGE, SdbReadBinaryTag)
  36. #pragma alloc_text(PAGE, SdbGetBinaryTagData)
  37. #endif // KERNEL_MODE && ALLOC_PRAGMA
  38. DWORD
  39. SdbpGetTagHeadSize(
  40. PDB pdb, // IN - pdb to use
  41. TAGID tiWhich // IN - record to get info on
  42. )
  43. /*++
  44. Return: The size of the non-data (TAG & SIZE) portion of the record.
  45. Desc: Returns the size of the non-data part of a tag in the DB, which is
  46. to say the tag itself (a WORD), and possibly the size (a DWORD).
  47. So this function will return 2 if the tag has an implied size,
  48. 6 if the tag has a size after it, and 0 if there was an error.
  49. --*/
  50. {
  51. TAG tWhich;
  52. DWORD dwRetOffset;
  53. DWORD dwOffset = (DWORD)tiWhich;
  54. if (!SdbpReadMappedData(pdb, (DWORD)tiWhich, &tWhich, sizeof(TAG))) {
  55. DBGPRINT((sdlError, "SdbpGetTagHeadSize", "Error reading tag.\n"));
  56. return 0;
  57. }
  58. dwRetOffset = sizeof(TAG);
  59. if (GETTAGTYPE(tWhich) >= TAG_TYPE_LIST) {
  60. dwRetOffset += sizeof(DWORD);
  61. }
  62. return dwRetOffset;
  63. }
  64. //
  65. // This macro is used by the *ReadTypeTag primitives.
  66. //
  67. #define READDATATAG(dataType, tagType, dtDefault) \
  68. { \
  69. dataType dtReturn = dtDefault; \
  70. \
  71. assert(pdb); \
  72. \
  73. if (GETTAGTYPE(SdbGetTagFromTagID(pdb, tiWhich)) != tagType) { \
  74. DBGPRINT((sdlError, \
  75. "READDATATAG", \
  76. "TagID 0x%X, Tag 0x%X not of the expected type.\n", \
  77. tiWhich, \
  78. (DWORD)SdbGetTagFromTagID(pdb, tiWhich))); \
  79. return dtDefault; \
  80. } \
  81. \
  82. if (!SdbpReadTagData(pdb, tiWhich, &dtReturn, sizeof(dataType))) { \
  83. return dtDefault; \
  84. } \
  85. \
  86. return dtReturn; \
  87. }
  88. BYTE
  89. SdbReadBYTETag(PDB pdb, TAGID tiWhich, BYTE jDefault)
  90. {
  91. READDATATAG(BYTE, TAG_TYPE_BYTE, jDefault);
  92. }
  93. WORD SdbReadWORDTag(PDB pdb, TAGID tiWhich, WORD wDefault)
  94. {
  95. READDATATAG(WORD, TAG_TYPE_WORD, wDefault);
  96. }
  97. DWORD SdbReadDWORDTag(PDB pdb, TAGID tiWhich, DWORD dwDefault)
  98. {
  99. READDATATAG(DWORD, TAG_TYPE_DWORD, dwDefault);
  100. }
  101. ULONGLONG SdbReadQWORDTag(PDB pdb, TAGID tiWhich, ULONGLONG qwDefault)
  102. {
  103. READDATATAG(ULONGLONG, TAG_TYPE_QWORD, qwDefault);
  104. }
  105. //
  106. // This macro is used by the *ReadTypeTag primitives.
  107. //
  108. #define READTYPETAGREF(fnReadTypeTag, dtDefault) \
  109. { \
  110. PDB pdb; \
  111. TAGID tiWhich; \
  112. \
  113. if (!SdbTagRefToTagID(hSDB, trWhich, &pdb, &tiWhich)) { \
  114. DBGPRINT((sdlError, "READTYPETAGREF", "Can't convert tag ref.\n")); \
  115. return dtDefault; \
  116. } \
  117. \
  118. return fnReadTypeTag(pdb, tiWhich, dtDefault); \
  119. }
  120. BYTE SdbReadBYTETagRef(HSDB hSDB, TAGREF trWhich, BYTE jDefault)
  121. {
  122. READTYPETAGREF(SdbReadBYTETag, jDefault);
  123. }
  124. WORD SdbReadWORDTagRef(HSDB hSDB, TAGREF trWhich, WORD wDefault)
  125. {
  126. READTYPETAGREF(SdbReadWORDTag, wDefault);
  127. }
  128. DWORD SdbReadDWORDTagRef(HSDB hSDB, TAGREF trWhich, DWORD dwDefault)
  129. {
  130. READTYPETAGREF(SdbReadDWORDTag, dwDefault);
  131. }
  132. ULONGLONG SdbReadQWORDTagRef(HSDB hSDB, TAGREF trWhich, ULONGLONG qwDefault)
  133. {
  134. READTYPETAGREF(SdbReadQWORDTag, qwDefault);
  135. }
  136. DWORD
  137. SdbGetTagDataSize(
  138. IN PDB pdb, // DB to use
  139. IN TAGID tiWhich // record to get size of
  140. )
  141. /*++
  142. Return: The size of the data portion of the record.
  143. Desc: Returns the size of the data portion of the given tag, i.e. the
  144. part after the tag WORD and the (possible) size DWORD.
  145. --*/
  146. {
  147. TAG tWhich;
  148. DWORD dwSize;
  149. DWORD dwOffset = (DWORD)tiWhich;
  150. assert(pdb);
  151. tWhich = SdbGetTagFromTagID(pdb, tiWhich);
  152. switch (GETTAGTYPE(tWhich)) {
  153. case TAG_TYPE_NULL:
  154. dwSize = 0;
  155. break;
  156. case TAG_TYPE_BYTE:
  157. dwSize = 1;
  158. break;
  159. case TAG_TYPE_WORD:
  160. dwSize = 2;
  161. break;
  162. case TAG_TYPE_DWORD:
  163. dwSize = 4;
  164. break;
  165. case TAG_TYPE_QWORD:
  166. dwSize = 8;
  167. break;
  168. case TAG_TYPE_STRINGREF:
  169. dwSize = 4;
  170. break;
  171. default:
  172. dwSize = 0;
  173. if (!SdbpReadMappedData(pdb, dwOffset + sizeof(TAG), &dwSize, sizeof(DWORD))) {
  174. DBGPRINT((sdlError, "SdbGetTagDataSize", "Error reading size data\n"));
  175. }
  176. break;
  177. }
  178. return dwSize;
  179. }
  180. DWORD
  181. SdbpGetTagRefDataSize(
  182. IN HSDB hSDB,
  183. IN TAGREF trWhich
  184. )
  185. /*++
  186. Return: The size of the data portion of the record.
  187. Desc: Returns the data size of the tag pointed to by TAGREF.
  188. Useful for finding out how much to allocate before
  189. calling SdbpReadBinaryTagRef.
  190. --*/
  191. {
  192. PDB pdb;
  193. TAGID tiWhich;
  194. try {
  195. if (!SdbTagRefToTagID(hSDB, trWhich, &pdb, &tiWhich)) {
  196. DBGPRINT((sdlError, "SdbpGetTagRefDataSize", "Can't convert tag ref.\n"));
  197. return 0;
  198. }
  199. return SdbGetTagDataSize(pdb, tiWhich);
  200. } except (SHIM_EXCEPT_HANDLER) {
  201. ;
  202. }
  203. return 0;
  204. }
  205. BOOL
  206. SdbpReadTagData(
  207. IN PDB pdb, // DB to use
  208. IN TAGID tiWhich, // record to read
  209. OUT PVOID pBuffer, // buffer to fill
  210. IN DWORD dwBufferSize // size of buffer
  211. )
  212. /*++
  213. Return: TRUE if the data was read, FALSE if not.
  214. Desc: An internal function used to read the data from a tag into a buffer.
  215. It does not check the type of the TAG, and should only be used internally.
  216. --*/
  217. {
  218. DWORD dwOffset;
  219. DWORD dwSize;
  220. assert(pdb && pBuffer);
  221. dwSize = SdbGetTagDataSize(pdb, tiWhich);
  222. if (dwSize > dwBufferSize) {
  223. DBGPRINT((sdlError,
  224. "SdbpReadTagData",
  225. "Buffer too small. Avail: %d, Need: %d.\n",
  226. dwBufferSize,
  227. dwSize));
  228. return FALSE;
  229. }
  230. dwOffset = tiWhich + SdbpGetTagHeadSize(pdb, tiWhich);
  231. if (!SdbpReadMappedData(pdb, dwOffset, pBuffer, dwSize)) {
  232. DBGPRINT((sdlError,
  233. "SdbpReadTagData",
  234. "Error reading tag data.\n"));
  235. return FALSE;
  236. }
  237. return TRUE;
  238. }
  239. BOOL
  240. SdbReadStringTagRef(
  241. IN HSDB hSDB, // handle to the database channel
  242. IN TAGREF trWhich, // string or stringref tag to read
  243. OUT LPTSTR pwszBuffer, // buffer to fill
  244. IN DWORD dwBufferSize // size of passed-in buffer
  245. )
  246. /*++
  247. Return: TRUE if the string was read, FALSE if not.
  248. Desc: Reads a tag of type STRING or STRINGREF into a buffer. If the
  249. type is STRING, the data is read directly from the tag.
  250. If the type is STRINGREF, the string is read from the string
  251. table at the end of the file. Which one it is should be
  252. transparent to the caller.
  253. --*/
  254. {
  255. PDB pdb;
  256. TAGID tiWhich;
  257. try {
  258. if (!SdbTagRefToTagID(hSDB, trWhich, &pdb, &tiWhich)) {
  259. DBGPRINT((sdlError, "SdbReadStringTagRef", "Can't convert tag ref.\n"));
  260. return FALSE;
  261. }
  262. return SdbReadStringTag(pdb, tiWhich, pwszBuffer, dwBufferSize);
  263. } except (SHIM_EXCEPT_HANDLER) {
  264. ;
  265. }
  266. return FALSE;
  267. }
  268. BOOL
  269. SdbpReadBinaryTagRef(
  270. IN HSDB hSDB, // handle to the database channel
  271. IN TAGREF trWhich, // BINARY tag to read
  272. OUT PBYTE pBuffer, // buffer to fill
  273. IN DWORD dwBufferSize // size of passed-in buffer
  274. )
  275. /*++
  276. Return: TRUE if the buffer was read, FALSE if not.
  277. Desc: Reads a tag of type BINARY into pBuffer. Use SdbpGetTagRefDataSize
  278. to get the size of the buffer before calling this routine.
  279. --*/
  280. {
  281. PDB pdb;
  282. TAGID tiWhich;
  283. try {
  284. if (!SdbTagRefToTagID(hSDB, trWhich, &pdb, &tiWhich)) {
  285. DBGPRINT((sdlError, "SdbpReadBinaryTagRef", "Can't convert tag ref.\n"));
  286. return FALSE;
  287. }
  288. return SdbReadBinaryTag(pdb, tiWhich, pBuffer, dwBufferSize);
  289. } except (SHIM_EXCEPT_HANDLER) {
  290. }
  291. return FALSE;
  292. }
  293. PVOID
  294. SdbpGetMappedTagData(
  295. IN PDB pdb, // DB to use
  296. IN TAGID tiWhich // record to read
  297. )
  298. /*++
  299. Return: The data pointer or NULL on failure.
  300. Desc: An internal function used to get a pointer to the tag data.
  301. It works only if the DB is mapped.
  302. --*/
  303. {
  304. PVOID pReturn;
  305. DWORD dwOffset;
  306. assert(pdb);
  307. dwOffset = tiWhich + SdbpGetTagHeadSize(pdb, tiWhich);
  308. pReturn = SdbpGetMappedData(pdb, dwOffset);
  309. if (pReturn == NULL) {
  310. DBGPRINT((sdlError, "SdbpGetMappedTagData", "Error getting ptr to tag data.\n"));
  311. }
  312. return pReturn;
  313. }
  314. DWORD
  315. SdbpGetStringRefLength(
  316. IN HSDB hSDB,
  317. IN TAGREF trString
  318. )
  319. /*++
  320. Return: BUGBUG: ?
  321. Desc: BUGBUG: ?
  322. --*/
  323. {
  324. PDB pdb = NULL;
  325. TAGID tiString = TAGID_NULL;
  326. DWORD dwLength = 0;
  327. LPCTSTR lpszString;
  328. if (!SdbTagRefToTagID(hSDB, trString, &pdb, &tiString)) {
  329. DBGPRINT((sdlError,
  330. "SdbGetStringRefLength",
  331. "Failed to convert tag 0x%x to tagid\n",
  332. trString));
  333. return dwLength;
  334. }
  335. lpszString = SdbGetStringTagPtr(pdb, tiString);
  336. if (lpszString != NULL) {
  337. dwLength = _tcslen(lpszString);
  338. }
  339. return dwLength;
  340. }
  341. LPCTSTR
  342. SdbpGetStringRefPtr(
  343. IN HSDB hSDB,
  344. IN TAGREF trString
  345. )
  346. {
  347. PDB pdb = NULL;
  348. TAGID tiString = TAGID_NULL;
  349. if (!SdbTagRefToTagID(hSDB, trString, &pdb, &tiString)) {
  350. DBGPRINT((sdlError, "SdbGetStringRefPtr",
  351. "Failed to convert tag 0x%x to tagid\n", trString));
  352. return NULL;
  353. }
  354. return SdbGetStringTagPtr(pdb, tiString);
  355. }
  356. STRINGREF
  357. SdbpReadStringRef(
  358. IN PDB pdb, // PDB to use
  359. IN TAGID tiWhich // record of type STRINGREF
  360. )
  361. /*++
  362. Return: Returns the stringref, or STRINGREF_NULL on failure.
  363. Desc: Used to read a stringref tag directly; normally one would just read
  364. it like a string, and let the DB fix up string refs. But a low-level
  365. tool may need to know exactly what it's reading.
  366. --*/
  367. {
  368. STRINGREF srReturn = STRINGREF_NULL;
  369. assert(pdb);
  370. if (GETTAGTYPE(SdbGetTagFromTagID(pdb, tiWhich)) != TAG_TYPE_STRINGREF) {
  371. DBGPRINT((sdlError,
  372. "SdbpReadStringRef",
  373. "TagID 0x%08X, Tag %04X not STRINGREF type.\n",
  374. tiWhich,
  375. (DWORD)SdbGetTagFromTagID(pdb, tiWhich)));
  376. return STRINGREF_NULL;
  377. }
  378. if (!SdbpReadTagData(pdb, tiWhich, &srReturn, sizeof(STRINGREF))) {
  379. DBGPRINT((sdlError, "SdbpReadStringRef", "Error reading data.\n"));
  380. return STRINGREF_NULL;
  381. }
  382. return srReturn;
  383. }
  384. BOOL
  385. SdbReadStringTag(
  386. IN PDB pdb, // DB to use
  387. IN TAGID tiWhich, // record of type STRING or STRINGREF
  388. OUT LPTSTR pwszBuffer, // buffer to fill
  389. IN DWORD dwBufferSize // size in characters of buffer (leave room for zero!)
  390. )
  391. /*++
  392. Return: TRUE if successful, or FALSE if the string can't be found or the
  393. buffer is too small.
  394. Desc: Reads a string from the DB into szBuffer. If the tag is of
  395. type STRING, the string is just read from the data portion of
  396. the tag. If the tag is of type STRINGREF, the db reads the STRINGREF,
  397. then uses it to read the string from the string table at the end of
  398. the file. Either way, it's transparent to the caller.
  399. --*/
  400. {
  401. TAG tWhich;
  402. BOOL bSuccess;
  403. assert(pdb && pwszBuffer);
  404. tWhich = SdbGetTagFromTagID(pdb, tiWhich);
  405. if (GETTAGTYPE(tWhich) == TAG_TYPE_STRING) {
  406. //
  407. // Read an actual string.
  408. //
  409. return(READ_STRING(pdb, tiWhich, pwszBuffer, dwBufferSize));
  410. } else if (GETTAGTYPE(tWhich) == TAG_TYPE_STRINGREF) {
  411. //
  412. // Read a string reference, then get the string out of the table
  413. //
  414. STRINGREF srWhich = SdbpReadStringRef(pdb, tiWhich);
  415. if (srWhich == 0) {
  416. DBGPRINT((sdlError, "SdbReadStringTag", "Error getting StringRef.\n"));
  417. return FALSE;
  418. }
  419. return SdbpReadStringFromTable(pdb, srWhich, pwszBuffer, dwBufferSize);
  420. }
  421. //
  422. // This ain't no kind of string at all
  423. //
  424. return FALSE;
  425. }
  426. LPTSTR
  427. SdbGetStringTagPtr(
  428. IN PDB pdb, // DB to use
  429. IN TAGID tiWhich // record of type STRING or STRINGREF
  430. )
  431. /*++
  432. Return: Returns a pointer if successful, or NULL if the string can't be found.
  433. Desc: Gets a pointer to the string. If the tag is of type STRING,
  434. the string is just obtained from the data portion of the tag.
  435. If the tag is of type STRINGREF, the db reads the STRINGREF,
  436. then uses it to get the string from the string table at the end
  437. of the file. Either way, it's transparent to the caller.
  438. --*/
  439. {
  440. TAG tWhich;
  441. LPTSTR pszReturn = NULL;
  442. assert(pdb);
  443. tWhich = SdbGetTagFromTagID(pdb, tiWhich);
  444. if (GETTAGTYPE(tWhich) == TAG_TYPE_STRING) {
  445. //
  446. // Read an actual string.
  447. //
  448. pszReturn = CONVERT_STRINGPTR(pdb,
  449. SdbpGetMappedTagData(pdb, tiWhich),
  450. TAG_TYPE_STRING,
  451. tiWhich);
  452. } else if (GETTAGTYPE(tWhich) == TAG_TYPE_STRINGREF) {
  453. //
  454. // Read a string reference, then get the string out of the table.
  455. //
  456. STRINGREF srWhich = SdbpReadStringRef(pdb, tiWhich);
  457. if (srWhich == 0) {
  458. DBGPRINT((sdlError, "SdbReadStringTag", "Error getting StringRef.\n"));
  459. return NULL;
  460. }
  461. pszReturn = CONVERT_STRINGPTR(pdb,
  462. SdbpGetMappedStringFromTable(pdb, srWhich),
  463. TAG_TYPE_STRINGREF,
  464. srWhich);
  465. }
  466. //
  467. // This ain't no kind of string at all.
  468. //
  469. return pszReturn;
  470. }
  471. BOOL
  472. SdbpReadStringFromTable(
  473. IN PDB pdb, // DB to use
  474. IN STRINGREF srData, // STRINGREF to get
  475. OUT LPTSTR szBuffer, // buffer to fill
  476. IN DWORD dwBufferSize // size of buffer
  477. )
  478. /*++
  479. Return: TRUE if the string was read, FALSE if not.
  480. Desc: Reads a string out of the string table, given a STRINGREF.
  481. The STRINGREF is a direct offset from the beginning of the
  482. STRINGTABLE tag that should exist at the end of the db.
  483. --*/
  484. {
  485. TAGID tiWhich;
  486. TAG tWhich;
  487. PDB pdbString = NULL;
  488. assert(pdb && srData && szBuffer);
  489. if (pdb->bWrite) {
  490. //
  491. // When we're writing, the string table is in a separate DB.
  492. //
  493. if (!pdb->pdbStringTable) {
  494. DBGPRINT((sdlError, "SdbpReadStringFromTable", "No stringtable in DB.\n"));
  495. return FALSE;
  496. }
  497. //
  498. // Adjust for the slightly different offsets in the other DB.
  499. //
  500. tiWhich = srData - sizeof(TAG) - sizeof(DWORD) + sizeof(DB_HEADER);
  501. pdbString = pdb->pdbStringTable;
  502. } else {
  503. //
  504. // The STRINGREF is an offset from the beginning of the string table.
  505. //
  506. if (pdb->tiStringTable == TAGID_NULL) {
  507. pdb->tiStringTable = SdbFindFirstTag(pdb, TAGID_ROOT, TAG_STRINGTABLE);
  508. if (pdb->tiStringTable == TAGID_NULL) {
  509. DBGPRINT((sdlError, "SdbpReadStringFromTable", "No stringtable in DB.\n"));
  510. return FALSE;
  511. }
  512. }
  513. tiWhich = pdb->tiStringTable + srData;
  514. pdbString = pdb;
  515. }
  516. tWhich = SdbGetTagFromTagID(pdbString, tiWhich);
  517. if (tWhich != TAG_STRINGTABLE_ITEM) {
  518. DBGPRINT((sdlError, "SdbpReadStringFromTable", "Pulled out a non-stringtable item.\n"));
  519. return FALSE;
  520. }
  521. return READ_STRING(pdbString, tiWhich, szBuffer, dwBufferSize);
  522. }
  523. WCHAR*
  524. SdbpGetMappedStringFromTable(
  525. IN PDB pdb, // DB to use
  526. IN STRINGREF srData // STRINGREF to get
  527. )
  528. /*++
  529. Return: A pointer to a string or NULL.
  530. Desc: Gets a pointer to a string in the string table, given a STRINGREF.
  531. The STRINGREF is a direct offset from the beginning of the STRINGTABLE
  532. tag that should exist at the end of the db.
  533. --*/
  534. {
  535. TAGID tiWhich;
  536. TAG tWhich;
  537. PDB pdbString = NULL;
  538. assert(pdb && srData);
  539. if (pdb->bWrite) {
  540. //
  541. // When we're writing, the string table is in a separate DB.
  542. //
  543. if (pdb->pdbStringTable == NULL) {
  544. DBGPRINT((sdlError, "SdbpGetMappedStringFromTable", "No stringtable in DB.\n"));
  545. return NULL;
  546. }
  547. //
  548. // Adjust for the slightly different offsets in the other DB
  549. //
  550. tiWhich = srData - sizeof(TAG) - sizeof(DWORD) + sizeof(DB_HEADER);
  551. pdbString = pdb->pdbStringTable;
  552. } else {
  553. if (pdb->tiStringTable == TAGID_NULL) {
  554. pdb->tiStringTable = SdbFindFirstTag(pdb, TAGID_ROOT, TAG_STRINGTABLE);
  555. if (pdb->tiStringTable == TAGID_NULL) {
  556. DBGPRINT((sdlError, "SdbpGetMappedStringFromTable", "No stringtable in DB.\n"));
  557. return NULL;
  558. }
  559. }
  560. //
  561. // The STRINGREF is an offset from the beginning of the string table.
  562. //
  563. tiWhich = pdb->tiStringTable + srData;
  564. pdbString = pdb;
  565. }
  566. tWhich = SdbGetTagFromTagID(pdbString, tiWhich);
  567. if (tWhich != TAG_STRINGTABLE_ITEM) {
  568. DBGPRINT((sdlError,
  569. "SdbpGetMappedStringFromTable",
  570. "Pulled out a non-stringtable item.\n"));
  571. return NULL;
  572. }
  573. return (WCHAR*)SdbpGetMappedTagData(pdbString, tiWhich);
  574. }
  575. BOOL
  576. SdbReadBinaryTag(
  577. IN PDB pdb, // DB to use
  578. IN TAGID tiWhich, // record of BASIC TYPE BINARY
  579. OUT PBYTE pBuffer, // buffer to fill
  580. IN DWORD dwBufferSize // buffer size
  581. )
  582. /*++
  583. Return: TRUE if the data was read, FALSE if not.
  584. Desc: Reads data from a tag of type BINARY into pBuffer.
  585. Returns FALSE if the tag is not type BINARY, or the buffer is too small.
  586. --*/
  587. {
  588. assert(pdb);
  589. if (GETTAGTYPE(SdbGetTagFromTagID(pdb, tiWhich)) != TAG_TYPE_BINARY) {
  590. DBGPRINT((sdlError,
  591. "SdbReadBinaryTag",
  592. "TagID 0x%08X, Tag %04X not BINARY type.\n",
  593. tiWhich,
  594. (DWORD)SdbGetTagFromTagID(pdb, tiWhich)));
  595. return FALSE;
  596. }
  597. if (!SdbpReadTagData(pdb, tiWhich, pBuffer, dwBufferSize)) {
  598. DBGPRINT((sdlError, "SdbReadBinaryTag", "Error reading buffer.\n"));
  599. return FALSE;
  600. }
  601. return TRUE;
  602. }
  603. PVOID
  604. SdbGetBinaryTagData(
  605. IN PDB pdb, // pointer to the database to use
  606. IN TAGID tiWhich // tagid of the binary tag
  607. )
  608. /*++
  609. Return: pointer to the binary data referenced by tiWhich or NULL if
  610. tiWhich does not refer to the binary tag or if tiWhich is invalid.
  611. Desc: Function returns pointer to the [mapped] binary data referred to by
  612. tiWhich parameter in the database pdb.
  613. --*/
  614. {
  615. assert(pdb);
  616. if (GETTAGTYPE(SdbGetTagFromTagID(pdb, tiWhich)) != TAG_TYPE_BINARY) {
  617. DBGPRINT((sdlError,
  618. "SdbGetBinaryTagData",
  619. "TagID 0x%08X, Tag %04X not BINARY type.\n",
  620. tiWhich,
  621. (DWORD)SdbGetTagFromTagID(pdb, tiWhich)));
  622. return NULL;
  623. }
  624. return SdbpGetMappedTagData(pdb, tiWhich);
  625. }