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.
368 lines
7.6 KiB
368 lines
7.6 KiB
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
// Copyright (C) 1992-1997 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// This source code is only intended as a supplement to the
|
|
// Microsoft Foundation Classes Reference and related
|
|
// electronic documentation provided with the library.
|
|
// See these sources for detailed information regarding the
|
|
// Microsoft Foundation Classes product.
|
|
|
|
#ifdef _MAC
|
|
#error CFindFile is not supported on the Macintosh
|
|
#endif
|
|
|
|
#include "stdafx.h"
|
|
#include "filefind.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// CFindFile implementation
|
|
|
|
CFindFile::CFindFile()
|
|
{
|
|
m_pFoundInfo = NULL;
|
|
m_pNextInfo = NULL;
|
|
m_hContext = NULL;
|
|
m_chDirSeparator = '\\';
|
|
}
|
|
|
|
CFindFile::~CFindFile()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
void CFindFile::Close()
|
|
{
|
|
if (m_pFoundInfo != NULL)
|
|
{
|
|
delete m_pFoundInfo;
|
|
m_pFoundInfo = NULL;
|
|
}
|
|
|
|
if (m_pNextInfo != NULL)
|
|
{
|
|
delete m_pNextInfo;
|
|
m_pNextInfo = NULL;
|
|
}
|
|
|
|
if (m_hContext != NULL && m_hContext != INVALID_HANDLE_VALUE)
|
|
{
|
|
CloseContext();
|
|
m_hContext = NULL;
|
|
}
|
|
}
|
|
|
|
void CFindFile::CloseContext()
|
|
{
|
|
::FindClose(m_hContext);
|
|
return;
|
|
}
|
|
|
|
BOOL CFindFile::FindFile(LPCTSTR pstrName /* = NULL */,
|
|
DWORD dwUnused /* = 0 */)
|
|
{
|
|
UNUSED_ALWAYS(dwUnused);
|
|
Close();
|
|
m_pNextInfo = new WIN32_FIND_DATA;
|
|
m_bGotLast = FALSE;
|
|
|
|
if (pstrName == NULL)
|
|
pstrName = _T("*.*");
|
|
_tcsncpy(((WIN32_FIND_DATA*) m_pNextInfo)->cFileName, pstrName,_tcslen(((WIN32_FIND_DATA*) m_pNextInfo)->cFileName));
|
|
|
|
m_hContext = ::FindFirstFile(pstrName, (WIN32_FIND_DATA*) m_pNextInfo);
|
|
|
|
if (m_hContext == INVALID_HANDLE_VALUE)
|
|
{
|
|
DWORD dwTemp = ::GetLastError();
|
|
Close();
|
|
::SetLastError(dwTemp);
|
|
return FALSE;
|
|
}
|
|
|
|
LPTSTR pstrRoot = m_strRoot.GetBufferSetLength(_MAX_PATH);
|
|
LPCTSTR pstr = _tfullpath(pstrRoot, pstrName, _MAX_PATH);
|
|
|
|
// passed name isn't a valid path but was found by the API
|
|
ASSERT(pstr != NULL);
|
|
if (pstr == NULL)
|
|
{
|
|
m_strRoot.ReleaseBuffer(-1);
|
|
Close();
|
|
::SetLastError(ERROR_INVALID_NAME);
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
// find the last forward or backward whack
|
|
LPTSTR pstrBack = _tcsrchr(pstrRoot, '\\');
|
|
LPTSTR pstrFront = _tcsrchr(pstrRoot, '/');
|
|
|
|
if (pstrFront != NULL || pstrBack != NULL)
|
|
{
|
|
if (pstrFront == NULL)
|
|
pstrFront = pstrRoot;
|
|
if (pstrBack == NULL)
|
|
pstrBack = pstrRoot;
|
|
|
|
// from the start to the last whack is the root
|
|
|
|
if (pstrFront >= pstrBack)
|
|
*pstrFront = '\0';
|
|
else
|
|
*pstrBack = '\0';
|
|
}
|
|
m_strRoot.ReleaseBuffer(-1);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CFindFile::MatchesMask(DWORD dwMask) const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pFoundInfo != NULL)
|
|
return (!!(((LPWIN32_FIND_DATA) m_pFoundInfo)->dwFileAttributes & dwMask));
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CFindFile::GetLastAccessTime(FILETIME* pTimeStamp) const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT(pTimeStamp != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pFoundInfo != NULL && pTimeStamp != NULL)
|
|
{
|
|
*pTimeStamp = ((LPWIN32_FIND_DATA) m_pFoundInfo)->ftLastAccessTime;
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CFindFile::GetLastWriteTime(FILETIME* pTimeStamp) const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT(pTimeStamp != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pFoundInfo != NULL && pTimeStamp != NULL)
|
|
{
|
|
*pTimeStamp = ((LPWIN32_FIND_DATA) m_pFoundInfo)->ftLastWriteTime;
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CFindFile::GetCreationTime(FILETIME* pTimeStamp) const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pFoundInfo != NULL && pTimeStamp != NULL)
|
|
{
|
|
*pTimeStamp = ((LPWIN32_FIND_DATA) m_pFoundInfo)->ftCreationTime;
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CFindFile::GetLastAccessTime(CTime& refTime) const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pFoundInfo != NULL)
|
|
{
|
|
refTime = CTime(((LPWIN32_FIND_DATA) m_pFoundInfo)->ftLastAccessTime);
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CFindFile::GetLastWriteTime(CTime& refTime) const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pFoundInfo != NULL)
|
|
{
|
|
refTime = CTime(((LPWIN32_FIND_DATA) m_pFoundInfo)->ftLastWriteTime);
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CFindFile::GetCreationTime(CTime& refTime) const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pFoundInfo != NULL)
|
|
{
|
|
refTime = CTime(((LPWIN32_FIND_DATA) m_pFoundInfo)->ftCreationTime);
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CFindFile::IsDots() const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
// return TRUE if the file name is "." or ".." and
|
|
// the file is a directory
|
|
|
|
BOOL bResult = FALSE;
|
|
if (m_pFoundInfo != NULL && IsDirectory())
|
|
{
|
|
LPWIN32_FIND_DATA pFindData = (LPWIN32_FIND_DATA) m_pFoundInfo;
|
|
if (pFindData->cFileName[0] == '.')
|
|
{
|
|
if (pFindData->cFileName[1] == '\0' ||
|
|
(pFindData->cFileName[1] == '.' &&
|
|
pFindData->cFileName[2] == '\0'))
|
|
{
|
|
bResult = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
BOOL CFindFile::FindNextFile()
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
|
|
if (m_hContext == NULL)
|
|
return FALSE;
|
|
if (m_pFoundInfo == NULL)
|
|
m_pFoundInfo = new WIN32_FIND_DATA;
|
|
|
|
ASSERT_VALID(this);
|
|
|
|
void* pTemp = m_pFoundInfo;
|
|
m_pFoundInfo = m_pNextInfo;
|
|
m_pNextInfo = pTemp;
|
|
|
|
return ::FindNextFile(m_hContext, (LPWIN32_FIND_DATA) m_pNextInfo);
|
|
}
|
|
|
|
CString CFindFile::GetFileURL() const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
CString strResult("file://");
|
|
strResult += GetFilePath();
|
|
return strResult;
|
|
}
|
|
|
|
CString CFindFile::GetRoot() const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
return m_strRoot;
|
|
}
|
|
|
|
CString CFindFile::GetFilePath() const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
CString strResult = m_strRoot;
|
|
if (strResult[strResult.GetLength()-1] != '\\' &&
|
|
strResult[strResult.GetLength()-1] != '/')
|
|
strResult += m_chDirSeparator;
|
|
strResult += GetFileName();
|
|
return strResult;
|
|
}
|
|
|
|
CString CFindFile::GetFileTitle() const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
CString strFullName = GetFileName();
|
|
CString strResult;
|
|
|
|
_tsplitpath(strFullName, NULL, NULL, strResult.GetBuffer(_MAX_PATH), NULL);
|
|
strResult.ReleaseBuffer();
|
|
return strResult;
|
|
}
|
|
|
|
CString CFindFile::GetFileName() const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
CString ret;
|
|
|
|
if (m_pFoundInfo != NULL)
|
|
ret = ((LPWIN32_FIND_DATA) m_pFoundInfo)->cFileName;
|
|
return ret;
|
|
}
|
|
|
|
DWORD CFindFile::GetLength() const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pFoundInfo != NULL)
|
|
return ((LPWIN32_FIND_DATA) m_pFoundInfo)->nFileSizeLow;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
#if defined(_X86_) || defined(_ALPHA_)
|
|
__int64 CFindFile::GetLength64() const
|
|
{
|
|
ASSERT(m_hContext != NULL);
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pFoundInfo != NULL)
|
|
return ((LPWIN32_FIND_DATA) m_pFoundInfo)->nFileSizeLow +
|
|
(((LPWIN32_FIND_DATA) m_pFoundInfo)->nFileSizeHigh << 32);
|
|
else
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
void CFindFile::Dump(CDumpContext& dc) const
|
|
{
|
|
CObject::Dump(dc);
|
|
dc << "\nm_hContext = " << (UINT) m_hContext;
|
|
}
|
|
|
|
void CFindFile::AssertValid() const
|
|
{
|
|
// if you trip the ASSERT in the else side, you've called
|
|
// a Get() function without having done at least one
|
|
// FindNext() call
|
|
|
|
if (m_hContext == NULL)
|
|
ASSERT(m_pFoundInfo == NULL && m_pNextInfo == NULL);
|
|
else
|
|
ASSERT(m_pFoundInfo != NULL && m_pNextInfo != NULL);
|
|
|
|
}
|
|
#endif
|
|
|
|
#ifdef AFX_INIT_SEG
|
|
#pragma code_seg(AFX_INIT_SEG)
|
|
#endif
|
|
|
|
IMPLEMENT_DYNAMIC(CFindFile, CObject)
|