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.

347 lines
9.7 KiB

  1. /*
  2. * file.c - File routines module.
  3. */
  4. /* Headers
  5. **********/
  6. #include "project.h"
  7. #pragma hdrstop
  8. /* Constants
  9. ************/
  10. /* size of file comparison buffer in bytes */
  11. #define COMP_BUF_SIZE (16U * 1024U)
  12. /* Module Variables
  13. *******************/
  14. /* lock count for file comparison buffer */
  15. PRIVATE_DATA ULONG MulcCompBufLock = 0;
  16. /* buffers for file comparison */
  17. PRIVATE_DATA PBYTE MrgbyteCompBuf1 = NULL;
  18. PRIVATE_DATA PBYTE MrgbyteCompBuf2 = NULL;
  19. /* length of file comparison buffers in bytes */
  20. PRIVATE_DATA UINT MucbCompBufLen = 0;
  21. /****************************** Public Functions *****************************/
  22. /*
  23. ** BeginComp()
  24. **
  25. ** Increments file comparison buffers' lock count.
  26. **
  27. ** Arguments: void
  28. **
  29. ** Returns: TWINRESULT
  30. **
  31. ** Side Effects: none
  32. */
  33. PUBLIC_CODE void BeginComp(void)
  34. {
  35. ASSERT((MrgbyteCompBuf1 && MrgbyteCompBuf2 && MucbCompBufLen > 0) ||
  36. (! MrgbyteCompBuf1 && ! MrgbyteCompBuf2 && ! MucbCompBufLen));
  37. ASSERT(MulcCompBufLock < ULONG_MAX);
  38. MulcCompBufLock++;
  39. return;
  40. }
  41. /*
  42. ** EndComp()
  43. **
  44. ** Decrements file comparison buffers' lock count.
  45. **
  46. ** Arguments: void
  47. **
  48. ** Returns: void
  49. **
  50. ** Side Effects: Frees file comparison buffers if lock count goes to 0.
  51. */
  52. PUBLIC_CODE void EndComp(void)
  53. {
  54. ASSERT((MrgbyteCompBuf1 && MrgbyteCompBuf2 && MucbCompBufLen > 0) ||
  55. (! MrgbyteCompBuf1 && ! MrgbyteCompBuf2 && ! MucbCompBufLen));
  56. ASSERT(MulcCompBufLock > 0 || (! MrgbyteCompBuf1 && ! MrgbyteCompBuf2 && ! MucbCompBufLen));
  57. if (EVAL(MulcCompBufLock > 0))
  58. MulcCompBufLock--;
  59. /* Are the comparison buffers still locked? */
  60. if (! MulcCompBufLock && MrgbyteCompBuf1 && MrgbyteCompBuf2)
  61. {
  62. /* No. Free them. */
  63. FreeMemory(MrgbyteCompBuf1);
  64. MrgbyteCompBuf1 = NULL;
  65. FreeMemory(MrgbyteCompBuf2);
  66. MrgbyteCompBuf2 = NULL;
  67. TRACE_OUT((TEXT("EndComp(): Two %u byte file comparison buffers freed."),
  68. MucbCompBufLen));
  69. MucbCompBufLen = 0;
  70. }
  71. return;
  72. }
  73. /*
  74. ** CompareFilesByHandle()
  75. **
  76. ** Determines whether or not two files are the same.
  77. **
  78. ** Arguments: h1 - DOS file handle to first open file
  79. ** h2 - DOS file handle to second open file
  80. ** pbIdentical - pointer to BOOL to be filled in with value
  81. ** indicating whether or not the files are
  82. ** identical
  83. **
  84. ** Returns: TWINRESULT
  85. **
  86. ** Side Effects: Changes the position of the file pointer of each file.
  87. */
  88. PUBLIC_CODE TWINRESULT CompareFilesByHandle(HANDLE h1, HANDLE h2,
  89. PBOOL pbIdentical)
  90. {
  91. TWINRESULT tr;
  92. ASSERT(IS_VALID_HANDLE(h1, FILE));
  93. ASSERT(IS_VALID_HANDLE(h2, FILE));
  94. ASSERT(IS_VALID_WRITE_PTR(pbIdentical, BOOL));
  95. ASSERT((MrgbyteCompBuf1 && MrgbyteCompBuf2 && MucbCompBufLen > 0) ||
  96. (! MrgbyteCompBuf1 && ! MrgbyteCompBuf2 && ! MucbCompBufLen));
  97. ASSERT(MulcCompBufLock || (! MrgbyteCompBuf1 && ! MrgbyteCompBuf2 && ! MucbCompBufLen));
  98. /* Have the comparison buffers already been allocated? */
  99. if (MrgbyteCompBuf1)
  100. tr = TR_SUCCESS;
  101. else
  102. {
  103. /* No. Allocate them. */
  104. tr = TR_OUT_OF_MEMORY;
  105. if (AllocateMemory(COMP_BUF_SIZE, &MrgbyteCompBuf1))
  106. {
  107. if (AllocateMemory(COMP_BUF_SIZE, &MrgbyteCompBuf2))
  108. {
  109. /* Success! */
  110. MucbCompBufLen = COMP_BUF_SIZE;
  111. tr = TR_SUCCESS;
  112. TRACE_OUT((TEXT("CompareFilesByHandle(): Two %u byte file comparison buffers allocated."),
  113. MucbCompBufLen));
  114. }
  115. else
  116. {
  117. FreeMemory(MrgbyteCompBuf1);
  118. MrgbyteCompBuf1 = NULL;
  119. }
  120. }
  121. }
  122. if (tr == TR_SUCCESS)
  123. {
  124. DWORD dwcbLen1;
  125. BeginComp();
  126. /* Get file lengths to compare. */
  127. tr = TR_SRC_READ_FAILED;
  128. dwcbLen1 = SetFilePointer(h1, 0, NULL, FILE_END);
  129. if (dwcbLen1 != INVALID_SEEK_POSITION)
  130. {
  131. DWORD dwcbLen2;
  132. dwcbLen2 = SetFilePointer(h2, 0, NULL, FILE_END);
  133. if (dwcbLen2 != INVALID_SEEK_POSITION)
  134. {
  135. /* Are the files the same length? */
  136. if (dwcbLen1 == dwcbLen2)
  137. {
  138. /* Yes. Move to the beginning of the files. */
  139. if (SetFilePointer(h1, 0, NULL, FILE_BEGIN) != INVALID_SEEK_POSITION)
  140. {
  141. if (SetFilePointer(h2, 0, NULL, FILE_BEGIN) != INVALID_SEEK_POSITION)
  142. {
  143. tr = TR_SUCCESS;
  144. do
  145. {
  146. DWORD dwcbRead1;
  147. if (ReadFile(h1, MrgbyteCompBuf1, MucbCompBufLen, &dwcbRead1, NULL))
  148. {
  149. DWORD dwcbRead2;
  150. if (ReadFile(h2, MrgbyteCompBuf2, MucbCompBufLen, &dwcbRead2, NULL))
  151. {
  152. if (dwcbRead1 == dwcbRead2)
  153. {
  154. /* At EOF? */
  155. if (! dwcbRead1)
  156. {
  157. /* Yes. */
  158. *pbIdentical = TRUE;
  159. break;
  160. }
  161. else if (MyMemComp(MrgbyteCompBuf1, MrgbyteCompBuf2, dwcbRead1) != CR_EQUAL)
  162. {
  163. /* Yes. */
  164. *pbIdentical = FALSE;
  165. break;
  166. }
  167. }
  168. else
  169. tr = TR_SRC_READ_FAILED;
  170. }
  171. else
  172. tr = TR_SRC_READ_FAILED;
  173. }
  174. else
  175. tr = TR_SRC_READ_FAILED;
  176. } while (tr == TR_SUCCESS);
  177. }
  178. }
  179. }
  180. else
  181. {
  182. /* No. Files different lengths. */
  183. *pbIdentical = FALSE;
  184. tr = TR_SUCCESS;
  185. }
  186. }
  187. }
  188. EndComp();
  189. }
  190. return(tr);
  191. }
  192. /*
  193. ** CompareFilesByName()
  194. **
  195. **
  196. **
  197. ** Arguments:
  198. **
  199. ** Returns: TWINRESULT
  200. **
  201. ** Side Effects: none
  202. */
  203. PUBLIC_CODE TWINRESULT CompareFilesByName(HPATH hpath1, HPATH hpath2,
  204. PBOOL pbIdentical)
  205. {
  206. TWINRESULT tr;
  207. ASSERT(IS_VALID_HANDLE(hpath1, PATH));
  208. ASSERT(IS_VALID_HANDLE(hpath2, PATH));
  209. ASSERT(IS_VALID_WRITE_PTR(pbIdentical, BOOL));
  210. /* Only verify source and destination volumes once up front. */
  211. if (IsPathVolumeAvailable(hpath1) &&
  212. IsPathVolumeAvailable(hpath2))
  213. {
  214. HANDLE h1;
  215. TCHAR rgchFile1[MAX_PATH_LEN];
  216. /* Try to open files. Assume sequential reads. */
  217. GetPathString(hpath1, 0, rgchFile1, ARRAYSIZE(rgchFile1));
  218. h1 = CreateFile(rgchFile1, GENERIC_READ, FILE_SHARE_READ, NULL,
  219. OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  220. if (h1 != INVALID_HANDLE_VALUE)
  221. {
  222. HANDLE h2;
  223. TCHAR rgchFile2[MAX_PATH_LEN];
  224. GetPathString(hpath2, 0, rgchFile2, ARRAYSIZE(rgchFile2));
  225. h2 = CreateFile(rgchFile2, GENERIC_READ, FILE_SHARE_READ, NULL,
  226. OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  227. if (h2 != INVALID_HANDLE_VALUE)
  228. {
  229. TRACE_OUT((TEXT("CompareFilesByHandle(): Comparing files %s and %s."),
  230. DebugGetPathString(hpath1),
  231. DebugGetPathString(hpath2)));
  232. tr = CompareFilesByHandle(h1, h2, pbIdentical);
  233. #ifdef DEBUG
  234. if (tr == TR_SUCCESS)
  235. {
  236. if (*pbIdentical)
  237. TRACE_OUT((TEXT("CompareFilesByHandle(): %s and %s are identical."),
  238. DebugGetPathString(hpath1),
  239. DebugGetPathString(hpath2)));
  240. else
  241. TRACE_OUT((TEXT("CompareFilesByHandle(): %s and %s are different."),
  242. DebugGetPathString(hpath1),
  243. DebugGetPathString(hpath2)));
  244. }
  245. #endif
  246. /*
  247. * Failing to close the file properly is not a failure condition here.
  248. */
  249. CloseHandle(h2);
  250. }
  251. else
  252. tr = TR_DEST_OPEN_FAILED;
  253. /*
  254. * Failing to close the file properly is not a failure condition here.
  255. */
  256. CloseHandle(h1);
  257. }
  258. else
  259. tr = TR_SRC_OPEN_FAILED;
  260. }
  261. else
  262. tr = TR_UNAVAILABLE_VOLUME;
  263. return(tr);
  264. }