Hello friends,
I am rewriting the diskperormance monitor driver with the capabilities of encryption and decryption.
Following is the code I’m using. I’m able to do operation like read a file write a file on the encypted disk ,
even I’m able to format the drive as FAT. But getting problem in formating the drive as NTFS,
some time i get problem in creating the partition also. I not able to workout the problem.
Could you please help me in solving the problem…
Thanks in advance
Maliye
//
// Temp Data Buffer
//
typedef struct _StrMDL {
struct _StrMDL *Next;
// Stores pointer to the user buffer return by MmMapLockedPages
PCHAR UserBuffer;
// Mapped system Address
PCHAR MappedSystemAdd;
// Byte Offset
ULONG ByteOffset;
// Store the number of bytes
ULONG ByteCount;
} StrMDL, *PStrMDL;
NTSTATUS DiskWrite( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PDEVICE_EXTENSION physicalDisk =
deviceExtension->PhysicalDevice->DeviceExtension;
PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
ULONG Count = 0,i;
PMDL StoreUserMdl;
PCHAR Buffer;
PMDL WriteBufferMdl;
PMDL PrmStoreUserMdl;
PMDL PrmStoreWriteMdl;
NTSTATUS Status;
KEVENT event;
PStrMDL PStrWriteBuffer;
PStrMDL StoreWriteBuffer;
//
// Mark IRP with status pending.
//
IoMarkIrpPending(Irp);
//
// Increment queue depth counter.
//
InterlockedIncrement(&deviceExtension->DiskCounters.QueueDepth);
if (deviceExtension != physicalDisk)
{
//
// Now get the physical disk counters and increment queue depth.
//
InterlockedIncrement(&physicalDisk->DiskCounters.QueueDepth);
}
//
// Copy current stack to next stack.
//
*nextIrpStack = *currentIrpStack;
//
// Time stamp current request start.
//
currentIrpStack->Parameters.Read.ByteOffset = KeQueryPerformanceCounter((PVOID)NULL);
//
// Set completion routine callback.
//
IoSetCompletionRoutine ( Irp,DiskIoCompletion,0,TRUE,TRUE,TRUE );
//
// Encryption module for write request.
//
PrmStoreUserMdl = StoreUserMdl = Irp -> MdlAddress;
// Write Buffer
StoreWriteBuffer = PStrWriteBuffer = ExAllocatePool ( NonPagedPool , sizeof ( PStrMDL ) );
PStrWriteBuffer -> UserBuffer = ExAllocatePool ( NonPagedPool ,
( ULONG ) StoreUserMdl -> ByteCount );
PStrWriteBuffer -> MappedSystemAdd = ExAllocatePool ( NonPagedPool ,
( ( ULONG ) StoreUserMdl -> ByteCount + StoreUserMdl -> ByteOffset ) );
PStrWriteBuffer -> Next = NULL;
if ( MmIsAddressValid ( StoreUserMdl -> MappedSystemVa ) )
{
RtlCopyMemory ( ( PStrWriteBuffer -> MappedSystemAdd + StoreUserMdl -> ByteOffset ),
( ( PCHAR ) StoreUserMdl -> MappedSystemVa + StoreUserMdl -> ByteOffset ),
StoreUserMdl -> ByteCount );
StoreUserMdl -> MappedSystemVa = PStrWriteBuffer -> MappedSystemAdd;
}
// Write Buffer
while ( StoreUserMdl != NULL )
{
Buffer = MmMapLockedPages ( StoreUserMdl, KernelMode );
// Write Buffer
if ( PStrWriteBuffer -> Next )
{
PStrWriteBuffer = PStrWriteBuffer -> Next;
PStrWriteBuffer -> UserBuffer = ExAllocatePool ( NonPagedPool ,
( ULONG ) StoreUserMdl -> ByteCount );
PStrWriteBuffer -> MappedSystemAdd = ExAllocatePool ( NonPagedPool ,
( ( ULONG ) StoreUserMdl -> ByteCount + StoreUserMdl -> ByteOffset ) );
if ( MmIsAddressValid ( StoreUserMdl -> MappedSystemVa ) )
{
RtlCopyMemory ( ( PStrWriteBuffer -> MappedSystemAdd + StoreUserMdl -> ByteOffset ), ( ( PCHAR ) StoreUserMdl -> MappedSystemVa + StoreUserMdl -> ByteOffset ), StoreUserMdl -> ByteCount );
StoreUserMdl -> MappedSystemVa = PStrWriteBuffer -> MappedSystemAdd;
}
}// End of if PStrWriteBuffer -> Next
if ( ( Buffer ) != ( (PCHAR) StoreUserMdl -> MappedSystemVa + ( StoreUserMdl -> ByteOffset ) ) )
{
for ( i = 0; i < ( ULONG ) StoreUserMdl -> ByteCount ; i++ )
{
++ * ( Buffer + i );
}
}
for ( i = 0; i < ( ULONG ) StoreUserMdl -> ByteCount ; i++ )
{
if ( MmIsAddressValid ( (PCHAR) StoreUserMdl -> MappedSystemVa
- ( StoreUserMdl -> ByteOffset + i ) ) )
{
++ * ( (PCHAR) StoreUserMdl -> MappedSystemVa
- ( StoreUserMdl -> ByteOffset + i ) );
}
}
StoreUserMdl = StoreUserMdl -> Next;
if ( StoreUserMdl )
{
PStrWriteBuffer -> Next = ExAllocatePool ( NonPagedPool , sizeof ( PStrMDL ) );
}
}// end of while
IoCallDriver ( deviceExtension->TargetDeviceObject, Irp );
return STATUS_PENDING;
}
NTSTATUS DiskRead( IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp )
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PDEVICE_EXTENSION physicalDisk =
deviceExtension->PhysicalDevice->DeviceExtension;
PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
ULONG Count,i;
PMDL StoreUserMdl;
//
// Mark IRP with status pending.
//
IoMarkIrpPending(Irp);
//
// Increment queue depth counter.
//
InterlockedIncrement(&deviceExtension->DiskCounters.QueueDepth);
if (deviceExtension != physicalDisk)
{
//
// Now get the physical disk counters and increment queue depth.
//
InterlockedIncrement(&physicalDisk->DiskCounters.QueueDepth);
}
//
// Copy current stack to next stack.
//
*nextIrpStack = *currentIrpStack;
//
// Time stamp current request start.
//
currentIrpStack->Parameters.Read.ByteOffset = KeQueryPerformanceCounter((PVOID)NULL);
//
// Set completion routine callback.
//
IoSetCompletionRoutine ( Irp, DiskIoCompletion,0,TRUE,TRUE,TRUE );
}// end of if disk number
IoCallDriver ( deviceExtension->TargetDeviceObject, Irp );
return STATUS_PENDING;
}
NTSTATUS DiskIoCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PDEVICE_EXTENSION physicalDisk = deviceExtension->PhysicalDevice->DeviceExtension;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
PDISK_PERFORMANCE partitionCounters = &deviceExtension->DiskCounters;
PDISK_PERFORMANCE diskCounters = &physicalDisk->DiskCounters;
LARGE_INTEGER timeStampStart = irpStack->Parameters.Read.ByteOffset;
LARGE_INTEGER timeStampComplete;
LARGE_INTEGER difference;
KIRQL currentIrql;
ULONG Count,i;
PMDL StoreUserMdl;
PCHAR Buffer;
UNREFERENCED_PARAMETER(Context);
//
// Time stamp current request complete.
//
timeStampComplete = KeQueryPerformanceCounter((PVOID)NULL);
//
// Decrement the queue depth counters for the volume and physical disk. This is
// done without the spinlock using the Interlocked functions. This is the only
// legal way to do this.
//
InterlockedDecrement(&partitionCounters->QueueDepth);
if (deviceExtension != physicalDisk) {
InterlockedDecrement(&diskCounters->QueueDepth);
}
//
// Update counters under spinlock protection.
//
KeAcquireSpinLock(&physicalDisk->Spinlock, ¤tIrql);
difference.QuadPart = timeStampComplete.QuadPart - timeStampStart.QuadPart;
if (irpStack->MajorFunction == IRP_MJ_READ)
{
//
// Add bytes in this request to bytes read counters.
//
partitionCounters->BytesRead.QuadPart += Irp->IoStatus.Information;
diskCounters->BytesRead.QuadPart += Irp->IoStatus.Information;
//
// Increment read requests processed counters.
//
partitionCounters->ReadCount++;
diskCounters->ReadCount++;
//
// Calculate request processing time.
//
partitionCounters->ReadTime.QuadPart += difference.QuadPart;
diskCounters->ReadTime.QuadPart += difference.QuadPart;
///*************
StoreUserMdl = Irp -> MdlAddress;
while ( StoreUserMdl != NULL )
{
//
// Mapped System Va decryption
//
Buffer = MmMapLockedPages ( StoreUserMdl, KernelMode );
if ( ( Buffer ) != ( (PCHAR) StoreUserMdl -> MappedSystemVa
- ( StoreUserMdl -> ByteOffset ) ) )
{
for ( i = 0; i < ( ULONG ) StoreUserMdl -> ByteCount ; i++ )
{
– * ( Buffer + i );
}
}
for ( i = 0; i < ( ULONG ) StoreUserMdl -> ByteCount ; i++ )
{
if ( MmIsAddressValid ( (PCHAR) StoreUserMdl -> MappedSystemVa
- ( StoreUserMdl -> ByteOffset + i ) ) )
{
– * ( (PCHAR) StoreUserMdl -> MappedSystemVa
- ( StoreUserMdl -> ByteOffset + i ) );
}
}
StoreUserMdl = StoreUserMdl -> Next;
}// end of while
}
else
{
//
// Add bytes in this request to bytes write counters.
//
partitionCounters->BytesWritten.QuadPart += Irp->IoStatus.Information;
diskCounters->BytesWritten.QuadPart += Irp->IoStatus.Information;
//
// Increment write requests processed counters.
//
partitionCounters->WriteCount++;
diskCounters->WriteCount++;
//
// Calculate request processing time.
//
partitionCounters->WriteTime.QuadPart += difference.QuadPart;
diskCounters->WriteTime.QuadPart += difference.QuadPart;
StoreUserMdl = Irp -> MdlAddress;
while ( StoreUserMdl != NULL )
{
Buffer = MmMapLockedPages ( StoreUserMdl, KernelMode );
if ( ( Buffer ) != ( (PCHAR) StoreUserMdl -> MappedSystemVa + ( StoreUserMdl -> ByteOffset ) ) )
{
for ( i = 0; i < ( ULONG ) StoreUserMdl -> ByteCount ; i++ )
{
– * ( Buffer + i );
}
}
for ( i = 0; i < ( ULONG ) StoreUserMdl -> ByteCount ; i++ )
{
if ( MmIsAddressValid ( (PCHAR) StoreUserMdl -> MappedSystemVa
- ( StoreUserMdl -> ByteOffset + i ) ) )
{
– * ( (PCHAR) StoreUserMdl -> MappedSystemVa
- ( StoreUserMdl -> ByteOffset + i ) );
}
}
//
// Store Next Mdl pointer to encrypt the next linked data.
//
StoreUserMdl = StoreUserMdl -> Next;
}// end of while
}// End of else
//
// Release spinlock.
//
KeReleaseSpinLock(&physicalDisk->Spinlock, currentIrql);
if (Irp->PendingReturned) {
IoMarkIrpPending(Irp);
}
return STATUS_SUCCESS;
}