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.

1023 lines
23 KiB

  1. //+----------------------------------------------------------------------------
  2. // File: util.cxx
  3. //
  4. // Synopsis:
  5. //
  6. //-----------------------------------------------------------------------------
  7. // Includes -------------------------------------------------------------------
  8. #include <core.hxx>
  9. // Globals --------------------------------------------------------------------
  10. const UCHAR SZ_NEWLINE[] = "\n\r";
  11. //+----------------------------------------------------------------------------
  12. // Function: CopyStream
  13. //
  14. // Synopsis:
  15. //
  16. //-----------------------------------------------------------------------------
  17. HRESULT
  18. CopyStream(
  19. IStream * pstmDest,
  20. IStream * pstmSrc,
  21. ULARGE_INTEGER cbCopy,
  22. ULARGE_INTEGER * pcbRead,
  23. ULARGE_INTEGER * pcbWritten)
  24. {
  25. DWORD cb = cbCopy.LowPart;
  26. DWORD cbStep = min(cb, 0xFFFF);
  27. DWORD cbRead, cbWritten;
  28. DWORD cbTotalRead = 0;
  29. DWORD cbTotalWritten = 0;
  30. void * pv = NULL;
  31. HRESULT hr = S_OK;
  32. if (cbCopy.HighPart)
  33. return E_INVALIDARG;
  34. pv = new BYTE[cbStep];
  35. if (!pv)
  36. return E_OUTOFMEMORY;
  37. while (cb)
  38. {
  39. cbRead = min(cbStep, cb);
  40. hr = pstmSrc->Read(pv, cbRead, &cbRead);
  41. if (hr || !cbRead)
  42. break;
  43. cbTotalRead += cbRead;
  44. hr = pstmDest->Write(pv, cbRead, &cbWritten);
  45. if (S_OK != hr)
  46. break;
  47. cbTotalWritten += cbWritten;
  48. if (cbWritten != cbRead)
  49. {
  50. hr = E_UNEXPECTED;
  51. break;
  52. }
  53. cb -= cbRead;
  54. }
  55. if (pcbRead)
  56. {
  57. pcbRead->HighPart = 0;
  58. pcbRead->LowPart = cbTotalRead;
  59. }
  60. if (pcbWritten)
  61. {
  62. pcbWritten->HighPart = 0;
  63. pcbWritten->LowPart = cbTotalWritten;
  64. }
  65. delete [] pv;
  66. return hr;
  67. }
  68. //+----------------------------------------------------------------------------
  69. // Member: Read
  70. //
  71. // Synopsis:
  72. //
  73. //-----------------------------------------------------------------------------
  74. STDMETHODIMP
  75. CMemoryStream::Read(
  76. void * pv,
  77. ULONG cb,
  78. ULONG * pcbRead)
  79. {
  80. Assert(_pbData);
  81. Assert(_ibPos <= _cbSize);
  82. cb = min(cb, _cbSize - _ibPos);
  83. ::memcpy(pv, _pbData + _ibPos, cb);
  84. _ibPos += cb;
  85. if (pcbRead)
  86. {
  87. *pcbRead = cb;
  88. }
  89. return S_OK;
  90. }
  91. //+----------------------------------------------------------------------------
  92. // Member: Write
  93. //
  94. // Synopsis:
  95. //
  96. //-----------------------------------------------------------------------------
  97. STDMETHODIMP
  98. CMemoryStream::Write(
  99. const void * pv,
  100. ULONG cb,
  101. ULONG * pcbWritten)
  102. {
  103. HRESULT hr = S_OK;
  104. Assert(_pbData);
  105. Assert(_ibPos <= _cbSize);
  106. if ((_ibPos + cb) > _cbSize)
  107. {
  108. hr = STG_E_MEDIUMFULL;
  109. goto Cleanup;
  110. }
  111. ::memcpy(_pbData + _ibPos, pv, cb);
  112. _ibPos += cb;
  113. Cleanup:
  114. if (pcbWritten)
  115. {
  116. *pcbWritten = (SUCCEEDED(hr) ? cb : 0);
  117. }
  118. return hr;
  119. }
  120. //+----------------------------------------------------------------------------
  121. // Member: Seek
  122. //
  123. // Synopsis:
  124. //
  125. //-----------------------------------------------------------------------------
  126. STDMETHODIMP
  127. CMemoryStream::Seek(
  128. LARGE_INTEGER dlibMove,
  129. DWORD dwOrigin,
  130. ULARGE_INTEGER * plibNewPosition)
  131. {
  132. LONG ibOffset = (LONG)dlibMove.LowPart;
  133. Assert(_pbData);
  134. // Ensure only 32-bits is in-use
  135. if (!(dlibMove.HighPart == 0 && ibOffset >= 0) &&
  136. !(dlibMove.HighPart == -1 && ibOffset < 0))
  137. return E_INVALIDARG;
  138. switch (dwOrigin)
  139. {
  140. case STREAM_SEEK_SET:
  141. break;
  142. case STREAM_SEEK_CUR:
  143. ibOffset = (LONG)_ibPos + ibOffset;
  144. break;
  145. case STREAM_SEEK_END:
  146. ibOffset = (LONG)_cbSize + ibOffset;
  147. break;
  148. default:
  149. return E_INVALIDARG;
  150. }
  151. // Ensure the new offset is within the correct range
  152. if ((ULONG)ibOffset > _cbSize)
  153. return E_INVALIDARG;
  154. // Store the new offset and return it
  155. _ibPos = (ULONG)ibOffset;
  156. if (plibNewPosition)
  157. {
  158. plibNewPosition->HighPart = 0;
  159. plibNewPosition->LowPart = _ibPos;
  160. }
  161. return S_OK;
  162. }
  163. //+----------------------------------------------------------------------------
  164. // Member: SetSize
  165. //
  166. // Synopsis:
  167. //
  168. //-----------------------------------------------------------------------------
  169. STDMETHODIMP
  170. CMemoryStream::SetSize(
  171. ULARGE_INTEGER libNewSize)
  172. {
  173. if (libNewSize.HighPart)
  174. return STG_E_MEDIUMFULL;
  175. if (libNewSize.LowPart <= _cbSize)
  176. {
  177. _cbSize = libNewSize.LowPart;
  178. }
  179. else
  180. {
  181. BYTE * pbData = new BYTE[libNewSize.LowPart];
  182. if (!pbData)
  183. return STG_E_MEDIUMFULL;
  184. if (_pbData && _cbSize)
  185. {
  186. ::memcpy(pbData, _pbData, _cbSize);
  187. }
  188. delete [] _pbData;
  189. _cbSize = libNewSize.LowPart;
  190. _pbData = pbData;
  191. }
  192. return S_OK;
  193. }
  194. //+----------------------------------------------------------------------------
  195. // Member: CopyTo
  196. //
  197. // Synopsis:
  198. //
  199. //-----------------------------------------------------------------------------
  200. STDMETHODIMP
  201. CMemoryStream::CopyTo(
  202. IStream * pstm,
  203. ULARGE_INTEGER cb,
  204. ULARGE_INTEGER * pcbRead,
  205. ULARGE_INTEGER * pcbWritten)
  206. {
  207. if (!pstm)
  208. return STG_E_INVALIDPOINTER;
  209. if (cb.HighPart || ((_ibPos + cb.LowPart) > _cbSize))
  210. return E_INVALIDARG;
  211. Assert(_pbData);
  212. return ::CopyStream(pstm, this, cb, pcbRead, pcbWritten);
  213. }
  214. //+----------------------------------------------------------------------------
  215. // Member: CBufferedStream
  216. //
  217. // Synopsis:
  218. //
  219. //-----------------------------------------------------------------------------
  220. CBufferedStream::CBufferedStream(
  221. IStream * pstm,
  222. ULONG cbNewLine,
  223. BOOL fRead)
  224. {
  225. Assert(_pstm);
  226. _fRead = fRead;
  227. _pb = NULL;
  228. _cb = 0;
  229. _ib = 0;
  230. _cbLine = 0;
  231. _cbNewLine = cbNewLine;
  232. _cbTotal = 0;
  233. _pstm = ::SAddRef(pstm);
  234. }
  235. //+----------------------------------------------------------------------------
  236. // Member: ~CBufferedStream
  237. //
  238. // Synopsis:
  239. //
  240. //-----------------------------------------------------------------------------
  241. CBufferedStream::~CBufferedStream()
  242. {
  243. Verify(SUCCEEDED(Flush()));
  244. ::SRelease(_pstm);
  245. delete [] _pb;
  246. }
  247. //+----------------------------------------------------------------------------
  248. // Member: Flush
  249. //
  250. // Synopsis:
  251. //
  252. //-----------------------------------------------------------------------------
  253. HRESULT
  254. CBufferedStream::Flush(
  255. ULONG * pcbWritten)
  256. {
  257. ULONG cbWritten;
  258. HRESULT hr = S_OK;
  259. Assert(_pstm);
  260. Implies(_cbNewLine, _ib <= (_cb + CB_NEWLINE));
  261. Implies(!_cbNewLine, _ib <= _cb);
  262. if (!pcbWritten)
  263. {
  264. pcbWritten = &cbWritten;
  265. }
  266. *pcbWritten = 0;
  267. // For read-only streams, "read" the rest of the buffer by setting the buffer index
  268. // (This will force a re-load during the next read)
  269. if (_fRead)
  270. {
  271. _ib = _cb;
  272. }
  273. // For write-only streams, write the buffer to the stream
  274. else if (_ib)
  275. {
  276. Assert(!_fRead);
  277. hr = _pstm->Write(_pb, _ib, pcbWritten);
  278. _cbTotal += *pcbWritten;
  279. if (S_OK == hr)
  280. {
  281. Assert(*pcbWritten == _ib);
  282. _ib = 0;
  283. }
  284. }
  285. return hr;
  286. }
  287. //+----------------------------------------------------------------------------
  288. // Member: Load
  289. //
  290. // Synopsis:
  291. //
  292. //-----------------------------------------------------------------------------
  293. HRESULT
  294. CBufferedStream::Load()
  295. {
  296. HRESULT hr;
  297. Assert(_fRead);
  298. hr = _pstm->Read(_pb, _cb, &_cbTotal);
  299. if (S_OK != hr)
  300. goto Cleanup;
  301. _ib = 0;
  302. Cleanup:
  303. return hr;
  304. }
  305. //+----------------------------------------------------------------------------
  306. // Member: SetBufferSize
  307. //
  308. // Synopsis:
  309. //
  310. //-----------------------------------------------------------------------------
  311. HRESULT
  312. CBufferedStream::SetBufferSize(
  313. ULONG cb)
  314. {
  315. // The buffer size cannot be changed once it has been set
  316. // Also, it is illegal to use a zero-sized buffer
  317. if (_pb || !cb)
  318. return E_FAIL;
  319. // Allocate a new buffer of the requested size
  320. // (If the caller requested automatic interjection of NEWLINEs, slightly increase
  321. // allocated buffer; the remembered size will continue to be that which they
  322. // requested)
  323. _pb = new BYTE[cb + (_cbNewLine ? CB_NEWLINE : 0)];
  324. if (!_pb)
  325. return E_OUTOFMEMORY;
  326. _cb = cb;
  327. _ib = (_fRead ? _cb : 0);
  328. return S_OK;
  329. }
  330. //+----------------------------------------------------------------------------
  331. // Member: Read
  332. //
  333. // Synopsis:
  334. //
  335. //-----------------------------------------------------------------------------
  336. STDMETHODIMP
  337. CBufferedStream::Read(
  338. void * pv,
  339. ULONG cb,
  340. ULONG * pcbRead)
  341. {
  342. ULONG cbTotalRead;
  343. ULONG cbRead;
  344. HRESULT hr = S_OK;
  345. Assert(_pb);
  346. Assert(_cb);
  347. Assert(_ib <= _cb);
  348. if (!pv)
  349. return E_INVALIDARG;
  350. if (!pcbRead)
  351. {
  352. pcbRead = &cbTotalRead;
  353. }
  354. *pcbRead = 0;
  355. // If bytes remain in the buffer, "read" those first
  356. if (_ib < _cbTotal)
  357. {
  358. cbRead = min(cb, _cbTotal-_ib);
  359. ::memcpy(pv, _pb+_ib, cbRead);
  360. _ib += cbRead;
  361. cb -= cbRead;
  362. pv = (void *)(((const BYTE *)pv) + cbRead);
  363. *pcbRead += cbRead;
  364. }
  365. // If bytes remain to be read, fetch them now
  366. if (cb)
  367. {
  368. Assert(_ib >= _cbTotal);
  369. Assert(_cbTotal <= _cb);
  370. // If the request fits within half of the buffer, then load a buffer full
  371. if (cb < (_cb/2))
  372. {
  373. hr = Load();
  374. if (S_OK != hr)
  375. goto Cleanup;
  376. cbRead = min(cb, _cbTotal);
  377. ::memcpy(pv, _pb, cbRead);
  378. _ib = cbRead;
  379. *pcbRead += cbRead;
  380. }
  381. // Otherwise, read directly into the callers buffer
  382. else
  383. {
  384. hr = _pstm->Read(pv, cb, pcbRead);
  385. }
  386. }
  387. Cleanup:
  388. return hr;
  389. }
  390. //+----------------------------------------------------------------------------
  391. // Member: Write
  392. //
  393. // Synopsis:
  394. //
  395. //-----------------------------------------------------------------------------
  396. STDMETHODIMP
  397. CBufferedStream::Write(
  398. const void * pv,
  399. ULONG cb,
  400. ULONG * pcbWritten)
  401. {
  402. const BYTE * pbSrc = (const BYTE *)pv;
  403. ULONG ibSrc = 0;
  404. ULONG cbWritten;
  405. HRESULT hr = S_OK;
  406. Assert(_pb);
  407. Assert(_cb);
  408. Assert(_ib <= _cb);
  409. if (!pv)
  410. return E_INVALIDARG;
  411. if (pcbWritten)
  412. {
  413. *pcbWritten = 0;
  414. }
  415. // Treat calls to write on a read-only stream as if the stream is full
  416. if (_fRead)
  417. {
  418. hr = STG_E_MEDIUMFULL;
  419. goto Cleanup;
  420. }
  421. // Write the bytes to the stream
  422. while (cb)
  423. {
  424. // Determine the number of bytes to write this time through
  425. cbWritten = min(cb, _cb-_ib);
  426. if (_cbNewLine)
  427. {
  428. cbWritten = min(cbWritten, _cbNewLine-_cbLine);
  429. }
  430. // Write the bytes to the local buffer
  431. ::memcpy(_pb + _ib, pbSrc + ibSrc, cbWritten);
  432. // Update the counters reflecting what has been written
  433. // (Adding a newline if necessary)
  434. cb -= cbWritten;
  435. ibSrc += cbWritten;
  436. _ib += cbWritten;
  437. if (_cbNewLine)
  438. {
  439. _cbLine += cbWritten;
  440. if (_cbLine >= _cbNewLine)
  441. {
  442. ::memcpy(_pb + _ib, SZ_NEWLINE, CB_NEWLINE);
  443. _cbLine = 0;
  444. _ib += CB_NEWLINE;
  445. }
  446. }
  447. // If the buffer is full, write it to the stream
  448. if (_ib >= _cb)
  449. {
  450. hr = Flush(&cbWritten);
  451. if (pcbWritten)
  452. {
  453. *pcbWritten += cbWritten;
  454. }
  455. if (S_OK != hr)
  456. goto Cleanup;
  457. }
  458. }
  459. Cleanup:
  460. return hr;
  461. }
  462. //+----------------------------------------------------------------------------
  463. // Member: CFileStream
  464. //
  465. // Synopsis:
  466. //
  467. //-----------------------------------------------------------------------------
  468. CFileStream::CFileStream()
  469. {
  470. _hFile = NULL;
  471. }
  472. //+----------------------------------------------------------------------------
  473. // Member: ~CFileStream
  474. //
  475. // Synopsis:
  476. //
  477. //-----------------------------------------------------------------------------
  478. CFileStream::~CFileStream()
  479. {
  480. if (_hFile)
  481. {
  482. ::CloseHandle(_hFile);
  483. }
  484. }
  485. //+----------------------------------------------------------------------------
  486. // Member: Init
  487. //
  488. // Synopsis:
  489. //
  490. //-----------------------------------------------------------------------------
  491. HRESULT
  492. CFileStream::Init(
  493. LPCWSTR wszFileName,
  494. DWORD dwDesiredAccess,
  495. DWORD dwShareMode,
  496. LPSECURITY_ATTRIBUTES pSecurityAttributes,
  497. DWORD dwCreationDistribution,
  498. DWORD dwFlagsAndAttributes,
  499. HANDLE hTemplateFile)
  500. {
  501. int len = WideCharToMultiByte(CP_ACP, 0, wszFileName, -1, 0, 0, NULL, NULL);
  502. LPSTR psz = new CHAR[len];
  503. if (psz)
  504. {
  505. if (::WideCharToMultiByte(CP_ACP, 0, wszFileName, -1, (LPSTR)psz, len, NULL, NULL))
  506. {
  507. _hFile = ::CreateFileA(psz, dwDesiredAccess, dwShareMode, pSecurityAttributes,
  508. dwCreationDistribution, dwFlagsAndAttributes, hTemplateFile);
  509. }
  510. delete [] psz;
  511. }
  512. else
  513. {
  514. return E_OUTOFMEMORY;
  515. }
  516. // CreateFile succeeded if we didn't get back INVALID_HANDLE_VALUE
  517. return ((_hFile != INVALID_HANDLE_VALUE)
  518. ? S_OK
  519. : GetWin32Hresult());
  520. }
  521. //+----------------------------------------------------------------------------
  522. // Member: GetFileSize
  523. //
  524. // Synopsis:
  525. //
  526. //-----------------------------------------------------------------------------
  527. HRESULT
  528. CFileStream::GetFileSize(
  529. ULONG * pcbSize)
  530. {
  531. Assert(_hFile);
  532. Assert(pcbSize);
  533. *pcbSize = ::GetFileSize(_hFile, NULL);
  534. return (*pcbSize == 0xFFFFFFFF
  535. ? GetWin32Hresult()
  536. : S_OK);
  537. }
  538. //+----------------------------------------------------------------------------
  539. // Member: Read
  540. //
  541. // Synopsis:
  542. //
  543. //-----------------------------------------------------------------------------
  544. STDMETHODIMP
  545. CFileStream::Read(
  546. void * pv,
  547. ULONG cb,
  548. ULONG * pcbRead)
  549. {
  550. ULONG cbRead;
  551. HRESULT hr = S_OK;
  552. if (!pv)
  553. return E_INVALIDARG;
  554. if (!pcbRead)
  555. {
  556. pcbRead = &cbRead;
  557. }
  558. hr = (::ReadFile(_hFile, pv, cb, pcbRead, NULL)
  559. ? S_OK
  560. : S_FALSE);
  561. return hr;
  562. }
  563. //+----------------------------------------------------------------------------
  564. // Member: Write
  565. //
  566. // Synopsis:
  567. //
  568. //-----------------------------------------------------------------------------
  569. STDMETHODIMP
  570. CFileStream::Write(
  571. const void * pv,
  572. ULONG cb,
  573. ULONG * pcbWritten)
  574. {
  575. ULONG cbWritten;
  576. HRESULT hr;
  577. if (!pv)
  578. return E_INVALIDARG;
  579. if (!pcbWritten)
  580. {
  581. pcbWritten = &cbWritten;
  582. }
  583. hr = (::WriteFile(_hFile, pv, cb, pcbWritten, NULL)
  584. ? S_OK
  585. : STG_E_MEDIUMFULL);
  586. return hr;
  587. }
  588. //+----------------------------------------------------------------------------
  589. // Member: Seek
  590. //
  591. // Synopsis:
  592. //
  593. //-----------------------------------------------------------------------------
  594. STDMETHODIMP
  595. CFileStream::Seek(
  596. LARGE_INTEGER dlibMove,
  597. DWORD dwOrigin,
  598. ULARGE_INTEGER * plibNewPosition)
  599. {
  600. DWORD dwMoveMethod;
  601. ULARGE_INTEGER libNewPosition;
  602. HRESULT hr;
  603. if (plibNewPosition)
  604. {
  605. plibNewPosition->HighPart = 0;
  606. plibNewPosition->LowPart = 0;
  607. }
  608. switch(dwOrigin)
  609. {
  610. case STREAM_SEEK_SET: dwMoveMethod = FILE_BEGIN; break;
  611. case STREAM_SEEK_CUR: dwMoveMethod = FILE_CURRENT; break;
  612. case STREAM_SEEK_END: dwMoveMethod = FILE_END; break;
  613. default:
  614. return E_INVALIDARG;
  615. }
  616. libNewPosition.LowPart = ::SetFilePointer(_hFile, dlibMove.LowPart, &dlibMove.HighPart, dwMoveMethod);
  617. libNewPosition.HighPart = dlibMove.HighPart;
  618. if (libNewPosition.LowPart == 0xFFFFFFFF &&
  619. ::GetLastError() != NO_ERROR)
  620. {
  621. hr = STG_E_INVALIDPOINTER;
  622. }
  623. else
  624. {
  625. if (plibNewPosition)
  626. {
  627. *plibNewPosition = libNewPosition;
  628. }
  629. hr = S_OK;
  630. }
  631. return hr;
  632. }
  633. //+----------------------------------------------------------------------------
  634. //
  635. // Member: SetSize
  636. //
  637. // Synopsis:
  638. //
  639. //-----------------------------------------------------------------------------
  640. STDMETHODIMP
  641. CFileStream::SetSize(
  642. ULARGE_INTEGER libNewSize)
  643. {
  644. LONG curLow, curHigh;
  645. BOOL fEOFSet;
  646. curHigh = 0;
  647. curLow = ::SetFilePointer(_hFile, 0, &curHigh, FILE_CURRENT);
  648. if (0xFFFFFFFF == ::SetFilePointer(_hFile, libNewSize.LowPart,
  649. (LONG *)&libNewSize.HighPart, FILE_BEGIN))
  650. {
  651. return STG_E_INVALIDFUNCTION;
  652. }
  653. fEOFSet = ::SetEndOfFile(_hFile);
  654. #ifdef _DEBUG
  655. Verify(0xFFFFFFFF != ::SetFilePointer(_hFile, curLow, &curHigh, FILE_BEGIN));
  656. #else
  657. ::SetFilePointer(_hFile, curLow, &curHigh, FILE_BEGIN);
  658. #endif
  659. return (fEOFSet
  660. ? S_OK
  661. : STG_E_MEDIUMFULL);
  662. }
  663. //+----------------------------------------------------------------------------
  664. //
  665. // Member: CopyTo
  666. //
  667. // Synopsis:
  668. //
  669. //-----------------------------------------------------------------------------
  670. STDMETHODIMP
  671. CFileStream::CopyTo(
  672. IStream * pstm,
  673. ULARGE_INTEGER cb,
  674. ULARGE_INTEGER * pcbRead,
  675. ULARGE_INTEGER * pcbWritten)
  676. {
  677. if (!pstm)
  678. return STG_E_INVALIDPOINTER;
  679. return ::CopyStream(pstm, this, cb, pcbRead, pcbWritten);
  680. }
  681. //+----------------------------------------------------------------------------
  682. //
  683. // Member: PrivateQueryInterface
  684. //
  685. // Synopsis:
  686. //
  687. //-----------------------------------------------------------------------------
  688. HRESULT
  689. CFileStream::PrivateQueryInterface(
  690. REFIID riid,
  691. void ** ppvObj)
  692. {
  693. if (riid == IID_IStream)
  694. *ppvObj = (IStream *)this;
  695. if (*ppvObj)
  696. return S_OK;
  697. else
  698. return parent::PrivateQueryInterface(riid, ppvObj);
  699. }
  700. //+----------------------------------------------------------------------------
  701. // Function: CoAlloc
  702. //
  703. // Synopsis:
  704. //
  705. //-----------------------------------------------------------------------------
  706. void *
  707. CoAlloc(
  708. ULONG cb)
  709. {
  710. Assert(TLS(dll.pmalloc));
  711. return TLS(dll.pmalloc)->Alloc(cb);
  712. }
  713. //+----------------------------------------------------------------------------
  714. // Function: CoFree
  715. //
  716. // Synopsis:
  717. //
  718. //-----------------------------------------------------------------------------
  719. void
  720. CoFree(
  721. void * pv)
  722. {
  723. if (!pv)
  724. return;
  725. Assert(TLS(dll.pmalloc));
  726. Assert(CoDidAlloc(pv));
  727. TLS(dll.pmalloc)->Free(pv);
  728. }
  729. //+----------------------------------------------------------------------------
  730. // Function: CoGetSize
  731. //
  732. // Synopsis:
  733. //
  734. //-----------------------------------------------------------------------------
  735. ULONG
  736. CoGetSize(
  737. void * pv)
  738. {
  739. Assert(TLS(dll.pmalloc));
  740. Assert(CoDidAlloc(pv));
  741. return (ULONG)(TLS(dll.pmalloc)->GetSize(pv));
  742. }
  743. //+----------------------------------------------------------------------------
  744. // Function: CoDidAlloc
  745. //
  746. // Synopsis:
  747. //
  748. //-----------------------------------------------------------------------------
  749. BOOL
  750. CoDidAlloc(
  751. void * pv)
  752. {
  753. Assert(TLS(dll.pmalloc));
  754. return (!pv || TLS(dll.pmalloc)->DidAlloc(pv) == 1
  755. ? TRUE
  756. : FALSE);
  757. }
  758. #ifdef _NOCRT
  759. //+----------------------------------------------------------------------------
  760. // Function: purecall
  761. //
  762. // Synopsis: _SHIP build replacement for CRT vtable routine
  763. //
  764. //-----------------------------------------------------------------------------
  765. int __cdecl
  766. _purecall()
  767. {
  768. return 0;
  769. }
  770. //+----------------------------------------------------------------------------
  771. // Function: _tcslen
  772. //
  773. // Synopsis:
  774. //
  775. //-----------------------------------------------------------------------------
  776. extern "C" size_t __cdecl
  777. _tcslen(
  778. const TCHAR * psz)
  779. {
  780. for (size_t i=0; *psz; psz++, i++);
  781. return i;
  782. }
  783. //+----------------------------------------------------------------------------
  784. // Function: memcmp
  785. //
  786. // Synopsis:
  787. //
  788. //-----------------------------------------------------------------------------
  789. extern "C" int __cdecl
  790. memcmp(
  791. const void * pv1,
  792. const void * pv2,
  793. size_t cb)
  794. {
  795. size_t i;
  796. int d;
  797. for (i=0, d=0; i < cb && !d; i++)
  798. d = (*(const BYTE *)pv1) - (*(const BYTE *)pv2);
  799. return d;
  800. }
  801. //+----------------------------------------------------------------------------
  802. // Function: memcpy
  803. //
  804. // Synopsis:
  805. //
  806. //-----------------------------------------------------------------------------
  807. extern "C" void * __cdecl
  808. memcpy(
  809. void * pvDest,
  810. const void * pvSrc,
  811. size_t cb)
  812. {
  813. for (size_t i=0; i < cb; i++)
  814. ((BYTE *)pvDest)[i] = ((const BYTE *)pvSrc)[i];
  815. return pvDest;
  816. }
  817. //+----------------------------------------------------------------------------
  818. // Function: memset
  819. //
  820. // Synopsis:
  821. //
  822. //-----------------------------------------------------------------------------
  823. extern "C" void * __cdecl
  824. memset(
  825. void * pv,
  826. int c,
  827. size_t cb)
  828. {
  829. for (size_t i=0; i < cb; i++)
  830. ((BYTE *)pv)[i] = (BYTE)c;
  831. return pv;
  832. }
  833. //+----------------------------------------------------------------------------
  834. // Function: memmove
  835. //
  836. // Synopsis:
  837. //
  838. //-----------------------------------------------------------------------------
  839. extern "C" void * __cdecl
  840. memmove(
  841. void * pvDest,
  842. const void * pvSrc,
  843. size_t cb)
  844. {
  845. BYTE * pb1;
  846. BYTE * pb2;
  847. if (pvSrc < pvDest)
  848. {
  849. pb1 = (BYTE *)pvDest + cb;
  850. pb2 = (BYTE *)pvSrc + cb;
  851. for (; cb; cb--)
  852. {
  853. *pb1-- = *pb2--;
  854. }
  855. }
  856. else if (pvSrc > pvDest)
  857. {
  858. pb1 = (BYTE *)pvDest;
  859. pb2 = (BYTE *)pvSrc;
  860. for (; cb; cb--)
  861. {
  862. *pb1++ = *pb2++;
  863. }
  864. }
  865. return pvDest;
  866. }
  867. #endif // _NOCRT