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.

162 lines
4.0 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: MemSer.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. CMemSerStream::CMemSerStream( unsigned cb )
  31. : _cb( cb )
  32. {
  33. _pb = new BYTE[cb];
  34. if (_pb != NULL) {
  35. _pbCurrent = _pb;
  36. _pbEnd = _pb + _cb;
  37. }
  38. }
  39. CMemSerStream::CMemSerStream( BYTE * pb, ULONG cb )
  40. : _cb( 0 ),
  41. _pb( pb ),
  42. _pbCurrent( _pb ),
  43. _pbEnd(_pb + cb)
  44. {
  45. }
  46. CMemSerStream::~CMemSerStream()
  47. {
  48. if ( _cb > 0 )
  49. delete [] _pb;
  50. }
  51. void CMemSerStream::PutByte( BYTE b )
  52. {
  53. HANDLE_OVERFLOW((_pbCurrent + 1) > _pbEnd);
  54. *_pbCurrent++ = b;
  55. }
  56. void CMemSerStream::PutChar( char const * pc, ULONG cc )
  57. {
  58. BYTE *pb = _pbCurrent;
  59. _pbCurrent += cc;
  60. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  61. memcpy( pb, pc, cc );
  62. }
  63. void CMemSerStream::PutWChar( WCHAR const * pwc, ULONG cc )
  64. {
  65. WCHAR * pwcTemp = AlignWCHAR(_pbCurrent);
  66. _pbCurrent = (BYTE *)(pwcTemp + cc);
  67. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  68. memcpy( pwcTemp, pwc, cc * sizeof(WCHAR) );
  69. }
  70. void CMemSerStream::PutUShort( USHORT us )
  71. {
  72. USHORT * pus = AlignUSHORT(_pbCurrent);
  73. _pbCurrent = (BYTE *)(pus + 1);
  74. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  75. *pus = us;
  76. }
  77. void CMemSerStream::PutULong( ULONG ul )
  78. {
  79. ULONG * pul = AlignULONG(_pbCurrent);
  80. _pbCurrent = (BYTE *)(pul + 1);
  81. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  82. *pul = ul;
  83. }
  84. void CMemSerStream::PutLong( long l )
  85. {
  86. long * pl = AlignLong(_pbCurrent);
  87. _pbCurrent = (BYTE *)(pl + 1);
  88. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  89. *pl = l;
  90. }
  91. void CMemSerStream::PutFloat( float f )
  92. {
  93. float * pf = AlignFloat(_pbCurrent);
  94. _pbCurrent = (BYTE *)(pf + 1);
  95. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  96. *pf = f;
  97. }
  98. void CMemSerStream::PutDouble( double d )
  99. {
  100. double * pd = AlignDouble(_pbCurrent);
  101. _pbCurrent = (BYTE *)(pd + 1);
  102. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  103. *pd = d;
  104. }
  105. void CMemSerStream::PutString( char const * psz )
  106. {
  107. ASSERT(IsAnsiString(psz, MAXULONG));
  108. ULONG len = strlen(psz);
  109. ULONG * pul = AlignULONG(_pbCurrent);
  110. BYTE *pb = (BYTE *)(pul + 1);
  111. _pbCurrent = pb + len;
  112. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  113. *pul = len;
  114. memcpy(pb, psz, len);
  115. }
  116. void CMemSerStream::PutWString( WCHAR const * pwsz )
  117. {
  118. ASSERT(IsUnicodeString(pwsz, MAXULONG));
  119. ULONG len = wcslen(pwsz);
  120. ULONG * pul = AlignULONG(_pbCurrent);
  121. BYTE *pb = (BYTE *)(pul + 1);
  122. _pbCurrent = pb + len * sizeof(WCHAR);
  123. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  124. *pul = len;
  125. memcpy(pb, pwsz, (len * sizeof(WCHAR)));
  126. }
  127. void CMemSerStream::PutBlob( BYTE const * pbBlob, ULONG cb )
  128. {
  129. BYTE *pb = _pbCurrent;
  130. _pbCurrent += cb;
  131. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  132. memcpy( pb, pbBlob, cb );
  133. }
  134. void CMemSerStream::PutGUID( GUID const & guid )
  135. {
  136. GUID * pguid = (GUID *)AlignGUID(_pbCurrent);
  137. _pbCurrent = (BYTE *)(pguid + 1);
  138. HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
  139. memcpy( pguid, &guid, sizeof(guid) );
  140. }