670 lines
16 KiB
C
670 lines
16 KiB
C
#include "precomp.h"
|
||
#include <ntddvol.h>
|
||
|
||
|
||
#define _ALLOC_TAG 'kdqw'
|
||
|
||
#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE
|
||
#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||
|
||
//
|
||
// struct
|
||
//
|
||
|
||
typedef enum _STORAGE_QUERY_TYPE {
|
||
PropertyStandardQuery = 0,
|
||
PropertyExistsQuery,
|
||
PropertyMaskQuery,
|
||
PropertyQueryMaxDefined
|
||
} STORAGE_QUERY_TYPE, * PSTORAGE_QUERY_TYPE;
|
||
|
||
typedef enum _STORAGE_PROPERTY_ID {
|
||
StorageDeviceProperty = 0,
|
||
StorageAdapterProperty,
|
||
StorageDeviceIdProperty,
|
||
StorageDeviceUniqueIdProperty,
|
||
StorageDeviceWriteCacheProperty,
|
||
StorageMiniportProperty,
|
||
StorageAccessAlignmentProperty,
|
||
StorageDeviceSeekPenaltyProperty,
|
||
StorageDeviceTrimProperty,
|
||
StorageDeviceWriteAggregationProperty
|
||
} STORAGE_PROPERTY_ID, * PSTORAGE_PROPERTY_ID;
|
||
|
||
|
||
typedef enum _STORAGE_BUS_TYPE {
|
||
BusTypeUnknown = 0x00,
|
||
BusTypeScsi,
|
||
BusTypeAtapi,
|
||
BusTypeAta,
|
||
BusType1394,
|
||
BusTypeSsa,
|
||
BusTypeFibre,
|
||
BusTypeUsb,
|
||
BusTypeRAID,
|
||
BusTypeiScsi,
|
||
BusTypeSas,
|
||
BusTypeSata,
|
||
BusTypeSd,
|
||
BusTypeMmc,
|
||
BusTypeVirtual,
|
||
BusTypeFileBackedVirtual,
|
||
BusTypeMax,
|
||
BusTypeMaxReserved = 0x7F
|
||
} STORAGE_BUS_TYPE, * PSTORAGE_BUS_TYPE;
|
||
|
||
|
||
typedef unsigned char BYTE;
|
||
|
||
typedef struct _STORAGE_PROPERTY_QUERY {
|
||
|
||
STORAGE_PROPERTY_ID PropertyId;
|
||
STORAGE_QUERY_TYPE QueryType;
|
||
unsigned char AdditionalParameters[1];
|
||
|
||
} STORAGE_PROPERTY_QUERY, * PSTORAGE_PROPERTY_QUERY;
|
||
|
||
|
||
typedef struct _STORAGE_DEVICE_DESCRIPTOR {
|
||
|
||
DWORD Version;
|
||
DWORD Size;
|
||
BYTE DeviceType;
|
||
BYTE DeviceTypeModifier;
|
||
BOOLEAN RemovableMedia;
|
||
BOOLEAN CommandQueueing;
|
||
DWORD VendorIdOffset;
|
||
DWORD ProductIdOffset;
|
||
DWORD ProductRevisionOffset;
|
||
DWORD SerialNumberOffset;
|
||
STORAGE_BUS_TYPE BusType;
|
||
DWORD RawPropertiesLength;
|
||
BYTE RawDeviceProperties[1];
|
||
|
||
} STORAGE_DEVICE_DESCRIPTOR, * PSTORAGE_DEVICE_DESCRIPTOR;
|
||
|
||
|
||
NTSTATUS
|
||
GetPhysicalDiskDeviceObject(
|
||
__in PDEVICE_OBJECT VolumeDeviceObject,
|
||
__out PDEVICE_OBJECT* PhysicalDiskDeviceObject
|
||
)
|
||
{
|
||
NTSTATUS status;
|
||
PIRP Irp;
|
||
KEVENT Event;
|
||
IO_STATUS_BLOCK Iosb;
|
||
PVOLUME_DISK_EXTENTS pDiskExtents = NULL;
|
||
// <20>˳<EFBFBD><CBB3>ϰ<EFBFBD> 4<><34> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Extent <20><><EFBFBD><EFBFBD> Ȯ<><C8AE>
|
||
ULONG extentsSize = sizeof(VOLUME_DISK_EXTENTS) + (sizeof(DISK_EXTENT) * 4);
|
||
UNICODE_STRING physicalDiskName;
|
||
WCHAR nameBuffer[64] = { 0 };
|
||
PFILE_OBJECT pFileObject = NULL;
|
||
PDEVICE_OBJECT pDevObj = NULL;
|
||
|
||
*PhysicalDiskDeviceObject = NULL;
|
||
|
||
// 1. <20><EFBFBD><DEB8><EFBFBD> <20>Ҵ<EFBFBD>
|
||
pDiskExtents = (PVOLUME_DISK_EXTENTS)ExAllocatePoolWithTag(NonPagedPool, extentsSize, 'dExt');
|
||
if (!pDiskExtents) return STATUS_INSUFFICIENT_RESOURCES;
|
||
|
||
// <20><EFBFBD><DEB8><EFBFBD> <20>ʱ<EFBFBD>ȭ (<28>߿<EFBFBD>)
|
||
RtlZeroMemory(pDiskExtents, extentsSize);
|
||
|
||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||
Irp = IoBuildDeviceIoControlRequest(
|
||
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
|
||
VolumeDeviceObject,
|
||
NULL, 0,
|
||
pDiskExtents, extentsSize,
|
||
FALSE, &Event, &Iosb
|
||
);
|
||
|
||
if (!Irp) {
|
||
ExFreePoolWithTag(pDiskExtents, 'dExt');
|
||
return STATUS_INSUFFICIENT_RESOURCES;
|
||
}
|
||
|
||
status = IoCallDriver(VolumeDeviceObject, Irp);
|
||
if (status == STATUS_PENDING) {
|
||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||
status = Iosb.Status;
|
||
}
|
||
|
||
if (!NT_SUCCESS(status)) {
|
||
ExFreePoolWithTag(pDiskExtents, 'dExt');
|
||
return status;
|
||
}
|
||
|
||
// [BSOD <20><><EFBFBD><EFBFBD> <20>ٽ<EFBFBD>] Extents <20><><EFBFBD><EFBFBD> Ȯ<><C8AE>!
|
||
if (pDiskExtents->NumberOfDiskExtents == 0)
|
||
{
|
||
KLogEx(DEBUG_TRACE_INFO, "No Disk Extents found.\n");
|
||
ExFreePoolWithTag(pDiskExtents, 'dExt');
|
||
return STATUS_UNSUCCESSFUL;
|
||
}
|
||
|
||
__try
|
||
{
|
||
// 2. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ũ <20≯<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
ULONG diskNumber = pDiskExtents->Extents[0].DiskNumber;
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD> <20>Լ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (!NT_SUCCESS(RtlStringCbPrintfW(nameBuffer, sizeof(nameBuffer), L"\\Device\\Harddisk%u\\DR0", diskNumber)))
|
||
{
|
||
status = STATUS_BUFFER_OVERFLOW;
|
||
__leave;
|
||
}
|
||
|
||
RtlInitUnicodeString(&physicalDiskName, nameBuffer);
|
||
|
||
KLogEx(DEBUG_TRACE_INFO, "Trying to open: %S\n", nameBuffer);
|
||
|
||
// 3. <20><><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ȹ<><C8B9> (<28><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||
// InstanceSetup<75><70><EFBFBD><EFBFBD> <20><> ȣ<><C8A3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
status = IoGetDeviceObjectPointer(
|
||
&physicalDiskName,
|
||
FILE_READ_ATTRIBUTES, // <20><><EFBFBD><EFBFBD> <20>ּ<EFBFBD>ȭ
|
||
&pFileObject,
|
||
&pDevObj
|
||
);
|
||
|
||
if (NT_SUCCESS(status))
|
||
{
|
||
ObReferenceObject(pDevObj); // <20><><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD> <20><>ü <20><><EFBFBD><EFBFBD>
|
||
ObDereferenceObject(pFileObject); // <20><><EFBFBD><EFBFBD> <20><>ü <20>ݱ<EFBFBD>
|
||
*PhysicalDiskDeviceObject = pDevObj;
|
||
}
|
||
else
|
||
{
|
||
KLogEx(DEBUG_TRACE_ERROR, "IoGetDeviceObjectPointer Failed: 0x%x\n", status);
|
||
}
|
||
}
|
||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||
{
|
||
KLogEx(DEBUG_TRACE_ERROR, "Exception in GetPhysicalDiskDeviceObject\n");
|
||
status = STATUS_UNHANDLED_EXCEPTION;
|
||
}
|
||
|
||
ExFreePoolWithTag(pDiskExtents, 'dExt');
|
||
return status;
|
||
}
|
||
|
||
NTSTATUS
|
||
QueryDeviceProperty(
|
||
__in PDEVICE_OBJECT pDevice,
|
||
__in DEVICE_REGISTRY_PROPERTY DevProperty,
|
||
__out PVOID* ppBuffer,
|
||
__out PULONG pResultLength
|
||
)
|
||
{
|
||
|
||
NTSTATUS status;
|
||
PVOID pBuffer = NULL;
|
||
ULONG BufferSize = 0;
|
||
|
||
ASSERT(ARGUMENT_PRESENT(pDevice));
|
||
|
||
// sskim - 171122 Added.
|
||
// FltGetDiskDeviceObject<63><74> <20><><EFBFBD><EFBFBD> pDevice<63><65> PDO<44><4F><EFBFBD><EFBFBD> Verifier<65><72><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (FDO<44><4F> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߰<EFBFBD>)
|
||
//pDevice = IoGetDeviceAttachmentBaseRef(pDevice);
|
||
|
||
status = IoGetDeviceProperty(
|
||
pDevice,
|
||
DevProperty,
|
||
BufferSize,
|
||
NULL,
|
||
&BufferSize
|
||
);
|
||
|
||
if (NT_SUCCESS(status))
|
||
{
|
||
return STATUS_NOT_SUPPORTED;
|
||
}
|
||
|
||
while (status == STATUS_BUFFER_TOO_SMALL)
|
||
{
|
||
pBuffer = ExAllocatePoolWithTag(PagedPool, BufferSize, _ALLOC_TAG);
|
||
if (!pBuffer)
|
||
{
|
||
return STATUS_NO_MEMORY;
|
||
}
|
||
|
||
status = IoGetDeviceProperty(
|
||
pDevice,
|
||
DevProperty,
|
||
BufferSize,
|
||
pBuffer,
|
||
&BufferSize
|
||
);
|
||
|
||
if (NT_SUCCESS(status))
|
||
{
|
||
*ppBuffer = pBuffer;
|
||
*pResultLength = BufferSize;
|
||
return status;
|
||
}
|
||
|
||
ExFreePool(pBuffer);
|
||
pBuffer = NULL;
|
||
}
|
||
|
||
ASSERT(!pBuffer);
|
||
|
||
return status;
|
||
}
|
||
|
||
//#define QUERY_BUFFER_SIZE 0x2000
|
||
//NTSTATUS SafeSetVolumContextParam(PUCHAR pucDest, DWORD dwSize, PUCHAR pucSrc, DWORD dwOffset)
|
||
//{
|
||
// int size = 0;
|
||
// PCHAR pszName = NULL;
|
||
//
|
||
// if (dwOffset == 0)
|
||
// return STATUS_UNSUCCESSFUL;
|
||
//
|
||
// if (dwOffset >= dwSize)
|
||
// return STATUS_UNSUCCESSFUL;
|
||
//
|
||
// if (dwOffset >= (QUERY_BUFFER_SIZE - 10))
|
||
// return STATUS_UNSUCCESSFUL;
|
||
//
|
||
// pszName = (char*)GetPtr(pucSrc, dwOffset);
|
||
// size = (int)strlen(pszName);
|
||
//
|
||
// KLogEx(DEBUG_TRACE_INFO, "SafeSetVolumContextParam, size(%d)\n", size);
|
||
//
|
||
// if (size > VOLUME_DESCRIPTION_LENGTH)
|
||
// {
|
||
// size = VOLUME_DESCRIPTION_LENGTH - 1;
|
||
// }
|
||
//
|
||
// RtlCopyMemory(pucDest, pszName, size);
|
||
// return STATUS_SUCCESS;
|
||
//}
|
||
|
||
|
||
// <20><>ũ<EFBFBD><C5A9> <20><><EFBFBD><EFBFBD> (<28><><EFBFBD>ٸ<EFBFBD> <20>߰<EFBFBD> <20>ʿ<EFBFBD>)
|
||
#ifndef QUERY_BUFFER_SIZE
|
||
#define QUERY_BUFFER_SIZE 0x2000
|
||
#endif
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD> (<28>빮<EFBFBD><EBB9AE> <20><>ȯ <20><><EFBFBD><EFBFBD>)
|
||
NTSTATUS SafeSetVolumContextParam(
|
||
__in PUCHAR pucDest, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Context <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||
__in ULONG ulSrcTotalSize, // <20><><EFBFBD><EFBFBD> <20><>ü <20><><EFBFBD><EFBFBD> ũ<><C5A9> (pDesc->Size)
|
||
__in PUCHAR pucSrcBase, // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ּ<EFBFBD> (pDesc)
|
||
__in ULONG ulOffset // <20><><EFBFBD>ڿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
)
|
||
{
|
||
ULONG i = 0;
|
||
PCHAR pSrcStr = NULL;
|
||
|
||
// 1. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȿ<EFBFBD><C8BF> <20>˻<EFBFBD>
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<>̰ų<CCB0>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ũ<>⸦ <20><><EFBFBD><EFBFBD><EEB3AA> <20><><EFBFBD><EFBFBD>
|
||
if (ulOffset == 0 || ulOffset >= ulSrcTotalSize)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̹Ƿ<CCB9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٴ<EFBFBD> <20>ܼ<EFBFBD><DCBC><EFBFBD> NULL ó<><C3B3><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (pucDest) pucDest[0] = 0;
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
// 2. <20><><EFBFBD>ڿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
pSrcStr = (PCHAR)(pucSrcBase + ulOffset);
|
||
|
||
// 3. <20><><EFBFBD>ڿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>빮<EFBFBD><EBB9AE> <20><>ȯ <20><><EFBFBD><EFBFBD>
|
||
// <20><><EFBFBD><EFBFBD>:
|
||
// A. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ũ<><C5A9>(VOLUME_DESCRIPTION_LENGTH - 1)<29><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>
|
||
// B. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>(pucSrcBase + ulSrcTotalSize)<29><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> (Memory Access Violation <20><><EFBFBD><EFBFBD>)
|
||
// C. NULL <20><><EFBFBD>ڸ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
|
||
for (i = 0; i < VOLUME_DESCRIPTION_LENGTH - 1; i++)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> üũ (Overflow <20><><EFBFBD><EFBFBD>)
|
||
if ((ULONG_PTR)(pSrcStr + i) >= (ULONG_PTR)(pucSrcBase + ulSrcTotalSize))
|
||
break;
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD> <20><>(NULL) üũ
|
||
if (pSrcStr[i] == 0)
|
||
break;
|
||
|
||
// [<5B><>û<EFBFBD>Ͻ<EFBFBD> <20><><EFBFBD><EFBFBD>] <20>빮<EFBFBD>ڷ<EFBFBD> <20><>ȯ<EFBFBD>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
pucDest[i] = RtlUpperChar(pSrcStr[i]);
|
||
}
|
||
|
||
// 4. NULL Termination <20><><EFBFBD><EFBFBD>
|
||
pucDest[i] = 0;
|
||
|
||
KLogEx(DEBUG_TRACE_INFO, "Copied Length(%d), Content(%s)\n", i, pucDest);
|
||
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
typedef struct _STORAGE_DEVICE_ID_DESCRIPTOR {
|
||
ULONG Version;
|
||
ULONG Size;
|
||
ULONG NumberOfIdentifiers;
|
||
UCHAR Identifiers[1]; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD> <20>迭
|
||
} STORAGE_DEVICE_ID_DESCRIPTOR, * PSTORAGE_DEVICE_ID_DESCRIPTOR;
|
||
|
||
NTSTATUS
|
||
GetStorageDeviceId(
|
||
__in PDEVICE_OBJECT DeviceObject,
|
||
__out PWCHAR* OutInstanceId
|
||
)
|
||
{
|
||
NTSTATUS status = STATUS_SUCCESS;
|
||
PIRP Irp;
|
||
KEVENT Event;
|
||
IO_STATUS_BLOCK Iosb;
|
||
STORAGE_PROPERTY_QUERY PropQuery = { 0 };
|
||
PSTORAGE_DEVICE_ID_DESCRIPTOR pDesc = NULL;
|
||
PVOID QueryBuffer = NULL;
|
||
ULONG QuerySize = 1024; // <20>˳<EFBFBD><CBB3>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
|
||
*OutInstanceId = NULL;
|
||
|
||
// 1. <20><EFBFBD><DEB8><EFBFBD> <20>Ҵ<EFBFBD>
|
||
QueryBuffer = ExAllocatePoolWithTag(PagedPool, QuerySize, 'StoI');
|
||
if (!QueryBuffer) return STATUS_INSUFFICIENT_RESOURCES;
|
||
|
||
RtlZeroMemory(QueryBuffer, QuerySize);
|
||
|
||
// 2. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>: StorageDeviceIdProperty (<28>߿<EFBFBD>!)
|
||
PropQuery.PropertyId = StorageDeviceIdProperty; // enum <20><>: 2
|
||
PropQuery.QueryType = PropertyStandardQuery;
|
||
|
||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||
|
||
// 3. IRP <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
|
||
Irp = IoBuildDeviceIoControlRequest(
|
||
IOCTL_STORAGE_QUERY_PROPERTY,
|
||
DeviceObject,
|
||
&PropQuery,
|
||
sizeof(PropQuery),
|
||
QueryBuffer,
|
||
QuerySize,
|
||
FALSE,
|
||
&Event,
|
||
&Iosb
|
||
);
|
||
|
||
if (!Irp)
|
||
{
|
||
ExFreePoolWithTag(QueryBuffer, 'StoI');
|
||
return STATUS_INSUFFICIENT_RESOURCES;
|
||
}
|
||
|
||
status = IoCallDriver(DeviceObject, Irp);
|
||
|
||
if (status == STATUS_PENDING)
|
||
{
|
||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||
status = Iosb.Status;
|
||
}
|
||
|
||
// 4. <20><><EFBFBD><EFBFBD> <20>Ľ<EFBFBD>
|
||
if (NT_SUCCESS(status) && Iosb.Information > sizeof(STORAGE_DEVICE_ID_DESCRIPTOR))
|
||
{
|
||
pDesc = (PSTORAGE_DEVICE_ID_DESCRIPTOR)QueryBuffer;
|
||
|
||
if (pDesc->NumberOfIdentifiers > 0)
|
||
{
|
||
// Identifiers<72><73> Null<6C><6C> <20><><EFBFBD>е<EFBFBD> ANSI <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD><EFBFBD><EFBFBD> <20>迭<EFBFBD>Դϴ<D4B4>.
|
||
// ù <20><>° <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC><EFBFBD><EFBFBD> PnP ID (Hardware ID)<29>Դϴ<D4B4>.
|
||
PCHAR pAnsiId = (PCHAR)pDesc->Identifiers;
|
||
|
||
// ANSI String -> Unicode String <20><>ȯ <20>ʿ<EFBFBD>
|
||
ANSI_STRING ansiStr;
|
||
UNICODE_STRING uniStr;
|
||
|
||
RtlInitAnsiString(&ansiStr, pAnsiId);
|
||
|
||
status = RtlAnsiStringToUnicodeString(&uniStr, &ansiStr, TRUE); // TRUE: Allocate Memory
|
||
|
||
if (NT_SUCCESS(status))
|
||
{
|
||
// ȣ<><C8A3><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20><><EFBFBD><EFBFBD> (ȣ<><C8A3><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD>߿<EFBFBD> ExFreePool <20>ؾ<EFBFBD> <20><>)
|
||
// RtlAnsiStringToUnicodeString<6E><67> <20>Ҵ<EFBFBD><D2B4><EFBFBD> <20><><EFBFBD>۴<EFBFBD> PagedPool<6F>Դϴ<D4B4>.
|
||
// <20><><EFBFBD>⼭<EFBFBD><E2BCAD> ȣ<><C8A3><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>ۿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰų<CFB0>, uniStr.Buffer<65><72> <20>״<EFBFBD><D7B4><EFBFBD> <20>ݴϴ<DDB4>.
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD>纻<EFBFBD><E7BABB> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (NonPagedPool <20><><EFBFBD><EFBFBD> <20><>)
|
||
ULONG uniSize = uniStr.Length + sizeof(WCHAR);
|
||
PWCHAR pResult = ExAllocatePoolWithTag(NonPagedPool, uniSize, 'IDst');
|
||
|
||
if (pResult)
|
||
{
|
||
RtlZeroMemory(pResult, uniSize);
|
||
RtlCopyMemory(pResult, uniStr.Buffer, uniStr.Length);
|
||
*OutInstanceId = pResult;
|
||
}
|
||
|
||
RtlFreeUnicodeString(&uniStr); // <20>ӽ<EFBFBD> <20><>ȯ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
}
|
||
}
|
||
}
|
||
|
||
ExFreePoolWithTag(QueryBuffer, 'StoI');
|
||
return status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
GetStorageProperty(
|
||
__in PDEVICE_OBJECT device_object,
|
||
__in PVOLUME_CONTEXT pVolumeContext
|
||
)
|
||
{
|
||
PIRP Irp;
|
||
KEVENT Event;
|
||
NTSTATUS status = STATUS_SUCCESS;
|
||
IO_STATUS_BLOCK Iosb;
|
||
STORAGE_PROPERTY_QUERY PropQuery = { 0, };
|
||
PVOID QueryBuffer = NULL;
|
||
ULONG QuerySize = QUERY_BUFFER_SIZE;
|
||
PSTORAGE_DEVICE_DESCRIPTOR pDesc;
|
||
|
||
//ULONG size = 0;
|
||
|
||
__try
|
||
{
|
||
QueryBuffer = ExAllocatePoolWithTag(PagedPool, QuerySize, _ALLOC_TAG);
|
||
if (!QueryBuffer)
|
||
{
|
||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||
__leave;
|
||
}
|
||
|
||
RtlZeroMemory(&PropQuery, sizeof(PropQuery));
|
||
RtlZeroMemory(QueryBuffer, QuerySize);
|
||
PropQuery.PropertyId = StorageDeviceProperty;
|
||
PropQuery.QueryType = PropertyStandardQuery;
|
||
|
||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||
|
||
Irp = IoBuildDeviceIoControlRequest(
|
||
IOCTL_STORAGE_QUERY_PROPERTY,
|
||
device_object,
|
||
&PropQuery,
|
||
sizeof(PropQuery),
|
||
QueryBuffer,
|
||
QuerySize,
|
||
FALSE,
|
||
&Event,
|
||
&Iosb
|
||
);
|
||
|
||
if (!Irp)
|
||
{
|
||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||
__leave;
|
||
}
|
||
|
||
status = IoCallDriver(device_object, Irp);
|
||
|
||
if (status == STATUS_PENDING)
|
||
{
|
||
KeWaitForSingleObject(
|
||
&Event,
|
||
Executive,
|
||
KernelMode,
|
||
FALSE,
|
||
(PLARGE_INTEGER)NULL
|
||
);
|
||
|
||
status = Iosb.Status;
|
||
}
|
||
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
__leave;
|
||
}
|
||
|
||
if (Iosb.Information < sizeof(STORAGE_DEVICE_DESCRIPTOR))
|
||
{
|
||
status = STATUS_UNSUCCESSFUL;
|
||
__leave;
|
||
}
|
||
|
||
pDesc = (PSTORAGE_DEVICE_DESCRIPTOR)QueryBuffer;
|
||
if (!pDesc)
|
||
__leave;
|
||
|
||
if (pDesc->Size > Iosb.Information)
|
||
{
|
||
if (pDesc->Size > QuerySize) pDesc->Size = (ULONG)Iosb.Information;
|
||
}
|
||
|
||
KLogEx(DEBUG_TRACE_INFO, "Version(%x),Size(%x),DeviceType(%x),DeviceTypeModifier(%x)\n", pDesc->Version, pDesc->Size, pDesc->DeviceType, pDesc->DeviceTypeModifier);
|
||
KLogEx(DEBUG_TRACE_INFO, "bustype(%d),Removal(%d),vidoffset(%x),pidoffset(%x)\n", pDesc->BusType, pDesc->RemovableMedia, pDesc->VendorIdOffset, pDesc->ProductIdOffset);
|
||
KLogEx(DEBUG_TRACE_INFO, "ProductRevisionOffset(%d),SerialNumberOffset(%d)\n", pDesc->ProductRevisionOffset, pDesc->SerialNumberOffset);
|
||
|
||
pVolumeContext->bustype = pDesc->BusType;
|
||
SafeSetVolumContextParam(pVolumeContext->vendorid, pDesc->Size, (PUCHAR)pDesc, pDesc->VendorIdOffset);
|
||
SafeSetVolumContextParam(pVolumeContext->productid, pDesc->Size, (PUCHAR)pDesc, pDesc->ProductIdOffset);
|
||
SafeSetVolumContextParam(pVolumeContext->productrevisionlevel, pDesc->Size, (PUCHAR)pDesc, pDesc->ProductRevisionOffset);
|
||
SafeSetVolumContextParam(pVolumeContext->vendorspecific, pDesc->Size, (PUCHAR)pDesc, pDesc->SerialNumberOffset);
|
||
}
|
||
__finally
|
||
{
|
||
if (QueryBuffer)
|
||
{
|
||
ExFreePoolWithTag(QueryBuffer, _ALLOC_TAG);
|
||
QueryBuffer = NULL;
|
||
}
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
NTSTATUS
|
||
GetVolumeProperties(
|
||
__in PCFLT_RELATED_OBJECTS FltObjects,
|
||
__in PVOLUME_CONTEXT pVolumeContext
|
||
)
|
||
{
|
||
|
||
NTSTATUS status = STATUS_SUCCESS;
|
||
PDEVICE_OBJECT pDevice = NULL;
|
||
PVOID pBuffer = NULL;
|
||
ULONG PropertySize = 0;
|
||
PWCHAR pDeviceId = NULL;
|
||
PDEVICE_OBJECT physicalDeviceObject = NULL;
|
||
|
||
ASSERT(ARGUMENT_PRESENT(pVolumeContext));
|
||
|
||
__try
|
||
{
|
||
/*status = FltGetDiskDeviceObject(FltObjects->Volume, &pDevice);
|
||
if (!NT_SUCCESS(status))
|
||
{
|
||
pDevice = NULL;
|
||
__leave;
|
||
}*/
|
||
|
||
status = GetPhysicalDiskDeviceObject((PDEVICE_OBJECT)FltObjects->Volume, &pDevice);
|
||
|
||
status = GetStorageProperty(pDevice, pVolumeContext);
|
||
status = QueryDeviceProperty(pDevice, DevicePropertyRemovalPolicy, &pBuffer, &PropertySize);
|
||
|
||
if (NT_SUCCESS(status))
|
||
{
|
||
PDEVICE_REMOVAL_POLICY pRemovalPolicy = (PDEVICE_REMOVAL_POLICY)pBuffer;
|
||
pVolumeContext->removalpolicy = *pRemovalPolicy;
|
||
//pVolumeContext->device_object = pDevice;
|
||
KLogEx(DEBUG_TRACE_INFO, " REMOVAL_POLICY pDevice(%p),removalpolicy(%d)\n", pDevice, pVolumeContext->removalpolicy);
|
||
ExFreePoolWithTag(pBuffer, _ALLOC_TAG);
|
||
pBuffer = NULL;
|
||
}
|
||
else
|
||
{
|
||
KLogEx(DEBUG_TRACE_INFO, "Query DevicePropertyRemovalPolicy Failed 0x%x\n", status);
|
||
}
|
||
|
||
status = QueryDeviceProperty(pDevice, DevicePropertyHardwareID, &pBuffer, &PropertySize);
|
||
if (NT_SUCCESS(status))
|
||
{
|
||
KLogEx(DEBUG_TRACE_INFO, "[PnP] Hardware ID: %S\n", pBuffer);
|
||
ExFreePoolWithTag(pBuffer, _ALLOC_TAG);
|
||
pBuffer = NULL;
|
||
}
|
||
else
|
||
{
|
||
KLogEx(DEBUG_TRACE_INFO, "Query DevicePropertyHardwareID Failed 0x%x\n", status);
|
||
}
|
||
|
||
status = GetStorageDeviceId(pDevice, &pDeviceId);
|
||
if (NT_SUCCESS(status) && pDeviceId != NULL)
|
||
{
|
||
KLogEx(DEBUG_TRACE_INFO, "Found Device ID: %S\n", pDeviceId);
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>: "USB\VID_346D&PID_5678&REV_0100"
|
||
// <20><><EFBFBD>⼭ <20><><EFBFBD>ڿ<EFBFBD> <20>Ľ<EFBFBD><C4BD>Ͽ<EFBFBD> <20><>å <20><><EFBFBD><EFBFBD>
|
||
|
||
ExFreePoolWithTag(pDeviceId, 'IDst');
|
||
}
|
||
else
|
||
{
|
||
KLogEx(DEBUG_TRACE_INFO, "[IOCTL] Failed 0x%x. Trying PnP Query...\n", status);
|
||
|
||
// =================================================================
|
||
// <20>õ<EFBFBD> 2: PnP <20><><EFBFBD><EFBFBD> (PDO<44><4F><EFBFBD><EFBFBD> <20><>û) - HardwareID / InstanceID
|
||
// =================================================================
|
||
// IOCTL<54><4C> ó<><C3B3><EFBFBD>ϴ<EFBFBD> FDO<44><4F> <20><><EFBFBD><EFBFBD> <20>عٴ<D8B9>(PDO)<29><> <20><><EFBFBD>մϴ<D5B4>.
|
||
physicalDeviceObject = IoGetDeviceAttachmentBaseRef(pDevice);
|
||
|
||
if (physicalDeviceObject)
|
||
{
|
||
// PnP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> PDO<44><4F><EFBFBD><EFBFBD> <20>ؾ<EFBFBD> <20>մϴ<D5B4>.
|
||
// DevicePropertyHardwareID (<28><><EFBFBD><EFBFBD>Ʈ) <20>Ǵ<EFBFBD> DevicePropertyInstanceID (<28><><EFBFBD><EFBFBD>) <20>õ<EFBFBD>
|
||
PWCHAR pHardwareId = NULL;
|
||
|
||
// <20><><EFBFBD><EFBFBD> HardwareID<49><44> <20><><EFBFBD><EFBFBD> Ȯ<><C8AE><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD>(VID/PID)<29><> <20>ݴϴ<DDB4>.
|
||
// HardwareID<49><44> MULTI_SZ <20><><EFBFBD><EFBFBD><EFBFBD>̹Ƿ<CCB9> ù <20><>° <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20><><EFBFBD><EFBFBD> <20>˴ϴ<CBB4>.
|
||
status = QueryDeviceProperty(physicalDeviceObject, DevicePropertyHardwareID, &pHardwareId, &PropertySize);
|
||
|
||
if (NT_SUCCESS(status) && pHardwareId)
|
||
{
|
||
KLogEx(DEBUG_TRACE_INFO, "[PnP] Hardware ID: %S\n", pHardwareId);
|
||
ExFreePoolWithTag(pHardwareId, _ALLOC_TAG);
|
||
}
|
||
else
|
||
{
|
||
KLogEx(DEBUG_TRACE_INFO, "[PnP] Query DevicePropertyHardwareID Failed 0x%x\n", status);
|
||
}
|
||
|
||
ObDereferenceObject(physicalDeviceObject);
|
||
}
|
||
}
|
||
|
||
status = STATUS_SUCCESS;
|
||
}
|
||
__finally
|
||
{
|
||
if (pDevice)
|
||
ObDereferenceObject(pDevice);
|
||
}
|
||
|
||
return status;
|
||
}
|