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.

1027 lines
22 KiB

  1. /*++
  2. * File name:
  3. * bmpdb.c
  4. * Contents:
  5. * Bitmap database manager
  6. * Almost all functions ARE NOT thread safe
  7. *
  8. * Copyright (C) 1998-1999 Microsoft Corp.
  9. --*/
  10. #include <windows.h>
  11. #include <io.h>
  12. #include <fcntl.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include <string.h>
  16. #include <stdio.h>
  17. #include <malloc.h>
  18. #include "bmpdb.h"
  19. #pragma warning(disable:4706) // assignment within conditional expression
  20. #define DB_NAME "bmpcache.db" // Database name
  21. #define TEMPDB_NAME "bmpcache.tmp" // Temp file, used to recopy the database
  22. // Global data
  23. int g_hDB = 0; // Handle to the opened database
  24. int g_hTempDB; // Temp handle
  25. BOOL g_bNeedToPack; // True if some entrys are deleted
  26. /*
  27. * Internal functions definition
  28. --*/
  29. void _PackDB(void);
  30. /*++
  31. * Function:
  32. * OpenDB
  33. * Description:
  34. * Opens and initializes the database
  35. * Arguments:
  36. * bWrite - TRUE if the caller wants to write in the database
  37. * Return value:
  38. * TRUE on success
  39. * Called by:
  40. * InitCache
  41. --*/
  42. BOOL OpenDB(BOOL bWrite)
  43. {
  44. int hFile, rv = TRUE;
  45. int oflag;
  46. if (g_hDB)
  47. // Already initialized
  48. goto exitpt;
  49. oflag = (bWrite)?_O_RDWR|_O_CREAT:_O_RDONLY;
  50. hFile = _open(DB_NAME, oflag|_O_BINARY, _S_IREAD|_S_IWRITE);
  51. if (hFile == -1)
  52. rv = FALSE;
  53. else
  54. g_hDB = hFile;
  55. g_bNeedToPack = FALSE;
  56. exitpt:
  57. return rv;
  58. }
  59. /*++
  60. * Function:
  61. * CloseDB
  62. * Description:
  63. * Closes the database deletes entry if necessary
  64. * Called by:
  65. * DeleteCache
  66. --*/
  67. VOID CloseDB(VOID)
  68. {
  69. if (!g_hDB)
  70. goto exitpt;
  71. if (g_bNeedToPack)
  72. _PackDB();
  73. else
  74. _close(g_hDB);
  75. g_hDB = 0;
  76. exitpt:
  77. ;
  78. }
  79. /*++
  80. * Function:
  81. * ReadGroup (Thread dependent)
  82. * Description:
  83. * Read the structure which represents
  84. * a bitmap group with the same IDs
  85. * Arguments:
  86. * nOffset - offset in the DB file
  87. * pGroup - pointer to the result
  88. * Return value:
  89. * TRUE on success
  90. * Called by:
  91. * internaly
  92. --*/
  93. BOOL ReadGroup(FOFFSET nOffset, PGROUPENTRY pGroup)
  94. {
  95. int rv = FALSE;
  96. if (!g_hDB)
  97. goto exitpt;
  98. if (_lseek(g_hDB, nOffset, SEEK_SET) != nOffset)
  99. goto exitpt;
  100. if (_read(g_hDB, pGroup, sizeof(*pGroup)) != sizeof(*pGroup))
  101. goto exitpt;
  102. rv = TRUE;
  103. exitpt:
  104. return rv;
  105. }
  106. /*++
  107. * Function:
  108. * WriteGroup (Thread dep)
  109. * Description:
  110. * Writes GROUPENTRY in the DB file
  111. * Arguments:
  112. * nOffset - where to store
  113. * pGroup - what to store
  114. * Return value:
  115. * TRUE on success
  116. * Called by:
  117. * internaly
  118. --*/
  119. BOOL WriteGroup(FOFFSET nOffset, PGROUPENTRY pGroup)
  120. {
  121. BOOL rv = FALSE;
  122. if (!g_hDB || !pGroup)
  123. goto exitpt;
  124. if (_lseek(g_hDB, nOffset, SEEK_SET) != nOffset)
  125. goto exitpt;
  126. if (_write(g_hDB, pGroup, sizeof(*pGroup)) != sizeof(*pGroup))
  127. goto exitpt;
  128. rv = TRUE;
  129. exitpt:
  130. return rv;
  131. }
  132. /*++
  133. * Function:
  134. * EnumerateGroups (thread dep)
  135. * Description:
  136. * Enumerates all groups from the DB
  137. * Arguments:
  138. * pfnEnumGrpProc - Callback function
  139. * pParam - Parameter passed to the callback
  140. * Called by:
  141. * internaly
  142. --*/
  143. VOID EnumerateGroups(PFNENUMGROUPS pfnEnumGrpProc, PVOID pParam)
  144. {
  145. GROUPENTRY Group;
  146. BOOL bRun;
  147. FOFFSET nOffs = 0;
  148. bRun = ReadGroup(nOffs, &Group);
  149. while(bRun) {
  150. if (!Group.bDeleted)
  151. bRun = pfnEnumGrpProc(nOffs, &Group, pParam) &&
  152. (Group.FOffsNext != 0);
  153. if (bRun)
  154. {
  155. nOffs = Group.FOffsNext;
  156. if (nOffs)
  157. bRun = ReadGroup(nOffs, &Group);
  158. else
  159. bRun = FALSE;
  160. }
  161. }
  162. }
  163. /*++
  164. * Function:
  165. * ReadBitmapHeader (Thread dep)
  166. * Description:
  167. * Read only the header of the bitmap
  168. * Arguments:
  169. * nOffset - where in the file
  170. * pBitmap - returned structure
  171. * Return value:
  172. * TRUE on success
  173. * Called by:
  174. * Internaly
  175. --*/
  176. BOOL ReadBitmapHeader(FOFFSET nOffset, PBMPENTRY pBitmap)
  177. {
  178. BOOL rv = FALSE;
  179. if (!g_hDB || !pBitmap)
  180. goto exitpt;
  181. if (_lseek(g_hDB, nOffset, SEEK_SET) != nOffset)
  182. goto exitpt;
  183. if (_read(g_hDB, pBitmap, sizeof(*pBitmap)) != sizeof(*pBitmap))
  184. goto exitpt;
  185. rv = TRUE;
  186. exitpt:
  187. return rv;
  188. }
  189. /*++
  190. * Function:
  191. * WriteBitmapHeader (Thread dep)
  192. * Description:
  193. * Writes only the bitmap header
  194. * Arguments:
  195. * nOffset - where to store
  196. * pBitmap - what to store
  197. * Return value:
  198. * TRUE on success
  199. * Called by:
  200. * internaly
  201. --*/
  202. BOOL WriteBitmapHeader(FOFFSET nOffset, PBMPENTRY pBitmap)
  203. {
  204. BOOL rv = FALSE;
  205. if (!g_hDB || !pBitmap)
  206. goto exitpt;
  207. if (_lseek(g_hDB, nOffset, SEEK_SET) != nOffset)
  208. goto exitpt;
  209. if (_write(g_hDB, pBitmap, sizeof(*pBitmap)) != sizeof(*pBitmap))
  210. goto exitpt;
  211. rv = TRUE;
  212. exitpt:
  213. return rv;
  214. }
  215. /*++
  216. * Function:
  217. * ReadBitmap (Thread dependent)
  218. * Description:
  219. * Read the whole bitmap and allocates memory for it
  220. * Arguments:
  221. * nOffset - from where
  222. * Return value:
  223. * Pointer to the result, NULL on error
  224. * Called by:
  225. * internaly
  226. --*/
  227. PBMPENTRY ReadBitmap(FOFFSET nOffset)
  228. {
  229. PBMPENTRY rv = NULL;
  230. if (!g_hDB)
  231. goto exitpt;
  232. rv = (PBMPENTRY) malloc(sizeof(*rv));
  233. if (rv)
  234. {
  235. rv->pData = NULL;
  236. if (!ReadBitmapHeader(nOffset, rv))
  237. goto exitpt1;
  238. rv->pData = malloc(rv->nDataSize);
  239. if (rv->pData &&
  240. _read(g_hDB, rv->pData, rv->nDataSize) != (long)rv->nDataSize)
  241. {
  242. goto exitpt1;
  243. }
  244. }
  245. exitpt:
  246. return rv;
  247. exitpt1:
  248. if (rv)
  249. {
  250. if (rv->pData)
  251. free(rv->pData);
  252. free(rv);
  253. }
  254. return NULL;
  255. }
  256. /*++
  257. * Function:
  258. * FreeBitmap
  259. * Description:
  260. * Frees the resources allocated in ReadBitmap
  261. * Arguments:
  262. * pBmp - The bitmap
  263. * Called by:
  264. * internaly
  265. --*/
  266. VOID FreeBitmap(PBMPENTRY pBmp)
  267. {
  268. if (pBmp)
  269. {
  270. if (pBmp->pData)
  271. free(pBmp->pData);
  272. free(pBmp);
  273. }
  274. }
  275. /*++
  276. * Function:
  277. * EnumerateBitmaps
  278. * Description:
  279. * Enumaretes all bitmaps within a group
  280. * Arguments:
  281. * nOffset - Location
  282. * pfnEnumProc - Callback
  283. * pParam - callback parameter
  284. * Called by:
  285. * internaly
  286. --*/
  287. VOID EnumerateBitmaps(FOFFSET nOffset, PFNENUMBITMAPS pfnEnumProc, PVOID pParam)
  288. {
  289. PBMPENTRY pBmp;
  290. BOOL bRun = TRUE;
  291. while(bRun && nOffset && (pBmp = ReadBitmap(nOffset)))
  292. {
  293. if (!pBmp->bDeleted)
  294. bRun = pfnEnumProc(nOffset, pBmp, pParam);
  295. nOffset = pBmp->FOffsNext;
  296. FreeBitmap(pBmp);
  297. }
  298. }
  299. /*++
  300. * Function:
  301. * FindGroup
  302. * Description:
  303. * Retrieves a group by ID
  304. * Arguments:
  305. * szWText - the ID
  306. * Return value:
  307. * Group location, -1 on error
  308. --*/
  309. FOFFSET FindGroup(LPWSTR szWText)
  310. {
  311. GROUPENTRY Group;
  312. BOOL bRun;
  313. FOFFSET rv = 0;
  314. bRun = ReadGroup(0, &Group);
  315. while(bRun)
  316. {
  317. if (!Group.bDeleted && !wcscmp(Group.WText, szWText))
  318. break;
  319. if (!Group.FOffsNext)
  320. bRun = FALSE;
  321. else
  322. {
  323. rv = Group.FOffsNext;
  324. bRun = ReadGroup(Group.FOffsNext, &Group);
  325. }
  326. }
  327. if (!bRun)
  328. rv = -1;
  329. return rv;
  330. }
  331. /*++
  332. * Function:
  333. * FindBitmap
  334. * Description:
  335. * Finds a bitmap by ID and comment
  336. * Arguments:
  337. * szWText - ID
  338. * szComment - the comment
  339. * Return value:
  340. * The location of the bitmap, -1 on error
  341. --*/
  342. FOFFSET FindBitmap(LPWSTR szWText, char *szComment)
  343. {
  344. FOFFSET nGrpOffs, nBmpOffs;
  345. GROUPENTRY group;
  346. BMPENTRY Bitmap;
  347. FOFFSET rv = -1;
  348. BOOL bRun;
  349. if ((nGrpOffs = FindGroup(szWText)) == -1)
  350. goto exitpt;
  351. if (!ReadGroup(nGrpOffs, &group))
  352. goto exitpt;
  353. nBmpOffs = group.FOffsBmp;
  354. bRun = TRUE;
  355. while(bRun)
  356. {
  357. bRun = ReadBitmapHeader(nBmpOffs, &Bitmap);
  358. if (bRun)
  359. {
  360. if (!Bitmap.bDeleted && !strcmp(Bitmap.szComment, szComment))
  361. break;
  362. nBmpOffs = Bitmap.FOffsNext;
  363. }
  364. }
  365. if (bRun)
  366. rv = nBmpOffs;
  367. exitpt:
  368. return rv;
  369. }
  370. /*++
  371. * Function:
  372. * CheckSum
  373. * Description:
  374. * Calculates a check sum for block of memory
  375. * Helps for bitmaps comapring
  376. * Arguments:
  377. * pData - pointer to the block
  378. * nLen - block size
  379. * Return value:
  380. * the checksum
  381. * Called by:
  382. * AddBitMap, Glyph2String
  383. --*/
  384. UINT
  385. CheckSum(PVOID pData, UINT nLen)
  386. {
  387. UINT nChkSum = 0;
  388. BYTE *pbBlock = (BYTE *)pData;
  389. for(;nLen; nLen--, pbBlock++)
  390. nChkSum += (*pbBlock);
  391. return nChkSum;
  392. }
  393. /*++
  394. * Function:
  395. * AddBitmap (Thread dependent)
  396. * Description:
  397. * Adds a BitMap to the DB
  398. * Arguments:
  399. * pBitmap - the bitmap
  400. * szWText - ID
  401. * Return value:
  402. * TRUE on success
  403. * Called by:
  404. * glyphspy.c
  405. --*/
  406. BOOL AddBitMap(PBMPENTRY pBitmap, LPCWSTR szWText)
  407. {
  408. BMPENTRY bmp;
  409. GROUPENTRY group;
  410. INT_PTR strl;
  411. BOOL rv = FALSE;
  412. FOFFSET lGroupOffs, lBmpOffs;
  413. GROUPENTRY grpTemp;
  414. BMPENTRY bmpTemp;
  415. FOFFSET nOffs;
  416. // PVOID pData;
  417. if (!g_hDB || !pBitmap || !pBitmap->pData || !wcslen(szWText))
  418. goto exitpt;
  419. memset(&group, 0, sizeof(group));
  420. memset(&bmp, 0, sizeof(bmp));
  421. bmp.nDataSize = pBitmap->nDataSize;
  422. bmp.bmiSize = pBitmap->bmiSize;
  423. bmp.bmpSize = pBitmap->bmpSize;
  424. bmp.xSize = pBitmap->xSize;
  425. bmp.ySize = pBitmap->ySize;
  426. bmp.nChkSum = CheckSum(pBitmap->pData, pBitmap->nDataSize);
  427. strcpy(bmp.szComment, pBitmap->szComment);
  428. strl = wcslen(szWText);
  429. if (strl > (sizeof(group.WText) - 1)/sizeof(WCHAR))
  430. strl = (sizeof(group.WText) - 1)/sizeof(WCHAR);
  431. wcsncpy(group.WText, szWText, strl);
  432. group.WText[strl] = 0;
  433. // Create group
  434. if ((lGroupOffs = FindGroup(group.WText)) == -1)
  435. {
  436. // A new group will be created
  437. lGroupOffs = _lseek(g_hDB, 0, SEEK_END);
  438. group.FOffsMe = lGroupOffs;
  439. if (_write(g_hDB, &group, sizeof(group)) != sizeof(group))
  440. {
  441. goto exitpt;
  442. }
  443. // Add this group to the list
  444. if (lGroupOffs)
  445. {
  446. nOffs = 0;
  447. while(ReadGroup(nOffs, &grpTemp) && grpTemp.FOffsNext)
  448. nOffs = grpTemp.FOffsNext;
  449. grpTemp.FOffsNext = lGroupOffs;
  450. if (!WriteGroup(nOffs, &grpTemp))
  451. goto exitpt;
  452. }
  453. } else {
  454. if (ReadGroup(lGroupOffs, &group) == -1)
  455. goto exitpt;
  456. }
  457. // Write the bitmap itself
  458. lBmpOffs = _lseek(g_hDB, 0, SEEK_END);
  459. bmp.FOffsMe = lBmpOffs;
  460. if (_write(g_hDB, &bmp, sizeof(bmp)) != sizeof(bmp))
  461. {
  462. goto exitpt;
  463. }
  464. if (_write(g_hDB, pBitmap->pData, pBitmap->nDataSize) !=
  465. (long)pBitmap->nDataSize)
  466. {
  467. goto exitpt;
  468. }
  469. // Add the bitmap to the list
  470. if (group.FOffsBmp)
  471. {
  472. nOffs = group.FOffsBmp;
  473. // Find end of the list and add
  474. while(ReadBitmapHeader(nOffs, &bmpTemp) && bmpTemp.FOffsNext)
  475. nOffs = bmpTemp.FOffsNext;
  476. bmpTemp.FOffsNext = lBmpOffs;
  477. if (!WriteBitmapHeader(nOffs, &bmpTemp))
  478. goto exitpt;
  479. } else {
  480. // No list add to group pointer
  481. group.FOffsBmp = lBmpOffs;
  482. if (!WriteGroup(lGroupOffs, &group))
  483. goto exitpt;
  484. }
  485. rv = TRUE;
  486. exitpt:
  487. return rv;
  488. }
  489. /*++
  490. * Ascii version of AddBitMap
  491. --*/
  492. BOOL AddBitMapA(PBMPENTRY pBitmap, LPCSTR szAText)
  493. {
  494. WCHAR szWText[MAX_STRING_LENGTH];
  495. BOOL rv = FALSE;
  496. // INT ccAText = strlen(szAText);
  497. if (!strlen(szAText) ||
  498. !MultiByteToWideChar(
  499. CP_ACP,
  500. MB_ERR_INVALID_CHARS,
  501. szAText,
  502. -1,
  503. szWText,
  504. MAX_STRING_LENGTH - 1))
  505. goto exitpt;
  506. rv = AddBitMap(pBitmap, szWText);
  507. exitpt:
  508. return rv;
  509. }
  510. /*++
  511. * Function:
  512. * DeleteBitmapByPointer (Thread dep)
  513. * Description:
  514. * Deletes a bitmap identified by pointer
  515. * Arguments:
  516. * nBmpOffset - the pointer
  517. * Return value:
  518. * TRUE on success
  519. * Called by:
  520. * glyphspy.c
  521. --*/
  522. BOOL DeleteBitmapByPointer(FOFFSET nBmpOffs)
  523. {
  524. BMPENTRY Bitmap;
  525. BOOL rv = FALSE;
  526. if (!g_hDB || !nBmpOffs)
  527. goto exitpt;
  528. if (!ReadBitmapHeader(nBmpOffs, &Bitmap))
  529. goto exitpt;
  530. if (Bitmap.bDeleted)
  531. goto exitpt;
  532. Bitmap.bDeleted = TRUE;
  533. if (!WriteBitmapHeader(nBmpOffs, &Bitmap))
  534. goto exitpt;
  535. g_bNeedToPack = TRUE;
  536. rv = TRUE;
  537. exitpt:
  538. return rv;
  539. }
  540. /*++
  541. * Function:
  542. * DeleteGroupByPointer (Thread dep)
  543. * Description:
  544. * Deletes group with the same ID by pointer
  545. * Arguments:
  546. * nGrpOffs - the pointer
  547. * Return value:
  548. * TRUE on success
  549. * Called by:
  550. * glyphspy.c
  551. --*/
  552. BOOL DeleteGroupByPointer(FOFFSET nGrpOffs)
  553. {
  554. GROUPENTRY Group;
  555. BOOL rv = FALSE;
  556. if (!g_hDB)
  557. goto exitpt;
  558. if (!ReadGroup(nGrpOffs, &Group))
  559. goto exitpt;
  560. if (Group.bDeleted)
  561. goto exitpt;
  562. Group.bDeleted = TRUE;
  563. if (!WriteGroup(nGrpOffs, &Group))
  564. goto exitpt;
  565. g_bNeedToPack = TRUE;
  566. rv = TRUE;
  567. exitpt:
  568. return rv;
  569. }
  570. /*++
  571. * Function:
  572. * DeleteBitmap (Thread dep)
  573. * Description:
  574. * Deletes a bitmap identified by ID and comment
  575. * Arguments:
  576. * szWText - the ID
  577. * szComment - the comment
  578. * Return value:
  579. * TRUE on success
  580. --*/
  581. BOOL DeleteBitmap(LPWSTR szWText, char *szComment)
  582. {
  583. FOFFSET nBmpOffs;
  584. BOOL rv = FALSE;
  585. BMPENTRY Bitmap;
  586. if (!g_hDB)
  587. goto exitpt;
  588. nBmpOffs = FindBitmap(szWText, szComment);
  589. if (nBmpOffs == -1)
  590. goto exitpt;
  591. if (!ReadBitmapHeader(nBmpOffs, &Bitmap))
  592. goto exitpt;
  593. if (Bitmap.bDeleted)
  594. goto exitpt;
  595. Bitmap.bDeleted = TRUE;
  596. if (!WriteBitmapHeader(nBmpOffs, &Bitmap))
  597. goto exitpt;
  598. g_bNeedToPack = TRUE;
  599. rv = TRUE;
  600. exitpt:
  601. return rv;
  602. }
  603. /*++
  604. * Function:
  605. * _PackDB (Thread dep)
  606. * Description:
  607. * Copies the all database in new file removing
  608. * the deleted entrys
  609. * If it fails leaves the old file
  610. * Called by:
  611. * CloseDB
  612. --*/
  613. void _PackDB(void)
  614. {
  615. GROUPENTRY group;
  616. FOFFSET lGrpOffs = 0;
  617. FOFFSET lBmpOffs;
  618. if (!g_bNeedToPack)
  619. goto exitpt;
  620. g_hTempDB = _open(TEMPDB_NAME,
  621. _O_RDWR|_O_TRUNC|_O_CREAT|_O_BINARY,
  622. _S_IREAD|_S_IWRITE);
  623. if (g_hTempDB == -1)
  624. goto exitpt;
  625. do {
  626. if (!ReadGroup(lGrpOffs, &group))
  627. goto exitpt;
  628. if (!group.bDeleted)
  629. {
  630. lBmpOffs = group.FOffsBmp;
  631. while(lBmpOffs)
  632. {
  633. BMPENTRY Bitmap;
  634. if (!ReadBitmapHeader(lBmpOffs, &Bitmap))
  635. goto exitpt;
  636. if (!Bitmap.bDeleted)
  637. {
  638. PBMPENTRY pBmp = ReadBitmap(lBmpOffs);
  639. if (pBmp)
  640. {
  641. int hSwap;
  642. hSwap = g_hDB;
  643. g_hDB = g_hTempDB;
  644. g_hTempDB = hSwap;
  645. AddBitMap(pBmp,
  646. group.WText);
  647. hSwap = g_hDB;
  648. g_hDB = g_hTempDB;
  649. g_hTempDB = hSwap;
  650. FreeBitmap(pBmp);
  651. }
  652. }
  653. lBmpOffs = Bitmap.FOffsNext;
  654. }
  655. }
  656. lGrpOffs = group.FOffsNext;
  657. } while (lGrpOffs);
  658. _close(g_hTempDB);
  659. _close(g_hDB);
  660. remove(DB_NAME);
  661. rename(TEMPDB_NAME, DB_NAME);
  662. exitpt:
  663. ;
  664. }
  665. /*++
  666. * Function:
  667. * _CollectGroups (Thread dep)
  668. * Description:
  669. * Callback function wich collects all groups
  670. * from the database in linked list
  671. * Arguments:
  672. * nOffs - pointer to group record in the database
  673. * pGroup - ghe group
  674. * ppList - the list
  675. * Return value:
  676. * TRUE on success
  677. * Called by:
  678. * GetGroupList thru EnumerateGroups
  679. --*/
  680. BOOL _cdecl _CollectGroups(FOFFSET nOffs,
  681. PGROUPENTRY pGroup,
  682. PGROUPENTRY *ppList)
  683. {
  684. BOOL rv = FALSE;
  685. PGROUPENTRY pNewGrp, pIter, pPrev;
  686. UNREFERENCED_PARAMETER(nOffs);
  687. if (!pGroup)
  688. goto exitpt;
  689. pNewGrp = (PGROUPENTRY) malloc(sizeof(*pNewGrp));
  690. if (!pNewGrp)
  691. goto exitpt;
  692. memcpy(pNewGrp, pGroup, sizeof(*pNewGrp));
  693. // Add to the end of the queue
  694. pNewGrp->pNext = NULL;
  695. pPrev = NULL;
  696. pIter = *ppList;
  697. while(pIter)
  698. {
  699. pPrev = pIter;
  700. pIter = pIter->pNext;
  701. }
  702. if (pPrev)
  703. pPrev->pNext = pNewGrp;
  704. else
  705. (*ppList) = pNewGrp;
  706. rv = TRUE;
  707. exitpt:
  708. return rv;
  709. }
  710. /*++
  711. * Function:
  712. * GetGroupList
  713. * Description:
  714. * Gets all groups from the database
  715. * Return value:
  716. * linked list
  717. * Called by:
  718. * InitCache, glyphspy.c
  719. --*/
  720. PGROUPENTRY GetGroupList(VOID)
  721. {
  722. PGROUPENTRY pList = NULL;
  723. EnumerateGroups( (PFNENUMGROUPS) _CollectGroups, &pList);
  724. return pList;
  725. }
  726. /*++
  727. * Function:
  728. * FreeGroupList
  729. * Description:
  730. * Frees the list allocated in GetGroupList
  731. * Arguments:
  732. * pList - the list
  733. * Called by:
  734. * DeleteCache, glyphspy.c
  735. --*/
  736. VOID FreeGroupList(PGROUPENTRY pList)
  737. {
  738. PGROUPENTRY pTmp, pIter = pList;
  739. while(pIter)
  740. {
  741. pTmp = pIter;
  742. pIter = pIter->pNext;
  743. free(pTmp);
  744. }
  745. }
  746. /*++
  747. * Function:
  748. * _CollectBitmaps (thread dep)
  749. * Description:
  750. * collects bitmaps in linked list
  751. * Arguments:
  752. * nOffs - pointer in the file
  753. * pBitmap - the bitmap
  754. * ppList - the list
  755. * Return value:
  756. * TRUE on success
  757. * Called by:
  758. * GetBitmapList thru EnumerateBitmaps
  759. --*/
  760. BOOL _cdecl _CollectBitmaps(FOFFSET nOffs,PBMPENTRY pBitmap, PBMPENTRY *ppList)
  761. {
  762. BOOL rv = FALSE;
  763. PBMPENTRY pNewBmp, pIter, pPrev;
  764. UNREFERENCED_PARAMETER(nOffs);
  765. if (!pBitmap)
  766. goto exitpt;
  767. pNewBmp = (PBMPENTRY) malloc(sizeof(*pNewBmp));
  768. if (!pNewBmp)
  769. goto exitpt;
  770. memcpy(pNewBmp, pBitmap, sizeof(*pNewBmp));
  771. if (pNewBmp->nDataSize)
  772. {
  773. pNewBmp->pData = malloc(pNewBmp->nDataSize);
  774. if (!pNewBmp->pData)
  775. goto exitpt1;
  776. memcpy(pNewBmp->pData, pBitmap->pData, pNewBmp->nDataSize);
  777. } else
  778. pNewBmp->pData = NULL;
  779. // Add to the end of the queue
  780. pNewBmp->pNext = NULL;
  781. pPrev = NULL;
  782. pIter = *ppList;
  783. while(pIter)
  784. {
  785. pPrev = pIter;
  786. pIter = pIter->pNext;
  787. }
  788. if (pPrev)
  789. pPrev->pNext = pNewBmp;
  790. else
  791. (*ppList) = pNewBmp;
  792. rv = TRUE;
  793. exitpt:
  794. return rv;
  795. exitpt1:
  796. free(pNewBmp);
  797. return FALSE;
  798. }
  799. /*++
  800. * Function:
  801. * GetBitmapList (thread dep)
  802. * Description:
  803. * Gets all bitmaps within a group
  804. * Return value:
  805. * linked list
  806. * Called by:
  807. * Glyph2String, BitmapCacheLookup, glyphspy.c
  808. --*/
  809. PBMPENTRY GetBitmapList(HDC hDC, FOFFSET nOffs)
  810. {
  811. PBMPENTRY pList = NULL;
  812. PBMPENTRY pIter;
  813. EnumerateBitmaps(nOffs, (PFNENUMBITMAPS) _CollectBitmaps, &pList);
  814. pIter = pList;
  815. while(pIter)
  816. {
  817. // Create bitmaps if needed
  818. if (hDC)
  819. {
  820. if (!pIter->bmiSize)
  821. pIter->hBitmap =
  822. CreateBitmap(pIter->xSize,
  823. pIter->ySize,
  824. 1, 1,
  825. pIter->pData);
  826. else {
  827. pIter->hBitmap =
  828. CreateDIBitmap(hDC,
  829. (BITMAPINFOHEADER *)
  830. pIter->pData,
  831. CBM_INIT,
  832. ((BYTE *)(pIter->pData)) + pIter->bmiSize,
  833. (BITMAPINFO *)
  834. pIter->pData,
  835. DIB_PAL_COLORS);
  836. DeleteDC(hDC);
  837. }
  838. } else
  839. pIter->hBitmap = NULL;
  840. pIter = pIter->pNext;
  841. }
  842. return pList;
  843. }
  844. /*++
  845. * Function:
  846. * FreeBitmapList
  847. * Description:
  848. * Deletes resources allocated by GetBitmapList
  849. * Arguments:
  850. * pList - the list
  851. * Called by:
  852. * DeleteCache, glyphspy.c
  853. --*/
  854. VOID FreeBitmapList(PBMPENTRY pList)
  855. {
  856. PBMPENTRY pTmp, pIter = pList;
  857. while(pIter)
  858. {
  859. pTmp = pIter;
  860. pIter = pIter->pNext;
  861. if (pTmp->hBitmap)
  862. DeleteObject(pTmp->hBitmap);
  863. if ( pTmp->pData )
  864. free( pTmp->pData );
  865. free(pTmp);
  866. }
  867. }