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
220 lines
6.6 KiB
/*******************************************************************************
|
|
*
|
|
* (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
|
|
|