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.

395 lines
8.9 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  5. //
  6. // File: ilbmem.cx
  7. //
  8. // Contents: ILockBytes memory implementation
  9. //
  10. // Classes: CMapBytes
  11. //
  12. //--------------------------------------------------------------------------
  13. #include "headers.cxx"
  14. #include <memory.h>
  15. #include "ilb.hxx"
  16. #if DBG == 1
  17. #ifndef _UNIX // on unix we use static lib, so the symbol is defined
  18. DECLARE_INFOLEVEL(ol, DEB_ERROR);
  19. #endif
  20. #endif
  21. //+-------------------------------------------------------------------------
  22. //
  23. // Member: CMapBytes::CMapBytes, public
  24. //
  25. // Synopsis: constructor
  26. //
  27. // Effects: initialize member variables
  28. //
  29. // Derivation: ILockBytes
  30. //
  31. // Notes: Returns a fully initialized CMapBytes (ref count == 1)
  32. //
  33. //--------------------------------------------------------------------------
  34. CMapBytes::CMapBytes(void)
  35. {
  36. _ulSize = 0;
  37. _pv = 0;
  38. _ulRef = 1;
  39. }
  40. //+-------------------------------------------------------------------------
  41. //
  42. // Member: CMapBytes::QueryInterface, public
  43. //
  44. // Arguments: [riid] - interface id
  45. // [ppvObj] - place holder for interface
  46. //
  47. // Returns: Always fails
  48. //
  49. // Derivation: ILockBytes
  50. //
  51. // Notes: Not used in tests
  52. //
  53. //--------------------------------------------------------------------------
  54. STDMETHODIMP CMapBytes::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  55. {
  56. *ppvObj = NULL;
  57. return ResultFromScode(STG_E_INVALIDFUNCTION);
  58. }
  59. //+-------------------------------------------------------------------------
  60. //
  61. // Member: CMapBytes::AddRef, public
  62. //
  63. // Synopsis: add reference
  64. //
  65. // Returns: post reference count
  66. //
  67. // Derivation: ILockBytes
  68. //
  69. //--------------------------------------------------------------------------
  70. STDMETHODIMP_(ULONG) CMapBytes::AddRef(void)
  71. {
  72. _ulRef++;
  73. return(_ulRef);
  74. }
  75. //+-------------------------------------------------------------------------
  76. //
  77. // Member: CMapBytes::Release, public
  78. //
  79. // Synopsis: release reference
  80. //
  81. // Effects: deletes object when reference count reaches zero
  82. //
  83. // Returns: post reference count
  84. //
  85. // Derivation: ILockBytes
  86. //
  87. //--------------------------------------------------------------------------
  88. STDMETHODIMP_(ULONG) CMapBytes::Release(void)
  89. {
  90. _ulRef--;
  91. if (_ulRef > 0)
  92. return(_ulRef);
  93. free(_pv);
  94. delete this;
  95. return(0);
  96. }
  97. //+-------------------------------------------------------------------------
  98. //
  99. // Member: CMapBytes::ReadAt
  100. //
  101. // Synopsis: Reads bytes from memory
  102. //
  103. // Arguments: [ulOffset] - byte offset
  104. // [pv] - input buffer
  105. // [cb] - count of bytes to read
  106. // [pcbRead] - count of bytes read
  107. //
  108. // Returns: SCODE
  109. //
  110. // Modifies: pv, pcbRead
  111. //
  112. // Derivation: ILockBytes
  113. //
  114. //--------------------------------------------------------------------------
  115. STDMETHODIMP CMapBytes::ReadAt(ULARGE_INTEGER uliOffset,
  116. VOID HUGEP *pv,
  117. ULONG cb,
  118. ULONG *pcbRead)
  119. {
  120. olAssert(ULIGetHigh(uliOffset) == 0);
  121. ULONG ulOffset = ULIGetLow(uliOffset);
  122. if (ulOffset >= _ulSize)
  123. {
  124. // truncate read
  125. cb = 0;
  126. }
  127. else if (cb > (_ulSize - ulOffset))
  128. {
  129. // truncate range that exceeds size
  130. cb = _ulSize - ulOffset;
  131. }
  132. memcpy(pv, (void*)(((BYTE*)_pv) + ulOffset), (size_t) cb);
  133. *pcbRead = cb;
  134. return NOERROR;
  135. }
  136. //+-------------------------------------------------------------------------
  137. //
  138. // Member: CMapBytes::WriteAt, public
  139. //
  140. // Synopsis: Writes bytes to memory
  141. //
  142. // Effects: May change memory size
  143. //
  144. // Arguments: [uliOffset] - byte offset
  145. // [pv] - output buffer
  146. // [cb] - count of bytes to write
  147. // [pcbWritten] - count of bytes written
  148. //
  149. // Returns: SCODE
  150. //
  151. // Modifies: pcbWritten
  152. //
  153. // Derivation: ILockBytes
  154. //
  155. // Notes: This implementation doesn't write partial buffers.
  156. //
  157. //--------------------------------------------------------------------------
  158. STDMETHODIMP CMapBytes::WriteAt(ULARGE_INTEGER uliOffset,
  159. VOID const HUGEP *pv,
  160. ULONG cb,
  161. ULONG FAR *pcbWritten)
  162. {
  163. olAssert(ULIGetHigh(uliOffset) == 0);
  164. ULONG ulOffset = ULIGetLow(uliOffset);
  165. HRESULT hr;
  166. if (ulOffset + cb > _ulSize)
  167. {
  168. // increase memory buffer to accomodate write
  169. ULARGE_INTEGER uliSize;
  170. ULISetHigh(uliSize, 0);
  171. ULISetLow(uliSize, ulOffset + cb);
  172. hr = SetSize(uliSize);
  173. if (FAILED(DfGetScode(hr)))
  174. {
  175. // don't bother writing partial buffers
  176. *pcbWritten = 0;
  177. return hr;
  178. }
  179. }
  180. memcpy((void *)(((BYTE*)_pv) + ulOffset), pv, (size_t) cb);
  181. *pcbWritten = cb;
  182. return NOERROR;
  183. }
  184. //+-------------------------------------------------------------------------
  185. //
  186. // Member: CMapBytes::Flush, public
  187. //
  188. // Synopsis: flushes memory - not appropriate for this implementation
  189. //
  190. // Effects: none
  191. //
  192. // Returns: SUCCESS_SUCCESS
  193. //
  194. // Derivation: ILockBytes
  195. //
  196. //--------------------------------------------------------------------------
  197. STDMETHODIMP CMapBytes::Flush(void)
  198. {
  199. return NOERROR;
  200. }
  201. //+-------------------------------------------------------------------------
  202. //
  203. // Member: CMapBytes::GetSize, public
  204. //
  205. // Synopsis: gets memory buffer size
  206. //
  207. // Arguments: [pcb] - size place holder
  208. //
  209. // Returns: SUCCESS_SUCCESS
  210. //
  211. // Modifies: pcb
  212. //
  213. // Derivation: ILockBytes
  214. //
  215. //--------------------------------------------------------------------------
  216. STDMETHODIMP CMapBytes::GetSize(ULARGE_INTEGER FAR *pcb)
  217. {
  218. ULISetHigh(*pcb, 0);
  219. ULISetLow(*pcb, _ulSize);
  220. return NOERROR;
  221. }
  222. //+-------------------------------------------------------------------------
  223. //
  224. // Member: CMapBytes::SetSize, public
  225. //
  226. // Synopsis: sets memory buffer size
  227. //
  228. // Effects: may change buffer size
  229. //
  230. // Arguments: [ulicb] - new memory size
  231. //
  232. // Returns: SCODE
  233. //
  234. // Derivation: ILockBytes
  235. //
  236. // Algorithm: realloc the buffer
  237. //
  238. //--------------------------------------------------------------------------
  239. STDMETHODIMP CMapBytes::SetSize(ULARGE_INTEGER ulicb)
  240. {
  241. olAssert(ULIGetHigh(ulicb) == 0);
  242. ULONG cb = ULIGetLow(ulicb);
  243. if (cb == _ulSize)
  244. return NOERROR;
  245. void *pv = realloc(_pv, (size_t) cb);
  246. if ((cb > 0) && (pv == NULL))
  247. {
  248. // Unable to allocate memory
  249. // Leave current memory and size alone
  250. return ResultFromScode(E_OUTOFMEMORY);
  251. }
  252. _pv = pv;
  253. _ulSize = cb;
  254. return NOERROR;
  255. }
  256. //+-------------------------------------------------------------------------
  257. //
  258. // Member: CMapBytes::LockRegion, public
  259. //
  260. // Synopsis: not supported (intentionally)
  261. //
  262. // Effects: asserts if called
  263. //
  264. // Arguments: [libOffset] - lock range offset
  265. // [cb] - lock range size
  266. // [dwLockType] - lock type
  267. //
  268. // Returns: STG_E_INVALIDFUNCTION
  269. //
  270. // Derivation: ILockBytes
  271. //
  272. //--------------------------------------------------------------------------
  273. STDMETHODIMP CMapBytes::LockRegion(ULARGE_INTEGER libOffset,
  274. ULARGE_INTEGER cb,
  275. DWORD dwLockType)
  276. {
  277. olAssert(0 && "Can't lock CMapBytes");
  278. return ResultFromScode(STG_E_INVALIDFUNCTION);
  279. }
  280. //+-------------------------------------------------------------------------
  281. //
  282. // Member: CMapBytes::UnLockRegion, public
  283. //
  284. // Synopsis: not supported (intentionally)
  285. //
  286. // Effects: asserts if called
  287. //
  288. // Arguments: [libOffset] - lock range offset
  289. // [cb] - lock range size
  290. // [dwLockType] - lock type
  291. //
  292. // Returns: STG_E_INVALIDFUNCTION
  293. //
  294. // Derivation: ILockBytes
  295. //
  296. //--------------------------------------------------------------------------
  297. STDMETHODIMP CMapBytes::UnlockRegion(ULARGE_INTEGER libOffset,
  298. ULARGE_INTEGER cb,
  299. DWORD dwLockType)
  300. {
  301. olAssert(0 && "Can't unlock CMapBytes");
  302. return ResultFromScode(STG_E_INVALIDFUNCTION);
  303. }
  304. //+-------------------------------------------------------------------------
  305. //
  306. // Member: CMapBytes::Stat, public
  307. //
  308. // Synopsis: Provide instance information
  309. //
  310. // Arguments: [pstatstg] - status buffer
  311. // [grfStatFlag] - status flags
  312. //
  313. // Returns: SCODE
  314. //
  315. // Modifies: pstatstg
  316. //
  317. // Derivation: ILockBytes
  318. //
  319. // Notes: No time stamps
  320. //
  321. //--------------------------------------------------------------------------
  322. STDMETHODIMP CMapBytes::Stat(STATSTG FAR *pstatstg, DWORD grfStatFlag)
  323. {
  324. memset(pstatstg, 0, sizeof(STATSTG));
  325. if ((grfStatFlag & STATFLAG_NONAME) == 0)
  326. {
  327. static char const abName[] = "Memory";
  328. HRESULT hr;
  329. if (FAILED(DfGetScode(hr = drtMemAlloc(sizeof(abName),
  330. (void **) &pstatstg->pwcsName))))
  331. return hr;
  332. memcpy(pstatstg->pwcsName, abName, sizeof(abName));
  333. }
  334. pstatstg->type = STGTY_LOCKBYTES;
  335. ULISetHigh(pstatstg->cbSize, 0);
  336. ULISetLow(pstatstg->cbSize, _ulSize);
  337. pstatstg->grfMode = STGM_READWRITE | STGM_DIRECT | STGM_SHARE_EXCLUSIVE;
  338. return NOERROR;
  339. }