My write routine is right ? help

Hello, everyone.

my program includes two parts. App and filter driver program.
in app, it set encryption folder and encryption key. these encryption info
is save in registry.
in filter driver program, it reads encryption info from registry, and
encrypt or decrypt the files in the encryption folder.

case1: I open a encrypted text file (A.text) in encryption path with
notepad.exe, the file content is decrypted and is plaintext. but after i
save as to another text file(B.text), immediately open B.txt, the content is
also right(plain text). But after i restart my machine, reopen the B.txt,
the content is cryptograph, why is it plaintext??

case2: Create a mdb file in encryption path, and open this database file,
then i create one table, append several records and save this mdb file.
close and reopen the database file, it can be opened and it is right, but
after i restart my machine, reopen the mdb database file, it can’t be opened
and be damaged. why ???

my SfWrite routine is as follow, the code exists bugs?? help
NTSTATUS
EdWrite (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PSFILTER_DEVICE_EXTENSION DevExt = (PSFILTER_DEVICE_EXTENSION)
DeviceObject->DeviceExtension;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PREAD_WRITE_COMPLETION_CONTEXT CompletionCtx = NULL;
PVOID OldBuffer = NULL;
PVOID MyBuffer = NULL;
LONG Length = 0;
LONG Offset = 0;
NTSTATUS Status = STATUS_SUCCESS;
char key[64];
wchar_t tkey[64];
char* buffer4096;
LONG bufferLen = 512;
LONG enLen = 0;
LONG partLen = 0;
unsigned short klen = 0;

UNICODE_STRING DriveLetter;
UNICODE_STRING FullName;
WCHAR TEMP[512];
ULONG i=0;
USHORT u = 0;

PAGED_CODE();

ASSERT(!IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject));
ASSERT(IS_MY_DEVICE_OBJECT(DeviceObject));

if (!DevExt->StorageStackDeviceObject)
{
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DevExt->AttachedToDeviceObject, Irp);
}

// Filter IRPs with three kinds of flags
if (!(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO |
IRP_SYNCHRONOUS_PAGING_IO)))
{
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DevExt->AttachedToDeviceObject, Irp);
}

// Get filePath(FullName), then check file is under ENC_PATH or not; in
the other words, filter the files in ENC_PATH
if(FileObject->FileName.Buffer)
{
RtlInitEmptyUnicodeString(&FullName, TEMP, FileObject->
FileName.Length + 2);
FullName.Length = 0;

FullName.Buffer[0] = DriveLetter.Buffer[0];
FullName.Buffer[1] = L’:';

for ( u = 2; u < FileObject->FileName.Length + 2; u++)
{
FullName.Buffer[u] = FileObject->FileName.Buffer[u - 2];
}

FullName.Length = FileObject->FileName.Length + 2;

for (u = 0; u < FileObject->FileName.Length + 2; u++)
{
FullName.Buffer[u] = towupper(FullName.Buffer[u]);
}

if(NULL == wcsstr(FullName.Buffer, ENC_PATH))
{
RtlFreeUnicodeString(&FullName);
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DevExt->AttachedToDeviceObject, Irp);
}
}
else
{
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DevExt->AttachedToDeviceObject, Irp);
}

// Encrypt the writing content with RC4 algorithm, encryption block is
512byte.
do
{
if (Irp->MdlAddress)
{
//KdPrint((“Irp->MdlAddress”));
OldBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
}
else
{
PMDL Mdl;

KdPrint((“Irp->UserBuffer”));

Mdl = IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE,
NULL);
if (Mdl == NULL)
{
KdPrint((“Write: IoAllocateMdl failed\n”));
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}

try
{
MmProbeAndLockPages(Mdl, Irp->RequestorMode, IoReadAccess);
}
except (EXCEPTION_EXECUTE_HANDLER)
{
KdPrint((“Write: STATUS_INVALID_USER_BUFFER\n”));
IoFreeMdl(Mdl);
Status = STATUS_INVALID_USER_BUFFER;
break;
}

MmUnlockPages(Mdl);
IoFreeMdl(Mdl);

OldBuffer = Irp->UserBuffer;

}

