#include "FileRuleChecker.h"
#include "WildCards.h"
#include "KernelHandleGuard.h"
#include "StringUtils.h"
#include <boost/bind.hpp>
namespace HideDriver
{
bool IsNameReserved(const wchar_t* fileName,size_t nameSize)
{
if(nameSize == 1 && fileName[0] == L'.')
return true;
if(nameSize == 2 && fileName[0] == L'.' && fileName[1] == L'.')
return true;
return false;
}
void GetFilePath(HANDLE FileHandle,std::wstring* filepath)
{
PFILE_OBJECT fileObj;
NTSTATUS ret_status =
ObReferenceObjectByHandle(FileHandle,FILE_ALL_ACCESS,*IoFileObjectType,
KernelMode,(PVOID*)(&fileObj),NULL);
if( !NT_SUCCESS(ret_status) )
throw std::exception(__FUNCTION__" ObReferenceObjectByHandle fail.");
utils::ObjectGuard guard(fileObj);
UNICODE_STRING DevName;
RtlVolumeDeviceToDosName(fileObj->DeviceObject,&DevName);
*filepath = std::wstring(DevName.Buffer,DevName.Length/2);
*filepath += std::wstring(fileObj->FileName.Buffer,fileObj->FileName.Length/2);
// For root directory fileObj->FileName contain '\'
// Adding '\' symbol only if this is not a root directory
if(fileObj->FileName.Length > 2)
*filepath += L'\\';
}
bool IsStringHasPath(const std::wstring& ruleObjName)
{
return (ruleObjName.find(L'\\') != std::wstring::npos);
}
bool FileNameChecker(wchar_t* nameToCheck,
size_t nameSize,
const std::wstring& ruleObjName,
const HideAlgorithm::NtQueryDirParams& params)
{
if(IsNameReserved(nameToCheck,nameSize))
return false;
if(IsStringHasPath(ruleObjName))
{
std::wstring filePath;
GetFilePath(params.FileHandle,&filePath);
filePath += std::wstring(nameToCheck,nameSize);
return utils::ApplyWildCards(ruleObjName,filePath);
}
else
{
return utils::ApplyWildCards(ruleObjName.c_str(),
ruleObjName.size(),nameToCheck,nameSize);
}
}
bool FileRuleChecker::CheckFile(wchar_t* nameToCheck,
size_t nameSize,
const HideAlgorithm::NtQueryDirParams& params)
{
return ruleChecker_.CheckRules(
boost::bind(&FileNameChecker,nameToCheck,
nameSize,_1,params));
}
}