host/common/win32/InmageDriverInterface.cpp (168 lines of code) (raw):
#include "portablehelpers.h"
#include <winioctl.h>
#include "InmFltIoctl.h"
#include "InmFltInterface.h"
#include "InmageDriverInterface.h"
#include <vector>
InmageDriverInterface::InmageDriverInterface() :
m_hInmageDevice(INVALID_HANDLE_VALUE)
{
m_hInmageDevice = CreateFile(INMAGE_DISK_FILTER_DOS_DEVICE_NAME,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE == m_hInmageDevice) {
DebugPrintf(SV_LOG_ERROR, "Failed to open device %s error=%d\n", INMAGE_DISK_FILTER_DOS_DEVICE_NAME, GetLastError());
}
}
InmageDriverInterface::~InmageDriverInterface()
{
if (INVALID_HANDLE_VALUE != m_hInmageDevice) {
CloseHandle(m_hInmageDevice);
}
m_hInmageDevice = INVALID_HANDLE_VALUE;
}
bool InmageDriverInterface::IsDiskRecoveryRequired()
{
DebugPrintf(SV_LOG_DEBUG, "Entering %s\n", FUNCTION_NAME);
if (INVALID_HANDLE_VALUE == m_hInmageDevice) {
DebugPrintf(SV_LOG_ERROR, "%s: Device handle is invalid\n", FUNCTION_NAME);
return false;
}
DRIVER_FLAGS_OUTPUT driverFlags = { 0 };
DWORD dwBytes;
if (!DeviceIoControl(m_hInmageDevice, IOCTL_INMAGE_GET_DRIVER_FLAGS, NULL, 0, &driverFlags, sizeof(driverFlags), &dwBytes, NULL)){
DebugPrintf(SV_LOG_ERROR, "IOCTL_INMAGE_GET_DRIVER_FLAGS failed with error=%d\n", GetLastError());
return false;
}
DebugPrintf(SV_LOG_DEBUG, "Driver Flags: 0x%08x\n", driverFlags.ulFlags);
DebugPrintf(SV_LOG_DEBUG, "Exiting %s\n", FUNCTION_NAME);
return TEST_FLAG(driverFlags.ulFlags, DRIVER_FLAG_DISK_RECOVERY_NEEDED);
}
void InmageDriverInterface::SetSanPolicyToOnlineForAllDisks()
{
DebugPrintf(SV_LOG_DEBUG, "Entering %s\n", FUNCTION_NAME);
if (INVALID_HANDLE_VALUE == m_hInmageDevice) {
DebugPrintf(SV_LOG_ERROR, "%s: Device handle is invalid\n", FUNCTION_NAME);
return;
}
SET_SAN_POLICY sanPolicy = { 0 };
sanPolicy.ulFlags |= SET_SAN_ALL_DEVICES_FLAGS;
sanPolicy.ulPolicy = 0;
DWORD dwBytes;
if (!DeviceIoControl(m_hInmageDevice, IOCTL_INMAGE_SET_SAN_POLICY, &sanPolicy, sizeof(sanPolicy), NULL, 0, &dwBytes, NULL)) {
DebugPrintf(SV_LOG_ERROR, "IOCTL_INMAGE_SET_SAN_POLICY failed for device %s error=%d\n", INMAGE_DISK_FILTER_DOS_DEVICE_NAME, GetLastError());
return;
}
DebugPrintf(SV_LOG_DEBUG, "Exiting %s\n", FUNCTION_NAME);
}
bool InmageDriverInterface::GetDiskIndexList(std::set<SV_ULONG>& diskIndexList)
{
DebugPrintf(SV_LOG_DEBUG, "Entering %s\n", FUNCTION_NAME);
if (INVALID_HANDLE_VALUE == m_hInmageDevice) {
DebugPrintf(SV_LOG_ERROR, "%s: Device handle is invalid\n", FUNCTION_NAME);
return false;
}
PDISKINDEX_INFO pDiskIndexList = NULL;
DWORD size, dwBytes;
std::vector<UCHAR> Buffer(256 * sizeof(SV_ULONG));
pDiskIndexList = (PDISKINDEX_INFO)&Buffer[0];
memset(pDiskIndexList, 0, Buffer.size());
BOOL bSuccess = DeviceIoControl(m_hInmageDevice, IOCTL_INMAGE_GET_DISK_INDEX_LIST, NULL, 0, pDiskIndexList, Buffer.size(), &dwBytes, NULL);
if (bSuccess){
for (ULONG ulIndex = 0; ulIndex < pDiskIndexList->ulNumberOfDisks; ulIndex++) {
DebugPrintf(SV_LOG_DEBUG, "%s: Adding disk %d\n", FUNCTION_NAME, pDiskIndexList->aDiskIndex[ulIndex]);
diskIndexList.insert(pDiskIndexList->aDiskIndex[ulIndex]);
}
}
else {
DebugPrintf(SV_LOG_ERROR, "IOCTL_INMAGE_GET_DISK_INDEX_LIST failed for device %s err=%d\n",
INMAGE_DISK_FILTER_DOS_DEVICE_NAME,
GetLastError());
}
DebugPrintf(SV_LOG_DEBUG, "Exiting %s\n", FUNCTION_NAME);
return (bSuccess == TRUE);
}
bool InmageDriverInterface::StopFilteringAll()
{
DebugPrintf(SV_LOG_DEBUG, "Entering %s\n", FUNCTION_NAME);
if (INVALID_HANDLE_VALUE == m_hInmageDevice) {
DebugPrintf(SV_LOG_ERROR, "%s: Device handle is invalid\n", FUNCTION_NAME);
return false;
}
STOP_FILTERING_INPUT stopFilteringInput = { 0 };
stopFilteringInput.ulFlags = (STOP_ALL_FILTERING_FLAGS | STOP_FILTERING_FLAGS_DELETE_BITMAP);
DWORD dwBytes;
BOOL bSuccess = DeviceIoControl(m_hInmageDevice, IOCTL_INMAGE_STOP_FILTERING_DEVICE, &stopFilteringInput, sizeof(stopFilteringInput), NULL, 0, &dwBytes, NULL);
if (bSuccess) {
DebugPrintf(SV_LOG_ALWAYS, "Filtering Stopped for all devices\n");
}
else {
DWORD dwError = GetLastError();
if (ERROR_FILE_NOT_FOUND == dwError) {
DebugPrintf(SV_LOG_ALWAYS, "None of Devices are protected\n");
bSuccess = TRUE;
}
else {
DebugPrintf(SV_LOG_ERROR, "IOCTL_INMAGE_STOP_FILTERING_DEVICE failed with err=%d\n", dwError);
}
}
DebugPrintf(SV_LOG_DEBUG, "Exiting %s\n", FUNCTION_NAME);
return (bSuccess == TRUE);
}
bool InmageDriverInterface::GetDriverStats()
{
DebugPrintf(SV_LOG_DEBUG, "Entering %s\n", FUNCTION_NAME);
ULONG ulSize = sizeof(VOLUME_STATS_DATA) + MAX_NUM_DISKS_SUPPORTED * sizeof(VOLUME_STATS);
std::vector<UCHAR> Buffer(ulSize, 0);
if (INVALID_HANDLE_VALUE == m_hInmageDevice) {
DebugPrintf(SV_LOG_ERROR, "%s: Device handle is invalid\n", FUNCTION_NAME);
return false;
}
PVOLUME_STATS_DATA pVolumeStatsData = (PVOLUME_STATS_DATA) &Buffer[0];
DWORD dwBytes;
BOOL bSuccess = DeviceIoControl(m_hInmageDevice, IOCTL_INMAGE_GET_VOLUME_STATS, NULL, 0, pVolumeStatsData, ulSize, &dwBytes, NULL);
if (bSuccess) {
DebugPrintf(SV_LOG_ALWAYS, "Received stats for %d devices\n", pVolumeStatsData->ulVolumesReturned);
ULONG ulBytesUsed = sizeof(VOLUME_STATS_DATA);
for (ULONG ulIdx = 0; ulIdx < pVolumeStatsData->ulVolumesReturned; ulIdx++) {
PVOLUME_STATS pVolumeStats = (PVOLUME_STATS)((PUCHAR)pVolumeStatsData + ulBytesUsed);
std::wstring wDeviceId(pVolumeStats->VolumeGUID);
std::string sDeviceId(wDeviceId.begin(), wDeviceId.end());
DebugPrintf(SV_LOG_DEBUG, "Disk%2d: DeviceId: %s\n", ulIdx, sDeviceId.c_str());
ulBytesUsed += sizeof(VOLUME_STATS);
}
}
else {
DWORD dwError = GetLastError();
DebugPrintf(SV_LOG_ERROR, "IOCTL_INMAGE_GET_VOLUME_STATS failed with err=%d\n", dwError);
}
DebugPrintf(SV_LOG_DEBUG, "Exiting %s\n", FUNCTION_NAME);
return (bSuccess == TRUE);
}
bool InmageDriverInterface::GetDriverStats(std::string sDeviceId)
{
DebugPrintf(SV_LOG_DEBUG, "Entering %s\n", FUNCTION_NAME);
ULONG ulSize = sizeof(VOLUME_STATS_DATA) + MAX_NUM_DISKS_SUPPORTED * sizeof(VOLUME_STATS);
std::vector<UCHAR> Buffer(ulSize, 0);
std::wstring wsDviceId(sDeviceId.begin(), sDeviceId.end());
if (INVALID_HANDLE_VALUE == m_hInmageDevice) {
DebugPrintf(SV_LOG_ERROR, "%s: Device handle is invalid\n", FUNCTION_NAME);
return false;
}
PVOLUME_STATS_DATA pVolumeStatsData = (PVOLUME_STATS_DATA)&Buffer[0];
DWORD dwBytes;
BOOL bSuccess = DeviceIoControl(m_hInmageDevice, IOCTL_INMAGE_GET_VOLUME_STATS, (PVOID) (wsDviceId.c_str()), sizeof(wsDviceId.c_str()), pVolumeStatsData, ulSize, &dwBytes, NULL);
if (bSuccess) {
DebugPrintf(SV_LOG_ALWAYS, "Received stats for %d devices\n", pVolumeStatsData->ulVolumesReturned);
}
else {
DWORD dwError = GetLastError();
DebugPrintf(SV_LOG_ERROR, "IOCTL_INMAGE_GET_VOLUME_STATS failed with err=%d\n", dwError);
}
DebugPrintf(SV_LOG_DEBUG, "Exiting %s\n", FUNCTION_NAME);
return (bSuccess == TRUE);
}