if (!OldBuffer)
{
KdPrint((“Write: STATUS_INVALID_PARAMETER\n”));
Status = STATUS_INVALID_PARAMETER;
break;
}

CompletionCtx =
ExAllocateFromNPagedLookasideList(&gReadWriteCompletionCtxLookAsideList);
if (!CompletionCtx)
{
KdPrint((“Write: STATUS_INSUFFICIENT_RESOURCES\n”));
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}

MyBuffer = ExAllocatePoolWithTag(NonPagedPool,Length,
SFLT_POOL_TAG);
if (!MyBuffer)
{
KdPrint((“Write: STATUS_INSUFFICIENT_RESOURCES\n”));
ExFreePool(CompletionCtx);
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}

CompletionCtx->OldMdl = Irp->MdlAddress;
CompletionCtx->OldUserBuffer = Irp->UserBuffer;
CompletionCtx->OldSystemBuffer = Irp->AssociatedIrp.SystemBuffer;

CompletionCtx->MdlForUserBuffer = NULL;

CompletionCtx->OldBuffer = OldBuffer;
CompletionCtx->MyBuffer = MyBuffer;
CompletionCtx->Length = Length;

Irp->MdlAddress = IoAllocateMdl(MyBuffer, Length, FALSE, TRUE,
NULL);
if (!Irp->MdlAddress)
{
KdPrint((“Write: STATUS_INSUFFICIENT_RESOURCES\n”));
Irp->MdlAddress = CompletionCtx->OldMdl;
ExFreePool(CompletionCtx);
ExFreePool(MyBuffer);
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}

//KdPrint((“Write: Encrypt %ws\n”, wfn));

buffer4096 = ExAllocatePoolWithTag(NonPagedPool, bufferLen,
SFLT_POOL_TAG);
if (!buffer4096)
{
KdPrint((“no memory(sfwrite complete”));
Irp->MdlAddress = CompletionCtx->OldMdl;
ExFreePool(CompletionCtx);
ExFreePool(MyBuffer);
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}

while (Length > 0)
{
if (Length - bufferLen > 0)
{
enLen = bufferLen;
}
else
{
enLen = Length;
}

RtlCopyMemory(buffer4096, (char*)OldBuffer + partLen, enLen);
crypt(buffer4096,enLen, key, klen);
RtlCopyMemory((char*)MyBuffer + partLen, buffer4096, enLen);
Length = Length - bufferLen;
partLen = partLen + bufferLen;

}

ExFreePoolWithTag(buffer4096, SFLT_POOL_TAG);
MmBuildMdlForNonPagedPool(Irp->MdlAddress);
Irp->UserBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);

IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, EdWriteCompletion, CompletionCtx, TRUE,
TRUE,TRUE);
return IoCallDriver(DevExt->AttachedToDeviceObject, Irp);

} while (FALSE);

Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);

return Status;

}

NTSTATUS EdWriteCompletion(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
PREAD_WRITE_COMPLETION_CONTEXT CompletionCtx =
(PREAD_WRITE_COMPLETION_CONTEXT) Context;

UNREFERENCED_PARAMETER(DeviceObject);

if (Irp->PendingReturned)
IoMarkIrpPending(Irp);

IoFreeMdl(Irp->MdlAddress);
Irp->MdlAddress = CompletionCtx->OldMdl;
Irp->UserBuffer = CompletionCtx->OldUserBuffer;
Irp->AssociatedIrp.SystemBuffer = CompletionCtx->OldSystemBuffer;

ExFreePoolWithTag(CompletionCtx->MyBuffer, SFLT_POOL_TAG);
ExFreeToNPagedLookasideList(&gReadWriteCompletionCtxLookAsideList,
CompletionCtx);

return STATUS_SUCCESS;

}

in any case, thanks everyone.