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.

335 lines
7.2 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. ScriptableStream.cpp
  5. Abstract:
  6. This file contains the implementation of the CPCHScriptableStream class,
  7. which is a scriptable wrapper for IStream.
  8. Revision History:
  9. Davide Massarenti (Dmassare) 10/06/2000
  10. created
  11. ******************************************************************************/
  12. #include "stdafx.h"
  13. ////////////////////////////////////////////////////////////////////////////////
  14. HRESULT CPCHScriptableStream::ReadToHGLOBAL( /*[in]*/ long lCount, /*[out]*/ HGLOBAL& hg, /*[out]*/ ULONG& lReadTotal )
  15. {
  16. __HCP_FUNC_ENTRY( "CPCHScriptableStream::ReadToHGLOBAL" );
  17. HRESULT hr;
  18. lReadTotal = 0;
  19. if(lCount < 0)
  20. {
  21. static const ULONG c_BUFSIZE = 4096;
  22. ULONG lRead;
  23. __MPC_EXIT_IF_ALLOC_FAILS(hr, hg, ::GlobalAlloc( GMEM_FIXED, c_BUFSIZE ));
  24. while(1)
  25. {
  26. HGLOBAL hg2;
  27. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FileStream::Read( &((BYTE*)hg)[lReadTotal], c_BUFSIZE, &lRead ));
  28. if(hr == S_FALSE || lRead == 0) break;
  29. lReadTotal += lRead;
  30. //
  31. // Increase buffer.
  32. //
  33. __MPC_EXIT_IF_ALLOC_FAILS(hr, hg2, ::GlobalReAlloc( hg, lReadTotal + c_BUFSIZE, 0 ));
  34. hg = hg2;
  35. }
  36. }
  37. else
  38. {
  39. __MPC_EXIT_IF_ALLOC_FAILS(hr, hg, ::GlobalAlloc( GMEM_FIXED, lCount ));
  40. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FileStream::Read( hg, lCount, &lReadTotal ));
  41. }
  42. hr = S_OK;
  43. __HCP_FUNC_CLEANUP;
  44. __HCP_FUNC_EXIT(hr);
  45. }
  46. /////////////////////////////////////////////////////////////////////////////
  47. STDMETHODIMP CPCHScriptableStream::get_Size( /*[out, retval]*/ long *plSize )
  48. {
  49. __HCP_FUNC_ENTRY( "CPCHScriptableStream::get_Size" );
  50. HRESULT hr;
  51. STATSTG stat;
  52. __MPC_PARAMCHECK_BEGIN(hr)
  53. __MPC_PARAMCHECK_POINTER_AND_SET(plSize,0);
  54. __MPC_PARAMCHECK_END();
  55. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FileStream::Stat( &stat, STATFLAG_NONAME ));
  56. *plSize = (long)stat.cbSize.QuadPart;
  57. hr = S_OK;
  58. __HCP_FUNC_CLEANUP;
  59. __HCP_FUNC_EXIT(hr);
  60. }
  61. STDMETHODIMP CPCHScriptableStream::Read( /*[in]*/ long lCount, /*[out, retval]*/ VARIANT *pvData )
  62. {
  63. __HCP_FUNC_ENTRY( "CPCHScriptableStream::Read" );
  64. HRESULT hr;
  65. CComVariant vArray;
  66. HGLOBAL hg = NULL;
  67. ULONG lReadTotal;
  68. __MPC_PARAMCHECK_BEGIN(hr)
  69. __MPC_PARAMCHECK_NOTNULL(pvData);
  70. __MPC_PARAMCHECK_END();
  71. __MPC_EXIT_IF_METHOD_FAILS(hr, ReadToHGLOBAL( lCount, hg, lReadTotal ));
  72. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertBufferToVariant( (BYTE*)hg, (DWORD)lReadTotal, vArray ));
  73. __MPC_EXIT_IF_METHOD_FAILS(hr, vArray.Detach( pvData ));
  74. hr = S_OK;
  75. __HCP_FUNC_CLEANUP;
  76. if(hg) ::GlobalFree( hg );
  77. __HCP_FUNC_EXIT(hr);
  78. }
  79. STDMETHODIMP CPCHScriptableStream::ReadHex( /*[in]*/ long lCount, /*[out, retval]*/ BSTR *pbstrData )
  80. {
  81. __HCP_FUNC_ENTRY( "CPCHScriptableStream::ReadHex" );
  82. HRESULT hr;
  83. HGLOBAL hg = NULL;
  84. ULONG lReadTotal;
  85. __MPC_PARAMCHECK_BEGIN(hr)
  86. __MPC_PARAMCHECK_POINTER_AND_SET(pbstrData,0);
  87. __MPC_PARAMCHECK_END();
  88. __MPC_EXIT_IF_METHOD_FAILS(hr, ReadToHGLOBAL( lCount, hg, lReadTotal ));
  89. if(lReadTotal)
  90. {
  91. CComBSTR bstrHex;
  92. HGLOBAL hg2;
  93. //
  94. // Trim down the size of the HGLOBAL.
  95. //
  96. __MPC_EXIT_IF_ALLOC_FAILS(hr, hg2, ::GlobalReAlloc( hg, lReadTotal, 0 ));
  97. hg = hg2;
  98. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHGlobalToHex( hg, bstrHex ));
  99. *pbstrData = bstrHex.Detach();
  100. }
  101. hr = S_OK;
  102. __HCP_FUNC_CLEANUP;
  103. if(hg) ::GlobalFree( hg );
  104. __HCP_FUNC_EXIT(hr);
  105. }
  106. STDMETHODIMP CPCHScriptableStream::Write( /*[in]*/ long lCount, /*[in]*/ VARIANT vData, /*[out, retval]*/ long *plWritten )
  107. {
  108. __HCP_FUNC_ENTRY( "CPCHScriptableStream::get_Size" );
  109. HRESULT hr;
  110. BYTE* rgBuf = NULL;
  111. DWORD dwLen = 0;
  112. bool fAccessData = false;
  113. __MPC_PARAMCHECK_BEGIN(hr)
  114. __MPC_PARAMCHECK_POINTER_AND_SET(plWritten,0);
  115. __MPC_PARAMCHECK_END();
  116. switch(vData.vt)
  117. {
  118. case VT_EMPTY:
  119. case VT_NULL:
  120. break;
  121. case VT_ARRAY | VT_UI1:
  122. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertVariantToBuffer( &vData, rgBuf, dwLen ));
  123. break;
  124. case VT_ARRAY | VT_VARIANT:
  125. {
  126. long lBound; ::SafeArrayGetLBound( vData.parray, 1, &lBound );
  127. long uBound; ::SafeArrayGetUBound( vData.parray, 1, &uBound );
  128. VARIANT* pSrc;
  129. DWORD dwPos;
  130. dwLen = uBound - lBound + 1;
  131. __MPC_EXIT_IF_ALLOC_FAILS(hr, rgBuf, new BYTE[dwLen]);
  132. __MPC_EXIT_IF_METHOD_FAILS(hr, ::SafeArrayAccessData( vData.parray, (LPVOID*)&pSrc ));
  133. fAccessData = true;
  134. for(dwPos=0; dwPos<dwLen; dwPos++, pSrc++)
  135. {
  136. CComVariant v;
  137. __MPC_EXIT_IF_METHOD_FAILS(hr, ::VariantChangeType( &v, pSrc, 0, VT_UI1 ));
  138. rgBuf[dwPos] = v.bVal;
  139. }
  140. }
  141. break;
  142. }
  143. if(dwLen && rgBuf)
  144. {
  145. ULONG lWritten;
  146. //
  147. // Just write the requested number of bytes.
  148. //
  149. if(lCount >= 0 && dwLen > lCount) dwLen = lCount;
  150. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FileStream::Write( rgBuf, dwLen, &lWritten ));
  151. *plWritten = lWritten;
  152. }
  153. hr = S_OK;
  154. __HCP_FUNC_CLEANUP;
  155. if(fAccessData) ::SafeArrayUnaccessData( vData.parray );
  156. delete [] rgBuf;
  157. __HCP_FUNC_EXIT(hr);
  158. }
  159. STDMETHODIMP CPCHScriptableStream::WriteHex( /*[in]*/ long lCount, /*[in]*/ BSTR bstrData, /*[out, retval]*/ long *plWritten )
  160. {
  161. __HCP_FUNC_ENTRY( "CPCHScriptableStream::get_Size" );
  162. HRESULT hr;
  163. HGLOBAL hg = NULL;
  164. __MPC_PARAMCHECK_BEGIN(hr)
  165. __MPC_PARAMCHECK_POINTER_AND_SET(plWritten,0);
  166. __MPC_PARAMCHECK_END();
  167. if(STRINGISPRESENT(bstrData))
  168. {
  169. CComBSTR bstrHex( bstrData );
  170. ULONG lWritten = 0;
  171. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHexToHGlobal( bstrHex, hg, true ));
  172. if(hg)
  173. {
  174. DWORD dwSize = ::GlobalSize( hg );
  175. //
  176. // Just write the requested number of bytes.
  177. //
  178. if(lCount >= 0 && lCount > dwSize) lCount = dwSize;
  179. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FileStream::Write( (BYTE*)hg, lCount, &lWritten ));
  180. }
  181. *plWritten = lWritten;
  182. }
  183. hr = S_OK;
  184. __HCP_FUNC_CLEANUP;
  185. if(hg) ::GlobalFree( hg );
  186. __HCP_FUNC_EXIT(hr);
  187. }
  188. STDMETHODIMP CPCHScriptableStream::Seek( /*[in]*/ long lOffset, /*[in]*/ BSTR bstrOrigin, /*[out, retval]*/ long *plNewPos )
  189. {
  190. __HCP_FUNC_ENTRY( "CPCHScriptableStream::get_Size" );
  191. HRESULT hr;
  192. DWORD dwOrigin;
  193. LARGE_INTEGER liMove;
  194. ULARGE_INTEGER liNewPos;
  195. __MPC_PARAMCHECK_BEGIN(hr)
  196. __MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrOrigin);
  197. __MPC_PARAMCHECK_POINTER_AND_SET(plNewPos,0);
  198. __MPC_PARAMCHECK_END();
  199. if (!_wcsicmp( bstrOrigin, L"SET" )) dwOrigin = STREAM_SEEK_SET;
  200. else if(!_wcsicmp( bstrOrigin, L"CUR" )) dwOrigin = STREAM_SEEK_CUR;
  201. else if(!_wcsicmp( bstrOrigin, L"END" )) dwOrigin = STREAM_SEEK_END;
  202. else __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
  203. liMove.QuadPart = lOffset;
  204. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FileStream::Seek( liMove, dwOrigin, &liNewPos ));
  205. *plNewPos = liNewPos.QuadPart;
  206. hr = S_OK;
  207. __HCP_FUNC_CLEANUP;
  208. __HCP_FUNC_EXIT(hr);
  209. }
  210. STDMETHODIMP CPCHScriptableStream::Close()
  211. {
  212. MPC::FileStream::Close();
  213. return S_OK;
  214. }