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.

389 lines
8.7 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. All rights reserved
  4. Module Name:
  5. checkpoint.cxx
  6. Abstract:
  7. This file implements a class (or for 'C' handle based) calls to set and
  8. restore system breakpoints.
  9. Author:
  10. Mark Lawrence (mlawrenc).
  11. Environment:
  12. User Mode -Win32
  13. Revision History:
  14. --*/
  15. #include "spllibp.hxx"
  16. #pragma hdrstop
  17. #include "checkpoint.hxx"
  18. #include "safewrap.hxx"
  19. TSystemRestorePoint::
  20. TSystemRestorePoint(
  21. VOID
  22. ) : m_hLibrary(NULL),
  23. m_pfnSetRestorePoint(NULL),
  24. m_bSystemRestoreSet(FALSE),
  25. m_hr(E_FAIL)
  26. {
  27. memset(&m_RestorePointInfo, 0, sizeof(m_RestorePointInfo));
  28. m_hr = Initialize();
  29. }
  30. TSystemRestorePoint::
  31. ~TSystemRestorePoint(
  32. VOID
  33. )
  34. {
  35. if (m_hLibrary)
  36. {
  37. FreeLibrary(m_hLibrary);
  38. }
  39. }
  40. HRESULT
  41. TSystemRestorePoint::
  42. IsValid(
  43. VOID
  44. ) const
  45. {
  46. return m_hr;
  47. }
  48. /*++
  49. Routine Name:
  50. StartSystemRestorePoint
  51. Routine Description:
  52. This routine starts a system restore point in the AddPrinterDriver code.
  53. Arguments:
  54. pszServer - The server name on which we are setting the restore point.
  55. pszDriverName - The driver name of which we are trying to install.
  56. hInst - The hInstance of the resource library.
  57. ResId - The resource id to use for the message string.
  58. Return Value:
  59. An HRESULT.
  60. --*/
  61. HRESULT
  62. TSystemRestorePoint::
  63. StartSystemRestorePoint(
  64. IN PCWSTR pszServer,
  65. IN PCWSTR pszDriverName,
  66. IN HINSTANCE hInst,
  67. IN UINT ResId
  68. )
  69. {
  70. HRESULT hRetval = E_FAIL;
  71. STATEMGRSTATUS SMgrStatus;
  72. WCHAR szDriverName[MAX_DESC];
  73. WCHAR szMessage[MAX_DESC];
  74. hRetval = pszDriverName && hInst ? S_OK : HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
  75. //
  76. // We only set system restore points on the local machine for now.
  77. //
  78. if (SUCCEEDED(hRetval) && !pszServer)
  79. {
  80. if (SUCCEEDED(hRetval))
  81. {
  82. if (LoadString(hInst, ResId, szMessage, COUNTOF(szMessage)))
  83. {
  84. //
  85. // We have to check here if the length of the message
  86. // is at least two (because of the string terminator and
  87. // at least one format specifier)
  88. //
  89. if (lstrlen(szMessage) > 2)
  90. {
  91. hRetval = S_OK;
  92. }
  93. else
  94. {
  95. hRetval = HResultFromWin32(ERROR_RESOURCE_DATA_NOT_FOUND);
  96. }
  97. }
  98. else
  99. {
  100. hRetval = GetLastErrorAsHResult();
  101. }
  102. }
  103. if (SUCCEEDED(hRetval))
  104. {
  105. PWSTR pszArray[1];
  106. //
  107. // Now we calculate how much of the driver name we can fit into the
  108. // message (which is only 64 characters). This is
  109. // MAX_DESC - (strlen(szMessage) - 2) - 1.
  110. //
  111. StringCchCopyW(szDriverName, MAX_DESC - wcslen(szMessage) + 2, pszDriverName);
  112. pszArray[0] = szDriverName;
  113. hRetval = FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  114. szMessage,
  115. 0,
  116. 0,
  117. m_RestorePointInfo.szDescription,
  118. COUNTOF(m_RestorePointInfo.szDescription),
  119. (va_list *)pszArray) ? S_OK : GetLastErrorAsHResult();
  120. }
  121. //
  122. // Now that we have the system restore point, set it.
  123. //
  124. if (SUCCEEDED(hRetval))
  125. {
  126. m_RestorePointInfo.dwEventType = BEGIN_NESTED_SYSTEM_CHANGE;
  127. m_RestorePointInfo.dwRestorePtType = DEVICE_DRIVER_INSTALL;
  128. m_RestorePointInfo.llSequenceNumber = 0;
  129. hRetval = m_pfnSetRestorePoint(&m_RestorePointInfo, &SMgrStatus) ? S_OK : HRESULT_FROM_WIN32(SMgrStatus.nStatus);
  130. }
  131. if (SUCCEEDED(hRetval))
  132. {
  133. m_bSystemRestoreSet = TRUE;
  134. }
  135. else
  136. {
  137. //
  138. // Failing to set the system restore point should not stop us adding
  139. // the printer driver.
  140. //
  141. hRetval = S_OK;
  142. }
  143. }
  144. return hRetval;
  145. }
  146. /*++
  147. Routine Name:
  148. EndSystemRestorePoint
  149. Routine Description:
  150. This function either completes the system restore point or it cancels it
  151. if whoever was doing the installation tells us to.
  152. Arguments:
  153. bCancel - If TRUE, the restore point should be cancelled.
  154. Return Value:
  155. An HRESULT.
  156. --*/
  157. HRESULT
  158. TSystemRestorePoint::
  159. EndSystemRestorePoint(
  160. IN BOOL bCancel
  161. )
  162. {
  163. HRESULT hRetval = S_OK;
  164. STATEMGRSTATUS SMgrStatus;
  165. if (m_bSystemRestoreSet)
  166. {
  167. m_RestorePointInfo.dwEventType = END_NESTED_SYSTEM_CHANGE;
  168. m_RestorePointInfo.dwRestorePtType = bCancel ? CANCELLED_OPERATION : DEVICE_DRIVER_INSTALL;
  169. hRetval = m_pfnSetRestorePoint(&m_RestorePointInfo, &SMgrStatus) ? S_OK : HRESULT_FROM_WIN32(SMgrStatus.nStatus);
  170. }
  171. return hRetval;
  172. }
  173. /******************************************************************************
  174. Private Methods
  175. ******************************************************************************/
  176. /*++
  177. Routine Name:
  178. Initialize
  179. Routine Description:
  180. Load the system restore library and get the address of the system restore
  181. function.
  182. Arguments:
  183. None
  184. Return Value:
  185. An HRESULT
  186. --*/
  187. HRESULT
  188. TSystemRestorePoint::
  189. Initialize(
  190. VOID
  191. )
  192. {
  193. HRESULT hRetval = E_FAIL;
  194. m_hLibrary = LoadLibraryFromSystem32(L"srclient.dll");
  195. hRetval = m_hLibrary ? S_OK : GetLastErrorAsHResult();
  196. if (SUCCEEDED(hRetval))
  197. {
  198. m_pfnSetRestorePoint = reinterpret_cast<PFnSRSetRestorePoint>(GetProcAddress(m_hLibrary, "SRSetRestorePointW"));
  199. hRetval = m_pfnSetRestorePoint ? S_OK : GetLastErrorAsHResult();
  200. }
  201. return hRetval;
  202. }
  203. /*++
  204. Routine Name:
  205. StartSystemRestorePoint
  206. Routine Description:
  207. This form of the function is for C callers, it is handle based.
  208. Arguments:
  209. pszServer - The server on which we are doing the restore point.
  210. pszDriverName - The driver name we are installing.
  211. hInst - The instance in which the resource which we want to load is.
  212. ResId - The Resource Id.
  213. Return Value:
  214. An HRESULT
  215. --*/
  216. extern "C"
  217. HANDLE
  218. StartSystemRestorePoint(
  219. IN PCWSTR pszServer,
  220. IN PCWSTR pszDriverName,
  221. IN HINSTANCE hInst,
  222. IN UINT ResId
  223. )
  224. {
  225. HRESULT hRetval = E_FAIL;
  226. HANDLE hRestorePoint = NULL;
  227. #ifdef _WIN64
  228. return NULL;
  229. #endif
  230. TSystemRestorePoint *pSystemRestorePoint = new TSystemRestorePoint;
  231. hRetval = pSystemRestorePoint ? pSystemRestorePoint->IsValid() : E_OUTOFMEMORY;
  232. if (SUCCEEDED(hRetval))
  233. {
  234. hRetval = pSystemRestorePoint->StartSystemRestorePoint(pszServer, pszDriverName, hInst, ResId);
  235. }
  236. if (SUCCEEDED(hRetval))
  237. {
  238. hRestorePoint = pSystemRestorePoint;
  239. pSystemRestorePoint = NULL;
  240. }
  241. else
  242. {
  243. SetLastError(HRESULT_CODE(hRetval));
  244. }
  245. delete pSystemRestorePoint;
  246. return hRestorePoint;
  247. }
  248. /*++
  249. Routine Name:
  250. EndSystemRestorePoint
  251. Routine Description:
  252. This form of the function is for C callers, it is handle based.
  253. Note: This also closes the handle.
  254. Arguments:
  255. hRestorePoint - The system restore point.
  256. bCancel - If TRUE, the system restore point should be cancelled
  257. and not completed.
  258. Return Value:
  259. An HRESULT
  260. --*/
  261. extern "C"
  262. BOOL
  263. EndSystemRestorePoint(
  264. IN HANDLE hRestorePoint,
  265. IN BOOL bCancel
  266. )
  267. {
  268. HRESULT hRetval = E_FAIL;
  269. TSystemRestorePoint *pRestorePoint = reinterpret_cast<TSystemRestorePoint *>(hRestorePoint);
  270. #ifdef _WIN64
  271. return SUCCEEDED( E_FAIL );
  272. #endif
  273. hRetval = pRestorePoint ? S_OK : HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
  274. if (SUCCEEDED(hRetval))
  275. {
  276. hRetval = pRestorePoint->EndSystemRestorePoint(bCancel);
  277. delete pRestorePoint;
  278. }
  279. if (FAILED(hRetval))
  280. {
  281. SetLastError(HRESULT_CODE(hRetval));
  282. }
  283. return SUCCEEDED(hRetval);
  284. }