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.
|
|
//
// copied from fusion\util\io.cpp with minor changes
//
// xiaoyuw@ 09/05/2001
//
#include "stdinc.h"
#include "macros.h"
#include "fusionbuffer.h"
#include "fusionhandle.h"
#include "fuseio.h"
static BOOL FusionpIsDotOrDotDot( PCWSTR str ) { return ((str[0] == L'.') && ((str[1] == L'\0') || ((str[1] == L'.') && (str[2] == L'\0')))); }
static BOOL IsStarOrStarDotStar( PCWSTR str ) { return (str[0] == '*' && (str[1] == 0 || (str[1] == '.' && str[2] == '*' && str[3] == 0))); }
CDirWalk::ECallbackResult CDirWalk::WalkHelper( ) { const PCWSTR* fileFilter = NULL; BOOL fGotAll = FALSE; BOOL fThisIsAll = FALSE; CFindFile hFind; SIZE_T directoryLength = m_strParent.Cch(); ECallbackResult result = eKeepWalking;
::ZeroMemory(&m_fileData, sizeof(m_fileData)); result |= m_callback(eBeginDirectory, this); if (result & (eError | eSuccess)) { goto Exit; }
if ((result & eStopWalkingFiles) == 0) { for (fileFilter = m_fileFiltersBegin ; fileFilter != m_fileFiltersEnd ; ++fileFilter) { //
// FindFirstFile equates *.* with *, so we do too.
//
fThisIsAll = ::IsStarOrStarDotStar(*fileFilter); fGotAll = fGotAll || fThisIsAll; if (!m_strParent.Win32EnsureTrailingPathSeparator()) goto Error; if (!m_strParent.Win32Append(*fileFilter, (*fileFilter != NULL) ? ::wcslen(*fileFilter) : 0)) goto Error; hFind = ::FindFirstFileW(m_strParent, &m_fileData); m_strParent.Left(directoryLength); if (hFind != INVALID_HANDLE_VALUE) { do { if (::FusionpIsDotOrDotDot(m_fileData.cFileName)) continue;
if (!m_strLastObjectFound.Win32Assign(m_fileData.cFileName, ::wcslen(m_fileData.cFileName))) { goto Error; }
//
// we recurse on directories only if we are getting all of them
// otherwise we do them afterward
//
// the order directories are visited is therefore inconsistent, but
// most applications should be happy enough with the eEndDirectory
// notification (to implement rd /q/s)
//
if (m_fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (fThisIsAll && (result & eStopWalkingDirectories) == 0) { if (!m_strParent.Win32Append("\\", 1)) { goto Error; } if (!m_strParent.Win32Append(m_fileData.cFileName, ::wcslen(m_fileData.cFileName))) { goto Error; } result |= WalkHelper(); } } else { if ((result & eStopWalkingFiles) == 0) { result |= m_callback(eFile, this); } } m_strParent.Left(directoryLength); if (result & (eError | eSuccess)) { goto Exit; } if (fThisIsAll) { if ((result & eStopWalkingDirectories) && (result & eStopWalkingFiles)) { if (!hFind.Win32Close()) { goto Error; } goto StopWalking; } } else { if (result & eStopWalkingFiles) { if (!hFind.Win32Close()) { goto Error; } goto StopWalking; } } } while(::FindNextFileW(hFind, &m_fileData)); if (::GetLastError() != ERROR_NO_MORE_FILES) { goto Error; } if (!hFind.Win32Close()) { goto Error; } } } } StopWalking:; //
// make another pass with * to get all directories, if we haven't already
//
if (!fGotAll && (result & eStopWalkingDirectories) == 0) { if (!m_strParent.Win32Append("\\*", 2)) { goto Error; } hFind = ::FindFirstFileW(m_strParent, &m_fileData); m_strParent.Left(directoryLength); if (hFind != INVALID_HANDLE_VALUE) { do { if (::FusionpIsDotOrDotDot(m_fileData.cFileName)) continue;
if ((m_fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) { continue; }
if (!m_strLastObjectFound.Win32Assign(m_fileData.cFileName, ::wcslen(m_fileData.cFileName))) { goto Error; }
if (!m_strParent.Win32Append("\\", 1)) { goto Error; } if (!m_strParent.Win32Append(m_fileData.cFileName, ::wcslen(m_fileData.cFileName))) { goto Error; } result |= WalkHelper(); m_strParent.Left(directoryLength);
if (result & (eError | eSuccess)) { goto Exit; } if (result & eStopWalkingDirectories) { goto StopWalkingDirs; } } while(::FindNextFileW(hFind, &m_fileData)); if (::GetLastError() != ERROR_NO_MORE_FILES) { goto Error; } StopWalkingDirs: if (!hFind.Win32Close()) { goto Error; } } } ::ZeroMemory(&m_fileData, sizeof(m_fileData)); result |= m_callback(eEndDirectory, this); if (result & (eError | eSuccess)) { goto Exit; }
result = eKeepWalking; Exit: if ((result & eStopWalkingDeep) == 0) { result &= ~(eStopWalkingFiles | eStopWalkingDirectories); } if (result & eError) { result |= (eStopWalkingFiles | eStopWalkingDirectories | eStopWalkingDeep); } return result; Error: result |= eError; goto Exit; }
CDirWalk::CDirWalk() { const static PCWSTR defaultFileFilter[] = { L"*" };
m_fileFiltersBegin = defaultFileFilter; m_fileFiltersEnd = defaultFileFilter + NUMBER_OF(defaultFileFilter); }
BOOL CDirWalk::Walk() { BOOL fSuccess = FALSE; //
// Save off the original path length before we go twiddling m_strParent
//
m_cchOriginalPath = m_strParent.Cch();
ECallbackResult result = WalkHelper(); if (result & eError) { if (::GetLastError() == ERROR_SUCCESS) // forget to set lasterror ?
::SetLastError(ERROR_INSTALL_FAILURE); goto Exit; } fSuccess = TRUE; Exit: return fSuccess; }
|