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.

422 lines
9.9 KiB

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