Source code of Windows XP (NT5)
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.

252 lines
6.0 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: MemDeSer.cxx
  7. //
  8. // History: 29-Jul-94 KyleP Created
  9. //
  10. //
  11. // The CMemSerStream and CDeMemSerStream have different requirements for
  12. // handling buffer overflow conditions. In the case of the driver this
  13. // is indicative of a corrupted stream and we would like to raise an
  14. // exception. On the other hand in Query implementation we deal with
  15. // streams whose sizes are precomputed in the user mode. Therefore we
  16. // do not wish to incur any additional penalty in handling such situations.
  17. // In debug builds this condition is asserted while in retail builds it is
  18. // ignored. The CMemSerStream and CMemDeSerStream implementation are
  19. // implemented using a macro HANDLE_OVERFLOW(fOverflow) which take the
  20. // appropriate action.
  21. //
  22. //--------------------------------------------------------------------------
  23. #include <pch.cxx>
  24. #pragma hdrstop
  25. #include "serover.hxx"
  26. #if DBGPROP
  27. BOOLEAN IsUnicodeString(WCHAR const *pwszname, ULONG cb);
  28. BOOLEAN IsAnsiString(CHAR const *pszname, ULONG cb);
  29. #endif
  30. BYTE CMemDeSerStream::GetByte()
  31. {
  32. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  33. BYTE b = *_pbCurrent;
  34. _pbCurrent += 1;
  35. return(b);
  36. }
  37. void CMemDeSerStream::SkipByte()
  38. {
  39. _pbCurrent += 1;
  40. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  41. }
  42. void CMemDeSerStream::GetChar( char * pc, ULONG cc )
  43. {
  44. BYTE *pb = _pbCurrent;
  45. _pbCurrent += cc;
  46. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  47. memcpy( pc, pb, cc );
  48. }
  49. void CMemDeSerStream::SkipChar( ULONG cc )
  50. {
  51. _pbCurrent += cc;
  52. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  53. }
  54. void CMemDeSerStream::GetWChar( WCHAR * pwc, ULONG cc )
  55. {
  56. WCHAR * pwcTemp = AlignWCHAR(_pbCurrent);
  57. _pbCurrent = (BYTE *)(pwcTemp + cc);
  58. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  59. memcpy( pwc, pwcTemp, cc * sizeof(WCHAR) );
  60. }
  61. void CMemDeSerStream::SkipWChar( ULONG cc )
  62. {
  63. WCHAR * pwcTemp = AlignWCHAR(_pbCurrent);
  64. _pbCurrent = (BYTE *)(pwcTemp + cc);
  65. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  66. }
  67. USHORT CMemDeSerStream::GetUShort()
  68. {
  69. USHORT * pus = AlignUSHORT(_pbCurrent);
  70. _pbCurrent = (BYTE *)(pus + 1);
  71. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  72. return( *pus );
  73. }
  74. void CMemDeSerStream::SkipUShort()
  75. {
  76. USHORT * pus = AlignUSHORT(_pbCurrent);
  77. _pbCurrent = (BYTE *)(pus + 1);
  78. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  79. }
  80. ULONG CMemDeSerStream::GetULong()
  81. {
  82. ULONG * pul = AlignULONG(_pbCurrent);
  83. _pbCurrent = (BYTE *)(pul + 1);
  84. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  85. return( *pul );
  86. }
  87. void CMemDeSerStream::SkipULong()
  88. {
  89. ULONG * pul = AlignULONG(_pbCurrent);
  90. _pbCurrent = (BYTE *)(pul + 1);
  91. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  92. }
  93. long CMemDeSerStream::GetLong()
  94. {
  95. long * pl = AlignLong(_pbCurrent);
  96. _pbCurrent = (BYTE *)(pl + 1);
  97. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  98. return( *pl );
  99. }
  100. void CMemDeSerStream::SkipLong()
  101. {
  102. long * pl = AlignLong(_pbCurrent);
  103. _pbCurrent = (BYTE *)(pl + 1);
  104. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  105. }
  106. #if defined(KERNEL) // Can not return floats in the kernel
  107. ULONG CMemDeSerStream::GetFloat()
  108. {
  109. ASSERT( sizeof(ULONG) == sizeof(float) );
  110. ULONG * pf = (ULONG *) AlignFloat(_pbCurrent);
  111. #else
  112. float CMemDeSerStream::GetFloat()
  113. {
  114. float * pf = AlignFloat(_pbCurrent);
  115. #endif
  116. _pbCurrent = (BYTE *)(pf + 1);
  117. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  118. return( *pf );
  119. }
  120. void CMemDeSerStream::SkipFloat()
  121. {
  122. float * pf = AlignFloat(_pbCurrent);
  123. _pbCurrent = (BYTE *)(pf + 1);
  124. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  125. }
  126. #if defined(KERNEL) // Can not return doubles in the kernel
  127. LONGLONG CMemDeSerStream::GetDouble()
  128. {
  129. ASSERT( sizeof(LONGLONG) == sizeof(double) );
  130. LONGLONG * pd = (LONGLONG *) AlignDouble(_pbCurrent);
  131. #else
  132. double CMemDeSerStream::GetDouble()
  133. {
  134. double * pd = AlignDouble(_pbCurrent);
  135. #endif
  136. _pbCurrent = (BYTE *)(pd + 1);
  137. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  138. return( *pd );
  139. }
  140. void CMemDeSerStream::SkipDouble()
  141. {
  142. double * pd = AlignDouble(_pbCurrent);
  143. _pbCurrent = (BYTE *)(pd + 1);
  144. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  145. }
  146. ULONG CMemDeSerStream::PeekULong()
  147. {
  148. ULONG * pul = AlignULONG(_pbCurrent);
  149. HANDLE_OVERFLOW(((BYTE *)pul + sizeof(ULONG)) > _pbEnd);
  150. return( *pul );
  151. }
  152. char * CMemDeSerStream::GetString()
  153. {
  154. ULONG * pul = AlignULONG(_pbCurrent);
  155. _pbCurrent = (BYTE *)(pul + 1);
  156. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  157. ULONG len = *pul;
  158. CHAR *pszTemp = (CHAR *)_pbCurrent;
  159. _pbCurrent += len;
  160. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  161. char * psz = new char[len+1];
  162. if (psz != NULL) {
  163. memcpy(psz, pszTemp, len);
  164. psz[len] = '\0';
  165. ASSERT(IsAnsiString(psz, len + 1));
  166. }
  167. return(psz);
  168. }
  169. WCHAR * CMemDeSerStream::GetWString()
  170. {
  171. ULONG * pul = AlignULONG(_pbCurrent);
  172. _pbCurrent = (BYTE *)(pul + 1);
  173. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  174. ULONG len = *pul;
  175. WCHAR *pwszTemp = (WCHAR *)_pbCurrent;
  176. _pbCurrent += len * sizeof(WCHAR);
  177. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  178. WCHAR * pwsz = new WCHAR[len + 1];
  179. if (pwsz != NULL) {
  180. memcpy(pwsz, pwszTemp, len * sizeof(WCHAR) );
  181. pwsz[len] = L'\0';
  182. ASSERT(IsUnicodeString(pwsz, (len + 1) * sizeof(WCHAR)));
  183. }
  184. return(pwsz);
  185. }
  186. void CMemDeSerStream::GetBlob( BYTE * pb, ULONG cb )
  187. {
  188. BYTE *pbTemp = _pbCurrent;
  189. _pbCurrent += cb;
  190. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  191. memcpy( pb, pbTemp, cb );
  192. }
  193. void CMemDeSerStream::SkipBlob( ULONG cb )
  194. {
  195. _pbCurrent += cb;
  196. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  197. }
  198. void CMemDeSerStream::GetGUID( GUID & guid )
  199. {
  200. GUID * pguid = (GUID *)AlignGUID(_pbCurrent);
  201. _pbCurrent = (BYTE *)(pguid + 1);
  202. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  203. guid = *pguid;
  204. }
  205. void CMemDeSerStream::SkipGUID()
  206. {
  207. GUID * pguid = (GUID *)AlignGUID(_pbCurrent);
  208. _pbCurrent = (BYTE *)(pguid + 1);
  209. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  210. }