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.

238 lines
7.0 KiB

  1. // stream i/o functions
  2. #include "stdafx.h"
  3. #include <comutil.h>
  4. #include <memory>
  5. // Used Defines
  6. #define THROW_ON_FAILURE(hr) if (FAILED(hr)) _com_issue_error(hr);
  7. #define THROW_ERROR(hr) _com_issue_error(hr);
  8. /*+-------------------------------------------------------------------------*
  9. * ReadScalar
  10. *
  11. * Reads a scalar value from a stream.
  12. *--------------------------------------------------------------------------*/
  13. template<class T>
  14. static IStream& ReadScalar (IStream& stm, T& t)
  15. {
  16. ULONG cbActuallyRead;
  17. HRESULT hr = stm.Read (&t, sizeof (t), &cbActuallyRead);
  18. THROW_ON_FAILURE(hr);
  19. if (cbActuallyRead != sizeof (t))
  20. _com_issue_error (E_FAIL);
  21. return (stm);
  22. }
  23. /*+-------------------------------------------------------------------------*
  24. * WriteScalar
  25. *
  26. * Writes a scalar value to a stream.
  27. *--------------------------------------------------------------------------*/
  28. template<class T>
  29. static IStream& WriteScalar (IStream& stm, const T& t)
  30. {
  31. ULONG cbActuallyWritten;
  32. HRESULT hr = stm.Write (&t, sizeof (t), &cbActuallyWritten);
  33. THROW_ON_FAILURE(hr);
  34. if (cbActuallyWritten != sizeof (t))
  35. THROW_ERROR(E_FAIL);
  36. return (stm);
  37. }
  38. //----------------------------------------------------------------
  39. // Define by-value stream operators
  40. //----------------------------------------------------------------
  41. #define DefineScalarStreamOperators(scalar_type) \
  42. IStream& operator>> (IStream& stm, scalar_type& t) \
  43. { return (ReadScalar (stm, t)); } \
  44. IStream& operator<< (IStream& stm, scalar_type t) \
  45. { return (WriteScalar (stm, t)); }
  46. DefineScalarStreamOperators ( bool);
  47. DefineScalarStreamOperators ( char);
  48. DefineScalarStreamOperators (unsigned char);
  49. DefineScalarStreamOperators ( short);
  50. DefineScalarStreamOperators (unsigned short);
  51. DefineScalarStreamOperators ( int);
  52. DefineScalarStreamOperators (unsigned int);
  53. DefineScalarStreamOperators ( long);
  54. DefineScalarStreamOperators (unsigned long);
  55. //----------------------------------------------------------------
  56. // Define by-value stream operators
  57. //----------------------------------------------------------------
  58. #define DefineScalarStreamOperatorsByRef(scalar_type) \
  59. IStream& operator>> (IStream& stm, scalar_type& t) \
  60. { return (ReadScalar (stm, t)); } \
  61. IStream& operator<< (IStream& stm, const scalar_type& t) \
  62. { return (WriteScalar (stm, t)); }
  63. DefineScalarStreamOperatorsByRef(CLSID);
  64. DefineScalarStreamOperatorsByRef(FILETIME);
  65. /*+-------------------------------------------------------------------------*
  66. * ReadString
  67. *
  68. * Reads a std::basic_string of char type CH from a stream. The string should
  69. * have been written with a DWORD character count preceding an array of
  70. * characters that is not NULL-terminated.
  71. *--------------------------------------------------------------------------*/
  72. template<class CH>
  73. static IStream& ReadString (IStream& stm, std::basic_string<CH>& str)
  74. {
  75. /*
  76. * read the length
  77. */
  78. DWORD cch;
  79. stm >> cch;
  80. /*
  81. * allocate a buffer for the characters
  82. */
  83. std::auto_ptr<CH> spBuffer (new (std::nothrow) CH[cch + 1]);
  84. CH* pBuffer = spBuffer.get();
  85. if (pBuffer == NULL)
  86. THROW_ERROR(E_OUTOFMEMORY);
  87. /*
  88. * read the characters
  89. */
  90. ULONG cbActuallyRead;
  91. const ULONG cbToRead = cch * sizeof (CH);
  92. HRESULT hr = stm.Read (pBuffer, cbToRead, &cbActuallyRead);
  93. THROW_ON_FAILURE(hr);
  94. if (cbToRead != cbActuallyRead)
  95. THROW_ERROR(E_FAIL);
  96. /*
  97. * terminate the character array and assign it to the string
  98. */
  99. pBuffer[cch] = 0;
  100. /*
  101. * assign it to the string (clear the string first to work around
  102. * the bug described in KB Q172398)
  103. */
  104. str.erase();
  105. str = pBuffer;
  106. return (stm);
  107. }
  108. /*+-------------------------------------------------------------------------*
  109. * ReadString for byte_string
  110. *
  111. * Specialization of ReadString for a string of bytes which may contain NULLs.
  112. * he string should have been written with a DWORD character count preceding
  113. * an array of characters that is not NULL-terminated.
  114. *--------------------------------------------------------------------------*/
  115. static IStream& ReadString (IStream& stm, std::basic_string<BYTE>& str)
  116. {
  117. /*
  118. * read the length
  119. */
  120. DWORD cch;
  121. stm >> cch;
  122. if (cch == 0)
  123. {
  124. str.erase();
  125. }
  126. else
  127. {
  128. /*
  129. * allocate a buffer for the characters
  130. */
  131. std::auto_ptr<BYTE> spBuffer (new (std::nothrow) BYTE[cch]);
  132. BYTE* pBuffer = spBuffer.get();
  133. if (pBuffer == NULL)
  134. THROW_ERROR(E_OUTOFMEMORY);
  135. /*
  136. * read the characters
  137. */
  138. ULONG cbActuallyRead;
  139. const ULONG cbToRead = cch;
  140. HRESULT hr = stm.Read (pBuffer, cbToRead, &cbActuallyRead);
  141. THROW_ON_FAILURE(hr);
  142. if (cbToRead != cbActuallyRead)
  143. THROW_ERROR(E_FAIL);
  144. /*
  145. * assign it to the string (clear the string first to work around
  146. * the bug described in KB Q172398)
  147. */
  148. str.erase();
  149. str.assign(pBuffer, cch);
  150. }
  151. return (stm);
  152. }
  153. /*+-------------------------------------------------------------------------*
  154. * WriteString
  155. *
  156. * Writes a std::basic_string of char type CH to a stream. The string is
  157. * written with a DWORD character count preceding an array of characters that
  158. * is not NULL-terminated.
  159. *--------------------------------------------------------------------------*/
  160. template<class CH>
  161. static IStream& WriteString (IStream& stm, const std::basic_string<CH>& str)
  162. {
  163. /*
  164. * write the length
  165. */
  166. DWORD cch = str.length();
  167. stm << cch;
  168. if (cch > 0)
  169. {
  170. /*
  171. * write the characters
  172. */
  173. ULONG cbActuallyWritten;
  174. const ULONG cbToWrite = cch * sizeof (CH);
  175. HRESULT hr = stm.Write (str.data(), cbToWrite, &cbActuallyWritten);
  176. THROW_ON_FAILURE(hr);
  177. if (cbToWrite != cbActuallyWritten)
  178. THROW_ERROR(E_FAIL);
  179. }
  180. return (stm);
  181. }
  182. //-----------------------------------------------------------------
  183. // Define basic string stream operators
  184. //-----------------------------------------------------------------
  185. #define DefineStringStreamOperators(string_type) \
  186. IStream& operator>> (IStream& stm, string_type& str) \
  187. { return (ReadString (stm, str)); } \
  188. IStream& operator<< (IStream& stm, const string_type& str) \
  189. { return (WriteString (stm, str)); }
  190. DefineStringStreamOperators(tstring);
  191. DefineStringStreamOperators(byte_string);