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.

234 lines
6.9 KiB

  1. /*++
  2. Copyright (C) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. writer.cpp
  5. Abstract:
  6. Volume SnapShot Writer for WMI
  7. History:
  8. a-shawnb 06-Nov-00 Created
  9. --*/
  10. #include "precomp.h"
  11. #include "writer.h"
  12. #include <genutils.h> // for EnableAllPrivileges()
  13. #include <malloc.h>
  14. #include <stdio.h>
  15. #include <helper.h>
  16. CWbemVssWriter::CWbemVssWriter() : CVssWriter(),
  17. m_pBackupRestore(NULL),
  18. m_hResFailure(S_OK),
  19. m_FailurePos(-1)
  20. {
  21. }
  22. CWbemVssWriter::~CWbemVssWriter()
  23. {
  24. if (m_pBackupRestore)
  25. {
  26. m_pBackupRestore->Resume();
  27. m_pBackupRestore->Release();
  28. m_pBackupRestore = NULL;
  29. }
  30. }
  31. HRESULT STDMETHODCALLTYPE
  32. CWbemVssWriter::LogFailure(HRESULT hr)
  33. {
  34. #ifdef DBG
  35. ERRORTRACE((LOG_WINMGMT,"CWbemVssWriter experienced failure %08x at position %d\n",m_hResFailure,m_FailurePos));
  36. #else
  37. DEBUGTRACE((LOG_WINMGMT,"CWbemVssWriter experienced failure %08x at position %d\n",m_hResFailure,m_FailurePos));
  38. #endif
  39. return CVssWriter::SetWriterFailure(hr);
  40. }
  41. // {A6AD56C2-B509-4e6c-BB19-49D8F43532F0}
  42. static VSS_ID s_WRITERID = {0xa6ad56c2, 0xb509, 0x4e6c, 0xbb, 0x19, 0x49, 0xd8, 0xf4, 0x35, 0x32, 0xf0};
  43. static LPCWSTR s_WRITERNAME = L"WMI Writer";
  44. HRESULT CWbemVssWriter::Initialize()
  45. {
  46. return CVssWriter::Initialize(s_WRITERID, s_WRITERNAME, VSS_UT_SYSTEMSERVICE, VSS_ST_OTHER);
  47. }
  48. extern HRESULT GetRepositoryDirectory(wchar_t wszRepositoryDirectory[MAX_PATH+1]);
  49. #define IF_FAILED_RETURN_FALSE( _hr_ ) \
  50. if (FAILED(_hr_)) { m_hResFailure = _hr_; m_FailurePos = __LINE__; return false; }
  51. bool STDMETHODCALLTYPE CWbemVssWriter::OnIdentify(IN IVssCreateWriterMetadata *pMetadata)
  52. {
  53. OnDeleteObjIf<HRESULT,
  54. CWbemVssWriter,
  55. HRESULT(STDMETHODCALLTYPE CWbemVssWriter::*)(HRESULT),
  56. &CWbemVssWriter::LogFailure> CallMe(this,VSS_E_WRITERERROR_RETRYABLE);
  57. wchar_t wszRepositoryDirectory[MAX_PATH+1];
  58. HRESULT hr = GetRepositoryDirectory(wszRepositoryDirectory);
  59. IF_FAILED_RETURN_FALSE(hr);
  60. hr = pMetadata->AddComponent( VSS_CT_FILEGROUP,
  61. NULL,
  62. L"WMI",
  63. L"Windows Managment Instrumentation",
  64. NULL,
  65. 0,
  66. false,
  67. false,
  68. false);
  69. IF_FAILED_RETURN_FALSE(hr);
  70. hr = pMetadata->AddFilesToFileGroup(NULL,
  71. L"WMI",
  72. wszRepositoryDirectory,
  73. L"*.*",
  74. true,
  75. NULL);
  76. IF_FAILED_RETURN_FALSE(hr);
  77. hr = pMetadata->SetRestoreMethod(VSS_RME_RESTORE_AT_REBOOT,
  78. NULL,
  79. NULL,
  80. VSS_WRE_NEVER,
  81. true);
  82. IF_FAILED_RETURN_FALSE(hr);
  83. CallMe.dismiss(); // if returning true, do not set a failure
  84. return true;
  85. }
  86. bool STDMETHODCALLTYPE CWbemVssWriter::OnPrepareSnapshot()
  87. {
  88. return true;
  89. }
  90. //
  91. // to debug Volume Snapshot failure in IOStress we introduced
  92. // some self instrumentation that did relay on RtlCaptureStackBacktrace
  93. // that function works only if there is a proper stack frame
  94. // the general trick to force stack frames on i386 is the usage of _alloca
  95. //
  96. //#ifdef _X86_
  97. // DWORD * pDW = (DWORD *)_alloca(sizeof(DWORD));
  98. //#endif
  99. // enable generation of stack frames here
  100. #pragma optimize( "y", off )
  101. //
  102. // Doing the Job on this method, we will have a time-out guarantee
  103. // We sync the OnFreeze and the OnAbort/OnThaw calls,
  104. // so that, if a TimeOut occurs, we are not arbitrarly unlocking the repository
  105. //
  106. ///////////////////////////////////////////////////////////////
  107. bool STDMETHODCALLTYPE CWbemVssWriter::OnFreeze()
  108. {
  109. OnDeleteObjIf<HRESULT,
  110. CWbemVssWriter,
  111. HRESULT(STDMETHODCALLTYPE CWbemVssWriter::*)(HRESULT),
  112. &CWbemVssWriter::LogFailure> CallMe(this,VSS_E_WRITERERROR_RETRYABLE);
  113. CInCritSec ics(&m_Lock);
  114. // m_pBackupRestore should always be NULL coming into this
  115. if (m_pBackupRestore)
  116. {
  117. m_hResFailure = E_UNEXPECTED;
  118. m_FailurePos = __LINE__;
  119. return false;
  120. }
  121. HRESULT hr = CoCreateInstance(CLSID_WbemBackupRestore, 0, CLSCTX_INPROC_SERVER,
  122. IID_IWbemBackupRestoreEx, (LPVOID *) &m_pBackupRestore);
  123. IF_FAILED_RETURN_FALSE(hr);
  124. hr = EnableAllPrivileges(TOKEN_PROCESS);
  125. IF_FAILED_RETURN_FALSE(hr);
  126. hr = m_pBackupRestore->Pause();
  127. if (FAILED(hr))
  128. {
  129. m_pBackupRestore->Release();
  130. m_pBackupRestore = NULL;
  131. m_hResFailure = hr;
  132. m_FailurePos = __LINE__;
  133. return false;
  134. }
  135. CallMe.dismiss(); // if returning true, do not set a failure
  136. return true;
  137. }
  138. bool STDMETHODCALLTYPE CWbemVssWriter::OnThaw()
  139. {
  140. OnDeleteObjIf<HRESULT,
  141. CWbemVssWriter,
  142. HRESULT(STDMETHODCALLTYPE CWbemVssWriter::*)(HRESULT),
  143. &CWbemVssWriter::LogFailure> CallMe(this,VSS_E_WRITERERROR_RETRYABLE);
  144. CInCritSec ics(&m_Lock);
  145. if (!m_pBackupRestore)
  146. {
  147. m_hResFailure = E_UNEXPECTED;
  148. m_FailurePos = __LINE__;
  149. // if m_pBackupRestore is NULL, then we haven't been
  150. // asked to prepare or we failed our preparation
  151. return false;
  152. }
  153. HRESULT hr = m_pBackupRestore->Resume();
  154. if (FAILED(hr))
  155. {
  156. m_hResFailure = hr;
  157. m_FailurePos = __LINE__;
  158. }
  159. m_pBackupRestore->Release();
  160. m_pBackupRestore = NULL;
  161. bool bRet = SUCCEEDED(hr);
  162. CallMe.dismiss(bRet); // if returning true, do not set a failure
  163. return bRet;
  164. }
  165. bool STDMETHODCALLTYPE CWbemVssWriter::OnAbort()
  166. {
  167. OnDeleteObjIf<HRESULT,
  168. CWbemVssWriter,
  169. HRESULT(STDMETHODCALLTYPE CWbemVssWriter::*)(HRESULT),
  170. &CWbemVssWriter::LogFailure> CallMe(this,VSS_E_WRITERERROR_RETRYABLE);
  171. CInCritSec ics(&m_Lock);
  172. HRESULT hr = WBEM_S_NO_ERROR;
  173. if (m_pBackupRestore)
  174. {
  175. hr = m_pBackupRestore->Resume();
  176. if (FAILED(hr))
  177. {
  178. m_hResFailure = hr;
  179. m_FailurePos = __LINE__;
  180. }
  181. m_pBackupRestore->Release();
  182. m_pBackupRestore = NULL;
  183. }
  184. bool bRet = SUCCEEDED(hr);
  185. CallMe.dismiss(bRet); // if returning true, do not set a failure
  186. return bRet;
  187. }
  188. #pragma optimize( "", on )