/*++ Copyright (c) 2000-2001 Microsoft Corporation Module Name: direntrs.cpp Abstract: Implementation of the directory entries class. Given a path to a directory, creates two linked lists, one a list of all sub-directories (including mountpoints) and another a list of non-directories. Author: Stefan R. Steiner [ssteiner] 02-21-2000 Revision History: --*/ #include "stdafx.h" #include "direntrs.h" /*++ Routine Description: Constructor for CDirectoryEntries. Arguments: pcDumpParameters - The command-line dump parameters block cwsDirPath - The path to the directory or file to get the directory entries for. Return Value: Can throw an exception. DWORD Win32 error only. --*/ CDirectoryEntries::CDirectoryEntries( IN CDumpParameters *pcDumpParameters, IN const CBsString& cwsDirPath ) : m_pcParams( pcDumpParameters ), m_cwsDirPath( cwsDirPath ) { DWORD dwRet; dwRet = GetDirectoryEntries(); if ( dwRet != ERROR_SUCCESS ) throw( dwRet ); } /*++ Routine Description: Destructor for the CDirectoryEntries class Arguments: NONE Return Value: NONE --*/ CDirectoryEntries::~CDirectoryEntries() { SDirectoryEntry *pDE; // // Iterate through the sub-directory list and delete each element // CVssDLListIterator< SDirectoryEntry * > cDirListIter( m_cDirList ); while( cDirListIter.GetNext( pDE ) ) delete pDE; // // Iterate through the file list and delete each element // CVssDLListIterator< SDirectoryEntry * > cFileListIter( m_cFileList ); while( cFileListIter.GetNext( pDE ) ) delete pDE; } /*++ Routine Description: Performs the actual retrieval of directory entries. Arguments: NONE Return Value: Any DWORD WIN32 error --*/ DWORD CDirectoryEntries::GetDirectoryEntries() { DWORD dwRet = ERROR_SUCCESS; HANDLE hFind; try { WIN32_FIND_DATAW sFindData; // // Now enumerate the directory list // hFind = ::FindFirstFileEx( m_cwsDirPath, FindExInfoStandard, &sFindData, FindExSearchNameMatch, NULL, 0 ); if ( hFind == INVALID_HANDLE_VALUE ) { dwRet = ::GetLastError(); if ( dwRet == ERROR_NO_MORE_FILES || dwRet == ERROR_FILE_NOT_FOUND ) return 0; else { // Calling code will print out an error message if necessary return dwRet; } } // // Now run through the directory // do { // Check and make sure the file such as "." and ".." are not considered if( ::wcscmp( sFindData.cFileName, L".") != 0 && ::wcscmp( sFindData.cFileName, L"..") != 0 ) { SDirectoryEntry *psDirEntry; psDirEntry = new SDirectoryEntry; if ( psDirEntry == NULL ) { dwRet = ::GetLastError(); m_pcParams->ErrPrint( L"GetDirectoryEntries: dirPath: '%s', new() returned dwRet: %d", m_cwsDirPath.c_str(), dwRet ); ::FindClose( hFind ); return dwRet; } // // NOTE!! The following cast makes the assumption that WIN32_FILE_ATTRIBUTE_DATA // is a subset of WIN32_FIND_DATAW // psDirEntry->m_sFindData = *( WIN32_FILE_ATTRIBUTE_DATA * )&sFindData; psDirEntry->m_cwsFileName = sFindData.cFileName; // // Short name is empty if the file name is a conformant 8.3 name. // if ( sFindData.cAlternateFileName[0] != L'\0' ) psDirEntry->m_cwsShortName = sFindData.cAlternateFileName; if ( psDirEntry->m_sFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { // // Add to directory list // m_cDirList.AddTail( psDirEntry ); } else { // // Add to file list // m_cFileList.AddTail( psDirEntry ); } } } while ( ::FindNextFile( hFind, &sFindData ) ); dwRet = ::GetLastError(); if ( dwRet == ERROR_NO_MORE_FILES ) dwRet = ERROR_SUCCESS; else m_pcParams->ErrPrint( L"GetDirectoryEntries: Got an unexpected error, FindNextFile('%s'), dwRet: %d", m_cwsDirPath.c_str(), dwRet ); } catch ( DWORD dwRetThrown ) { dwRet = dwRetThrown; m_pcParams->ErrPrint( L"GetDirectoryEntries: Caught an exception, dirPath: '%s', dwRet: %d", m_cwsDirPath.c_str(), dwRet ); } catch ( ... ) { dwRet = ::GetLastError(); m_pcParams->ErrPrint( L"GetDirectoryEntries: Caught an unknown exception, dirPath: '%s'", m_cwsDirPath.c_str() ); } ::FindClose( hFind ); return dwRet; }