Commits

Billy O'Neal committed ec39a6c

Lots of work on the new search paradigm. Nonrecursive and recursive searches are done. Also through out unreferenced option to show .. and . .

Comments (0)

Files changed (10)

pevLib/fileData.cpp

 #include <iomanip>
 #include <iostream>
 #include <algorithm>
+#include <cstring>
 #include <windows.h>
 #include <shlwapi.h>
 #include <Wincrypt.h>
 
 //Constructors
 // Build filedata records
-FileData::FileData(const WIN32_FIND_DATA &rawData, const std::basic_string<TCHAR>& root)
+FileData::FileData(const WIN32_FIND_DATA &rawData, const std::wstring& root)
 {
 	bits = 0;
 
 	//Copy the contents of the win32finddata structure to our internals
-	fileName = rawData.cFileName;
+	std::size_t cFileNameLen = std::wcslen(rawData.cFileName);
+	fileName.reserve(root.size() + cFileNameLen);
+	fileName.append(root).append(rawData.cFileName, cFileNameLen);
 	setAttributesAccordingToDWORD(rawData.dwFileAttributes);
-
-	//Add the path root to the current filename
-	fileName.insert(0,root);
 }
 FileData::FileData(const std::wstring& fileNameBuild) : fileName(fileNameBuild), versionInformationBlock(NULL)
 {
 	} while (*sortPointer++);
 	return 0;
 }
-std::basic_string<TCHAR> FileData::getAttributesString() const
+std::wstring FileData::getAttributesString() const
 {
-	std::basic_string<TCHAR> result;
+	std::wstring result;
 	result.reserve(7);
 	if (bits & DIRECTORY)
 		result.append(1, L'd');
 	appendAttributeCharacter(result, L'e', REPARSE);
 	return result;
 }
-std::basic_string<TCHAR> FileData::getPEAttribsString() const
+std::wstring FileData::getPEAttribsString() const
 {
 	if (!(bits & PEENUMERATED))
 		initPortableExecutable();
-	std::basic_string<TCHAR> result;
+	std::wstring result;
 	result.reserve(6);
 	appendAttributeCharacter(result, L'1', ISPE);
 	appendAttributeCharacter(result, L'2', DEBUG);
 	return result;
 }
 
-void inline FileData::appendAttributeCharacter(std::basic_string<TCHAR> &result, const TCHAR attributeCharacter, const size_t curBit) const
+void inline FileData::appendAttributeCharacter(std::wstring &result, const TCHAR attributeCharacter, const size_t curBit) const
 {
 	if (bits & curBit)
 		result.append(1, attributeCharacter);

pevLib/fileData.h

 	void setAttributesAccordingToDWORD(DWORD win32Attribs) const;
 
 	//Internal calculation functions
-	void inline appendAttributeCharacter(std::basic_string<TCHAR> &result, const TCHAR attributeCharacter, const size_t curBit) const;
+	void inline appendAttributeCharacter(std::wstring &result, const TCHAR attributeCharacter, const size_t curBit) const;
 	std::wstring getVersionInformationString(const std::wstring&) const;
 	template <typename hashType> std::wstring getHash() const;
 
 	//Returns the Win32 handle for the file
 	HANDLE getFileHandle(bool readOnly = true) const;
 	//Construct a fileData record using a Win32FindData structure and a search path.
-	FileData(const WIN32_FIND_DATA &rawData, const std::basic_string<TCHAR>& root);
+	FileData(const WIN32_FIND_DATA &rawData, const std::wstring& root);
 	//Construct a fileData record using a raw filename
 	FileData(const std::wstring &fileNameBuild);
 
 	inline unsigned __int64 getSize() const;
 
 	//Filename
-	inline const std::basic_string<TCHAR> & getFileName() const;
+	inline const std::wstring & getFileName() const;
 
 	//Access times
 	inline const FILETIME getLastAccessTime() const;
 	result |= attributeData.nFileSizeLow;
 	return result;
 }
-inline const std::basic_string<TCHAR> & FileData::getFileName() const
+inline const std::wstring & FileData::getFileName() const
 {
 	return fileName;
 }

