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.

455 lines
10 KiB

  1. /******************************************************************************
  2. *
  3. * Copyright (c) 2000 Microsoft Corporation
  4. *
  5. * Module Name:
  6. * changelog.cpp
  7. *
  8. * Abstract:
  9. * CChangeLogEnum functions
  10. *
  11. * Revision History:
  12. * Brijesh Krishnaswami (brijeshk) 03/17/2000
  13. * created
  14. *
  15. *****************************************************************************/
  16. #include "precomp.h"
  17. #ifdef THIS_FILE
  18. #undef THIS_FILE
  19. #endif
  20. static char __szTraceSourceFile[] = __FILE__;
  21. #define THIS_FILE __szTraceSourceFile
  22. // CHANGELOG ENUMERATION METHODS
  23. // constructors
  24. CChangeLogEntryEnum::CChangeLogEntryEnum()
  25. {
  26. m_fForward = TRUE;
  27. m_pRestorePointEnum = NULL;
  28. m_fHaveLock = FALSE;
  29. m_dwTargetRPNum = 0;
  30. m_fIncludeCurRP = FALSE;
  31. GetSystemDrive(m_szDrive);
  32. }
  33. CChangeLogEntryEnum::CChangeLogEntryEnum(
  34. LPWSTR pszDrive,
  35. BOOL fForward,
  36. DWORD dwRPNum,
  37. BOOL fIncludeCurRP)
  38. {
  39. m_fForward = fForward;
  40. m_pRestorePointEnum = NULL;
  41. m_dwTargetRPNum = dwRPNum;
  42. m_fHaveLock = FALSE;
  43. m_fIncludeCurRP = fIncludeCurRP;
  44. lstrcpy(m_szDrive, pszDrive);
  45. }
  46. // destructor
  47. CChangeLogEntryEnum::~CChangeLogEntryEnum()
  48. {
  49. FindClose();
  50. }
  51. // return first/last change log entry across all restore points
  52. extern "C" DWORD WINAPI
  53. CChangeLogEntryEnum::FindFirstChangeLogEntry(
  54. CChangeLogEntry& cle)
  55. {
  56. DWORD dwRc = ERROR_INTERNAL_ERROR;
  57. BOOL fSkipLastLog;
  58. TENTER("CChangeLogEntryEnum::FindFirstChangeLogEntry");
  59. // initialize the lock object
  60. dwRc = m_DSLock.Init(); // don't create mutex
  61. if (dwRc != ERROR_SUCCESS)
  62. {
  63. trace(0, "! m_DSLock.Init : %ld", dwRc);
  64. goto done;
  65. }
  66. // get mutually exclusive access to the datastore
  67. LOCKORLEAVE(m_fHaveLock);
  68. // get the first/last restore point
  69. m_pRestorePointEnum = new CRestorePointEnum(m_szDrive, m_fForward, ! m_fIncludeCurRP);
  70. if (! m_pRestorePointEnum)
  71. {
  72. TRACE(0, "Out of memory");
  73. goto done;
  74. }
  75. dwRc = m_pRestorePointEnum->FindFirstRestorePoint(m_RPTemp);
  76. if (ERROR_SUCCESS != dwRc && ERROR_FILE_NOT_FOUND != dwRc)
  77. {
  78. TRACE(0, "! FindFirstRestorePoint : %ld", dwRc);
  79. goto done;
  80. }
  81. // gone past target restore point?
  82. if (m_dwTargetRPNum)
  83. {
  84. if (m_fForward)
  85. {
  86. if (m_dwTargetRPNum < m_RPTemp.GetNum())
  87. {
  88. dwRc = ERROR_NO_MORE_ITEMS;
  89. goto done;
  90. }
  91. }
  92. else
  93. {
  94. if (m_dwTargetRPNum > m_RPTemp.GetNum())
  95. {
  96. dwRc = ERROR_NO_MORE_ITEMS;
  97. goto done;
  98. }
  99. }
  100. }
  101. // get the first/last change log entry in this restore point
  102. dwRc = m_RPTemp.FindFirstChangeLogEntry(m_szDrive,
  103. m_fForward,
  104. cle);
  105. if (ERROR_NO_MORE_ITEMS == dwRc)
  106. {
  107. dwRc = FindNextChangeLogEntry(cle);
  108. }
  109. done:
  110. if (ERROR_SUCCESS != dwRc)
  111. {
  112. UNLOCK(m_fHaveLock);
  113. }
  114. TLEAVE();
  115. return dwRc;
  116. }
  117. // return next/prev change log entry across all restore points
  118. extern "C" DWORD WINAPI
  119. CChangeLogEntryEnum::FindNextChangeLogEntry(
  120. CChangeLogEntry& cle)
  121. {
  122. DWORD dwRc = ERROR_INTERNAL_ERROR;
  123. BOOL fSkipLastLog;
  124. TENTER("CChangeLogEntryEnum::FindNextChangeLogEntry");
  125. // get the next change log entry in the current restore point
  126. if (! m_pRestorePointEnum)
  127. {
  128. TRACE(0, "m_pRestorePointEnum=NULL");
  129. goto done;
  130. }
  131. dwRc = m_RPTemp.FindNextChangeLogEntry(cle);
  132. while (ERROR_NO_MORE_ITEMS == dwRc) // all entries done
  133. {
  134. // get the next restore point
  135. m_RPTemp.FindClose();
  136. dwRc = m_pRestorePointEnum->FindNextRestorePoint(m_RPTemp);
  137. if (ERROR_SUCCESS != dwRc && dwRc != ERROR_FILE_NOT_FOUND) // all restore points done
  138. {
  139. TRACE(0, "! FindFirstRestorePoint : %ld", dwRc);
  140. goto done;
  141. }
  142. // gone past target restore point?
  143. if (m_dwTargetRPNum)
  144. {
  145. if (m_fForward)
  146. {
  147. if (m_dwTargetRPNum < m_RPTemp.GetNum())
  148. {
  149. dwRc = ERROR_NO_MORE_ITEMS;
  150. goto done;
  151. }
  152. }
  153. else
  154. {
  155. if (m_dwTargetRPNum > m_RPTemp.GetNum())
  156. {
  157. dwRc = ERROR_NO_MORE_ITEMS;
  158. goto done;
  159. }
  160. }
  161. }
  162. // get the first change log entry in this restore point
  163. dwRc = m_RPTemp.FindFirstChangeLogEntry(m_szDrive,
  164. m_fForward,
  165. cle);
  166. }
  167. // return this entry
  168. done:
  169. TLEAVE();
  170. return dwRc;
  171. }
  172. // release memory, lock and close handles
  173. DWORD WINAPI
  174. CChangeLogEntryEnum::FindClose()
  175. {
  176. TENTER("CChangeLogEntryEnum::FindClose");
  177. m_RPTemp.FindClose();
  178. if (m_pRestorePointEnum)
  179. {
  180. m_pRestorePointEnum->FindClose();
  181. delete m_pRestorePointEnum;
  182. m_pRestorePointEnum = NULL;
  183. }
  184. UNLOCK(m_fHaveLock);
  185. TLEAVE();
  186. return ERROR_SUCCESS;
  187. }
  188. // RESTORE POINT ENUMERATION METHODS
  189. // constructors
  190. CRestorePointEnum::CRestorePointEnum()
  191. {
  192. // defaults
  193. m_fForward = TRUE;
  194. GetSystemDrive(m_szDrive);
  195. m_fSkipLast = FALSE;
  196. m_pCurrentRp = NULL;
  197. }
  198. CRestorePointEnum::CRestorePointEnum(LPWSTR pszDrive, BOOL fForward, BOOL fSkipLast)
  199. {
  200. m_fForward = fForward;
  201. lstrcpy(m_szDrive, pszDrive);
  202. m_fSkipLast = fSkipLast;
  203. m_pCurrentRp = NULL;
  204. }
  205. // destructor
  206. CRestorePointEnum::~CRestorePointEnum()
  207. {
  208. FindClose();
  209. }
  210. // to find the first restore point on a given drive - forward or backward
  211. DWORD
  212. CRestorePointEnum::FindFirstRestorePoint(CRestorePoint& RestorePoint)
  213. {
  214. WIN32_FIND_DATA *pFindData = new WIN32_FIND_DATA;
  215. DWORD dwRc = ERROR_SUCCESS;
  216. TENTER("CRestorePointEnum::FindFirstRestorePoint");
  217. if (! pFindData)
  218. {
  219. trace(0, "Cannot allocate pFindData");
  220. dwRc = ERROR_OUTOFMEMORY;
  221. goto done;
  222. }
  223. // construct drive:\_restore\RP directory
  224. {
  225. WCHAR szCurPath[MAX_PATH];
  226. MakeRestorePath(szCurPath, m_szDrive, s_cszRPDir);
  227. if (FALSE == FindFile._FindFirstFile(szCurPath, L"", pFindData, m_fForward, FALSE))
  228. {
  229. dwRc = ERROR_NO_MORE_ITEMS;
  230. goto done;
  231. }
  232. }
  233. // get the current restore point
  234. if (m_fSkipLast)
  235. {
  236. m_pCurrentRp = new CRestorePoint();
  237. if (! m_pCurrentRp)
  238. {
  239. trace(0, "Cannot allocate memory for m_pCurrentRp");
  240. dwRc = ERROR_OUTOFMEMORY;
  241. goto done;
  242. }
  243. dwRc = GetCurrentRestorePoint(*m_pCurrentRp);
  244. if (dwRc != ERROR_SUCCESS && dwRc != ERROR_FILE_NOT_FOUND)
  245. {
  246. TRACE(0, "! GetCurrentRestorePoint : %ld", dwRc);
  247. goto done;
  248. }
  249. // check if this is the current restore point
  250. // and if client wants it
  251. if (0 == lstrcmpi(pFindData->cFileName, m_pCurrentRp->GetDir()))
  252. {
  253. if (m_fForward)
  254. {
  255. // we are done
  256. dwRc = ERROR_NO_MORE_ITEMS;
  257. goto done;
  258. }
  259. else
  260. {
  261. // skip this
  262. dwRc = FindNextRestorePoint(RestorePoint);
  263. goto done;
  264. }
  265. }
  266. }
  267. // read restore point data from log
  268. // if the enumeration is happening on the system drive
  269. RestorePoint.SetDir(pFindData->cFileName);
  270. if (IsSystemDrive(m_szDrive))
  271. dwRc = RestorePoint.ReadLog();
  272. done:
  273. if (pFindData)
  274. delete pFindData;
  275. TLEAVE();
  276. return dwRc;
  277. }
  278. // to find the next/previous restore point on a given drive
  279. DWORD
  280. CRestorePointEnum::FindNextRestorePoint(CRestorePoint& RestorePoint)
  281. {
  282. DWORD dwRc = ERROR_SUCCESS;
  283. WIN32_FIND_DATA FindData;
  284. TENTER("CRestorePointEnum::FindNextRestorePoint");
  285. {
  286. WCHAR szCurPath[MAX_PATH];
  287. MakeRestorePath(szCurPath, m_szDrive, s_cszRPDir);
  288. if (FALSE == FindFile._FindNextFile(szCurPath, L"", &FindData))
  289. {
  290. dwRc = ERROR_NO_MORE_ITEMS;
  291. goto done;
  292. }
  293. }
  294. if (m_fSkipLast)
  295. {
  296. // check if this is the current restore point
  297. // and if client wants it
  298. if (! m_pCurrentRp)
  299. {
  300. trace(0, "m_pCurrentRp = NULL");
  301. dwRc = ERROR_INTERNAL_ERROR;
  302. goto done;
  303. }
  304. if (0 == lstrcmpi(FindData.cFileName, m_pCurrentRp->GetDir()))
  305. {
  306. if (m_fForward)
  307. {
  308. // we are done
  309. dwRc = ERROR_NO_MORE_ITEMS;
  310. goto done;
  311. }
  312. }
  313. }
  314. // read restore point data from log
  315. // if the enumeration is happening on the system drive
  316. RestorePoint.SetDir(FindData.cFileName);
  317. if (IsSystemDrive(m_szDrive))
  318. dwRc = RestorePoint.ReadLog();
  319. done:
  320. TLEAVE();
  321. return dwRc;
  322. }
  323. // nothing here
  324. DWORD
  325. CRestorePointEnum::FindClose()
  326. {
  327. TENTER("CRestorePointEnum::FindClose");
  328. if (m_pCurrentRp)
  329. {
  330. delete m_pCurrentRp;
  331. m_pCurrentRp = NULL;
  332. }
  333. TLEAVE();
  334. return ERROR_SUCCESS;
  335. }
  336. DWORD WINAPI
  337. GetCurrentRestorePoint(CRestorePoint& rp)
  338. {
  339. DWORD dwErr;
  340. WCHAR szSystemDrive[MAX_SYS_DRIVE]=L"";
  341. CRestorePointEnum *prpe = NULL;
  342. GetSystemDrive(szSystemDrive);
  343. prpe = new CRestorePointEnum(szSystemDrive, FALSE, FALSE); // enum backward, don't skip last
  344. if (! prpe)
  345. {
  346. dwErr = ERROR_OUTOFMEMORY;
  347. return dwErr;
  348. }
  349. dwErr = prpe->FindFirstRestorePoint(rp);
  350. prpe->FindClose ();
  351. delete prpe;
  352. return dwErr;
  353. }