a file systems filter driver,in the IRP_MJ_CREATE routine£¬I modified
the FileObject->FileName with new file name then return
STATUS_REPARSE.
when open a file(and directory)or create a file(and directory),it
work well.such as open C:\My Document\XXXX\xxx.txt,it will redirect
the path to d:\My Document\yyyyy\xxx.txt.( C:\My Document\XXXX\ will
rediret to d:\My Document\yyyyy).and the content of the C:\My
Document\XXXX\ are the same of d:\My Document\yyyyy.
but when in C:\My Document\XXXX,i select a directory,right click it,
come out the context menu,select the “Delete”,come out a dialog to
confirm and click “OK”,come out a dialog say: the directory is used
by another…
it is the same to delete a file from context menu but can delete a
file with press the “Delete” key in keyboard and can not delete a
directory.
the follow is my code of IRP_MJ_CREATE:
TSTATUS PadLockFilterCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP
Irp )
{
NTSTATUS status;
#if WINVER >= 0x0501
KLOCK_QUEUE_HANDLE LockHandle;
#else
KIRQL oldIrql;
#endif
// KEVENT waitEvent;
PIO_STACK_LOCATION irpSp;
//////////////////////////////////////////////////////////////////////////
//Brilly added
PUNICODE_STRING FileName=NULL;
PVOID FileNameBuffer=NULL;
//UNICODE_STRING NewFileName;
GET_NAME_CONTROL nameControl;
PLIST_ENTRY pEntry,pHead;
PPADLOCKFILTER_MAP_INFO_LIST pdElement;
PWSTR FindPos=NULL;
BOOLEAN bRedirectFileOpen = FALSE;
ULONG ulOrignalFileLen=0;
ULONG ulNewFileLen=0;
//Added end
//////////////////////////////////////////////////////////////////////////
PAGED_CODE();
//////////////////////////////////////////////////////////////////////////
//
// Get current IRP stack
//
irpSp = IoGetCurrentIrpStackLocation( Irp );
//
// If this is for our control device object, don’t allow it to be
opened.
//
if ( IS_MY_CONTROL_DEVICE_OBJECT( DeviceObject ) && irpSp-
MajorFunction != IRP_MJ_QUERY_INFORMATION )
{
DBGS(“IRP_Create IS_MY_CONTROL_DEVICE_OBJECT( DeviceObject )”);
// ÔÀ´µÄ´úÂ룬²»´¦Àí
//Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
//Irp->IoStatus.Information = 0;
//IoCompleteRequest( Irp, IO_NO_INCREMENT );
//return STATUS_INVALID_DEVICE_REQUEST;
//End
//
// A CREATE request is being made on our gControlDeviceObject.
// See if someone else has it open. If so, disallow this open.
//
#if WINVER >= 0x0501
KeAcquireInStackQueuedSpinLock(
&gPadLockFilter_ControlDeviceStateLock,&LockHandle );
#else
KeAcquireSpinLock( &gPadLockFilter_ControlDeviceStateLock, &oldIrql
);
#endif
if (gPadLockFilter_ControlDeviceState != CLOSED)
{
Irp->IoStatus.Status = STATUS_DEVICE_ALREADY_ATTACHED;
Irp->IoStatus.Information = 0;
}
else
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = FILE_OPENED;
gPadLockFilter_ControlDeviceState = OPENED;
}
#if WINVER >= 0x0501
KeReleaseInStackQueuedSpinLock( &LockHandle );
#else
KeReleaseSpinLock( &gPadLockFilter_ControlDeviceStateLock, oldIrql
);
#endif
//
// Since this is our gControlDeviceObject, we complete the
// irp here.
//
status = Irp->IoStatus.Status;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return status;
}
ASSERT( IS_MY_DEVICE_OBJECT( DeviceObject ) );
//
// Copy the stack and set our Completion routine
//
FileName = PadLockFilterGetFullPathName(irpSp->FileObject,
&nameControl);
#if WINVER >= 0x0501
KeAcquireInStackQueuedSpinLock( &gPadLockFilter_MapListAccessLock,
&LockHandle );
#else
KeAcquireSpinLock( &gPadLockFilter_MapListAccessLock,&oldIrql);
#endif
pEntry = pHead = & gPadLockFilter_FileMapHead;
if ( pEntry != NULL )
{
while ( pEntry->Flink != pHead ) //look up the list to find that
is filename will modify.
{
ASSERT( pEntry->Flink != NULL );
pdElement = CONTAINING_RECORD( pEntry->Flink ,
PADLOCKFILTER_MAP_INFO_LIST ,linkfield);
ASSERT (pdElement != NULL );
ASSERT ( pdElement->pwstrRealFilePath != NULL );
ASSERT ( pdElement->pwstrMapFilePath != NULL );
ASSERT ( FileName != NULL );
ASSERT ( FileName->Buffer != NULL );
FindPos = wcsstr( FileName->Buffer,pdElement->pwstrRealFilePath);
if ( FindPos != NULL ) //ÔÚFileNameÖÐÕÒµ½Á˶ÔÓ¦µÄÓ³Éä·¾¶,µ«²»Ò»¶¨ÍêÈ«ÎǺÏ
{
BOOLEAN bDoRemap=FALSE;
size_t l;
size_t BufferMustLength=0;
size_t MaxBufferSize=0;
size_t lFileName=0;
RtlStringCchLengthW( FileName->Buffer, MAXPATHLEN, &lFileName);
DBGPUS(FileName);
RtlStringCchLengthW( pdElement->pwstrRealFilePath, MAXPATHLEN, &l
);
DBGX(“the realfilepath=%S”,pdElement->pwstrRealFilePath);
if ( wcscmp( FileName->Buffer,pdElement->pwstrRealFilePath) == 0
) //ÍêÈ«ÎǺÏ
{
DBGS(“the same!”);
bDoRemap = TRUE;
}
else if ( ( FindPos + l ) <= (FileName->Buffer + lFileName ) )
{
//DBGX(" the FindPos + l = %C", ( *(FindPos + l ) ) );
if ( *(FindPos + l ) == L’\’ ) //ÊǸÃÎļþ¼ÐϵÄÎļþ»òÎļþ¼Ð
{
DBGL;
bDoRemap = TRUE;
}
}
//bDoRemap = TRUE;
DBGD1( " bDoRemap " ,bDoRemap );
if ( TRUE == bDoRemap )
{
// \Device\Harddisk3\XXXX\yyyy\aaa.txt ===>ÕæÊµÂ·¾¶
// ------> \Device\Harddisk4\XXXX ===>Ó°Éä·¾¶
RtlStringCchLengthW( pdElement->pwstrMapFilePath , MAXPATHLEN,
&l);
BufferMustLength += l;
RtlStringCchLengthW( FindPos , MAXPATHLEN, &l);
BufferMustLength += l;
MaxBufferSize = MAXPATHLEN > BufferMustLength ? MAXPATHLEN :
BufferMustLength;
FileNameBuffer = ExAllocatePoolWithTag( NonPagedPool,
MaxBufferSize , PKFL_POOL_TAG );
if ( FileNameBuffer == NULL )
{
DBGBP;
goto FLAG_DONONE;
}
RtlZeroMemory( FileNameBuffer,MaxBufferSize);
RtlStringCchCatW( FileNameBuffer, MaxBufferSize ,pdElement-
pwstrMapFilePath );
RtlStringCchLengthW( pdElement->pwstrRealFilePath ,MAXPATHLEN,
&l);
if ( RtlStringCchCatW( FileNameBuffer,MaxBufferSize,FindPos + l
) == STATUS_BUFFER_OVERFLOW )
{
ExFreePool( FileNameBuffer );
DBGBP;
goto FLAG_DONONE;
}
//RtlAppendUnicodeToString( &NewFileName,FindPos+wcslen(
pdElement->pwstrRealFilePath ) );
DBGX(“the new file name=%S”,FileNameBuffer);
//ExFreePool( irpSp->FileObject->FileName.Buffer );
RtlFreeUnicodeString( &irpSp->FileObject->FileName);
RtlInitUnicodeString( &irpSp->FileObject->FileName,
FileNameBuffer);
#if WINVER >= 0x0501
KeReleaseInStackQueuedSpinLock( &LockHandle );
#else
KeReleaseSpinLock( &gPadLockFilter_MapListAccessLock, oldIrql );
#endif
PadLockFilterGetFileNameCleanup( &nameControl );
//RtlInitEmptyUnicodeString( &irpSp->FileObject->FileName ,
FileNameBuffer, MAXPATHLEN );
//RtlCopyUnicodeString( &irpSp->FileObject->FileName,
&NewFileName );
Irp->IoStatus.Information = IO_REPARSE;
//ExFreePool( FileNameBuffer);
Irp->IoStatus.Status = STATUS_REPARSE;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_REPARSE;
}
}
pEntry = pEntry->Flink ;
}
}
FLAG_DONONE:
#if WINVER >= 0x0501
KeReleaseInStackQueuedSpinLock( &LockHandle );
#else
KeReleaseSpinLock( &gPadLockFilter_MapListAccessLock, oldIrql );
#endif
PadLockFilterGetFileNameCleanup( &nameControl );
//
// Don’t put us on the stack then call the next driver
//
IoSkipCurrentIrpStackLocation( Irp );
return IoCallDriver( ( ( PPADLOCKFILTER_DEVICE_EXTENSION
)DeviceObject->DeviceExtension )->AttachedToDeviceObject, Irp );