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.

1131 lines
16 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. xbf.cxx
  5. Abstract:
  6. Classes to handle extensible buffers
  7. Author:
  8. Philippe Choquier (phillich) 17-oct-1996
  9. --*/
  10. #include <windows.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <mbstring.h>
  14. #include "lbxbf.hxx"
  15. //
  16. // Global functions
  17. //
  18. BOOL
  19. Unserialize(
  20. LPBYTE* ppB,
  21. LPDWORD pC,
  22. LPDWORD pU
  23. )
  24. /*++
  25. Routine Description:
  26. Unserialize a DWORD
  27. pU is updated with DWORD from *ppB, ppB & pC are updated
  28. Arguments:
  29. ppB - ptr to addr of buffer
  30. pC - ptr to byte count in buffer
  31. pU - ptr to DWORD where to unserialize
  32. Return Value:
  33. TRUE if successful, FALSE on error
  34. --*/
  35. {
  36. if ( *pC >= sizeof( DWORD ) )
  37. {
  38. *pU = *(DWORD UNALIGNED*)*ppB;
  39. *ppB += sizeof(DWORD);
  40. *pC -= sizeof(DWORD);
  41. return TRUE;
  42. }
  43. return FALSE;
  44. }
  45. BOOL
  46. Unserialize(
  47. LPBYTE* ppB,
  48. LPDWORD pC,
  49. LPBOOL pU
  50. )
  51. /*++
  52. Routine Description:
  53. Unserialize a BOOL
  54. pU is updated with BOOL from *ppB, ppB & pC are updated
  55. Arguments:
  56. ppB - ptr to addr of buffer
  57. pC - ptr to byte count in buffer
  58. pU - ptr to BOOL where to unserialize
  59. Return Value:
  60. TRUE if successful, FALSE on error
  61. --*/
  62. {
  63. if ( *pC >= sizeof( BOOL ) )
  64. {
  65. *pU = *(BOOL UNALIGNED*)*ppB;
  66. *ppB += sizeof(BOOL);
  67. *pC -= sizeof(BOOL);
  68. return TRUE;
  69. }
  70. return FALSE;
  71. }
  72. //
  73. // Extensible buffer class
  74. //
  75. BOOL
  76. CStoreXBF::Need(
  77. DWORD dwNeed
  78. )
  79. /*++
  80. Routine Description:
  81. Insure that CStoreXBF can store at least dwNeed bytes
  82. including bytes already stored.
  83. Arguments:
  84. dwNeed - minimum of bytes available for storage
  85. Return Value:
  86. TRUE if successful, FALSE on error
  87. --*/
  88. {
  89. if ( dwNeed > m_cAllocBuff )
  90. {
  91. dwNeed = ((dwNeed + m_cGrain)/m_cGrain)*m_cGrain;
  92. LPBYTE pN = (LPBYTE)LocalAlloc( LMEM_FIXED, dwNeed );
  93. if ( pN == NULL )
  94. {
  95. return FALSE;
  96. }
  97. if ( m_cUsedBuff )
  98. {
  99. memcpy( pN, m_pBuff, m_cUsedBuff );
  100. }
  101. m_cAllocBuff = dwNeed;
  102. LocalFree( m_pBuff );
  103. m_pBuff = pN;
  104. }
  105. return TRUE;
  106. }
  107. BOOL
  108. CStoreXBF::Save(
  109. HANDLE hFile
  110. )
  111. /*++
  112. Routine Description:
  113. Save to file
  114. Arguments:
  115. hFile - file handle
  116. Return Value:
  117. TRUE if successful, FALSE on error
  118. --*/
  119. {
  120. DWORD dwWritten;
  121. return WriteFile( hFile, GetBuff(), GetUsed(), &dwWritten, NULL ) &&
  122. dwWritten == GetUsed();
  123. }
  124. BOOL
  125. CStoreXBF::Load(
  126. HANDLE hFile
  127. )
  128. /*++
  129. Routine Description:
  130. Load from file
  131. Arguments:
  132. hFile - file handle
  133. Return Value:
  134. TRUE if successful, FALSE on error
  135. --*/
  136. {
  137. DWORD dwS = GetFileSize( hFile, NULL );
  138. DWORD dwRead;
  139. if ( dwS != 0xffffffff &&
  140. Need( dwS ) &&
  141. ReadFile( hFile, GetBuff(), dwS, &dwRead, NULL ) &&
  142. dwRead == dwS )
  143. {
  144. m_cUsedBuff = dwRead;
  145. return TRUE;
  146. }
  147. m_cUsedBuff = 0;
  148. return FALSE;
  149. }
  150. BOOL
  151. Serialize(
  152. CStoreXBF* pX,
  153. DWORD dw
  154. )
  155. /*++
  156. Routine Description:
  157. Serialize a DWORD in CStoreXBF
  158. Arguments:
  159. pX - ptr to CStoreXBF where to add serialized DWORD
  160. dw - DWORD to serialize
  161. Return Value:
  162. TRUE if successful, FALSE on error
  163. --*/
  164. {
  165. return pX->Append( (LPBYTE)&dw, sizeof(dw) );
  166. }
  167. BOOL
  168. Serialize(
  169. CStoreXBF* pX,
  170. BOOL f
  171. )
  172. /*++
  173. Routine Description:
  174. Serialize a BOOL in CStoreXBF
  175. Arguments:
  176. pX - ptr to CStoreXBF where to add serialized BOOL
  177. f - BOOL to serialize
  178. Return Value:
  179. TRUE if successful, FALSE on error
  180. --*/
  181. {
  182. return pX->Append( (LPBYTE)&f, sizeof(f) );
  183. }
  184. DWORD
  185. CPtrXBF::AddPtr(
  186. LPVOID pV
  187. )
  188. /*++
  189. Routine Description:
  190. Add a ptr to array
  191. Arguments:
  192. pV - ptr to be added at end of array
  193. Return Value:
  194. index ( 0-based ) in array where added or INDEX_ERROR if error
  195. --*/
  196. {
  197. DWORD i = GetNbPtr();
  198. if ( Append( (LPBYTE)&pV, sizeof(pV)) )
  199. {
  200. return i;
  201. }
  202. return INDEX_ERROR;
  203. }
  204. DWORD
  205. CPtrXBF::InsertPtr(
  206. DWORD iBefore,
  207. LPVOID pV
  208. )
  209. /*++
  210. Routine Description:
  211. Insert a ptr to array
  212. Arguments:
  213. iBefore - index where to insert entry, or 0xffffffff if add to array
  214. pV - ptr to be inserted
  215. Return Value:
  216. index ( 0-based ) in array where added or INDEX_ERROR if error
  217. --*/
  218. {
  219. if ( iBefore == INDEX_ERROR || iBefore >= GetNbPtr() )
  220. {
  221. return AddPtr( pV );
  222. }
  223. if ( AddPtr( NULL ) != INDEX_ERROR )
  224. {
  225. memmove( GetBuff()+(iBefore+1)*sizeof(LPVOID),
  226. GetBuff()+iBefore*sizeof(LPVOID),
  227. GetUsed()-(iBefore+1)*sizeof(LPVOID) );
  228. SetPtr( iBefore, pV );
  229. return iBefore;
  230. }
  231. return INDEX_ERROR;
  232. }
  233. BOOL
  234. CPtrXBF::DeletePtr(
  235. DWORD i
  236. )
  237. /*++
  238. Routine Description:
  239. Delete a ptr from array
  240. Arguments:
  241. i - index of ptr to delete
  242. Return Value:
  243. TRUE if success, otherwise FALSE
  244. --*/
  245. {
  246. memmove( GetBuff()+i*sizeof(LPVOID),
  247. GetBuff()+(i+1)*sizeof(LPVOID),
  248. GetUsed()-(i+1)*sizeof(LPVOID) );
  249. DecreaseUse( sizeof(LPVOID) );
  250. return TRUE;
  251. }
  252. BOOL
  253. CPtrXBF::Unserialize(
  254. LPBYTE* ppB,
  255. LPDWORD pC,
  256. DWORD cNbEntry
  257. )
  258. /*++
  259. Routine Description:
  260. Unserialize a ptr array
  261. Arguments:
  262. ppB - ptr to addr of buffer to unserialize from
  263. pC - ptr to count of bytes in buffer
  264. cNbEntry - # of ptr to unserialize from buffer
  265. Return Value:
  266. TRUE if success, otherwise FALSE
  267. --*/
  268. {
  269. Reset();
  270. if ( *pC >= cNbEntry * sizeof(LPVOID) &&
  271. Append( *ppB, cNbEntry * sizeof(LPVOID) ) )
  272. {
  273. *ppB += cNbEntry * sizeof(LPVOID);
  274. *pC -= cNbEntry * sizeof(LPVOID);
  275. return TRUE;
  276. }
  277. return FALSE;
  278. }
  279. BOOL
  280. CPtrXBF::Serialize(
  281. CStoreXBF* pX
  282. )
  283. /*++
  284. Routine Description:
  285. Serialize a ptr array
  286. Arguments:
  287. pX - ptr to CStoreXBF to serialize to
  288. Return Value:
  289. TRUE if success, otherwise FALSE
  290. --*/
  291. {
  292. return pX->Append( (LPBYTE)GetBuff(), (DWORD)GetUsed() );
  293. }
  294. BOOL
  295. CAllocString::Set(
  296. LPWSTR pS
  297. )
  298. /*++
  299. Routine Description:
  300. Set a string content, freeing prior content if any
  301. Arguments:
  302. pS - string to copy
  303. Return Value:
  304. TRUE if successful, FALSE on error
  305. --*/
  306. {
  307. size_t l;
  308. Reset();
  309. if ( m_pStr = (LPWSTR)LocalAlloc( LMEM_FIXED, l = (wcslen(pS)+1)*sizeof(WCHAR) ) )
  310. {
  311. memcpy( m_pStr, pS, l );
  312. return TRUE;
  313. }
  314. return FALSE;
  315. }
  316. BOOL
  317. CAllocString::Append(
  318. LPWSTR pS
  319. )
  320. /*++
  321. Routine Description:
  322. Append a string content
  323. Arguments:
  324. pS - string to append
  325. Return Value:
  326. TRUE if successful, FALSE on error
  327. --*/
  328. {
  329. size_t l = m_pStr ? wcslen(m_pStr )*sizeof(WCHAR) : 0;
  330. size_t nl;
  331. LPWSTR pStr;
  332. if ( pStr = (LPWSTR)LocalAlloc( LMEM_FIXED, l + (nl = (wcslen(pS)+1)*sizeof(WCHAR) )) )
  333. {
  334. memcpy( pStr, m_pStr, l );
  335. memcpy( pStr+l/sizeof(WCHAR), pS, nl );
  336. m_pStr = pStr;
  337. return TRUE;
  338. }
  339. return FALSE;
  340. }
  341. BOOL
  342. CAllocString::Unserialize(
  343. LPBYTE* ppb,
  344. LPDWORD pc
  345. )
  346. /*++
  347. Routine Description:
  348. Unserialize a string
  349. Arguments:
  350. ppB - ptr to addr of buffer to unserialize from
  351. pC - ptr to count of bytes in buffer
  352. Return Value:
  353. TRUE if success, otherwise FALSE
  354. --*/
  355. {
  356. DWORD dwL;
  357. if ( ::Unserialize( ppb, pc, &dwL ) &&
  358. (m_pStr = (LPWSTR)LocalAlloc( LMEM_FIXED, (dwL + 1) * sizeof(WCHAR))) )
  359. {
  360. memcpy( m_pStr, *ppb, dwL*sizeof(WCHAR) );
  361. m_pStr[dwL] = L'\0';
  362. *ppb += dwL*sizeof(WCHAR);
  363. *pc -= dwL*sizeof(WCHAR);
  364. return TRUE;
  365. }
  366. return FALSE;
  367. }
  368. BOOL
  369. CAllocString::Serialize(
  370. CStoreXBF* pX
  371. )
  372. /*++
  373. Routine Description:
  374. Serialize a string
  375. Arguments:
  376. pX - ptr to CStoreXBF to serialize to
  377. Return Value:
  378. TRUE if success, otherwise FALSE
  379. --*/
  380. {
  381. LPWSTR pS = m_pStr ? m_pStr : L"";
  382. return ::Serialize( pX, (DWORD)wcslen(pS) ) && pX->Append( pS );
  383. }
  384. BOOL
  385. CBlob::Set(
  386. LPBYTE pStr,
  387. DWORD cStr
  388. )
  389. /*++
  390. Routine Description:
  391. Store a buffer in a blob object
  392. buffer is copied inside blob
  393. blob is reset before copy
  394. Arguments:
  395. pStr - ptr to buffer to copy
  396. cStr - length of buffer
  397. Return Value:
  398. TRUE if success, otherwise FALSE
  399. --*/
  400. {
  401. Reset();
  402. return InitSet( pStr, cStr);
  403. }
  404. BOOL
  405. CBlob::InitSet(
  406. LPBYTE pStr,
  407. DWORD cStr
  408. )
  409. /*++
  410. Routine Description:
  411. Store a buffer in a blob object
  412. buffer is copied inside blob
  413. blob is not reset before copy, initial blob content ignored
  414. Arguments:
  415. pStr - ptr to buffer to copy
  416. cStr - length of buffer
  417. Return Value:
  418. TRUE if success, otherwise FALSE
  419. --*/
  420. {
  421. if ( m_pStr = (LPBYTE)LocalAlloc( LMEM_FIXED, cStr ) )
  422. {
  423. memcpy( m_pStr, pStr, cStr );
  424. m_cStr = cStr;
  425. return TRUE;
  426. }
  427. return FALSE;
  428. }
  429. BOOL
  430. CBlob::Unserialize(
  431. LPBYTE* ppB,
  432. LPDWORD pC
  433. )
  434. /*++
  435. Routine Description:
  436. Unserialize a blob
  437. Arguments:
  438. ppB - ptr to addr of buffer to unserialize from
  439. pC - ptr to count of bytes in buffer
  440. Return Value:
  441. TRUE if success, otherwise FALSE
  442. --*/
  443. {
  444. Reset();
  445. if ( ::Unserialize( ppB, pC, &m_cStr ) &&
  446. *pC >= m_cStr &&
  447. ( m_pStr = (LPBYTE)LocalAlloc( LMEM_FIXED, m_cStr ) ) )
  448. {
  449. memcpy( m_pStr, *ppB, m_cStr );
  450. *ppB += m_cStr;
  451. *pC -= m_cStr;
  452. }
  453. else
  454. {
  455. m_cStr = 0;
  456. return FALSE;
  457. }
  458. return TRUE;
  459. }
  460. BOOL
  461. CBlob::Serialize(
  462. CStoreXBF* pX
  463. )
  464. /*++
  465. Routine Description:
  466. Serialize a blob
  467. Arguments:
  468. pX - ptr to CStoreXBF to serialize to
  469. Return Value:
  470. TRUE if success, otherwise FALSE
  471. --*/
  472. {
  473. return ::Serialize( pX, m_cStr ) &&
  474. pX->Append( m_pStr, m_cStr );
  475. }
  476. CStrPtrXBF::~CStrPtrXBF(
  477. )
  478. /*++
  479. Routine Description:
  480. CStrPtrXBF destructor
  481. Arguments:
  482. None
  483. Return Value:
  484. Nothing
  485. --*/
  486. {
  487. DWORD iM = GetNbPtr();
  488. UINT i;
  489. for ( i = 0 ; i < iM ; ++i )
  490. {
  491. ((CAllocString*)GetPtrAddr(i))->Reset();
  492. }
  493. }
  494. DWORD
  495. CStrPtrXBF::AddEntry(
  496. LPWSTR pS
  497. )
  498. /*++
  499. Routine Description:
  500. Add a string to array
  501. string content is copied in array
  502. Arguments:
  503. pS - string to be added at end of array
  504. Return Value:
  505. index ( 0-based ) in array where added or INDEX_ERROR if error
  506. --*/
  507. {
  508. DWORD i;
  509. if ( (i = AddPtr( NULL )) != INDEX_ERROR )
  510. {
  511. return ((CAllocString*)GetPtrAddr(i))->Set( pS ) ? i : INDEX_ERROR;
  512. }
  513. return INDEX_ERROR;
  514. }
  515. DWORD
  516. CStrPtrXBF::InsertEntry(
  517. DWORD iBefore,
  518. LPWSTR pS
  519. )
  520. /*++
  521. Routine Description:
  522. Insert a string in array
  523. string content is copied in array
  524. Arguments:
  525. iBefore - index where to insert entry, or 0xffffffff if add to array
  526. pS - string to be inserted in array
  527. Return Value:
  528. index ( 0-based ) in array where added or INDEX_ERROR if error
  529. --*/
  530. {
  531. DWORD i;
  532. if ( (i = InsertPtr( iBefore, NULL )) != INDEX_ERROR )
  533. {
  534. return ((CAllocString*)GetPtrAddr(i))->Set( pS ) ? i : INDEX_ERROR;
  535. }
  536. return INDEX_ERROR;
  537. }
  538. BOOL
  539. CStrPtrXBF::DeleteEntry(
  540. DWORD i
  541. )
  542. /*++
  543. Routine Description:
  544. Delete a string from array
  545. Arguments:
  546. i - index of string to delete
  547. Return Value:
  548. TRUE if success, otherwise FALSE
  549. --*/
  550. {
  551. if ( i < GetNbPtr() )
  552. {
  553. ((CAllocString*)GetPtrAddr(i))->Reset();
  554. DeletePtr( i );
  555. return TRUE;
  556. }
  557. return FALSE;
  558. }
  559. BOOL
  560. CStrPtrXBF::Unserialize(
  561. LPBYTE* ppB,
  562. LPDWORD pC,
  563. DWORD cNbEntry
  564. )
  565. /*++
  566. Routine Description:
  567. Unserialize a string array
  568. Arguments:
  569. ppB - ptr to addr of buffer
  570. pC - ptr to byte count in buffer
  571. cNbEntry - # of entry to unserialize
  572. Return Value:
  573. TRUE if successful, FALSE on error
  574. --*/
  575. {
  576. UINT i;
  577. Reset();
  578. CAllocString empty;
  579. for ( i = 0 ; i < cNbEntry ; ++i )
  580. {
  581. if ( !Append( (LPBYTE)&empty, sizeof(empty)) ||
  582. !((CAllocString*)GetPtrAddr(i))->Unserialize( ppB, pC ) )
  583. {
  584. return FALSE;
  585. }
  586. }
  587. return TRUE;
  588. }
  589. BOOL
  590. CStrPtrXBF::Serialize(
  591. CStoreXBF* pX
  592. )
  593. /*++
  594. Routine Description:
  595. Serialize a string array
  596. Arguments:
  597. pX - ptr to CStoreXBF where to add serialized DWORD
  598. Return Value:
  599. TRUE if successful, FALSE on error
  600. --*/
  601. {
  602. UINT i;
  603. for ( i = 0 ; i < GetNbEntry() ; ++i )
  604. {
  605. if ( !((CAllocString*)GetPtrAddr(i))->Serialize( pX ) )
  606. {
  607. return FALSE;
  608. }
  609. }
  610. return TRUE;
  611. }
  612. CBlobXBF::~CBlobXBF(
  613. )
  614. /*++
  615. Routine Description:
  616. CBlobXBF destructor
  617. Arguments:
  618. None
  619. Return Value:
  620. Nothing
  621. --*/
  622. {
  623. DWORD iM = GetUsed()/sizeof(CBlob);
  624. UINT i;
  625. for ( i = 0 ; i < iM ; ++i )
  626. {
  627. GetBlob(i)->Reset();
  628. }
  629. }
  630. VOID CBlobXBF::Reset(
  631. )
  632. /*++
  633. Routine Description:
  634. Reset the blob content to NULL
  635. Arguments:
  636. None
  637. Return Value:
  638. Nothing
  639. --*/
  640. {
  641. DWORD iM = GetUsed()/sizeof(CBlob);
  642. UINT i;
  643. for ( i = 0 ; i < iM ; ++i )
  644. {
  645. GetBlob(i)->Reset();
  646. }
  647. CStoreXBF::Reset();
  648. }
  649. DWORD
  650. CBlobXBF::AddEntry(
  651. LPBYTE pS,
  652. DWORD cS
  653. )
  654. /*++
  655. Routine Description:
  656. Add a buffer to blob array
  657. buffer content is copied in array
  658. Arguments:
  659. pS - buffer to be added at end of array
  660. cS - length of buffer
  661. Return Value:
  662. index ( 0-based ) in array where added or INDEX_ERROR if error
  663. --*/
  664. {
  665. DWORD i = GetNbEntry();
  666. if ( Append( (LPBYTE)&pS, sizeof(CBlob) ) )
  667. {
  668. return GetBlob(i)->InitSet( pS, cS ) ? i : INDEX_ERROR;
  669. }
  670. return INDEX_ERROR;
  671. }
  672. DWORD
  673. CBlobXBF::InsertEntry(
  674. DWORD iBefore,
  675. LPBYTE pS,
  676. DWORD cS
  677. )
  678. /*++
  679. Routine Description:
  680. Insert a buffer in blob array
  681. buffer content is copied in array
  682. Arguments:
  683. iBefore - index where to insert entry, or 0xffffffff if add to array
  684. pS - buffer to be inserted in array
  685. cS - length of buffer
  686. Return Value:
  687. index ( 0-based ) in array where added or INDEX_ERROR if error
  688. --*/
  689. {
  690. DWORD i;
  691. if ( iBefore == INDEX_ERROR || iBefore >= GetNbEntry() )
  692. {
  693. return AddEntry( (LPBYTE)pS, cS );
  694. }
  695. if ( iBefore < GetNbEntry() && Append( (LPBYTE)&pS, sizeof(CBlob) ) )
  696. {
  697. memmove( GetBuff()+(iBefore+1)*sizeof(CBlob),
  698. GetBuff()+iBefore*sizeof(CBlob),
  699. GetUsed()-(iBefore+1)*sizeof(CBlob) );
  700. return GetBlob(iBefore)->InitSet( (LPBYTE)pS, cS ) ? iBefore : INDEX_ERROR;
  701. }
  702. return INDEX_ERROR;
  703. }
  704. BOOL
  705. CBlobXBF::DeleteEntry(
  706. DWORD i
  707. )
  708. /*++
  709. Routine Description:
  710. Delete a entry from blob array
  711. Arguments:
  712. i - index of string to delete
  713. Return Value:
  714. TRUE if success, otherwise FALSE
  715. --*/
  716. {
  717. if ( i < GetNbEntry() )
  718. {
  719. GetBlob(i)->Reset();
  720. memmove( GetBuff()+i*sizeof(CBlob),
  721. GetBuff()+(i+1)*sizeof(CBlob),
  722. GetUsed()-(i+1)*sizeof(CBlob) );
  723. DecreaseUse( sizeof(CBlob) );
  724. return TRUE;
  725. }
  726. return FALSE;
  727. }
  728. BOOL
  729. CBlobXBF::Unserialize(
  730. LPBYTE* ppB,
  731. LPDWORD pC,
  732. DWORD cNbEntry )
  733. /*++
  734. Routine Description:
  735. Unserialize a blob array
  736. Arguments:
  737. ppB - ptr to addr of buffer to unserialize from
  738. pC - ptr to count of bytes in buffer
  739. cNbEntry - # of ptr to unserialize from buffer
  740. Return Value:
  741. TRUE if success, otherwise FALSE
  742. --*/
  743. {
  744. UINT i;
  745. Reset();
  746. CBlob empty;
  747. for ( i = 0 ; i < cNbEntry ; ++i )
  748. {
  749. if ( !Append( (LPBYTE)&empty, sizeof(empty) ) ||
  750. !GetBlob(i)->Unserialize( ppB, pC ) )
  751. {
  752. return FALSE;
  753. }
  754. }
  755. return TRUE;
  756. }
  757. BOOL
  758. CBlobXBF::Serialize(
  759. CStoreXBF* pX
  760. )
  761. /*++
  762. Routine Description:
  763. Serialize a blob array
  764. Arguments:
  765. pX - ptr to CStoreXBF where to add serialized blob
  766. Return Value:
  767. TRUE if successful, FALSE on error
  768. --*/
  769. {
  770. UINT i;
  771. for ( i = 0 ; i < GetNbEntry() ; ++i )
  772. {
  773. if ( !GetBlob(i)->Serialize( pX ) )
  774. {
  775. return FALSE;
  776. }
  777. }
  778. return TRUE;
  779. }