pevLib/globalOptions.cpp

 
 std::vector<std::tr1::shared_ptr<regexClass> > globalOptions::regularExpressions;
 std::tr1::shared_ptr<criterion>  globalOptions::logicalTree;
-bool globalOptions::showall = false;
 bool globalOptions::debug = false;
 bool globalOptions::fullPath = false;
 bool globalOptions::summary = false;

pevLib/globalOptions.h

 public:
 	static std::vector<std::tr1::shared_ptr<regexClass> > regularExpressions;
 	static std::tr1::shared_ptr<criterion> logicalTree;
-	static bool showall;
 	static bool debug;
 	static bool fullPath;
 	static bool summary;

pevLib/mainScanner.cpp

 			}
 			//Remove the \* suffix used for the find functions
 			currentSearchDirectory.erase(currentSearchDirectory.length()-1);
-			if (globalOptions::showall)
-				globalOptions::showall = false; //. and .. should not be shown for recursed subdirectories
-			else
+			if (findData.cFileName[0] == L'.' && findData.cFileName[1] == NULL)
 			{
-				if (findData.cFileName[0] == L'.' && findData.cFileName[1] == NULL)
-					if (!FindNextFile(hFind,&findData)) //Skip .
-					{
-						disable64.enableFS();
-						foldersToScan.pop_front();
-						continue;
-					};
-				if (findData.cFileName[0] == L'.' && findData.cFileName[1] == L'.' && findData.cFileName[2] == NULL)
-					if (!FindNextFile(hFind,&findData)) //Skip ..
-					{
-						disable64.enableFS();
-						foldersToScan.pop_front();
-						continue;
-					};
+				if (!FindNextFile(hFind,&findData)) //Skip .
+				{
+					disable64.enableFS();
+					foldersToScan.pop_front();
+					continue;
+				}
+			}
+			if (findData.cFileName[0] == L'.' && findData.cFileName[1] == L'.' && findData.cFileName[2] == NULL)
+			{
+				if (!FindNextFile(hFind,&findData)) //Skip ..
+				{
+					disable64.enableFS();
+					foldersToScan.pop_front();
+					continue;
+				}
 			}
 			std::list<std::wstring>::iterator insPos = foldersToScan.begin();
 			insPos++;

pevLib/reportComponents.cpp

 #include "fileData.h"
 #include "reportComponents.hpp"
 
+namespace
+{
+	class ScopedFindHandle
+	{
+		HANDLE hInner;
+	public:
+		ScopedFindHandle(HANDLE hArg) : hInner(hArg)
+		{ }
+		HANDLE Get()
+		{
+			return hInner;
+		}
+		~ScopedFindHandle()
+		{
+			if (hInner == INVALID_HANDLE_VALUE)
+			{
+				return;
+			}
+			BOOL val = FindClose(hInner);
+			assert(val);
+		}
+	};
+
+	struct VectorFileDataAppender : public std::unary_function<void, const FileData&>
+	{
+		std::vector<FileData>& inserted;
+	public:
+		void operator()(const FileData& toInsert)
+		{
+			inserted.push_back(toInsert);
+		}
+		VectorFileDataAppender(std::vector<FileData>& toInsertTo) : inserted(toInsertTo)
+		{ }
+	};
+}
+
 namespace vFind {
 
 std::vector<FileData> IFilter::Results()
 	return std::vector<FileData>();
 }
 
-
-FileInput::FileInput( const std::wstring& rootPath )
+FileInput::FileInput(const std::wstring& rootPath) : root(rootPath)
 {
-	hSearch = FindFirstFile(rootPath.c_str(), &data);
 }
 
+void FileInput::Enumerate(const std::tr1::function<void(const FileData&)> nextStage)
+{
+	std::wstring rootPlusWildcard;
+	rootPlusWildcard.reserve(root.size() + 2);
+	rootPlusWildcard.append(root).append(L"\\*");
+	WIN32_FIND_DATAW data;
+	ScopedFindHandle hSearch(FindFirstFileW(rootPlusWildcard.c_str(), &data));
+	if (hSearch.Get() == INVALID_HANDLE_VALUE)
+	{
+		return;
+	}
+	do
+	{
+		//Throw out . and ..
+		if (data.cFileName[0] == L'.' && (data.cFileName[1] == L'\0' || (data.cFileName[1] == L'.' && data.cFileName[2] == L'\0')))
+		{
+			continue;
+		}
+		FileData answer(data, root);
+		nextStage(answer);
+	} while (FindNextFileW(hSearch.Get(), &data));
 }
