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.

292 lines
6.6 KiB

  1. /******************************************************************************
  2. *
  3. * Copyright (c) 2000 Microsoft Corporation
  4. *
  5. * Module Name:
  6. * snappatch.cpp
  7. *
  8. * Abstract:
  9. * functions for computing snapshot patch, and reconstructing snapshot from patch
  10. *
  11. * Revision History:
  12. * Brijesh Krishnaswami (brijeshk) 03/22/2001
  13. * created
  14. *
  15. *****************************************************************************/
  16. #include "snapshoth.h"
  17. #include "..\service\srconfig.h"
  18. DWORD g_dwPatchWindow = 0xFFFFFFFF;
  19. //
  20. // get patch window
  21. // 0 if patching is turned off
  22. //
  23. DWORD
  24. PatchGetPatchWindow()
  25. {
  26. DWORD dwErr = ERROR_SUCCESS;
  27. HKEY hKey = NULL;
  28. tenter("PatchGetPatchWindow");
  29. if (g_dwPatchWindow == 0xFFFFFFFF)
  30. {
  31. // uninitialized
  32. // read from the registry
  33. g_dwPatchWindow = 0;
  34. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  35. s_cszSRRegKey,
  36. 0,
  37. KEY_READ,
  38. &hKey))
  39. {
  40. RegReadDWORD(hKey, s_cszPatchWindow, &g_dwPatchWindow);
  41. RegCloseKey(hKey);
  42. }
  43. trace(0, "Initializing g_dwPatchWindow = %ld", g_dwPatchWindow);
  44. }
  45. tleave();
  46. return g_dwPatchWindow;
  47. }
  48. //
  49. // get reference rp for a given rp
  50. // RP1-RP10 -> reference is RP1
  51. // RP11-RP20 -> reference is RP11 and so on
  52. //
  53. DWORD
  54. PatchGetReferenceRpNum(
  55. DWORD dwCurrentRp)
  56. {
  57. if (PatchGetPatchWindow() == 0)
  58. return dwCurrentRp;
  59. else
  60. return (dwCurrentRp/PatchGetPatchWindow())*PatchGetPatchWindow() + 1;
  61. }
  62. DWORD
  63. PatchGetReferenceRpPath(
  64. DWORD dwCurrentRp,
  65. LPWSTR pszRefRpPath)
  66. {
  67. tenter("PatchGetReferenceRpPath");
  68. WCHAR szRp[MAX_RP_PATH], szSys[MAX_SYS_DRIVE]=L"";
  69. DWORD dwRefRpNum = PatchGetReferenceRpNum(dwCurrentRp);
  70. DWORD dwErr = ERROR_SUCCESS;
  71. wsprintf(szRp, L"%s%ld", s_cszRPDir, dwRefRpNum);
  72. GetSystemDrive(szSys);
  73. MakeRestorePath(pszRefRpPath, szSys, szRp);
  74. if (0xFFFFFFFF == GetFileAttributes(pszRefRpPath))
  75. {
  76. // RP directory does not exist -- it must've been fifoed
  77. // try RefRP
  78. trace(0, "Original rp does not exist -- trying RefRP");
  79. wsprintf(szRp,L" %s%ld", s_cszReferenceDir, dwRefRpNum);
  80. MakeRestorePath(pszRefRpPath, szSys, szRp);
  81. if (0xFFFFFFFF == GetFileAttributes(pszRefRpPath))
  82. {
  83. // this does not exist either -- something wrong
  84. trace(0, "RefRP does not exist either -- bailing");
  85. dwErr = ERROR_NOT_FOUND;
  86. goto Err;
  87. }
  88. }
  89. trace(0, "Current Rp: %ld, Reference : %S", dwCurrentRp, pszRefRpPath);
  90. Err:
  91. tleave();
  92. return dwErr;
  93. }
  94. //
  95. // extract rp number from path
  96. //
  97. DWORD
  98. PatchGetRpNumberFromPath(
  99. LPCWSTR pszPath,
  100. PDWORD pdwRpNum)
  101. {
  102. while (*pszPath != L'\0')
  103. {
  104. if (0 == wcsncmp(pszPath, s_cszRPDir, lstrlen(s_cszRPDir)))
  105. {
  106. pszPath += lstrlen(s_cszRPDir);
  107. *pdwRpNum = _wtol(pszPath);
  108. if (*pdwRpNum == 0)
  109. continue;
  110. else
  111. return ERROR_SUCCESS;
  112. }
  113. pszPath++;
  114. }
  115. return ERROR_NOT_FOUND;
  116. }
  117. //
  118. // compute the diff
  119. //
  120. DWORD
  121. PatchComputePatch(
  122. LPCWSTR pszCurrentDir)
  123. {
  124. tenter("PatchComputePatch");
  125. DWORD dwErr = ERROR_SUCCESS;
  126. WCHAR szTemp[MAX_PATH], szRef[MAX_PATH];
  127. FILE* f = NULL;
  128. DWORD dwCurRpNum;
  129. // check if patching is turned off
  130. if (PatchGetPatchWindow() == 0)
  131. {
  132. trace(0, "No patching");
  133. goto Err;
  134. }
  135. // get the reference directory for this rp
  136. CHECKERR(PatchGetRpNumberFromPath(pszCurrentDir, &dwCurRpNum),
  137. L"PatchGetRpNumberFromPath");
  138. CHECKERR(PatchGetReferenceRpPath(dwCurRpNum, szRef),
  139. L"PatchGetReferenceRpPath");
  140. // check if this directory is already patched
  141. lstrcpy(szTemp, pszCurrentDir);
  142. lstrcat(szTemp, L"\\");
  143. lstrcat(szTemp, s_cszPatchCompleteMarker);
  144. if (0xFFFFFFFF != GetFileAttributes(szTemp))
  145. {
  146. trace(0, "%S already patched", pszCurrentDir);
  147. goto Err;
  148. }
  149. // call the library api to compute the patch
  150. // this is a blocking call till the patching completes
  151. // progress callback is used to terminate it
  152. // PlaceHolder for library call (pszCurrentDir, szRef)
  153. // check if we completed the patch successfully
  154. // if so, then write a zero-byte file inside the directory to indicate this
  155. lstrcpy(szTemp, pszCurrentDir);
  156. lstrcat(szTemp, L"\\");
  157. lstrcat(szTemp, s_cszPatchCompleteMarker);
  158. f = (FILE *) _wfopen(szTemp, L"w");
  159. if (!f)
  160. {
  161. dwErr = GetLastError();
  162. trace(0, "! Cannot create %S : %ld", szTemp, dwErr);
  163. goto Err;
  164. }
  165. fclose(f);
  166. Err:
  167. tleave();
  168. return dwErr;
  169. }
  170. //
  171. // patch progress callback
  172. //
  173. BOOL
  174. PatchContinueCallback()
  175. {
  176. tenter("PatchContinueCallback");
  177. BOOL fRc;
  178. trace(0, "PatchContinueCallback called");
  179. if (!g_pSRConfig)
  180. {
  181. trace(0, "g_pSRConfig = NULL -- terminating patch");
  182. fRc = FALSE;
  183. }
  184. else if (IsStopSignalled(g_pSRConfig->m_hSRStopEvent))
  185. {
  186. trace(0, "Stop signalled -- terminating patch");
  187. fRc = FALSE;
  188. }
  189. else
  190. {
  191. fRc = TRUE;
  192. }
  193. tleave();
  194. return fRc;
  195. }
  196. //
  197. // reconstruct the original
  198. //
  199. DWORD
  200. PatchReconstructOriginal(
  201. LPCWSTR pszCurrentDir,
  202. LPWSTR pszDestDir)
  203. {
  204. tenter("PatchReconstructOriginal");
  205. DWORD dwErr = ERROR_SUCCESS;
  206. WCHAR szReferenceDir[MAX_PATH];
  207. WCHAR szSys[MAX_SYS_DRIVE]=L"";
  208. DWORD dwCurRpNum;
  209. // check if patching is turned off
  210. if (PatchGetPatchWindow() == 0)
  211. {
  212. trace(0, "No patching");
  213. goto Err;
  214. }
  215. CHECKERR(PatchGetRpNumberFromPath(pszCurrentDir, &dwCurRpNum),
  216. L"PatchGetRpNumberFromPath");
  217. CHECKERR(PatchGetReferenceRpPath(dwCurRpNum, szReferenceDir),
  218. L"PatchGetReferenceRpPath");
  219. // call the library api to reconstruct the snapshot
  220. // PlaceHolder for library call (pszCurrentDir, szReferenceDir, pszDestDir)
  221. Err:
  222. tleave();
  223. return dwErr;
  224. }