#include "stdafx.h"
#include "KernelCommunication.h"
#include "DriverWork.h"
#include "PackageParser.h"
#include "winioctl.h"
#include "Ioctl.h"
void CallToDriver(size_t ioctlCode,PWCHAR inBuf,DWORD inBufSize)
{
CHAR ret_data[256];
DWORD BytesReturned;
utils::DriverWork::Exchange(
_T("\\\\.\\HideDriver"),
ioctlCode,
inBuf, // Input string
inBufSize, // Size of input string
(PWCHAR)ret_data, // Output string
sizeof(ret_data), // Size of buffer for output string
&BytesReturned);
if(BytesReturned != 0)
throw std::runtime_error( std::string(ret_data) );
}
void SendRule(size_t ioctlCode,const HideRule& hideRule)
{
std::wstring buffer;
utils::PackThreeToOne(hideRule.name,
hideRule.accessProc,
hideRule.accessUser,
&buffer);
// Sending
PWCHAR str = (PWCHAR)buffer.c_str();
DWORD size = buffer.size();
size+=1; // Adding size of '\0' symbol
size*=2; // Take into consideration UNICODE size of character
CallToDriver(ioctlCode,str,size);
}
void KernelCommunication::AddRule(size_t ioctlCode,const HideRule& hideRule)
{
SendRule(ioctlCode,hideRule);
}
void KernelCommunication::DeleteRule(size_t ioctlCode,const HideRule& hideRule)
{
SendRule(ioctlCode,hideRule);
}
void KernelCommunication::DeleteAllRules(size_t ioctlCode)
{
WCHAR inBuf;
CallToDriver(ioctlCode,&inBuf,sizeof(inBuf));
}
void ParseOutputString(wchar_t* buffer,
size_t bufSize,
HideRuleList* ruleList)
{
std::wstring inputString(buffer,bufSize);
WStringList srtRuleList;
utils::UnPackByEOL(inputString,&srtRuleList);
WStringList::const_iterator it = srtRuleList.begin();
for( ; it != srtRuleList.end() ; ++it )
{
HideRule rule;
utils::UnPackThreeToOne(*it,&rule.name,&rule.accessProc,&rule.accessUser);
ruleList->push_back(rule);
}
}
void KernelCommunication::QueryRules(size_t ioctlCode,HideRuleList* ruleList)
{
WCHAR inBuf;
WCHAR ret_data[20*1024];
DWORD BytesReturned;
utils::DriverWork::Exchange(
_T("\\\\.\\HideDriver"),
ioctlCode,
&inBuf, // Input string
sizeof(inBuf), // Size of input string
ret_data, // Output string
sizeof(ret_data), // Size of buffer for output string
&BytesReturned);
if(BytesReturned == 0)
throw std::exception("Driver return empty string");
char* ret_DataA = (char*)ret_data;
char ret_code = ret_DataA[0];
char* ret_real_data = &ret_DataA[0] + 1;
if(ret_code != QUERY_SUCCESS)
throw std::runtime_error( std::string(ret_real_data) );
if(BytesReturned == 1)
return; // Hide rule list is empty
size_t real_data_size = (BytesReturned - 1); // 1 character for ret_code
size_t rule_data_size = real_data_size/2; // Unicode output
ParseOutputString((wchar_t*)ret_real_data,rule_data_size,ruleList);
}