Help needed regarding the disk encryption driver

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, &currentIrql);

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;

}