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.

612 lines
13 KiB

  1. #define INC_OLE2
  2. #include <windows.h>
  3. #include <windowsx.h>
  4. #include <cstream.h>
  5. #include <dbgtrace.h>
  6. #define Tracefn(fn)
  7. CImpIStream::CImpIStream(void)
  8. {
  9. SYSTEMTIME st;
  10. Tracefn("CImpIStream::CImpIStream");
  11. m_cRef = 1;
  12. m_cbSeek = 0;
  13. m_statstg.cbSize.LowPart = 0;
  14. memset(&m_statstg,0,sizeof(STATSTG));
  15. GetSystemTime(&st);
  16. SystemTimeToFileTime(&st,&m_statstg.ctime);
  17. }
  18. CImpIStream::~CImpIStream(void)
  19. {
  20. Tracefn("CImpIStream::~CImpIStream");
  21. }
  22. STDMETHODIMP CImpIStream::QueryInterface(
  23. REFIID riid,
  24. void __RPC_FAR *__RPC_FAR *ppvObject)
  25. {
  26. Tracefn("CImpIStream::QueryInterface");
  27. *ppvObject=NULL;
  28. if (IsEqualIID(riid, IID_IUnknown)
  29. || IsEqualIID(riid,IID_IStream))
  30. *ppvObject=(LPVOID)this;
  31. if( *ppvObject != NULL )
  32. {
  33. ((LPUNKNOWN)*ppvObject)->AddRef();
  34. return NOERROR;
  35. }
  36. return E_NOINTERFACE;
  37. }
  38. STDMETHODIMP_(ULONG) CImpIStream::AddRef(void)
  39. {
  40. Tracefn("CImpIStream::AddRef");
  41. InterlockedIncrement(&m_cRef);
  42. return m_cRef;
  43. }
  44. STDMETHODIMP_(ULONG) CImpIStream::Release(void)
  45. {
  46. ULONG cRefT;
  47. Tracefn("CImpIStream::Release");
  48. cRefT = InterlockedDecrement(&m_cRef);
  49. if( 0 == cRefT )
  50. delete this;
  51. return cRefT;
  52. }
  53. STDMETHODIMP CImpIStream::Read(
  54. void __RPC_FAR *pv,
  55. ULONG cb,
  56. ULONG __RPC_FAR *pcbRead)
  57. {
  58. Tracefn("CImpIStream::Read");
  59. return E_NOTIMPL;
  60. }
  61. STDMETHODIMP CImpIStream::Write(
  62. const void __RPC_FAR *pv,
  63. ULONG cb,
  64. ULONG __RPC_FAR *pcbWritten)
  65. {
  66. Tracefn("CImpIStream::Write");
  67. return E_NOTIMPL;
  68. }
  69. STDMETHODIMP CImpIStream::Seek(
  70. LARGE_INTEGER dlibMove,
  71. DWORD dwOrigin,
  72. ULARGE_INTEGER __RPC_FAR *plibNewPosition)
  73. {
  74. Tracefn("CImpIStream::Seek")
  75. return E_NOTIMPL;
  76. }
  77. STDMETHODIMP CImpIStream::SetSize(
  78. ULARGE_INTEGER libNewSize)
  79. {
  80. Tracefn("CImpIStream::SetSize");
  81. return E_NOTIMPL;
  82. }
  83. STDMETHODIMP CImpIStream::CopyTo(
  84. IStream __RPC_FAR *pstm,
  85. ULARGE_INTEGER cb,
  86. ULARGE_INTEGER __RPC_FAR *pcbRead,
  87. ULARGE_INTEGER __RPC_FAR *pcbWritten)
  88. {
  89. Tracefn("CImpIStream::CopyTo");
  90. return E_NOTIMPL;
  91. }
  92. STDMETHODIMP CImpIStream::Commit(
  93. DWORD grfCommitFlags)
  94. {
  95. Tracefn("CImpIStream::Commit");
  96. return S_OK;
  97. }
  98. STDMETHODIMP CImpIStream::Revert( void)
  99. {
  100. Tracefn("CImpIStream::Revert");
  101. return E_NOTIMPL;
  102. }
  103. STDMETHODIMP CImpIStream::LockRegion(
  104. ULARGE_INTEGER libOffset,
  105. ULARGE_INTEGER cb,
  106. DWORD dwLockType)
  107. {
  108. Tracefn("CImpIStream::LockRegion");
  109. return E_NOTIMPL;
  110. }
  111. STDMETHODIMP CImpIStream::UnlockRegion(
  112. ULARGE_INTEGER libOffset,
  113. ULARGE_INTEGER cb,
  114. DWORD dwLockType)
  115. {
  116. Tracefn("CImpIStream::UnlockRegion");
  117. return E_NOTIMPL;
  118. }
  119. STDMETHODIMP CImpIStream::Stat(
  120. STATSTG __RPC_FAR *pstatstg,
  121. DWORD grfStatFlag)
  122. {
  123. STATSTG * pstat = NULL;
  124. Tracefn("CImpIStream::Stat");
  125. if( !pstatstg )
  126. return STG_E_INVALIDPOINTER;
  127. memcpy(pstatstg,&m_statstg,sizeof(STATSTG));
  128. return NOERROR;
  129. }
  130. STDMETHODIMP CImpIStream::Clone(
  131. IStream __RPC_FAR *__RPC_FAR *ppstm)
  132. {
  133. Tracefn("CImpIStream::Clone");
  134. return E_NOTIMPL;
  135. }
  136. /* -------------------------------------------------------------------------
  137. CStreamMem
  138. ------------------------------------------------------------------------- */
  139. CStreamMem::CStreamMem(void)
  140. {
  141. Tracefn("CStreamMem::CStreamMem");
  142. m_pvData = NULL;
  143. m_fExternalData = FALSE;
  144. }
  145. CStreamMem::CStreamMem(PVOID pvData,ULONG cbSize)
  146. {
  147. Tracefn("CStreamMem::CStreamMem");
  148. m_pvData = pvData;
  149. m_cbSeek = 0;
  150. m_statstg.cbSize.LowPart = cbSize;
  151. m_fExternalData = TRUE;
  152. }
  153. CStreamMem::~CStreamMem(void)
  154. {
  155. Tracefn("CStreamMem::~CStreamMem");
  156. if( m_pvData && !m_fExternalData )
  157. free(m_pvData);
  158. }
  159. STDMETHODIMP CStreamMem::GetPointerFromStream(PVOID *ppv,DWORD *pdwSize)
  160. {
  161. HRESULT hr = NOERROR;
  162. if( NULL == ppv || NULL == pdwSize )
  163. return STG_E_INVALIDPOINTER;
  164. if( NULL != m_pvData )
  165. {
  166. *ppv = m_pvData;
  167. *pdwSize = m_statstg.cbSize.LowPart;
  168. }
  169. else
  170. {
  171. *ppv = NULL;
  172. *pdwSize = 0;
  173. }
  174. return hr;
  175. }
  176. // IStream
  177. STDMETHODIMP CStreamMem::Read(
  178. void __RPC_FAR *pv,
  179. ULONG cb,
  180. ULONG __RPC_FAR *pcbRead)
  181. {
  182. SYSTEMTIME st;
  183. ULONG cbRead = 0;
  184. Tracefn("CStreamMem::Read");
  185. if( pcbRead != NULL )
  186. *pcbRead = 0;
  187. _ASSERT(m_cbSeek <= m_statstg.cbSize.LowPart);
  188. // anything to do?
  189. if( cb == 0 || m_statstg.cbSize.LowPart == 0 || m_cbSeek == m_statstg.cbSize.LowPart )
  190. return NOERROR;
  191. // determine amount to copy
  192. cbRead = min(cb,m_statstg.cbSize.LowPart - m_cbSeek);
  193. if( cbRead > 0 )
  194. {
  195. // copy it
  196. CopyMemory(pv,(PBYTE)m_pvData + m_cbSeek,cbRead);
  197. // adjust seek pointer
  198. m_cbSeek += cbRead;
  199. }
  200. // update access time
  201. GetSystemTime(&st);
  202. SystemTimeToFileTime(&st,&m_statstg.atime);
  203. if( pcbRead != NULL )
  204. *pcbRead = cbRead;
  205. _ASSERT(m_cbSeek <= m_statstg.cbSize.LowPart);
  206. return NOERROR;
  207. }
  208. STDMETHODIMP CStreamMem::Write(
  209. const void __RPC_FAR *pv,
  210. ULONG cb,
  211. ULONG __RPC_FAR *pcbWritten)
  212. {
  213. ULONG cbNewSize = 0;
  214. PVOID pvMem = NULL;
  215. SYSTEMTIME st;
  216. Tracefn("CStreamMem::Write");
  217. if( pcbWritten != NULL)
  218. *pcbWritten = 0;
  219. // external data is readonly
  220. if( m_fExternalData )
  221. return STG_E_MEDIUMFULL;
  222. // anything to do?
  223. if( cb == 0 )
  224. return NOERROR;
  225. // determine new size
  226. cbNewSize = max(m_cbSeek + cb, m_statstg.cbSize.LowPart);
  227. if( m_pvData == NULL )
  228. {
  229. // no memory alloc yet
  230. if( NULL == (m_pvData = malloc(cbNewSize)) )
  231. return STG_E_MEDIUMFULL;
  232. m_statstg.cbSize.LowPart = cbNewSize;
  233. }
  234. else if( cbNewSize > m_statstg.cbSize.LowPart )
  235. {
  236. // grow existing memory
  237. if( NULL == (pvMem = realloc(m_pvData,cbNewSize)) )
  238. return STG_E_MEDIUMFULL;
  239. m_pvData = pvMem;
  240. m_statstg.cbSize.LowPart = cbNewSize;
  241. }
  242. // copy mem
  243. CopyMemory((PBYTE)m_pvData + m_cbSeek,pv,cb);
  244. // adjust seek pointer
  245. m_cbSeek += cb;
  246. // set the number of bytes actually written
  247. m_statstg.cbSize.LowPart = max(m_statstg.cbSize.LowPart,m_cbSeek);
  248. // return bytes written
  249. if( pcbWritten != NULL)
  250. *pcbWritten = cb;
  251. // update modify time
  252. GetSystemTime(&st);
  253. SystemTimeToFileTime(&st,&m_statstg.mtime);
  254. return NOERROR;
  255. }
  256. STDMETHODIMP CStreamMem::Seek(
  257. LARGE_INTEGER dlibMove,
  258. DWORD dwOrigin,
  259. ULARGE_INTEGER __RPC_FAR *plibNewPosition)
  260. {
  261. Tracefn("CStreamMem::Seek");
  262. // can we handle the seek?
  263. if( dlibMove.HighPart != 0 )
  264. return STG_E_WRITEFAULT;
  265. // handle the seek request
  266. switch( dwOrigin)
  267. {
  268. case STREAM_SEEK_SET:
  269. if( dlibMove.LowPart > m_statstg.cbSize.LowPart )
  270. return STG_E_WRITEFAULT;
  271. m_cbSeek = dlibMove.LowPart;
  272. break;
  273. case STREAM_SEEK_CUR:
  274. if( dlibMove.LowPart + m_cbSeek > m_statstg.cbSize.LowPart )
  275. return STG_E_WRITEFAULT;
  276. m_cbSeek += (int)dlibMove.LowPart;
  277. break;
  278. case STREAM_SEEK_END:
  279. if ((int)dlibMove.LowPart > 0 ||
  280. (ULONG)(-(int)dlibMove.LowPart) > m_statstg.cbSize.LowPart)
  281. {
  282. return STG_E_WRITEFAULT;
  283. }
  284. m_cbSeek = m_statstg.cbSize.LowPart + (int)dlibMove.LowPart;
  285. break;
  286. }
  287. // return new seek position
  288. if( plibNewPosition )
  289. {
  290. plibNewPosition->HighPart = 0;
  291. plibNewPosition->LowPart = m_cbSeek;
  292. }
  293. return NOERROR;
  294. }
  295. STDMETHODIMP CStreamMem::SetSize(
  296. ULARGE_INTEGER libNewSize)
  297. {
  298. PVOID pvMem = NULL;
  299. Tracefn("CStreamMem::SetSize");
  300. // external data is readonly
  301. if( m_fExternalData )
  302. return STG_E_MEDIUMFULL;
  303. // can we handle the new size?
  304. if( libNewSize.HighPart != 0 )
  305. return STG_E_MEDIUMFULL;
  306. // alloc mem
  307. if( !m_pvData )
  308. pvMem = malloc(libNewSize.LowPart);
  309. else
  310. pvMem = realloc(m_pvData,libNewSize.LowPart);
  311. if( !pvMem )
  312. return STG_E_MEDIUMFULL;
  313. // save mem info
  314. m_pvData = pvMem;
  315. m_statstg.cbSize.LowPart = libNewSize.LowPart;
  316. // adjust the number of bytes actually written
  317. m_statstg.cbSize.LowPart = min(m_statstg.cbSize.LowPart,m_statstg.cbSize.LowPart);
  318. return NOERROR;
  319. }
  320. STDMETHODIMP CStreamMem::CopyTo(
  321. IStream __RPC_FAR *pstm,
  322. ULARGE_INTEGER cb,
  323. ULARGE_INTEGER __RPC_FAR *pcbRead,
  324. ULARGE_INTEGER __RPC_FAR *pcbWritten)
  325. {
  326. Tracefn("CStreamMem::CopyTo");
  327. HRESULT hr = NOERROR;
  328. ULONG cbBytes = 0;
  329. ULONG cbWritten = 0;
  330. if( pstm == NULL )
  331. return STG_E_INVALIDPOINTER;
  332. cbBytes = min(m_statstg.cbSize.LowPart - m_cbSeek,cb.LowPart);
  333. if( pcbRead )
  334. pcbRead->QuadPart = cbBytes;
  335. if( cbBytes == 0 )
  336. return NOERROR;
  337. hr = pstm->Write((PBYTE)m_pvData + m_cbSeek,cbBytes,&cbWritten);
  338. if( pcbWritten )
  339. pcbWritten->QuadPart = cbWritten;
  340. return hr;
  341. }
  342. /* -------------------------------------------------------------------------
  343. CStreamFile
  344. ------------------------------------------------------------------------- */
  345. CStreamFile::CStreamFile(HANDLE hFile,BOOL fCloseHandle, BOOL fReadOnly)
  346. {
  347. Tracefn("CStreamFile::CStreamFile");
  348. _ASSERT(hFile != INVALID_HANDLE_VALUE);
  349. if( hFile == INVALID_HANDLE_VALUE )
  350. return;
  351. m_fCloseHandle = fCloseHandle;
  352. m_fReadOnly = fReadOnly;
  353. m_hFile = hFile;
  354. m_statstg.cbSize.LowPart = GetFileSize(m_hFile,NULL);
  355. }
  356. CStreamFile::~CStreamFile(void)
  357. {
  358. Tracefn("CStreamFile::~CStreamFile");
  359. if( m_fCloseHandle && m_hFile != INVALID_HANDLE_VALUE )
  360. CloseHandle(m_hFile);
  361. m_hFile = INVALID_HANDLE_VALUE;
  362. }
  363. // IStream
  364. STDMETHODIMP CStreamFile::Read(
  365. void __RPC_FAR *pv,
  366. ULONG cb,
  367. ULONG __RPC_FAR *pcbRead)
  368. {
  369. SYSTEMTIME st;
  370. Tracefn("CStreamFile::Read");
  371. if( m_hFile == INVALID_HANDLE_VALUE )
  372. return STG_E_INVALIDHANDLE;
  373. if( !pcbRead )
  374. return STG_E_INVALIDPOINTER;
  375. *pcbRead = 0;
  376. // anything to do?
  377. if( cb == 0 || m_statstg.cbSize.LowPart == 0 || m_cbSeek == m_statstg.cbSize.LowPart )
  378. return NOERROR;
  379. if( !ReadFile(m_hFile,pv,cb,pcbRead,NULL) )
  380. return HRESULT_FROM_WIN32(GetLastError());
  381. // adjust seek pointer
  382. m_cbSeek += *pcbRead;
  383. // update access time
  384. GetSystemTime(&st);
  385. SystemTimeToFileTime(&st,&m_statstg.atime);
  386. return NOERROR;
  387. }
  388. STDMETHODIMP CStreamFile::Write(
  389. const void __RPC_FAR *pv,
  390. ULONG cb,
  391. ULONG __RPC_FAR *pcbWritten)
  392. {
  393. ULONG cbNewSize = 0;
  394. ULONG cbWritten = 0;
  395. PVOID pvMem = NULL;
  396. SYSTEMTIME st;
  397. Tracefn("CStreamFile::Write");
  398. if( m_hFile == INVALID_HANDLE_VALUE )
  399. return STG_E_INVALIDHANDLE;
  400. if (m_fReadOnly)
  401. return STG_E_MEDIUMFULL;
  402. if( pcbWritten != NULL )
  403. *pcbWritten = 0;
  404. // anything to do?
  405. if( cb == 0 )
  406. return NOERROR;
  407. if( !WriteFile(m_hFile,pv,cb,&cbWritten,NULL) )
  408. return HRESULT_FROM_WIN32(GetLastError());
  409. m_cbSeek += cbWritten;
  410. if( m_cbSeek > m_statstg.cbSize.LowPart )
  411. {
  412. m_statstg.cbSize.LowPart = m_cbSeek;
  413. if( !SetEndOfFile(m_hFile) )
  414. return HRESULT_FROM_WIN32(GetLastError());
  415. }
  416. if( pcbWritten != NULL )
  417. *pcbWritten = cbWritten;
  418. // update modify time
  419. GetSystemTime(&st);
  420. SystemTimeToFileTime(&st,&m_statstg.mtime);
  421. return NOERROR;
  422. }
  423. STDMETHODIMP CStreamFile::Seek(
  424. LARGE_INTEGER dlibMove,
  425. DWORD dwOrigin,
  426. ULARGE_INTEGER __RPC_FAR *plibNewPosition)
  427. {
  428. Tracefn("CStreamFile::Seek");
  429. if( m_hFile == INVALID_HANDLE_VALUE )
  430. return STG_E_INVALIDHANDLE;
  431. // handle the seek request
  432. switch( dwOrigin)
  433. {
  434. case STREAM_SEEK_SET:
  435. m_cbSeek = dlibMove.LowPart;
  436. break;
  437. case STREAM_SEEK_CUR:
  438. m_cbSeek += (int)dlibMove.LowPart;
  439. break;
  440. case STREAM_SEEK_END:
  441. m_cbSeek = m_statstg.cbSize.LowPart + (int)dlibMove.LowPart;
  442. break;
  443. }
  444. // do seek
  445. if( -1L == SetFilePointer(m_hFile,m_cbSeek,NULL,FILE_BEGIN) )
  446. return HRESULT_FROM_WIN32(GetLastError());
  447. // return new seek position
  448. if( plibNewPosition )
  449. {
  450. plibNewPosition->HighPart = 0;
  451. plibNewPosition->LowPart = m_cbSeek;
  452. }
  453. return NOERROR;
  454. }
  455. STDMETHODIMP CStreamFile::SetSize(
  456. ULARGE_INTEGER libNewSize)
  457. {
  458. Tracefn("CStreamFile::SetSize");
  459. HRESULT hr = NOERROR;
  460. if( m_hFile == INVALID_HANDLE_VALUE )
  461. return STG_E_INVALIDHANDLE;
  462. // can we handle the new size?
  463. if( libNewSize.HighPart != 0 )
  464. return STG_E_MEDIUMFULL;
  465. // seek to new end of file
  466. if( -1L == SetFilePointer(m_hFile,libNewSize.LowPart,NULL,FILE_BEGIN) )
  467. return HRESULT_FROM_WIN32(GetLastError());
  468. // set end of file
  469. if( !SetEndOfFile(m_hFile) )
  470. {
  471. // get the error
  472. hr = HRESULT_FROM_WIN32(GetLastError());
  473. }
  474. else
  475. {
  476. // save new size.
  477. m_statstg.cbSize.LowPart = libNewSize.LowPart;
  478. }
  479. // restore seek pointer
  480. if( -1L == SetFilePointer(m_hFile,m_cbSeek,NULL,FILE_BEGIN) )
  481. hr = HRESULT_FROM_WIN32(GetLastError());
  482. return hr;
  483. }
  484. STDMETHODIMP CStreamFile::Commit(
  485. DWORD grfCommitFlags)
  486. {
  487. Tracefn("CStreamFile::Commit");
  488. HRESULT hr = S_OK;
  489. if( m_hFile == INVALID_HANDLE_VALUE )
  490. return STG_E_INVALIDHANDLE;
  491. if(!FlushFileBuffers(m_hFile))
  492. hr = HRESULT_FROM_WIN32(GetLastError());
  493. return hr;
  494. }