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.

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