+
+RecursiveFileInput::RecursiveFileInput(const std::wstring& rootPath) : root(rootPath)
+{ }
+
+static void RecursiveSearch(const std::wstring& root, const std::tr1::function<void(const FileData&)> nextStage)
+{
+	std::vector<FileData> currentSearchResults;
+	FileInput thisSearch(root);
+	thisSearch.Enumerate(VectorFileDataAppender(currentSearchResults));
+	std::vector<FileData>::iterator it = currentSearchResults.begin();
+	for (; it != currentSearchResults.end(); ++it)
+	{
+		nextStage(*it);
+		if (it->isDirectory())
+		{
+			RecursiveSearch(it->getFileName(), nextStage);
+		}
+	}
+}
+
+void RecursiveFileInput::Enumerate(const std::tr1::function<void(const FileData&)> nextStage)
+{
+	RecursiveSearch(root, nextStage);
+}
+
+}

pevLib/reportComponents.hpp

-//          Copyright Billy O'Neal 2011
+//              Copyright Billy O'Neal 2011
 // Distributed under the Boost Software License, Version 1.0.
 //    (See accompanying file LICENSE_1_0.txt or copy at
 //          http://www.boost.org/LICENSE_1_0.txt)
 //
 #pragma once
-#include <windows.h>
 #include <vector>
 #include <string>
+#include <functional>
+#include <windows.h>
+#include <boost/optional/optional_fwd.hpp>
+
+class FileData;
 
 namespace vFind {
 
-class FileData;
-
+// An input. Serves as a source of input items.
 struct IInputProvider
 {
 	virtual ~IInputProvider() { }
-	virtual FileData Next() = 0;
+	// Returns all entries from a given input by calling the indicated functor.
+	virtual void Enumerate(const std::tr1::function<void(const FileData&)> nextStage) = 0;
 };
 
 class FileInput : public IInputProvider
 {
-	WIN32_FIND_DATAW data;
-	HANDLE hSearch;
+	std::wstring root;
 public:
 	FileInput(const std::wstring& rootPath);
-	~FileInput();
-	virtual FileData Next();
+	virtual void Enumerate(const std::tr1::function<void(const FileData&)> nextStage);
 };
 
-class ProcessInput : public IInputProvider
+class RecursiveFileInput : public IInputProvider
 {
-	std::vector<std::wstring> processes;
-	std::vector<std::wstring>::iterator current;
+	std::wstring root;
 public:
-	ProcessInput();
-	virtual FileData Next();
+	RecursiveFileInput(const std::wstring& rootPath);
+	virtual void Enumerate(const std::tr1::function<void(const FileData&)> nextStage);
 };
 
 struct IFilter

pevLib/stlUtil.hpp

 //          http://www.boost.org/LICENSE_1_0.txt)
 //
 #pragma once
-#include <funtional>
+#include <functional>
 
 template <typename T>
 struct Deleter : public std::unary_function<void, T>

pevLib/utility.cpp

 	inputPath.assign(&resultRaw[0], neededLength - 1);
 	return inputPath;
 }
-void getShortPathName(const std::basic_string<TCHAR>& longPath, std::basic_string<TCHAR>& shortPath)
+void getShortPathName(const std::wstring& longPath, std::wstring& shortPath)
 {
 	DWORD bufferlen = GetShortPathName(longPath.c_str(),NULL,NULL);
     if (bufferlen == 0)
 	{
 		std::wcout << L"# DEBUGGING OUTPUT #\n";
 		std::wcout << L"Format:\n" << globalOptions::displaySpecification << L"\n\n";
-		if (globalOptions::showall)
-			std::wcout << "Include . and ..\n";
-		else
-			std::wcout << "Exclude . and ..\n";
 		if (globalOptions::debug)
 			std::wcout << L"Display debugging output\n";
 		if (globalOptions::fullPath)