|
|
/*******************************************************************************
* * (C) COPYRIGHT MICROSOFT CORPORATION, 2000 * * TITLE: UNIQFILE.H * * VERSION: 1.0 * * AUTHOR: ShaunIv * * DATE: 7/7/2000 * * DESCRIPTION: Creates a list of existing files in a directory, and ensures * that there new ones are not duplicates of these. * *******************************************************************************/ #ifndef __UNIQFILE_H_INCLUDED
#define __UNIQFILE_H_INCLUDED
#include <windows.h>
#include <simstr.h>
#include <wiacrc32.h>
class CFileUniquenessInformation { public: CSimpleString m_strFileName; // The full path to the file
ULONGLONG m_nFileSize; // The size of the file
mutable DWORD m_dwCrc; // The file's CRC. 0 means uninitialized. It is mutable because it can change in the accessor function
public: explicit CFileUniquenessInformation( LPCTSTR pszFileName=NULL, ULONGLONG nFileSize=0, DWORD dwCrc=0 ) : m_strFileName(pszFileName), m_nFileSize(nFileSize), m_dwCrc(dwCrc) { } CFileUniquenessInformation( CFileUniquenessInformation &other ) : m_strFileName(other.FileName()), m_nFileSize(other.FileSize()), m_dwCrc(other.Crc(false)) { } CFileUniquenessInformation &operator=( const CFileUniquenessInformation &other ) { if (this != &other) { m_strFileName = other.FileName(); m_nFileSize = other.FileSize(); m_dwCrc = other.Crc(false); } return *this; } const CSimpleString &FileName(void) const { return m_strFileName; } const ULONGLONG FileSize(void) const { return m_nFileSize; } DWORD Crc( bool bCalculate = true ) const { //
// Only calculate it if we have to
//
if (!m_dwCrc && bCalculate) { m_dwCrc = WiaCrc32::GenerateCrc32File(m_strFileName); } return m_dwCrc; } };
class CFileUniquenessList { private: CSimpleDynamicArray<CFileUniquenessInformation> m_FileList;
private: CFileUniquenessList( const CFileUniquenessList & ); CFileUniquenessList &operator=( const CFileUniquenessList & );
public: CFileUniquenessList( LPCTSTR pszDirectory = NULL ) { if (pszDirectory && lstrlen(pszDirectory)) { InitializeFileList(pszDirectory); } } void InitializeFileList( LPCTSTR pszDirectory ) { //
// Empty the file list
//
m_FileList.Destroy();
//
// Save the directory name
//
CSimpleString strDirectory = pszDirectory;
//
// Make sure we have a trailing backslash
//
if (!strDirectory.MatchLastCharacter(TEXT('\\'))) { strDirectory += TEXT("\\"); }
//
// Find all of the files in this directory
//
WIN32_FIND_DATA Win32FindData = {0}; HANDLE hFind = FindFirstFile( strDirectory + CSimpleString(TEXT("*.*")), &Win32FindData ); if (hFind != INVALID_HANDLE_VALUE) { BOOL bContinue = TRUE; while (bContinue) { //
// Add the file to the list
//
ULARGE_INTEGER nFileSize; nFileSize.LowPart = Win32FindData.nFileSizeLow; nFileSize.HighPart = Win32FindData.nFileSizeHigh; m_FileList.Append( CFileUniquenessInformation( strDirectory + CSimpleString(Win32FindData.cFileName), nFileSize.QuadPart )); bContinue = FindNextFile( hFind, &Win32FindData ); } FindClose(hFind); } } int FindIdenticalFile( LPCTSTR pszFileName, bool bAddIfUnsuccessful ) { //
// Assume failure
//
int nIndex = -1;
//
// Open the file for reading
//
HANDLE hFile = CreateFile( pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (INVALID_HANDLE_VALUE != hFile) { //
// Get the file size and make sure we didn't have an error
//
ULARGE_INTEGER nFileSize; nFileSize.LowPart = GetFileSize( hFile, &nFileSize.HighPart ); if (nFileSize.LowPart != static_cast<DWORD>(-1) || GetLastError() == NO_ERROR) { //
// We are only going to generate this file's CRC if we have to
//
DWORD dwCrc = 0;
//
// Loop through all of the files in this list
//
for (int i=0;i<m_FileList.Size();i++) { //
// Look for ones that have have size
//
if (m_FileList[i].FileSize() == nFileSize.QuadPart) { //
// If we haven't calculated this file's CRC, do so now and save it
//
if (!dwCrc) { dwCrc = WiaCrc32::GenerateCrc32Handle(hFile); }
//
// If these files have the same size and CRC, they are identical, so quit the loop
//
if (m_FileList[i].Crc() == dwCrc) { nIndex = i; break; } } }
//
// If we didn't find it in the list, add it if the caller requested it
//
if (nIndex == -1 && bAddIfUnsuccessful) { m_FileList.Append( CFileUniquenessInformation( pszFileName, nFileSize.QuadPart, dwCrc ) ); } }
//
// Close the file
//
CloseHandle(hFile); } return nIndex; } CSimpleString GetFileName( int nIndex ) { //
// Get the file name at index nIndex
//
CSimpleString strResult; if (nIndex >= 0 && nIndex < m_FileList.Size()) { strResult = m_FileList[nIndex].FileName(); } return strResult; } };
#endif //__UNIQFILE_H_INCLUDED
|