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.

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