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.

220 lines
6.6 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 2000
  4. *
  5. * TITLE: UNIQFILE.H
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 7/7/2000
  12. *
  13. * DESCRIPTION: Creates a list of existing files in a directory, and ensures
  14. * that there new ones are not duplicates of these.
  15. *
  16. *******************************************************************************/
  17. #ifndef __UNIQFILE_H_INCLUDED
  18. #define __UNIQFILE_H_INCLUDED
  19. #include <windows.h>
  20. #include <simstr.h>
  21. #include <wiacrc32.h>
  22. class CFileUniquenessInformation
  23. {
  24. public:
  25. CSimpleString m_strFileName; // The full path to the file
  26. ULONGLONG m_nFileSize; // The size of the file
  27. mutable DWORD m_dwCrc; // The file's CRC. 0 means uninitialized. It is mutable because it can change in the accessor function
  28. public:
  29. explicit CFileUniquenessInformation( LPCTSTR pszFileName=NULL, ULONGLONG nFileSize=0, DWORD dwCrc=0 )
  30. : m_strFileName(pszFileName),
  31. m_nFileSize(nFileSize),
  32. m_dwCrc(dwCrc)
  33. {
  34. }
  35. CFileUniquenessInformation( CFileUniquenessInformation &other )
  36. : m_strFileName(other.FileName()),
  37. m_nFileSize(other.FileSize()),
  38. m_dwCrc(other.Crc(false))
  39. {
  40. }
  41. CFileUniquenessInformation &operator=( const CFileUniquenessInformation &other )
  42. {
  43. if (this != &other)
  44. {
  45. m_strFileName = other.FileName();
  46. m_nFileSize = other.FileSize();
  47. m_dwCrc = other.Crc(false);
  48. }
  49. return *this;
  50. }
  51. const CSimpleString &FileName(void) const
  52. {
  53. return m_strFileName;
  54. }
  55. const ULONGLONG FileSize(void) const
  56. {
  57. return m_nFileSize;
  58. }
  59. DWORD Crc( bool bCalculate = true ) const
  60. {
  61. //
  62. // Only calculate it if we have to
  63. //
  64. if (!m_dwCrc && bCalculate)
  65. {
  66. m_dwCrc = WiaCrc32::GenerateCrc32File(m_strFileName);
  67. }
  68. return m_dwCrc;
  69. }
  70. };
  71. class CFileUniquenessList
  72. {
  73. private:
  74. CSimpleDynamicArray<CFileUniquenessInformation> m_FileList;
  75. private:
  76. CFileUniquenessList( const CFileUniquenessList & );
  77. CFileUniquenessList &operator=( const CFileUniquenessList & );
  78. public:
  79. CFileUniquenessList( LPCTSTR pszDirectory = NULL )
  80. {
  81. if (pszDirectory && lstrlen(pszDirectory))
  82. {
  83. InitializeFileList(pszDirectory);
  84. }
  85. }
  86. void InitializeFileList( LPCTSTR pszDirectory )
  87. {
  88. //
  89. // Empty the file list
  90. //
  91. m_FileList.Destroy();
  92. //
  93. // Save the directory name
  94. //
  95. CSimpleString strDirectory = pszDirectory;
  96. //
  97. // Make sure we have a trailing backslash
  98. //
  99. if (!strDirectory.MatchLastCharacter(TEXT('\\')))
  100. {
  101. strDirectory += TEXT("\\");
  102. }
  103. //
  104. // Find all of the files in this directory
  105. //
  106. WIN32_FIND_DATA Win32FindData = {0};
  107. HANDLE hFind = FindFirstFile( strDirectory + CSimpleString(TEXT("*.*")), &Win32FindData );
  108. if (hFind != INVALID_HANDLE_VALUE)
  109. {
  110. BOOL bContinue = TRUE;
  111. while (bContinue)
  112. {
  113. //
  114. // Add the file to the list
  115. //
  116. ULARGE_INTEGER nFileSize;
  117. nFileSize.LowPart = Win32FindData.nFileSizeLow;
  118. nFileSize.HighPart = Win32FindData.nFileSizeHigh;
  119. m_FileList.Append( CFileUniquenessInformation( strDirectory + CSimpleString(Win32FindData.cFileName), nFileSize.QuadPart ));
  120. bContinue = FindNextFile( hFind, &Win32FindData );
  121. }
  122. FindClose(hFind);
  123. }
  124. }
  125. int FindIdenticalFile( LPCTSTR pszFileName, bool bAddIfUnsuccessful )
  126. {
  127. //
  128. // Assume failure
  129. //
  130. int nIndex = -1;
  131. //
  132. // Open the file for reading
  133. //
  134. HANDLE hFile = CreateFile( pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
  135. if (INVALID_HANDLE_VALUE != hFile)
  136. {
  137. //
  138. // Get the file size and make sure we didn't have an error
  139. //
  140. ULARGE_INTEGER nFileSize;
  141. nFileSize.LowPart = GetFileSize( hFile, &nFileSize.HighPart );
  142. if (nFileSize.LowPart != static_cast<DWORD>(-1) || GetLastError() == NO_ERROR)
  143. {
  144. //
  145. // We are only going to generate this file's CRC if we have to
  146. //
  147. DWORD dwCrc = 0;
  148. //
  149. // Loop through all of the files in this list
  150. //
  151. for (int i=0;i<m_FileList.Size();i++)
  152. {
  153. //
  154. // Look for ones that have have size
  155. //
  156. if (m_FileList[i].FileSize() == nFileSize.QuadPart)
  157. {
  158. //
  159. // If we haven't calculated this file's CRC, do so now and save it
  160. //
  161. if (!dwCrc)
  162. {
  163. dwCrc = WiaCrc32::GenerateCrc32Handle(hFile);
  164. }
  165. //
  166. // If these files have the same size and CRC, they are identical, so quit the loop
  167. //
  168. if (m_FileList[i].Crc() == dwCrc)
  169. {
  170. nIndex = i;
  171. break;
  172. }
  173. }
  174. }
  175. //
  176. // If we didn't find it in the list, add it if the caller requested it
  177. //
  178. if (nIndex == -1 && bAddIfUnsuccessful)
  179. {
  180. m_FileList.Append( CFileUniquenessInformation( pszFileName, nFileSize.QuadPart, dwCrc ) );
  181. }
  182. }
  183. //
  184. // Close the file
  185. //
  186. CloseHandle(hFile);
  187. }
  188. return nIndex;
  189. }
  190. CSimpleString GetFileName( int nIndex )
  191. {
  192. //
  193. // Get the file name at index nIndex
  194. //
  195. CSimpleString strResult;
  196. if (nIndex >= 0 && nIndex < m_FileList.Size())
  197. {
  198. strResult = m_FileList[nIndex].FileName();
  199. }
  200. return strResult;
  201. }
  202. };
  203. #endif //__UNIQFILE_H_INCLUDED