1302 lines
37 KiB
C
1302 lines
37 KiB
C
/*++
|
||
|
||
Module Name:
|
||
|
||
cdsflt.c
|
||
|
||
Abstract:
|
||
|
||
This is the main module of the cds_flt miniFilter driver.
|
||
|
||
Environment:
|
||
|
||
Kernel mode
|
||
|
||
--*/
|
||
|
||
|
||
#include "precomp.h"
|
||
|
||
#pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers")
|
||
|
||
ULONG g_DebugLevel = 0;
|
||
BS1FLT g_bs1Flt;
|
||
|
||
PFLT_FILTER gFilterHandle;
|
||
ULONG_PTR OperationStatusCtx = 1;
|
||
|
||
ULONG gTraceFlags = 0;
|
||
#define _ALLOC_TAG 'kdqw'
|
||
BOOLEAN g_IsUnloadAllowed = TRUE;
|
||
|
||
/*************************************************************************
|
||
Prototypes
|
||
*************************************************************************/
|
||
|
||
//
|
||
// Assign text sections for each routine.
|
||
//
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(INIT, DriverEntry)
|
||
#pragma alloc_text(PAGE, Bs1FltUnload)
|
||
#pragma alloc_text(PAGE, Bs1FltInstanceQueryTeardown)
|
||
#pragma alloc_text(PAGE, Bs1FltInstanceSetup)
|
||
#pragma alloc_text(PAGE, Bs1FltInstanceTeardownStart)
|
||
#pragma alloc_text(PAGE, Bs1FltInstanceTeardownComplete)
|
||
#endif
|
||
|
||
//
|
||
// operation registration
|
||
//
|
||
|
||
CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
|
||
|
||
#if 1 // TODO - List all of the requests to filter.
|
||
{ IRP_MJ_CREATE,
|
||
0,
|
||
Bs1FltPreOperation,
|
||
Bs1FltPostOperation },
|
||
|
||
/* { IRP_MJ_CREATE_NAMED_PIPE,
|
||
0,
|
||
cdsfltPreOperation,
|
||
cdsfltPostOperation },*/
|
||
|
||
{ IRP_MJ_CLOSE,
|
||
0,
|
||
Bs1FltPreOperation,
|
||
Bs1FltPostOperation },
|
||
|
||
{ IRP_MJ_WRITE,
|
||
0,
|
||
Bs1FltPreOperation,
|
||
Bs1FltPostOperation },
|
||
|
||
{ IRP_MJ_READ,
|
||
0,
|
||
Bs1FltPreRead,
|
||
NULL },
|
||
/*
|
||
{ IRP_MJ_QUERY_INFORMATION,
|
||
0,
|
||
cdsfltPreOperation,
|
||
cdsfltPostOperation },*/
|
||
|
||
{ IRP_MJ_SET_INFORMATION,
|
||
0,
|
||
Bs1FltPreOperation,
|
||
Bs1FltPostOperation },
|
||
|
||
//{ IRP_MJ_QUERY_EA,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_SET_EA,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_FLUSH_BUFFERS,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_QUERY_VOLUME_INFORMATION,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_SET_VOLUME_INFORMATION,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_DIRECTORY_CONTROL,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_FILE_SYSTEM_CONTROL,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_DEVICE_CONTROL,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_INTERNAL_DEVICE_CONTROL,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_SHUTDOWN,
|
||
// 0,
|
||
// cdsfltPreOperationNoPostOperation,
|
||
// NULL }, //post operations not supported
|
||
|
||
//{ IRP_MJ_LOCK_CONTROL,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
{ IRP_MJ_CLEANUP,
|
||
0,
|
||
Bs1FltPreOperation,
|
||
Bs1FltPostOperation },
|
||
|
||
//{ IRP_MJ_CREATE_MAILSLOT,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_QUERY_SECURITY,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_SET_SECURITY,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_QUERY_QUOTA,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_SET_QUOTA,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_PNP,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_RELEASE_FOR_SECTION_SYNCHRONIZATION,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_ACQUIRE_FOR_MOD_WRITE,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_RELEASE_FOR_MOD_WRITE,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_ACQUIRE_FOR_CC_FLUSH,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_RELEASE_FOR_CC_FLUSH,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_FAST_IO_CHECK_IF_POSSIBLE,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_NETWORK_QUERY_OPEN,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_MDL_READ,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_MDL_READ_COMPLETE,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_PREPARE_MDL_WRITE,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_MDL_WRITE_COMPLETE,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_VOLUME_MOUNT,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
//{ IRP_MJ_VOLUME_DISMOUNT,
|
||
// 0,
|
||
// cdsfltPreOperation,
|
||
// cdsfltPostOperation },
|
||
|
||
#endif // TODO
|
||
|
||
{ IRP_MJ_OPERATION_END }
|
||
};
|
||
|
||
#define VOLUME_CONTEXT_POOLTAG 'b1vo'
|
||
const FLT_CONTEXT_REGISTRATION ContextRegistration[] = {
|
||
|
||
{
|
||
FLT_VOLUME_CONTEXT,
|
||
0,
|
||
Bs1FltCleanupVolumeContext,
|
||
sizeof(VOLUME_CONTEXT),
|
||
VOLUME_CONTEXT_POOLTAG
|
||
},
|
||
|
||
{ FLT_CONTEXT_END }
|
||
};
|
||
|
||
//
|
||
// This defines what we want to filter with FltMgr
|
||
//
|
||
|
||
CONST FLT_REGISTRATION FilterRegistration = {
|
||
|
||
sizeof( FLT_REGISTRATION ), // Size
|
||
FLT_REGISTRATION_VERSION, // Version
|
||
0, // Flags
|
||
|
||
ContextRegistration, // Context
|
||
Callbacks, // Operation callbacks
|
||
|
||
Bs1FltUnload, // MiniFilterUnload
|
||
|
||
Bs1FltInstanceSetup, // InstanceSetup
|
||
Bs1FltInstanceQueryTeardown, // InstanceQueryTeardown
|
||
NULL, // InstanceTeardownStart
|
||
NULL, // InstanceTeardownComplete
|
||
|
||
NULL, // GenerateFileName
|
||
NULL, // GenerateDestinationFileName
|
||
NULL // NormalizeNameComponent
|
||
|
||
};
|
||
|
||
/*
|
||
|
||
NTSTATUS
|
||
GetPnPDeviceId(
|
||
__in PDEVICE_OBJECT DeviceObject,
|
||
__in DEVICE_REGISTRY_PROPERTY RegistryProperty, // DevicePropertyHardwareID or DevicePropertyInstanceID
|
||
__out PWCHAR* IdString
|
||
)
|
||
{
|
||
NTSTATUS status;
|
||
ULONG resultLength = 0;
|
||
PVOID buffer = NULL;
|
||
|
||
// 1. <20>ʿ<EFBFBD><CABF><EFBFBD> <20><><EFBFBD><EFBFBD> ũ<><C5A9> <20><><EFBFBD>ϱ<EFBFBD>
|
||
status = IoGetDeviceProperty(
|
||
DeviceObject,
|
||
RegistryProperty,
|
||
0,
|
||
NULL,
|
||
&resultLength
|
||
);
|
||
|
||
if (status != STATUS_BUFFER_TOO_SMALL)
|
||
{
|
||
return STATUS_UNSUCCESSFUL;
|
||
}
|
||
|
||
// 2. <20><EFBFBD><DEB8><EFBFBD> <20>Ҵ<EFBFBD>
|
||
buffer = ExAllocatePoolWithTag(NonPagedPool, resultLength, 'PnPI');
|
||
if (!buffer)
|
||
{
|
||
return STATUS_INSUFFICIENT_RESOURCES;
|
||
}
|
||
|
||
// 3. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
status = IoGetDeviceProperty(
|
||
DeviceObject,
|
||
RegistryProperty,
|
||
resultLength,
|
||
buffer,
|
||
&resultLength
|
||
);
|
||
|
||
if (NT_SUCCESS(status))
|
||
{
|
||
*IdString = (PWCHAR)buffer;
|
||
}
|
||
else
|
||
{
|
||
ExFreePoolWithTag(buffer, 'PnPI');
|
||
*IdString = NULL;
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
NTSTATUS
|
||
Bs1FltGetUsb(
|
||
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||
_In_ FLT_INSTANCE_SETUP_FLAGS Flags,
|
||
_In_ DEVICE_TYPE VolumeDeviceType,
|
||
_In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType
|
||
)
|
||
{
|
||
NTSTATUS status = STATUS_SUCCESS;
|
||
PDEVICE_OBJECT diskDeviceObject = NULL;
|
||
PDEVICE_OBJECT physicalDeviceObject = NULL; // PDO
|
||
PWCHAR pInstanceId = NULL;
|
||
|
||
UNREFERENCED_PARAMETER(Flags);
|
||
UNREFERENCED_PARAMETER(VolumeDeviceType);
|
||
UNREFERENCED_PARAMETER(VolumeFilesystemType);
|
||
|
||
PAGED_CODE();
|
||
|
||
// 1. <20><>Ʈ<EFBFBD><C6AE>ũ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ũ<EFBFBD><C5A9> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> Skip
|
||
// (<28><>Ʈ<EFBFBD><C6AE>ũ <20><><EFBFBD><EFBFBD><EFBFBD>̺꿡<CCBA><EABFA1> DiskDeviceObject<63><74> <20><><EFBFBD>ϸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰų<CFB0> NULL<4C><4C> <20><><EFBFBD>ɴϴ<C9B4>)
|
||
if (VolumeDeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM)
|
||
{
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
// 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ũ <20><><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD> <20><>ü(Disk Device Object) ȹ<><C8B9>
|
||
status = FltGetDiskDeviceObject(FltObjects->Volume, &diskDeviceObject);
|
||
|
||
// <20><><EFBFBD><EFBFBD>ũ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD> <20>ƴϸ<C6B4>(RAM Disk, Network <20><>) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
|
||
if (NT_SUCCESS(status) && diskDeviceObject != NULL)
|
||
{
|
||
// 3. <20><><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ٴڿ<D9B4> <20>ִ<EFBFBD> PDO(Physical Device Object) ȹ<><C8B9>
|
||
// PnP <20><><EFBFBD><EFBFBD>(VID, PID <20><>)<29><> PDO<44><4F> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>.
|
||
physicalDeviceObject = IoGetDeviceAttachmentBaseRef(diskDeviceObject);
|
||
|
||
if (physicalDeviceObject != NULL)
|
||
{
|
||
// 4. Instance ID <20><>ȸ (<28><>: USB\VID_xxxx&PID_xxxx\Serial...)
|
||
status = GetPnPDeviceId(physicalDeviceObject, DevicePropertyInstanceID, &pInstanceId);
|
||
|
||
if (NT_SUCCESS(status) && pInstanceId != NULL)
|
||
{
|
||
KLogEx(DEBUG_TRACE_INFO, "[InstanceSetup] Vol=%p, InstanceID=%S\n",
|
||
FltObjects->Volume, pInstanceId);
|
||
|
||
// TODO: <20><><EFBFBD>⼭ pInstanceId<49><64> <20><><EFBFBD>ؽ<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>ϰų<CFB0> <20><>å Ȯ<>ο<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><> <20><EFBFBD><DEB8><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
ExFreePool(pInstanceId);
|
||
}
|
||
|
||
// [<5B>߿<EFBFBD>] IoGetDeviceAttachmentBaseRef<65><66> <20><><EFBFBD>۷<EFBFBD><DBB7><EFBFBD> ī<><C4AB>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ű<EFBFBD>Ƿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʼ<EFBFBD>
|
||
ObDereferenceObject(physicalDeviceObject);
|
||
}
|
||
|
||
// [<5B>߿<EFBFBD>] FltGetDiskDeviceObject<63><74> <20><><EFBFBD>۷<EFBFBD><DBB7><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ű<EFBFBD>Ƿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʼ<EFBFBD>
|
||
ObDereferenceObject(diskDeviceObject);
|
||
}
|
||
|
||
// InstanceSetup<75><70> <20><><EFBFBD><EFBFBD> STATUS_SUCCESS<53><53> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20><><EFBFBD>Ͱ<EFBFBD> <20>ٽ<EFBFBD><D9BD>ϴ<EFBFBD>.
|
||
// ID<49><44> <20><> <20><><EFBFBD>ߴٰ<DFB4> <20>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>н<EFBFBD>ų<EFBFBD><C5B3><EFBFBD><EFBFBD> <20><>å<EFBFBD><C3A5> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϼ<EFBFBD><CFBC><EFBFBD>.
|
||
return STATUS_SUCCESS;
|
||
}
|
||
*/
|
||
|
||
/*
|
||
NTSTATUS
|
||
Bs1FltInstanceSetup (
|
||
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||
_In_ FLT_INSTANCE_SETUP_FLAGS Flags,
|
||
_In_ DEVICE_TYPE VolumeDeviceType,
|
||
_In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType
|
||
)
|
||
|
||
//Routine Description:
|
||
//
|
||
// This routine is called whenever a new instance is created on a volume. This
|
||
// gives us a chance to decide if we need to attach to this volume or not.
|
||
//
|
||
// If this routine is not defined in the registration structure, automatic
|
||
// instances are always created.
|
||
//
|
||
//Arguments:
|
||
//
|
||
// FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
|
||
// opaque handles to this filter, instance and its associated volume.
|
||
//
|
||
// Flags - Flags describing the reason for this attach request.
|
||
//
|
||
//Return Value:
|
||
//
|
||
//STATUS_SUCCESS - attach
|
||
//STATUS_FLT_DO_NOT_ATTACH - do not attach
|
||
|
||
|
||
{
|
||
UCHAR volPropBuffer[sizeof(FLT_VOLUME_PROPERTIES) + 512];
|
||
PFLT_VOLUME_PROPERTIES volProp = (PFLT_VOLUME_PROPERTIES)volPropBuffer;
|
||
PDEVICE_OBJECT devObj = NULL;
|
||
WCHAR detail[512] = { 0, };
|
||
NTSTATUS status = STATUS_SUCCESS;
|
||
ULONG retLen = 0;
|
||
//UNICODE_STRING name = { 0, };
|
||
PUNICODE_STRING workingName = NULL;
|
||
USHORT size = 0;
|
||
PVOLUME_CONTEXT ctx = NULL;
|
||
//UNICODE_STRING processImagePath = { 0, };
|
||
//HANDLE ProcessId = 0;
|
||
|
||
//PVOLUME_CONTEXT volCtx = NULL;
|
||
|
||
UNREFERENCED_PARAMETER( FltObjects );
|
||
UNREFERENCED_PARAMETER( Flags );
|
||
UNREFERENCED_PARAMETER( VolumeDeviceType );
|
||
UNREFERENCED_PARAMETER( VolumeFilesystemType );
|
||
|
||
PAGED_CODE();
|
||
|
||
ASSERT(FltObjects->Filter == g_cdsflt.Filter);
|
||
|
||
KLogEx(DEBUG_TRACE_INFO, "Flags(%08x), vtype(%08x), vftype(%08x)\n", Flags, VolumeDeviceType, VolumeFilesystemType);
|
||
|
||
if (VolumeFilesystemType == FLT_FSTYPE_UNKNOWN ||
|
||
VolumeFilesystemType == FLT_FSTYPE_LANMAN ||
|
||
VolumeFilesystemType == FLT_FSTYPE_WEBDAV
|
||
)
|
||
{
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
status = FltAllocateContext(FltObjects->Filter, FLT_VOLUME_CONTEXT, sizeof(VOLUME_CONTEXT), NonPagedPool, &ctx);
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
KLogEx(DEBUG_TRACE_ERROR, "FltAllocateContext Return Fail %x\n", status);
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
try
|
||
{
|
||
|
||
RtlZeroMemory(ctx, sizeof(VOLUME_CONTEXT));
|
||
status = FltGetVolumeProperties(FltObjects->Volume, volProp, sizeof(volPropBuffer), &retLen);
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
KLogEx(DEBUG_TRACE_ERROR, "FltGetVolumeProperties Return Fail %x\n", status);
|
||
leave;
|
||
}
|
||
|
||
status = FltGetDiskDeviceObject(FltObjects->Volume, &devObj);
|
||
if (NT_SUCCESS(status))
|
||
{
|
||
status = RtlVolumeDeviceToDosName(devObj, &ctx->name);
|
||
ctx->device_type = devObj->DeviceType;
|
||
if (devObj)
|
||
ObDereferenceObject(devObj);
|
||
|
||
KLogEx(DEBUG_TRACE_INFO, "DosName(%S)\n", ctx->name.Buffer);
|
||
}
|
||
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
if (!MmIsAddressValid(ctx))
|
||
{
|
||
KLogEx(DEBUG_TRACE_ERROR, "MmIsAddressValid Return Fail");
|
||
leave;
|
||
}
|
||
|
||
if (volProp->RealDeviceName.Length > 0)
|
||
workingName = &volProp->RealDeviceName;
|
||
else if (volProp->FileSystemDeviceName.Length > 0)
|
||
workingName = &volProp->FileSystemDeviceName;
|
||
else
|
||
{
|
||
status = STATUS_FLT_DO_NOT_ATTACH;
|
||
KLogEx(DEBUG_TRACE_ERROR, "STATUS_FLT_DO_NOT_ATTACH -\n");
|
||
leave;
|
||
}
|
||
|
||
size = workingName->Length + sizeof(WCHAR);
|
||
|
||
status = UStrNew(&ctx->name, size);
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
KLogEx(DEBUG_TRACE_ERROR, "IStrNew Return Fail %x, size(%d)\n", status, size);
|
||
leave;
|
||
}
|
||
|
||
RtlCopyUnicodeString(&ctx->name, workingName);
|
||
RtlAppendUnicodeToString(&ctx->name, L":");
|
||
}
|
||
|
||
{
|
||
IO_STATUS_BLOCK Iosb = { 0, };
|
||
ULONG64 buf[8] = { 0, };
|
||
PFILE_FS_VOLUME_INFORMATION volumeInfo = NULL;
|
||
NTSTATUS querystatus = STATUS_SUCCESS;
|
||
|
||
volumeInfo = (PFILE_FS_VOLUME_INFORMATION)buf;
|
||
|
||
querystatus = FltQueryVolumeInformation(FltObjects->Instance, &Iosb, volumeInfo, sizeof(ULONG64) * 8, FileFsVolumeInformation);
|
||
|
||
if (querystatus == STATUS_SUCCESS)
|
||
{
|
||
if (volumeInfo->VolumeLabelLength > 0 && volumeInfo->VolumeLabelLength < 100)
|
||
{
|
||
memcpy(ctx->wLabel, volumeInfo->VolumeLabel, volumeInfo->VolumeLabelLength);
|
||
KLogEx(DEBUG_TRACE_INFO, "FltQueryVolumeInformation Return wLabel[%S]\n", ctx->wLabel);
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
GetVolumeProperties(FltObjects, ctx);
|
||
|
||
if (ctx && ctx->name.Buffer)
|
||
{
|
||
// KLogEx (<28><><EFBFBD><EFBFBD>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD> <20>ٸ<EFBFBD><D9B8><EFBFBD><EFBFBD><EFBFBD>, DbgPrint ȣȯ<C8A3>̶<EFBFBD><CCB6><EFBFBD> %wZ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||
// <20><><EFBFBD><EFBFBD> KLogEx<45><78> %wZ<77><5A> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´ٸ<C2B4> <20>Ʒ<EFBFBD> RtlStringCbPrintfW <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>
|
||
//KLogEx(DEBUG_TRACE_INFO,
|
||
// "Name(%wZ), BusType(%d), DeviceType(%d), VendorId(%.8hs), ProductId(%.16hs)\n",
|
||
// &ctx->name, // .Buffer<65><72> <20>ƴ϶<C6B4> <20><><EFBFBD><EFBFBD>ü <20>ּҸ<D6BC> <20>ѱ<EFBFBD> (%wZ)
|
||
// ctx->bustype,
|
||
// ctx->device_type,
|
||
// ctx->vendorid ? ctx->vendorid : (PUCHAR)"NULL",
|
||
// ctx->productid ? ctx->productid : (PUCHAR)"NULL"
|
||
//);
|
||
|
||
// RtlStringCbPrintfW (ǥ<><C7A5> Ŀ<><C4BF> <20>Լ<EFBFBD>)
|
||
RtlStringCbPrintfW(
|
||
detail,
|
||
sizeof(detail),
|
||
L"Name(%wZ), BusType(%d), DeviceType(%d), VendorId(%.16hs), ProductId(%.16hs), Revision(%.20hs), Serial(%.20hs)",
|
||
&ctx->name, // [<5B>ٽ<EFBFBD>] %s <20><><EFBFBD><EFBFBD> %wZ <20><><EFBFBD><EFBFBD>, Buffer <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ü <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
ctx->bustype,
|
||
ctx->device_type,
|
||
// ANSI <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><>: SCSI <20><><EFBFBD><EFBFBD>)<29><><EFBFBD><EFBFBD> <20><><EFBFBD≯<EFBFBD> <20><><EFBFBD><EFBFBD>(%.8hs)<29><><EFBFBD>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
ctx->vendorid ? ctx->vendorid : (PUCHAR)"NULL",
|
||
ctx->productid ? ctx->productid : (PUCHAR)"NULL",
|
||
ctx->productrevisionlevel ? ctx->productrevisionlevel : (PUCHAR)"NULL",
|
||
ctx->vendorspecific ? ctx->vendorspecific : (PUCHAR)"NULL"
|
||
);
|
||
|
||
SetConnectLog(FltObjects, ctx->device_type, 0, 0, L"system", detail);
|
||
}
|
||
|
||
status = FltSetVolumeContext(FltObjects->Volume, FLT_SET_CONTEXT_KEEP_IF_EXISTS, ctx, NULL);
|
||
KLogEx(DEBUG_TRACE_INFO, "state(%x)\n", status);
|
||
if (status == STATUS_FLT_CONTEXT_ALREADY_DEFINED)
|
||
status = STATUS_SUCCESS;
|
||
}
|
||
finally
|
||
{
|
||
if (ctx)
|
||
FltReleaseContext(ctx);
|
||
}
|
||
|
||
return STATUS_SUCCESS;
|
||
}
|
||
*/
|
||
|
||
NTSTATUS
|
||
Bs1FltInstanceSetup(
|
||
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||
_In_ FLT_INSTANCE_SETUP_FLAGS Flags,
|
||
_In_ DEVICE_TYPE VolumeDeviceType,
|
||
_In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType
|
||
)
|
||
{
|
||
//UCHAR volPropBuffer[sizeof(FLT_VOLUME_PROPERTIES) + 512];
|
||
//PFLT_VOLUME_PROPERTIES volProp = (PFLT_VOLUME_PROPERTIES)volPropBuffer;
|
||
//PUNICODE_STRING workingName = NULL;
|
||
//USHORT newNameSize = 0;
|
||
//ULONG retLen = 0;
|
||
//PFLT_GENERIC_WORKITEM workItem = NULL;
|
||
PDEVICE_OBJECT devObj = NULL;
|
||
WCHAR detail[1024] = { 0, };
|
||
NTSTATUS status = STATUS_SUCCESS;
|
||
|
||
PVOLUME_CONTEXT ctx = NULL;
|
||
PFULL_DISK_INFO diskInfo = NULL;
|
||
;
|
||
UCHAR labelBuf[sizeof(FILE_FS_VOLUME_INFORMATION) + 256] = { 0 };
|
||
PFILE_FS_VOLUME_INFORMATION volInfo = (PFILE_FS_VOLUME_INFORMATION)labelBuf;
|
||
IO_STATUS_BLOCK Iosb = { 0, };
|
||
|
||
UNREFERENCED_PARAMETER(Flags);
|
||
UNREFERENCED_PARAMETER(VolumeDeviceType);
|
||
UNREFERENCED_PARAMETER(VolumeFilesystemType);
|
||
|
||
PAGED_CODE();
|
||
|
||
// 1. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ý<EFBFBD><C3BD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (VolumeFilesystemType == FLT_FSTYPE_UNKNOWN ||
|
||
VolumeFilesystemType == FLT_FSTYPE_LANMAN ||
|
||
VolumeFilesystemType == FLT_FSTYPE_WEBDAV)
|
||
{
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
if(VolumeDeviceType != FILE_DEVICE_DISK_FILE_SYSTEM)
|
||
return STATUS_SUCCESS;
|
||
|
||
status = FltAllocateContext(FltObjects->Filter, FLT_VOLUME_CONTEXT, sizeof(VOLUME_CONTEXT), NonPagedPool, &ctx);
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
KLogEx(DEBUG_TRACE_ERROR, "FltAllocateContext Failed %x\n", status);
|
||
return status;
|
||
}
|
||
|
||
RtlZeroMemory(ctx, sizeof(VOLUME_CONTEXT));
|
||
|
||
__try
|
||
{
|
||
|
||
diskInfo = (PFULL_DISK_INFO)ExAllocatePoolWithTag(NonPagedPool, sizeof(FULL_DISK_INFO), _ALLOC_TAG);
|
||
if (diskInfo)
|
||
{
|
||
RtlZeroMemory(diskInfo, sizeof(FULL_DISK_INFO));
|
||
// ---------------------------------------------------------------------
|
||
// <20><><EFBFBD><EFBFBD>ũ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
// ---------------------------------------------------------------------
|
||
status = FltGetDiskDeviceObject(FltObjects->Volume, &devObj);
|
||
if (NT_SUCCESS(status) && devObj != NULL)
|
||
{
|
||
|
||
ctx->device_type = devObj->DeviceType;
|
||
// <20>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (BusType, Vendor, Product, Serial...)
|
||
// <20><> <20>Լ<EFBFBD><D4BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> PDO<44><4F> TopDevice<63><65> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<EFBFBD><DCBE>ɴϴ<C9B4>.
|
||
CollectAllDiskInfo(devObj, diskInfo);
|
||
|
||
ctx->bustype = diskInfo->BusType;
|
||
|
||
RtlStringCbCopyA((PCHAR)ctx->vendorid, sizeof(ctx->vendorid), diskInfo->VendorId);
|
||
RtlStringCbCopyA((PCHAR)ctx->productid, sizeof(ctx->productid), diskInfo->ProductId);
|
||
RtlStringCbCopyA((PCHAR)ctx->productrevisionlevel, sizeof(ctx->productrevisionlevel), diskInfo->Productrevisionlevel); // <20><><EFBFBD><EFBFBD>
|
||
RtlStringCbCopyA((PCHAR)ctx->vendorspecific, sizeof(ctx->vendorspecific), diskInfo->SerialNumber);
|
||
|
||
status = RtlVolumeDeviceToDosName(devObj, &ctx->name);
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD> <20><>ü <20><><EFBFBD><EFBFBD>
|
||
ObDereferenceObject(devObj);
|
||
|
||
KLogEx(DEBUG_TRACE_INFO, "DEBUG_TRACE_INFO, devObj(%p), ctx->vendorid(%s), ctx->productid(%s)\n", devObj, (PCHAR)ctx->vendorid, (PCHAR)ctx->productid);
|
||
|
||
if (devObj && devObj->DriverObject)
|
||
{
|
||
UNICODE_STRING driverName = devObj->DriverObject->DriverName;
|
||
|
||
KLogEx(DEBUG_TRACE_INFO, "Volume Driver Name: %wZ\n", &driverName);
|
||
|
||
// Ư<><C6AF> <20><><EFBFBD><EFBFBD><EFBFBD>̹<EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> <20><><EFBFBD>ԵǾ<D4B5> <20>ִ<EFBFBD><D6B4><EFBFBD> Ȯ<><C8AE>
|
||
if (wcsstr(driverName.Buffer, L"Secret") || wcsstr(driverName.Buffer, L"CNTDrive"))
|
||
{
|
||
KLogEx(DEBUG_TRACE_INFO, "Secretberry Virtual Drive Detected!\n");
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD><CCBA><EFBFBD><EFBFBD><EFBFBD> Ȯ<>εǸ<CEB5>, VendorID/ProductID<49><44> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
RtlStringCbCopyA((PCHAR)ctx->vendorid, sizeof(ctx->vendorid), "SecretBerry");
|
||
RtlStringCbCopyA((PCHAR)ctx->productid, sizeof(ctx->productid), "VirtualDisk");
|
||
EscapeJsonStringW(driverName.Buffer, diskInfo->Description, sizeof(diskInfo->Description));
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
else
|
||
{
|
||
KLogEx(DEBUG_TRACE_ERROR, "alloc fail\n");
|
||
}
|
||
|
||
// ---------------------------------------------------------------------
|
||
// 4. <20≯<EFBFBD> ȹ<><C8B9> <20><><EFBFBD><EFBFBD> <20><> Fallback (Volume Properties <20>̿<EFBFBD>)
|
||
// ---------------------------------------------------------------------
|
||
// ctx->name.buffer<65><72> null<6C≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> dos <20≯<EFBFBD><CCB8><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
//if (ctx->name.Buffer == NULL)
|
||
//{
|
||
// // volume properties <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
// status = FltGetVolumeProperties(FltObjects->Volume, volProp, sizeof(volPropBuffer), &retLen);
|
||
|
||
//
|
||
// if (NT_SUCCESS(status))
|
||
// {
|
||
// if (volProp->RealDeviceName.Length > 0)
|
||
// workingName = &volProp->RealDeviceName;
|
||
// else if (volProp->FileSystemDeviceName.Length > 0)
|
||
// workingName = &volProp->FileSystemDeviceName;
|
||
// }
|
||
|
||
// if (workingName != NULL)
|
||
// {
|
||
// // <20≯<EFBFBD> <20>Ҵ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD> (ustrnew<65><77> <20><EFBFBD><DEB8><EFBFBD> <20>Ҵ<EFBFBD> <20>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||
// // <20><>: \device\harddiskvolume1
|
||
// newNameSize = workingName->Length + sizeof(WCHAR); // null <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
|
||
// // <20><><EFBFBD><EFBFBD>: ustrnew <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ƿ<F0B8A3B9> ǥ<><C7A5> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
// // ctx->name.buffer = exallocatepool...(newnamesize);
|
||
// // <20><><EFBFBD>⼭<EFBFBD><E2BCAD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ustrnew ȣ<><C8A3> <20><><EFBFBD><EFBFBD>
|
||
// status = UStrNew(&ctx->name, newNameSize);
|
||
|
||
// if (NT_SUCCESS(status))
|
||
// {
|
||
// RtlCopyUnicodeString(&ctx->name, workingName);
|
||
// }
|
||
// }
|
||
// else
|
||
// {
|
||
// KLogEx(DEBUG_TRACE_ERROR, "failed to get volume name. do not attach.\n");
|
||
// //return status_flt_do_not_attach;
|
||
// }
|
||
//}
|
||
|
||
// ---------------------------------------------------------------------
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Label)
|
||
// ---------------------------------------------------------------------
|
||
{
|
||
status = FltQueryVolumeInformation(FltObjects->Instance, &Iosb, volInfo, sizeof(labelBuf), FileFsVolumeInformation);
|
||
if (NT_SUCCESS(status))
|
||
{
|
||
ULONG copyLen = (volInfo->VolumeLabelLength < sizeof(ctx->wLabel) - sizeof(WCHAR))
|
||
? volInfo->VolumeLabelLength
|
||
: sizeof(ctx->wLabel) - sizeof(WCHAR);
|
||
|
||
RtlCopyMemory(ctx->wLabel, volInfo->VolumeLabel, copyLen);
|
||
ctx->wLabel[copyLen / sizeof(WCHAR)] = L'\0'; // Null Terminate
|
||
KLogEx(DEBUG_TRACE_INFO, "Volume Driver Name: %S\n", ctx->wLabel);
|
||
}
|
||
}
|
||
|
||
if (ctx->name.Buffer)
|
||
{
|
||
FILE_FS_SIZE_INFORMATION sizeInfo;
|
||
// ULONG lengthReturned;
|
||
LONGLONG totalSizeBytes = 0;
|
||
LONGLONG freeSizeBytes = 0;
|
||
LONGLONG totaldecimalPart = 0;
|
||
LONGLONG freedecimalPart = 0;
|
||
|
||
status = FltQueryVolumeInformation(
|
||
FltObjects->Instance, // <20><><EFBFBD><EFBFBD> <20>ν<EFBFBD><CEBD>Ͻ<EFBFBD>
|
||
&Iosb, // IO_STATUS_BLOCK (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||
&sizeInfo, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ü
|
||
sizeof(sizeInfo), // <20><><EFBFBD><EFBFBD>ü ũ<><C5A9>
|
||
FileFsSizeInformation // <20><> ũ<><C5A9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><DEB6><EFBFBD> <20><>û
|
||
);
|
||
|
||
if (NT_SUCCESS(status))
|
||
{
|
||
// 1. <20><>ü <20><><EFBFBD><EFBFBD>ũ ũ<><C5A9> <20><><EFBFBD><EFBFBD> (Allocation Units * SectorsPerUnit * BytesPerSector)
|
||
totalSizeBytes = sizeInfo.TotalAllocationUnits.QuadPart * sizeInfo.SectorsPerAllocationUnit * sizeInfo.BytesPerSector;
|
||
|
||
// 2. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
freeSizeBytes = sizeInfo.AvailableAllocationUnits.QuadPart * sizeInfo.SectorsPerAllocationUnit * sizeInfo.BytesPerSector;
|
||
KLogEx(DEBUG_TRACE_INFO, "Total Size: %lld Bytes, Free: %lld Bytes\n", totalSizeBytes, freeSizeBytes);
|
||
}
|
||
else
|
||
{
|
||
KLogEx(DEBUG_TRACE_ERROR, "FltQueryVolumeInformation Failed: %x\n", status);
|
||
}
|
||
|
||
// {
|
||
// VOLUME_DETAILS volDetails;
|
||
|
||
// // 1. <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD> ȣ<><C8A3>
|
||
// status = GetAllVolumeDetails(FltObjects->Instance, &volDetails);
|
||
|
||
// if (NT_SUCCESS(status))
|
||
// {
|
||
// // 2. <20>α<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
// KLogEx(DEBUG_TRACE_INFO, "=== Volume Details ===\n");
|
||
// KLogEx(DEBUG_TRACE_INFO, " Name: %ws (FS: %ws), VolumSerial : %u\n", volDetails.VolumeLabel, volDetails.FileSystemName, volDetails.VolumeSerialNumber);
|
||
// //KLogEx(DEBUG_TRACE_INFO, " Guid : %ws\n", volDetails.VolumeGuid);
|
||
// KLogEx(DEBUG_TRACE_INFO, " Size: %lld / %lld Bytes\n", volDetails.FreeBytes, volDetails.TotalBytes);
|
||
// KLogEx(DEBUG_TRACE_INFO, " Serial: 0x%08X\n", volDetails.VolumeSerialNumber);
|
||
// KLogEx(DEBUG_TRACE_INFO, " Sector: Phy(%u), Log(%u)\n", volDetails.PhysicalBytesPerSector, volDetails.LogicalBytesPerSector);
|
||
|
||
// KLogEx(DEBUG_TRACE_INFO, " DeviceType(%u), DeviceCharacteristics(%u), FileSystemAttributes(%u)\n",
|
||
// volDetails.DeviceType, volDetails.DeviceCharacteristics, volDetails.FileSystemAttributes);
|
||
//
|
||
// // ReadOnly <20><><EFBFBD><EFBFBD> Ȯ<><C8AE> <20><><EFBFBD><EFBFBD>
|
||
// if (volDetails.FileSystemAttributes & FILE_READ_ONLY_VOLUME)
|
||
// {
|
||
// DbgPrint(" -> Warning: Read-Only Volume!\n");
|
||
// }
|
||
// }
|
||
// else
|
||
// {
|
||
//KLogEx(DEBUG_TRACE_INFO, "GetAllVolumeDetails Failed: %x\n", status);
|
||
// }
|
||
// }
|
||
|
||
totalSizeBytes = totalSizeBytes / ONEGB;
|
||
totaldecimalPart = ((totalSizeBytes % ONEGB) * 100) / ONEGB;
|
||
|
||
freeSizeBytes = freeSizeBytes / ONEGB;
|
||
freedecimalPart = ((freeSizeBytes % ONEGB) * 100) / ONEGB;
|
||
|
||
status = RtlStringCbPrintfW(
|
||
detail,
|
||
sizeof(detail),
|
||
L"{"
|
||
L"\"name\": \"%wZ\", " // %s -> %wZ (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||
L"\"freeGB\": \"%lld.%02lld\", "
|
||
L"\"totalGB\": \"%lld.%02lld\", "
|
||
L"\"vid\": \"%.16hs\", "
|
||
L"\"pid\": \"%.16hs\", "
|
||
L"\"rev\": \"%.20hs\", "
|
||
L"\"serial\": \"%.20hs\", "
|
||
L"\"instanceId\": \"%s\", "
|
||
L"\"enumerator\": \"%s\", "
|
||
L"\"friendlyName\": \"%s\", "
|
||
L"\"hardwareId\": \"%s\", "
|
||
L"\"description\": \"%s\""
|
||
//L"\"parentId\": \"%s\""
|
||
L"}",
|
||
&ctx->name,
|
||
freeSizeBytes, freedecimalPart,
|
||
totalSizeBytes, totaldecimalPart,
|
||
ctx->vendorid,
|
||
ctx->productid,
|
||
ctx->productrevisionlevel,
|
||
ctx->vendorspecific,
|
||
diskInfo->InstanceId,
|
||
diskInfo->EnumeratorName,
|
||
diskInfo->FriendlyName,
|
||
diskInfo->HardwareId,
|
||
diskInfo->Description
|
||
// diskInfo->ParentId
|
||
);
|
||
|
||
if (!NT_SUCCESS(status)) {
|
||
KLogEx(DEBUG_TRACE_ERROR, "RtlStringCbPrintfW failed: %x\n", status);
|
||
}
|
||
else
|
||
{
|
||
KLogEx(DEBUG_TRACE_INFO, "%S\n", detail);
|
||
}
|
||
|
||
if (NT_SUCCESS(status))
|
||
{
|
||
SetConnectLog(FltObjects, VolumeDeviceType, VolumeFilesystemType, 0, ctx->name.Buffer, L"System", detail);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
|
||
}
|
||
|
||
status = FltSetVolumeContext(FltObjects->Volume, FLT_SET_CONTEXT_KEEP_IF_EXISTS, ctx, NULL);
|
||
|
||
//workItem = FltAllocateGenericWorkItem();
|
||
//if (workItem) {
|
||
// // Volume <20><>ü <20><><EFBFBD><EFBFBD> ī<><C4AB>Ʈ <20><><EFBFBD><EFBFBD> (<28>۾<EFBFBD><DBBE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>忡<EFBFBD><E5BFA1> <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||
// FltObjectReference(FltObjects->Volume);
|
||
|
||
// FltQueueGenericWorkItem(
|
||
// workItem,
|
||
// FltObjects->Instance,
|
||
// SafeQueryIdRoutine, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD>
|
||
// DelayedWorkQueue,
|
||
// FltObjects->Volume
|
||
// );
|
||
//}
|
||
|
||
if (status == STATUS_FLT_CONTEXT_ALREADY_DEFINED)
|
||
status = STATUS_SUCCESS;
|
||
}
|
||
__finally
|
||
{
|
||
if(diskInfo)
|
||
{
|
||
ExFreePoolWithTag(diskInfo, _ALLOC_TAG);
|
||
}
|
||
|
||
if (ctx)
|
||
{
|
||
FltReleaseContext(ctx);
|
||
}
|
||
}
|
||
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
VOID
|
||
Bs1FltCleanupVolumeContext(
|
||
__in PFLT_CONTEXT Context,
|
||
__in FLT_CONTEXT_TYPE ContextType
|
||
)
|
||
{
|
||
PVOLUME_CONTEXT ctx = (PVOLUME_CONTEXT)Context;
|
||
|
||
PAGED_CODE();
|
||
|
||
UNREFERENCED_PARAMETER(ContextType);
|
||
|
||
if (ContextType != FLT_VOLUME_CONTEXT)
|
||
return;
|
||
|
||
if (!MmIsAddressValid(ctx))
|
||
return;
|
||
|
||
if (!MmIsAddressValid(ctx->name.Buffer))
|
||
return;
|
||
|
||
if (ctx->name.Buffer != NULL)
|
||
{
|
||
KLogEx(DEBUG_TRACE_INFO, "ctx->name(%S)\n", ctx->name.Buffer);
|
||
ExFreePool(ctx->name.Buffer);
|
||
ctx->name.Buffer = NULL;
|
||
}
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
Bs1FltInstanceQueryTeardown (
|
||
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||
_In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is called when an instance is being manually deleted by a
|
||
call to FltDetachVolume or FilterDetach thereby giving us a
|
||
chance to fail that detach request.
|
||
|
||
If this routine is not defined in the registration structure, explicit
|
||
detach requests via FltDetachVolume or FilterDetach will always be
|
||
failed.
|
||
|
||
Arguments:
|
||
|
||
FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
|
||
opaque handles to this filter, instance and its associated volume.
|
||
|
||
Flags - Indicating where this detach request came from.
|
||
|
||
Return Value:
|
||
|
||
Returns the status of this operation.
|
||
|
||
--*/
|
||
{
|
||
UNREFERENCED_PARAMETER( FltObjects );
|
||
UNREFERENCED_PARAMETER( Flags );
|
||
|
||
PAGED_CODE();
|
||
|
||
KLogEx(DEBUG_TRACE_INFO, "cdsflt!cdsfltInstanceQueryTeardown: Entered\n");
|
||
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
|
||
VOID
|
||
Bs1FltInstanceTeardownStart (
|
||
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||
_In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called at the start of instance teardown.
|
||
|
||
Arguments:
|
||
|
||
FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
|
||
opaque handles to this filter, instance and its associated volume.
|
||
|
||
Flags - Reason why this instance is being deleted.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
UNREFERENCED_PARAMETER( FltObjects );
|
||
UNREFERENCED_PARAMETER( Flags );
|
||
|
||
PAGED_CODE();
|
||
|
||
KLogEx(DEBUG_TRACE_INFO, "cdsflt!cdsfltInstanceTeardownStart: Entered\n");
|
||
}
|
||
|
||
|
||
VOID
|
||
Bs1FltInstanceTeardownComplete (
|
||
_In_ PCFLT_RELATED_OBJECTS FltObjects,
|
||
_In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called at the end of instance teardown.
|
||
|
||
Arguments:
|
||
|
||
FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
|
||
opaque handles to this filter, instance and its associated volume.
|
||
|
||
Flags - Reason why this instance is being deleted.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
UNREFERENCED_PARAMETER( FltObjects );
|
||
UNREFERENCED_PARAMETER( Flags );
|
||
|
||
PAGED_CODE();
|
||
|
||
KLogEx(DEBUG_TRACE_INFO, "Bs1FltInstanceTeardownComplete: Entered\n" );
|
||
}
|
||
|
||
|
||
/*************************************************************************
|
||
MiniFilter initialization and unload routines.
|
||
*************************************************************************/
|
||
|
||
NTSTATUS
|
||
DriverEntry(
|
||
_In_ PDRIVER_OBJECT DriverObject,
|
||
_In_ PUNICODE_STRING RegistryPath
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the initialization routine for this miniFilter driver. This
|
||
registers with FltMgr and initializes all global data structures.
|
||
|
||
Arguments:
|
||
|
||
DriverObject - Pointer to driver object created by the system to
|
||
represent this driver.
|
||
|
||
RegistryPath - Unicode string identifying where the parameters for this
|
||
driver are located in the registry.
|
||
|
||
Return Value:
|
||
|
||
Routine can return non success error codes.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS status;
|
||
PSECURITY_DESCRIPTOR sd;
|
||
UNICODE_STRING uni;
|
||
OBJECT_ATTRIBUTES oa;
|
||
|
||
UNREFERENCED_PARAMETER(RegistryPath);
|
||
|
||
g_DebugLevel = DEBUG_TRACE_INFO;
|
||
|
||
KLogEx(DEBUG_TRACE_INFO, "Entered\n");
|
||
KLogEx(DEBUG_TRACE_INFO, "RegPath(%S)(%d)\n", RegistryPath->Buffer, RegistryPath->Length);
|
||
|
||
RtlZeroMemory(&g_bs1Flt, sizeof(g_bs1Flt));
|
||
|
||
if (!NT_SUCCESS(USetConfiguration(RegistryPath)))
|
||
{
|
||
g_DebugLevel = 0;
|
||
}
|
||
|
||
g_DebugLevel = DEBUG_TRACE_ALL;
|
||
//
|
||
// Register with FltMgr to tell it our callback routines
|
||
//
|
||
KLogEx(DEBUG_TRACE_INFO, "DebugLevel(%x)\n", g_DebugLevel);
|
||
|
||
status = FltRegisterFilter(DriverObject,
|
||
&FilterRegistration,
|
||
&g_bs1Flt.Filter);
|
||
|
||
FLT_ASSERT(NT_SUCCESS(status));
|
||
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
KLogEx(DEBUG_TRACE_ERROR, "FltRegisterFilter status(%08x)\n", status);
|
||
return status;
|
||
}
|
||
|
||
//
|
||
// Start filtering i/o
|
||
//
|
||
|
||
USetProcessNameOffset();
|
||
g_bs1Flt.OsVersion = UGetKernelVersion();
|
||
g_bs1Flt.DriverObject = DriverObject;
|
||
g_bs1Flt.LogType = LOG_ALL;
|
||
|
||
RtlInitUnicodeString(&uni, BS1FLT_PORTNAME);
|
||
status = FltBuildDefaultSecurityDescriptor(&sd, FLT_PORT_ALL_ACCESS);
|
||
|
||
if (!NT_SUCCESS(status))
|
||
goto $cleanup;
|
||
|
||
InitializeObjectAttributes(&oa,
|
||
&uni,
|
||
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||
NULL,
|
||
sd);
|
||
|
||
status = FltCreateCommunicationPort(g_bs1Flt.Filter,
|
||
&g_bs1Flt.ServerPort,
|
||
&oa,
|
||
NULL,
|
||
Bs1FltPortConnect,
|
||
Bs1FltPortDisconnect,
|
||
Bs1FltMssageProc,
|
||
10);
|
||
|
||
FltFreeSecurityDescriptor(sd);
|
||
if (!NT_SUCCESS(status))
|
||
goto $cleanup;
|
||
|
||
g_bs1Flt.IsAttached = FALSE;
|
||
g_bs1Flt.ClientPort = NULL;
|
||
g_bs1Flt.IsShareWatched = FALSE;
|
||
g_bs1Flt.IsFolderProtect = FALSE;
|
||
g_bs1Flt.IsAttached = FALSE;
|
||
g_bs1Flt.IsDeviceProtect = FALSE;
|
||
|
||
Bs1FltPortInit();
|
||
|
||
Initlist();
|
||
InitProcessNotify();
|
||
PgInitialize();
|
||
Initlog();
|
||
Initpolicy();
|
||
|
||
|
||
status = FltStartFiltering(g_bs1Flt.Filter);
|
||
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
FltCloseCommunicationPort(g_bs1Flt.ServerPort);
|
||
goto $cleanup;
|
||
}
|
||
|
||
|
||
PgAddPid(0, PG_PID_ALLOW);
|
||
PgAddPid(4, PG_PID_ALLOW);
|
||
PgAddPid(8, PG_PID_ALLOW);
|
||
|
||
|
||
KLogEx(DEBUG_TRACE_INFO, "Success\n");
|
||
|
||
|
||
return STATUS_SUCCESS;
|
||
|
||
$cleanup:
|
||
KLogEx(DEBUG_TRACE_ERROR, "status(%08x)\n", status);
|
||
FltUnregisterFilter(g_bs1Flt.Filter);
|
||
|
||
return status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
Bs1FltUnload (
|
||
_In_ FLT_FILTER_UNLOAD_FLAGS Flags
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the unload routine for this miniFilter driver. This is called
|
||
when the minifilter is about to be unloaded. We can fail this unload
|
||
request if this is not a mandatory unload indicated by the Flags
|
||
parameter.
|
||
|
||
Arguments:
|
||
|
||
Flags - Indicating if this is a mandatory unload.
|
||
|
||
Return Value:
|
||
|
||
Returns STATUS_SUCCESS.
|
||
|
||
--*/
|
||
{
|
||
UNREFERENCED_PARAMETER( Flags );
|
||
|
||
PAGED_CODE();
|
||
|
||
KLogEx(DEBUG_TRACE_INFO, " Entered\n");
|
||
|
||
if (Flags & FLTFL_FILTER_UNLOAD_MANDATORY)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD> <20>۾<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
goto $Success;
|
||
}
|
||
|
||
if (g_IsUnloadAllowed == FALSE)
|
||
{
|
||
KLogEx(DEBUG_TRACE_INFO, "Unload blocked by Self-Defense policy.\n");
|
||
|
||
// <20><> <20><><EFBFBD><EFBFBD> <20>ڵ带 <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> fltmc unload<61><64> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
return STATUS_FLT_DO_NOT_DETACH;
|
||
}
|
||
|
||
$Success:
|
||
if (g_bs1Flt.ServerPort != NULL)
|
||
{
|
||
FltCloseCommunicationPort(g_bs1Flt.ServerPort);
|
||
g_bs1Flt.ServerPort = NULL;
|
||
}
|
||
|
||
//Bs1FltPortUnload();
|
||
g_bs1Flt.IsShareWatched = FALSE;
|
||
g_bs1Flt.IsFolderProtect = FALSE;
|
||
g_bs1Flt.IsAttached = FALSE;
|
||
g_bs1Flt.IsDeviceProtect = FALSE;
|
||
|
||
// if(g_RegistryPath.Buffer)
|
||
// PBStrFree(&g_RegistryPath);
|
||
|
||
CleanupProcessNotify();
|
||
|
||
CleanupFilelist();
|
||
CleanupPathlist();
|
||
CleanupProcesslist();
|
||
CleanupProcessProtectList();
|
||
Cleanuplog();
|
||
|
||
PgReset();
|
||
CleanupUsbDiskExceptionList();
|
||
|
||
StopRegFlt();
|
||
UnInstallProcessProtect();
|
||
#ifdef USB_PORT_HOOK
|
||
|
||
USBIrpHookCleanup();
|
||
BlueToothIrpHookCleanup();
|
||
MtpIrpHookCleanup();
|
||
CleanupUsbPortExceptionList();
|
||
#endif
|
||
|
||
if (g_bs1Flt.Filter != NULL)
|
||
{
|
||
FltUnregisterFilter(g_bs1Flt.Filter);
|
||
g_bs1Flt.Filter = NULL;
|
||
}
|
||
|
||
return STATUS_SUCCESS;
|
||
}
|