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.

161 lines
4.8 KiB

  1. /*--------------------------------------------------------------------------*
  2. *
  3. * Microsoft Windows
  4. * Copyright (C) Microsoft Corporation, 1999 - 1999
  5. *
  6. * File: serial.cpp
  7. *
  8. * Contents: Object serialization class implementation
  9. *
  10. * History: 11-Feb-99 vivekj Created
  11. *
  12. *--------------------------------------------------------------------------*/
  13. #include "stgio.h"
  14. #include "stddbg.h"
  15. #include "macros.h"
  16. #include <comdef.h>
  17. #include "serial.h"
  18. /*+-------------------------------------------------------------------------*
  19. *
  20. * CSerialObject::Write
  21. *
  22. * PURPOSE: Writes an object with version and size information. This information
  23. * is used when the object is read. If an unknown version of the object
  24. * is presented, the data is discarded. This way, all known data can
  25. * still be retrieved. (Useful for backward as well as forward compatibility.)
  26. *
  27. * PARAMETERS:
  28. * IStream & stm :
  29. *
  30. * RETURNS:
  31. * HRESULT
  32. *
  33. *+-------------------------------------------------------------------------*/
  34. HRESULT
  35. CSerialObjectRW::Write(IStream &stm)
  36. {
  37. HRESULT hr = S_OK;
  38. UINT nVersion = GetVersion();
  39. ULARGE_INTEGER nSeekPosMarker;
  40. ULARGE_INTEGER nSeekPosNextObj;
  41. LARGE_INTEGER lZero;
  42. LARGE_INTEGER lint;
  43. try
  44. {
  45. do // not a loop
  46. {
  47. lZero.LowPart = 0;
  48. lZero.HighPart= 0;
  49. lZero.QuadPart= 0; // just to be safe.
  50. stm << nVersion; // save the version information
  51. hr = stm.Seek(lZero, STREAM_SEEK_CUR, &nSeekPosMarker); // get the current location of the pointer
  52. BREAK_ON_FAIL(hr);
  53. ::ZeroMemory(&nSeekPosNextObj, sizeof(nSeekPosNextObj) );
  54. // should we use the low part only? Or will this cause a Y2K like crisis?
  55. stm << nSeekPosNextObj.QuadPart; // not the correct value; need to come back and fix (done below)
  56. #ifdef DBG
  57. ULARGE_INTEGER nSeekPosMarker2;
  58. hr = stm.Seek(lZero, STREAM_SEEK_CUR, &nSeekPosMarker2); // get the current location of the pointer
  59. BREAK_ON_FAIL(hr);
  60. #endif
  61. hr = WriteSerialObject(stm); // write the internal data
  62. BREAK_ON_FAIL(hr);
  63. hr = stm.Seek(lZero, STREAM_SEEK_CUR, &nSeekPosNextObj);
  64. BREAK_ON_FAIL(hr);
  65. // go back to the placeholder marker
  66. lint.QuadPart = nSeekPosMarker.QuadPart;
  67. hr = stm.Seek(lint, STREAM_SEEK_SET, NULL);
  68. BREAK_ON_FAIL(hr);
  69. stm << nSeekPosNextObj.QuadPart; // the correct value of the marker
  70. #ifdef DBG
  71. ULARGE_INTEGER nSeekPosMarker3;
  72. hr = stm.Seek(lZero, STREAM_SEEK_CUR, &nSeekPosMarker3); // get the current location of the pointer
  73. BREAK_ON_FAIL(hr);
  74. // make sure we're back in the same place
  75. ASSERT( (nSeekPosMarker2.QuadPart == nSeekPosMarker3.QuadPart) );
  76. #endif
  77. lint.QuadPart = nSeekPosNextObj.QuadPart;
  78. hr = stm.Seek(lint, STREAM_SEEK_SET, NULL);
  79. BREAK_ON_FAIL(hr);
  80. } while (false);
  81. }
  82. catch (_com_error& err)
  83. {
  84. hr = err.Error();
  85. ASSERT (false && "Caught _com_error");
  86. }
  87. return hr;
  88. }
  89. /*+-------------------------------------------------------------------------*
  90. *
  91. * CSerialObject::Read
  92. *
  93. * PURPOSE:
  94. *
  95. * PARAMETERS:
  96. * IStream & stm :
  97. *
  98. * RETURNS:
  99. * HRESULT - S_OK if able to read the object.
  100. * S_FALSE if skipped reading the object.
  101. * E_FAIL Could not skip the object or something catastrophic.
  102. *
  103. *+-------------------------------------------------------------------------*/
  104. HRESULT
  105. CSerialObject::Read(IStream &stm)
  106. {
  107. HRESULT hr = S_OK;
  108. UINT nVersion = 0;
  109. ULARGE_INTEGER nSeekPosMarker;
  110. ULARGE_INTEGER nSeekPosNextObj;
  111. LARGE_INTEGER lint;
  112. try
  113. {
  114. stm >> nVersion; // get the version number
  115. stm >> nSeekPosNextObj.QuadPart; // get the offset to the next object
  116. hr = ReadSerialObject(stm, nVersion);
  117. if (hr==S_FALSE) // data skipped?
  118. {
  119. // an unknown version. Throw the data for that object away and continue to read other objects
  120. lint.QuadPart = nSeekPosNextObj.QuadPart;
  121. hr = stm.Seek(lint, STREAM_SEEK_SET, NULL);
  122. if (SUCCEEDED (hr))
  123. hr = S_FALSE; // propagate "data skipped"
  124. }
  125. }
  126. catch (_com_error& err)
  127. {
  128. hr = err.Error();
  129. ASSERT (false && "Caught _com_error");
  130. }
  131. return (hr);
  132. }