#include "drvCommon.h"
#include "Ioctl.h"
#include "UserCommunication.h"
#include "PackageParser.h"
#include "scoped_action.h"
#include "boost/bind.hpp"
namespace HideDriver
{
void RemoveEOFSymbol(std::wstring* str)
{
while(true)
{
std::wstring::iterator it =
std::find(str->begin(),str->end(),L'\0');
if( it == str->end())
break;
str->erase(it);
}
}
HideRule ConvertString2Rule(WCHAR* pBuf,ULONG buf_size)
{
std::wstring inputString(pBuf,buf_size/2);
RemoveEOFSymbol(&inputString);
std::wstring nameParam;
std::wstring procParam;
std::wstring userParam;
utils::UnPackThreeToOne(inputString,
&nameParam,
&procParam,
&userParam);
WStringList procList;
utils::UnPackByComma(procParam,&procList);
WStringList userList;
utils::UnPackByComma(userParam,&userList);
HideRule newRule = {nameParam,procList,userList};
return newRule;
}
void RuleProcessor::AddRule(WCHAR* pBuf,ULONG buf_size)
{
DbgPrint("-HideDriver- Add Rule - Input string: %ws\n",pBuf);
HideRule newRule = ConvertString2Rule(pBuf,buf_size);
ruleHolder_->AddRule(newRule);
}
void RuleProcessor::DelRule(WCHAR* pBuf,ULONG buf_size)
{
DbgPrint("-HideDriver- Delete Rule - Input string: %ws\n",pBuf);
HideRule rule = ConvertString2Rule(pBuf,buf_size);
ruleHolder_->DelRule(rule);
}
void RuleProcessor::DelAllRules()
{
DbgPrint("-HideDriver- Delete All Rules\n");
ruleHolder_->DelAllRules();
}
void RuleProcessor::QueryRulesImpl(WCHAR* pBuf,ULONG buf_size,ULONG* bytesTxd)
{
const HideRuleList& hideRuleList = ruleHolder_->AcquireRuleList();
utils::scoped_action guard(boost::bind(&IRuleHolder::ReleaseRuleList,ruleHolder_));
if(hideRuleList.empty())
return;
WStringList strRuleList;
HideRuleList::const_iterator it = hideRuleList.begin();
for( ; it != hideRuleList.end() ; ++it )
{
std::wstring procParam;
utils::PackByComma(it->processList,&procParam);
std::wstring userParam;
utils::PackByComma(it->userList,&userParam);
std::wstring ruleString;
utils::PackThreeToOne(it->objectName,procParam,userParam,&ruleString);
strRuleList.push_back(ruleString);
}
std::wstring ruleListString;
utils::PackByEOL(strRuleList,&ruleListString);
if(ruleListString.empty())
{
*bytesTxd = 0;
return;
}
if(ruleListString.size() > buf_size)
throw std::exception("Buffer size is not enough to hold rule list");
memcpy(pBuf,ruleListString.c_str(),ruleListString.size()*2);
*bytesTxd = ruleListString.size()*2;
}
void RuleProcessor::QueryRules(WCHAR* pBuf,ULONG outputBufSize,ULONG* bytesTxd)
{
DbgPrint("-HideDriver- Query Rules\n");
// Need to dispatch exception message by hand
// to provide information type that will be returned
// First byte for information type
char* pDataBuf = (char*)pBuf + 1;
try
{
QueryRulesImpl((wchar_t*)pDataBuf,outputBufSize-1,bytesTxd);
char infoType = QUERY_SUCCESS;
memcpy(pBuf,&infoType,1);
*bytesTxd += 1;
}
catch(const std::exception& ex)
{
char infoType = QUERY_FAIL;
std::string error;
error += infoType;
error += ex.what();
throw std::runtime_error(error);
}
}
void FileCommunication::Initialize(utils::QueryMng& queryMng)
{
queryMng.Subscribe(IOCTL_ADD_FILE_HIDE_RULE,this);
queryMng.Subscribe(IOCTL_DEL_FILE_HIDE_RULE,this);
queryMng.Subscribe(IOCTL_CLEAR_FILE_HIDE_RULES,this);
queryMng.Subscribe(IOCTL_QUERY_FILE_HIDE_RULES,this);
}
void FileCommunication::Cleanup(utils::QueryMng& queryMng)
{
queryMng.UnSubscribe(IOCTL_ADD_FILE_HIDE_RULE,this);
queryMng.UnSubscribe(IOCTL_DEL_FILE_HIDE_RULE,this);
queryMng.UnSubscribe(IOCTL_CLEAR_FILE_HIDE_RULES,this);
queryMng.UnSubscribe(IOCTL_QUERY_FILE_HIDE_RULES,this);
}
void FileCommunication::Dispatch(ULONG controlCode,
WCHAR* buf,
ULONG inputBufSize,
ULONG outputBufSize,
ULONG* bytesTxd)
{
switch( controlCode )
{
case IOCTL_ADD_FILE_HIDE_RULE:
ruleProcessor_.AddRule(buf,inputBufSize); break;
case IOCTL_DEL_FILE_HIDE_RULE:
ruleProcessor_.DelRule(buf,inputBufSize); break;
case IOCTL_CLEAR_FILE_HIDE_RULES:
ruleProcessor_.DelAllRules(); break;
case IOCTL_QUERY_FILE_HIDE_RULES:
ruleProcessor_.QueryRules(buf,outputBufSize,bytesTxd); break;
default:
throw std::exception(__FUNCTION__"Wrong controlCode.");
}
}
void ProcessCommunication::Initialize(utils::QueryMng& queryMng)
{
queryMng.Subscribe(IOCTL_ADD_PROCESS_HIDE_RULE,this);
queryMng.Subscribe(IOCTL_DEL_PROCESS_HIDE_RULE,this);
queryMng.Subscribe(IOCTL_CLEAR_PROCESS_HIDE_RULES,this);
queryMng.Subscribe(IOCTL_QUERY_PROCESS_HIDE_RULES,this);
}
void ProcessCommunication::Cleanup(utils::QueryMng& queryMng)
{
queryMng.UnSubscribe(IOCTL_ADD_PROCESS_HIDE_RULE,this);
queryMng.UnSubscribe(IOCTL_DEL_PROCESS_HIDE_RULE,this);
queryMng.UnSubscribe(IOCTL_CLEAR_PROCESS_HIDE_RULES,this);
queryMng.UnSubscribe(IOCTL_QUERY_PROCESS_HIDE_RULES,this);
}
void ProcessCommunication::Dispatch(ULONG controlCode,
WCHAR* buf,
ULONG inputBufSize,
ULONG outputBufSize,
ULONG* bytesTxd)
{
switch( controlCode )
{
case IOCTL_ADD_PROCESS_HIDE_RULE:
ruleProcessor_.AddRule(buf,inputBufSize); break;
case IOCTL_DEL_PROCESS_HIDE_RULE:
ruleProcessor_.DelRule(buf,inputBufSize); break;
case IOCTL_CLEAR_PROCESS_HIDE_RULES:
ruleProcessor_.DelAllRules(); break;
case IOCTL_QUERY_PROCESS_HIDE_RULES:
ruleProcessor_.QueryRules(buf,outputBufSize,bytesTxd); break;
default:
throw std::exception(__FUNCTION__"Wrong controlCode.");
}
}
}