Query regarding Virtualizing File Properties

Greetings everyone,

I am trying to create a zero byte file on a disk using win32 createfile api
and then in my mini filter, I want to show a legitimate size for this file.
so far I have done the following:

captured irp_mj_query_info and in the classes which use file allocation
size and eof i have patched the output in post operation, I do this in post
operation because the other members of that class needs to be populated and
since mine is a legitimate file on the disk i let the FS handle it.

I have captured irp_mj_dir_ctl/irp_mn_query_dir and in the post op i have
again patched the file size (thank you don, peter for your inputs there
related to stream contexts)

i have also temporarily disabled network_query_open so that it falls back
to default paths.

after doing this, i see that both explorer and cmd.exe show file sizes
properly, even network shares work, GetfileSize api also works and I a,
able to achieve 90% of my target.

problem happens when someone right clicks on the file and does
‘properties’, there the file size shows is 0 bytes. i am unable to fool
this properties. i have read here in osr that not all queries for size is
sent to the kernel, ntset/queryinfo does some optimizations. but then how
do i get my goal with drivers? i cannot hook this api as it is illegal. is
there some flag i can pass while creating file in createfile() which will
force ntquery to always send query to driver? is there any other better
approach where no matter what flags are used in createfile driver always
gets all requests?

Process Monitor should show you which operation(s) you’re missing (I suggest
enabling Advanced Output).

Where do you plan on going from here? Note that things can become
significantly more complicated if you want to support I/O to the file.

-scott
OSR

“A P” wrote in message news:xxxxx@ntfsd…
Greetings everyone,

I am trying to create a zero byte file on a disk using win32 createfile api
and then in my mini filter, I want to show a legitimate size for this file.
so far I have done the following:

captured irp_mj_query_info and in the classes which use file allocation size
and eof i have patched the output in post operation, I do this in post
operation because the other members of that class needs to be populated and
since mine is a legitimate file on the disk i let the FS handle it.

I have captured irp_mj_dir_ctl/irp_mn_query_dir and in the post op i have
again patched the file size (thank you don, peter for your inputs there
related to stream contexts)

i have also temporarily disabled network_query_open so that it falls back to
default paths.

after doing this, i see that both explorer and cmd.exe show file sizes
properly, even network shares work, GetfileSize api also works and I a, able
to achieve 90% of my target.

problem happens when someone right clicks on the file and does ‘properties’,
there the file size shows is 0 bytes. i am unable to fool this properties. i
have read here in osr that not all queries for size is sent to the kernel,
ntset/queryinfo does some optimizations. but then how do i get my goal with
drivers? i cannot hook this api as it is illegal. is there some flag i can
pass while creating file in createfile() which will force ntquery to always
send query to driver? is there any other better approach where no matter
what flags are used in createfile driver always gets all requests?

hi scott,

thank you for your reply. i have already tried procmon and it doesnt show
any operation which queries the file size, are are few FileBasicInfo,
FileNameInfo calls but nothing which either queries EOF or allocsize. this
is on Win2k8r2

actually reads are handled in the driver already, the so is write, this bug
is as of now cosmetic, but irritating, and i need to get to bottom of it.

On Tue, Jun 4, 2013 at 9:02 PM, Scott Noone wrote:

> Process Monitor should show you which operation(s) you’re missing (I
> suggest enabling Advanced Output).
>
> Where do you plan on going from here? Note that things can become
> significantly more complicated if you want to support I/O to the file.
>
> -scott
> OSR
>
> “A P” wrote in message news:xxxxx@ntfsd…
>
> Greetings everyone,
>
> I am trying to create a zero byte file on a disk using win32 createfile
> api and then in my mini filter, I want to show a legitimate size for this
> file. so far I have done the following:
>
> captured irp_mj_query_info and in the classes which use file allocation
> size and eof i have patched the output in post operation, I do this in post
> operation because the other members of that class needs to be populated and
> since mine is a legitimate file on the disk i let the FS handle it.
>
> I have captured irp_mj_dir_ctl/irp_mn_query_**dir and in the post op i
> have again patched the file size (thank you don, peter for your inputs
> there related to stream contexts)
>
> i have also temporarily disabled network_query_open so that it falls back
> to default paths.
>
> after doing this, i see that both explorer and cmd.exe show file sizes
> properly, even network shares work, GetfileSize api also works and I a,
> able to achieve 90% of my target.
>
>
> problem happens when someone right clicks on the file and does
> ‘properties’, there the file size shows is 0 bytes. i am unable to fool
> this properties. i have read here in osr that not all queries for size is
> sent to the kernel, ntset/queryinfo does some optimizations. but then how
> do i get my goal with drivers? i cannot hook this api as it is illegal. is
> there some flag i can pass while creating file in createfile() which will
> force ntquery to always send query to driver? is there any other better
> approach where no matter what flags are used in createfile driver always
> gets all requests?
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.**cfm?name=ListServerhttp:
></http:>

File size information is retrieved either through the fastIO calls for
NetworkQueryOpen or the querystandard or through the irp based requests
for a directory query or file_query_info with the FileAllInfo,
FileNetworkOpenInfo or FileStandardInfo class.

In a mini-filter you need to set pre-op callbacks for the
IRP_MJ_QUERY_INFORMATION, IRP_MJ_DIRECTORY_CONTROL and the
IRP_MJ_NETWORK_QUERY_OPEN to handle all these requests.

You must be missing one of these. How are you ‘disabling’ the
network_query_open request?

Pete

On 6/4/2013 12:24 PM, A P wrote:

hi scott,
thank you for your reply. i have already tried procmon and it doesnt
show any operation which queries the file size, are are few
FileBasicInfo, FileNameInfo calls but nothing which either queries EOF
or allocsize. this is on Win2k8r2
actually reads are handled in the driver already, the so is write, this
bug is as of now cosmetic, but irritating, and i need to get to bottom
of it.

On Tue, Jun 4, 2013 at 9:02 PM, Scott Noone > mailto:xxxxx> wrote:
>
> Process Monitor should show you which operation(s) you’re missing (I
> suggest enabling Advanced Output).
>
> Where do you plan on going from here? Note that things can become
> significantly more complicated if you want to support I/O to the file.
>
> -scott
> OSR
>
> “A P” > wrote
> in message news:xxxxx@ntfsd…
>
> Greetings everyone,
>
> I am trying to create a zero byte file on a disk using win32
> createfile api and then in my mini filter, I want to show a
> legitimate size for this file. so far I have done the following:
>
> captured irp_mj_query_info and in the classes which use file
> allocation size and eof i have patched the output in post operation,
> I do this in post operation because the other members of that class
> needs to be populated and since mine is a legitimate file on the
> disk i let the FS handle it.
>
> I have captured irp_mj_dir_ctl/irp_mn_query___dir and in the post op
> i have again patched the file size (thank you don, peter for your
> inputs there related to stream contexts)
>
> i have also temporarily disabled network_query_open so that it falls
> back to default paths.
>
> after doing this, i see that both explorer and cmd.exe show file
> sizes properly, even network shares work, GetfileSize api also works
> and I a, able to achieve 90% of my target.
>
>
> problem happens when someone right clicks on the file and does
> ‘properties’, there the file size shows is 0 bytes. i am unable to
> fool this properties. i have read here in osr that not all queries
> for size is sent to the kernel, ntset/queryinfo does some
> optimizations. but then how do i get my goal with drivers? i cannot
> hook this api as it is illegal. is there some flag i can pass while
> creating file in createfile() which will force ntquery to always
> send query to driver? is there any other better approach where no
> matter what flags are used in createfile driver always gets all
> requests?
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.__cfm?name=ListServer
> http:
>
>
> — NTFSD is sponsored by OSR OSR is hiring!! Info at
> http://www.osr.com/careers For our schedule of debugging and file system
> seminars visit: http://www.osr.com/seminars To unsubscribe, visit the
> List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295</http:></mailto:xxxxx>

“A P” wrote in message news:xxxxx@ntfsd…
>this bug is as of now cosmetic, but irritating

If you’re leaking the actual size at any point then your filter is broken.
Applications can get very confused if you leak the wrong size to them.

The application has to get the size from somewhere. For my sanity I just ran
a quick check and I see fast I/O network query opens, fast I/O query
informations for standard information, as well as two directory
enumerations. Note that Process Monitor does not indicate the enumeration
level on the directory query, so either or both of these can return size
information.

Do you properly handle directory queries with a filter mask specified? For
example, does “dir foo.txt” show the correct size for your file?

-scott
OSR

“A P” wrote in message news:xxxxx@ntfsd…
hi scott,

thank you for your reply. i have already tried procmon and it doesnt show
any operation which queries the file size, are are few FileBasicInfo,
FileNameInfo calls but nothing which either queries EOF or allocsize. this
is on Win2k8r2

actually reads are handled in the driver already, the so is write, this bug
is as of now cosmetic, but irritating, and i need to get to bottom of it.

On Tue, Jun 4, 2013 at 9:02 PM, Scott Noone wrote:
Process Monitor should show you which operation(s) you’re missing (I suggest
enabling Advanced Output).

Where do you plan on going from here? Note that things can become
significantly more complicated if you want to support I/O to the file.

-scott
OSR

“A P” wrote in message news:xxxxx@ntfsd…

Greetings everyone,

I am trying to create a zero byte file on a disk using win32 createfile api
and then in my mini filter, I want to show a legitimate size for this file.
so far I have done the following:

captured irp_mj_query_info and in the classes which use file allocation size
and eof i have patched the output in post operation, I do this in post
operation because the other members of that class needs to be populated and
since mine is a legitimate file on the disk i let the FS handle it.

I have captured irp_mj_dir_ctl/irp_mn_query_dir and in the post op i have
again patched the file size (thank you don, peter for your inputs there
related to stream contexts)

i have also temporarily disabled network_query_open so that it falls back to
default paths.

after doing this, i see that both explorer and cmd.exe show file sizes
properly, even network shares work, GetfileSize api also works and I a, able
to achieve 90% of my target.

problem happens when someone right clicks on the file and does ‘properties’,
there the file size shows is 0 bytes. i am unable to fool this properties. i
have read here in osr that not all queries for size is sent to the kernel,
ntset/queryinfo does some optimizations. but then how do i get my goal with
drivers? i cannot hook this api as it is illegal. is there some flag i can
pass while creating file in createfile() which will force ntquery to always
send query to driver? is there any other better approach where no matter
what flags are used in createfile driver always gets all requests?


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

the list manager keeps rejecting the msg stating it is too large, so i will
break my email into two back to back messages…

PART#1

Scott, peter,
thank you for your interest in the topic. i cannot say how glad i am that
someone is trying to help me learn.
answering all the questions one by one:
[Peter] File size information is retrieved either through the fastIO calls
for NetworkQueryOpen or the querystandard or through the irp based requests
for a directory query or file_query_info with the FileAllInfo,
FileNetworkOpenInfo or FileStandardInfo class.
[AP] I hope I have handled all of them, I have posted relevant code
sections below in this same email for your guidance.

[Scott]If you’re leaking the actual size at any point then your filter is
broken. Applications can get very confused if you leak the wrong size to
them.
[AP] right you are, my english grammer and vocabulary is not so good,
perhaps i use worng words sometimes.
[Scott]Note that Process Monitor does not indicate the enumeration level on
the directory query, so either or both of these can return size information.
[AP] This I did not understand, can you please elaborate ‘level’?
[Scott]Do you properly handle directory queries with a filter mask
specified? For example, does “dir foo.txt” show the correct size for your
file?
[AP]yes, dir *.*, dir, dir *.ext, dir foo.* dir foor.ext all work from
cmd.exe

CODE

First this is registration section:
CONST FLT_OPERATION_REGISTRATION MyOpCallbacks = {
{ IRP_MJ_CREATE, // Listen to File Create calls
0,
MyCreatePreOp, // preoperation for Create
MyCreatePostOp }, // postoperation for Create
{ IRP_MJ_READ, // Listen to File Read calls
0,
MyReadPreOp, // preoperation for read
MyReadPostOp }, // postoperation for read
{ IRP_MJ_FAST_IO_CHECK_IF_POSSIBLE,
0,
MyFastIoCheckPreOp,
MyFastIoCheckPostOp },
{ IRP_MJ_QUERY_INFORMATION,
0,
MyQueryPreOp,
MyQueryPostOp },
{ IRP_MJ_SET_INFORMATION,
0,
MySetPreOp,
MySetPostOp },
{ IRP_MJ_DIRECTORY_CONTROL,
0,
MyDirCtrlPreOp,
MyDirCtrlPostOp },
{ IRP_MJ_NETWORK_QUERY_OPEN,
0,
MyNwQueryOpenPreOp,
NULL },
{ IRP_MJ_OPERATION_END }
};

const FLT_CONTEXT_REGISTRATION Contexts = {
{ FLT_INSTANCE_CONTEXT,
0,
MyInstanceCtxCleanup, // Destructor function
pointer
sizeof(MY_INSTANCE_CONTEXT),
MY_INSTANCE_CONTEXT_TAG },
{ FLT_STREAM_CONTEXT,
0,
MyStreamCtxCleanup,
My_STREAM_CONTEXT_SIZE,
MY_STREAMCTX_POOL_TAG },

{ FLT_CONTEXT_END }
};

CONST FLT_REGISTRATION MyRegistration = {
sizeof(FLT_REGISTRATION), // Size
FLT_REGISTRATION_VERSION, // Version
0, // Flags
Contexts, // Context
MyOpCallbacks, // Operation callbacks
MyUnload, // Unload Handler
MyInstanceSetup, // InstanceSetup
MyQueryTeardown, // InstanceQueryTeardown
MyInstanceTeardownStart, // InstanceTeardownStart
MyInstanceTeardownComplete, // InstanceTeardownComplete
NULL, // GenerateFileName
NULL, // GenerateDestinationFileName
NULL // NormalizeNameComponent
};

Next is DirCtl handling Code:
FLT_PREOP_CALLBACK_STATUS
MyDirCtrlPreOp (
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__deref_out_opt PVOID *CompletionContext
)
{
FLT_PREOP_CALLBACK_STATUS returnStatus =
FLT_PREOP_SUCCESS_NO_CALLBACK;
NTSTATUS status;
PMy_STREAM_CONTEXT pMyStreamCtx = NULL;
BOOLEAN bStreamCtxCreated = FALSE;

ASSERT(Data->Iopb->MajorFunction == IRP_MJ_DIRECTORY_CONTROL);

if (IRP_MN_QUERY_DIRECTORY == Data->Iopb->MinorFunction) {

// Now we try to locate a stream context for this Operation. A
stream context
// should have been allocated for a File of our interest in Create
Post-Op
status = MyFindOrCreateStreamContext(Data,
FALSE, //
do not create if one does not exist
&pMyStreamCtx,
&bStreamCtxCreated);
if (!NT_SUCCESS( status )) {

// This failure will most likely be because stream contexts
are not supported
// on the object we are trying to assign a context to or the
object is being
// deleted
goto Exit; // Fall back to Pass
through Mode
}
returnStatus = FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
Exit:
if (pMyStreamCtx != NULL) {
FltReleaseContext( pMyStreamCtx );
}
return returnStatus;
}

FLT_POSTOP_CALLBACK_STATUS
MyDirCtrlPostOp (
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__in PVOID CompletionContext,
__in FLT_POST_OPERATION_FLAGS Flags
)
{
PFLT_IO_PARAMETER_BLOCK Iopb = Data->Iopb;
ASSERT(Iopb->MajorFunction == IRP_MJ_DIRECTORY_CONTROL);
if (IRP_MN_QUERY_DIRECTORY == Iopb->MinorFunction) {
MyModifyPostDirCtrl(Data,
FltObjects,
CompletionContext,
Flags);
}
return FLT_POSTOP_FINISHED_PROCESSING;
}

FLT_POSTOP_CALLBACK_STATUS
MyModifyPostDirCtrl (
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__in_opt PVOID CompletionContext,
__in FLT_POST_OPERATION_FLAGS Flags)
{
ULONG nextOffset = 0;
PVOID SafeBuffer = NULL;
PFLT_IO_PARAMETER_BLOCK Iopb = Data->Iopb;
FLT_PARAMETERS Parameters = Iopb->Parameters;
NTSTATUS status = Data->IoStatus.Status;
PFLT_CONTEXT pFltContext = NULL;
UNREFERENCED_PARAMETER (FltObjects);
UNREFERENCED_PARAMETER (CompletionContext);

if (FlagOn (Flags, FLTFL_POST_OPERATION_DRAINING)) {
return FLT_POSTOP_FINISHED_PROCESSING;
}
if(Iopb->MinorFunction != IRP_MN_QUERY_DIRECTORY){
// we are only interested in Query Directory at the moment…
goto Exit;
}
if(Parameters.DirectoryControl.QueryDirectory.MdlAddress != NULL) {
SafeBuffer = MmGetSystemAddressForMdlSafe
(Parameters.DirectoryControl.QueryDirectory.MdlAddress,
NormalPagePriority);
}
else {
SafeBuffer =
Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer;
}
if (SafeBuffer == NULL) {
// Nothing much we can do here…
goto Exit;
}
if((status != STATUS_SUCCESS )){

goto Exit;
}
if(Parameters.DirectoryControl.QueryDirectory.Length == 0){
goto Exit;
}

status = FltGetInstanceContext(FltObjects->Instance,
&pFltContext);
if (!NT_SUCCESS( status ) && (status == STATUS_NOT_FOUND)){
// every time we attach to a volume we create an instance context,
// so if one isnt found we need not proceed as we are not interested
// in this volume at all
goto Exit;
}

switch (Parameters.DirectoryControl.QueryDirectory.FileInformationClass){
case FileBothDirectoryInformation:
case FileIdBothDirectoryInformation:
#if FLT_MGR_LONGHORN
status = ProcessRequest((PFILE_ID_BOTH_DIR_INFORMATION)
SafeBuffer, (PMy_INSTANCE_CONTEXT)pFltContext);
#else
status =ProcessRequest((PFILE_BOTH_DIR_INFORMATION)
SafeBuffer, (PMy_INSTANCE_CONTEXT)pFltContext);
#endif
break;
case FileFullDirectoryInformation:
status =ProcessRequest((PFILE_FULL_DIR_INFORMATION) SafeBuffer,
(PMy_INSTANCE_CONTEXT)pFltContext);
break;
default: {
MyDrvTrace(My_TRACELEVEL_HIGH,
(“Got %ws, Bypassing…\n”,
pQueryInfoClasses[Parameters.DirectoryControl.QueryDirectory.FileInformationClass]));
break;
}
}
if(status == STATUS_INSUFFICIENT_RESOURCES){ // Our memory
allocation failed
// We should fail this request and complain to IO Manager
Data->IoStatus.Status = status;
Data->IoStatus.Information = 0;
FltSetCallbackDataDirty( Data );
goto Exit;
}

Exit:
if(pFltContext){
FltReleaseContext(pFltContext);
}
return FLT_POSTOP_FINISHED_PROCESSING;
}

On Wed, Jun 5, 2013 at 2:15 AM, Scott Noone wrote:

> “A P” wrote in message news:xxxxx@ntfsd…
>
> this bug is as of now cosmetic, but irritating
>>
>
> If you’re leaking the actual size at any point then your filter is broken.
> Applications can get very confused if you leak the wrong size to them.
>
> The application has to get the size from somewhere. For my sanity I just
> ran a quick check and I see fast I/O network query opens, fast I/O query
> informations for standard information, as well as two directory
> enumerations. Note that Process Monitor does not indicate the enumeration
> level on the directory query, so either or both of these can return size
> information.
>
> Do you properly handle directory queries with a filter mask specified? For
> example, does “dir foo.txt” show the correct size for your file?
>
> -scott
> OSR
>
> “A P” wrote in message news:xxxxx@ntfsd…
>
> hi scott,
>
> thank you for your reply. i have already tried procmon and it doesnt show
> any operation which queries the file size, are are few FileBasicInfo,
> FileNameInfo calls but nothing which either queries EOF or allocsize. this
> is on Win2k8r2
>
> actually reads are handled in the driver already, the so is write, this
> bug is as of now cosmetic, but irritating, and i need to get to bottom of
> it.
>
>
>
>
> On Tue, Jun 4, 2013 at 9:02 PM, Scott Noone wrote:
> Process Monitor should show you which operation(s) you’re missing (I
> suggest enabling Advanced Output).
>
> Where do you plan on going from here? Note that things can become
> significantly more complicated if you want to support I/O to the file.
>
> -scott
> OSR
>
> “A P” wrote in message news:xxxxx@ntfsd…
>
> Greetings everyone,
>
> I am trying to create a zero byte file on a disk using win32 createfile
> api and then in my mini filter, I want to show a legitimate size for this
> file. so far I have done the following:
>
> captured irp_mj_query_info and in the classes which use file allocation
> size and eof i have patched the output in post operation, I do this in post
> operation because the other members of that class needs to be populated and
> since mine is a legitimate file on the disk i let the FS handle it.
>
> I have captured irp_mj_dir_ctl/irp_mn_query_**dir and in the post op i
> have again patched the file size (thank you don, peter for your inputs
> there related to stream contexts)
>
> i have also temporarily disabled network_query_open so that it falls back
> to default paths.
>
> after doing this, i see that both explorer and cmd.exe show file sizes
> properly, even network shares work, GetfileSize api also works and I a,
> able to achieve 90% of my target.
>
>
> problem happens when someone right clicks on the file and does
> ‘properties’, there the file size shows is 0 bytes. i am unable to fool
> this properties. i have read here in osr that not all queries for size is
> sent to the kernel, ntset/queryinfo does some optimizations. but then how
> do i get my goal with drivers? i cannot hook this api as it is illegal. is
> there some flag i can pass while creating file in createfile() which will
> force ntquery to always send query to driver? is there any other better
> approach where no matter what flags are used in createfile driver always
> gets all requests?
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.**cfm?name=ListServerhttp:
>
>
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.**cfm?name=ListServerhttp:
></http:></http:>

PART 2

Then I paste Query Handling:

FLT_PREOP_CALLBACK_STATUS
MyQueryPreOp (
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__deref_out_opt PVOID *CompletionContext
)

{

NTSTATUS status;
FLT_PREOP_CALLBACK_STATUS FltOpStatus =
FLT_PREOP_SUCCESS_NO_CALLBACK ;
PMy_STREAM_CONTEXT pStreamCtx = NULL;
PFLT_CONTEXT pFltContext = NULL;
BOOLEAN bStreamCtxCreated = FALSE;
PUCHAR pBuffer = NULL;
ULONG SessionId = 0; //
0 is an Invalid session Id
PWCHAR oNamePointer = NULL;
FLT_PARAMETERS Params =
Data->Iopb->Parameters;
BOOLEAN bIsFastIO = FALSE;

ASSERT(Data->Iopb->MajorFunction == IRP_MJ_QUERY_INFORMATION);

if (FltObjects->FileObject == NULL) {

MyDrvTrace(My_TRACELEVEL_HIGH, (“FltObjects->FileObject is
NULL\n”));

goto Exit;
}

bIsFastIO = FLT_IS_FASTIO_OPERATION(Data);

// Now we try to locate a stream context for this Read Operation. A
stream context
// should have been allocated for a File of our interest in Create
Post-Op

status = MyFindOrCreateStreamContext(Data,
FALSE, // do
not create if one does not exist
&pStreamCtx,
&bStreamCtxCreated);

if (!NT_SUCCESS( status )) {

// This failure will most likely be because stream contexts are
not supported
// on the object we are trying to assign a context to or the
object is being
// deleted

MyDrvTrace(My_TRACELEVEL_HIGH,
(“Got %ws, Failed to find stream context (Data = 0x%p,
FileObject = 0x%p), Bypassing…\n”,

pQueryInfoClasses[Params.QueryFileInformation.FileInformationClass],
Data,
FltObjects->FileObject) );

goto Exit; // Fall back to Pass
through Mode
}

// Extract the File Name form the Stream Context
// Operation needs to be done under Lock

pStreamCtx->Resource.SoAcquireObject();

oNamePointer = (PWCHAR)MyMmAllocateMemory(NonPagedPool,

pStreamCtx->FileName.Length + sizeof(WCHAR),
MyLAT_QUERYOP_POOL_TAG);

if(oNamePointer == NULL) {

MyDrvTrace(My_TRACELEVEL_HIGH,(“Allocation Failed\n”));

Data->IoStatus.Status = STATUS_UNSUCCESSFUL;
Data->IoStatus.Information = 0;
FltSetCallbackDataDirty( Data );

pStreamCtx->Resource.SoReleaseObject();
goto Exit;

}

MyMmZeroMemory(oNamePointer, pStreamCtx->FileName.Length +
sizeof(WCHAR));

MyMmCopyMemory(oNamePointer, pStreamCtx->FileName.Buffer,
pStreamCtx->FileName.Length);

pStreamCtx->Resource.SoReleaseObject();

// Okay so we got a name, lets get the session for it

// At this place I have some code to test whether this file name
interests me or not, which is removed in the posting

if(bIsFastIO){

MyDrvTrace(My_TRACELEVEL_LOW, (“Disabling FastIO for File : %ws\n”,
oNamePointer));
FltOpStatus = FLT_PREOP_DISALLOW_FASTIO;
goto Exit;
}

LARGE_INTEGER EOFParams;

MyMmZeroMemory(&EOFParams, sizeof(LARGE_INTEGER));

g_MyData.GetEmulationSize(oNamePointer, &EOFParams);

if(EOFParams.QuadPart == 0 ){ // This would mean that the
Session doesn’t need any emulation

MyDrvTrace(My_TRACELEVEL_HIGH,
(“Got %ws for File : %ws, but size emulation has been
disabled. Bypassing…\n”,

pQueryInfoClasses[Params.QueryFileInformation.FileInformationClass],
oNamePointer));
goto Exit;
}

switch (Params.QueryFileInformation.FileInformationClass) {

case FileStandardInformation:
case FileAllInformation:
case FileNetworkOpenInformation: {
// We will partially fulfill this, in Post-Op, as the rest of
the Info needs to be fetched from the FS
MyDrvTrace(My_TRACELEVEL_HIGH,
(“Got %ws for File : %ws, we will Fulfill this
partially in Post-Op, rest will be done by FS\n”,

pQueryInfoClasses[Params.QueryFileInformation.FileInformationClass],
oNamePointer));

// So lets set the Post-Op callback trigger
FltOpStatus = FLT_PREOP_SUCCESS_WITH_CALLBACK;
// and a completion context for us to work with…

size_t NameLen = wcslen(oNamePointer) * sizeof(WCHAR); //
The size of the string in Bytes
size_t Len = sizeof(QUERY_CTX) +
// The size of the struct
sizeof(WCHAR) +
// space for NULL character
NameLen;

*CompletionContext = MyMmAllocateMemory(NonPagedPool,
Len,

MyLAT_QUERYOP_POOL_TAG);
if(*CompletionContext == NULL){

Data->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
Data->IoStatus.Information = 0;
FltSetCallbackDataDirty( Data );
// Fail it by completing it…
FltOpStatus = FLT_PREOP_COMPLETE;

}

FltGetInstanceContext(FltObjects->Instance,
&pFltContext);

MyMmZeroMemory(*CompletionContext,
Len);

((PQUERY_CTX)(*CompletionContext))->EOFMarker = EOFParams;

if(pFltContext){

((PQUERY_CTX)(*CompletionContext))->AllocationSize.QuadPart
= ROUND_UP(EOFParams.QuadPart,
((PMy_INSTANCE_CONTEXT)pFltContext)->VolInfo.FSClusterSize);
}

MyMmCopyMemory(((PQUERY_CTX)(*CompletionContext))->Name,
oNamePointer,
NameLen);

break;
}

case FileEndOfFileInformation:{

// In our case the EOF would be the size of total File
Emulation
PFILE_END_OF_FILE_INFORMATION pEOFInfo =
(PFILE_END_OF_FILE_INFORMATION)Params.QueryFileInformation.InfoBuffer;

pEOFInfo->EndOfFile = EOFParams;

MyDrvTrace(My_TRACELEVEL_HIGH,
(“Got FileEndOfFileInformation for File : %ws.
EndOfFile = 0x%I64x\n”,
oNamePointer,
pEOFInfo->EndOfFile.QuadPart));

// We don’t want the FS to handle this so we will halt
processing and return from here
Data->IoStatus.Status = STATUS_SUCCESS;
Data->IoStatus.Information = 0;
FltSetCallbackDataDirty( Data );

FltOpStatus = FLT_PREOP_COMPLETE;
break;

}

case FilePositionInformation: {

PFILE_OBJECT pFO = FltObjects->FileObject;
PFILE_POSITION_INFORMATION pFPosInfo =
(PFILE_POSITION_INFORMATION)Params.QueryFileInformation.InfoBuffer;

// In MyRead We will be setting the Read Offset + Length as
FO.CurrentByteOffset, so just return that…
MyMmCopyMemory(&(pFPosInfo->CurrentByteOffset),
&pFO->CurrentByteOffset,
sizeof(LARGE_INTEGER));

MyDrvTrace(My_TRACELEVEL_MED,
(“Got FilePositionInformation for File : %ws.
CurrentByteOffset.Quadpart = 0x%I64x\n”,
oNamePointer,
pFO->CurrentByteOffset.QuadPart));

// We don’t want the FS to handle this so we will halt
processing and return from here
Data->IoStatus.Status = STATUS_SUCCESS;
Data->IoStatus.Information = 0;
FltSetCallbackDataDirty( Data );

FltOpStatus = FLT_PREOP_COMPLETE;
break;
}

default: {
MyDrvTrace(My_TRACELEVEL_HIGH,
(“Got %ws for File : %ws\n”,

pQueryInfoClasses[Params.QueryFileInformation.FileInformationClass],
oNamePointer));

break;
}
} //switch
(Data->Iopb->Parameters.QueryFileInformation.FileInformationClass)

Exit:
if(oNamePointer){

MyMmFreeMemory(oNamePointer, MyLAT_QUERYOP_POOL_TAG);
}

if (pStreamCtx != NULL) {

FltReleaseContext( pStreamCtx );
}

if (pFltContext != NULL) {

FltReleaseContext( pFltContext );
}

MyDrvTrace(My_TRACELEVEL_LOW, (“Exiting…\n”));
return FltOpStatus;
}

FLT_POSTOP_CALLBACK_STATUS
MyQueryPostOp (
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__in PVOID CompletionContext,
__in FLT_POST_OPERATION_FLAGS Flags
)

{
FLT_PARAMETERS Params = Data->Iopb->Parameters;

if(CompletionContext == NULL){

MyDrvTrace(My_TRACELEVEL_HIGH, (“Invalid Parameter, Got NULL in
CompletionContext…\n”));
goto Exit;

}

PWCHAR oNamePointer = (PWCHAR)((PQUERY_CTX)(CompletionContext))->Name;

// Okay, so we will be only called when we have triggered this in Pre-Op
// so it would be for one of the Classes of Info which we need to swoof
and
// change some data, keeping the other parts intact, i.e, what ever the
FS
// returned for those fields…

LARGE_INTEGER MyEOF;
LARGE_INTEGER AllocationSize;

MyMmZeroMemory(&MyEOF, sizeof(LARGE_INTEGER));
MyMmZeroMemory(&AllocationSize, sizeof(LARGE_INTEGER));

MyEOF = ((PQUERY_CTX)(CompletionContext))->EOFMarker;
// we only get a call back for Post is Emulation is enabled
AllocationSize = ((PQUERY_CTX)(CompletionContext))->AllocationSize;
// we only get a call back for Post is Emulation is enabled

switch (Params.QueryFileInformation.FileInformationClass) {

case FileStandardInformation:{

// For standard Info, we need to change the EOF location to our
own…
PFILE_STANDARD_INFORMATION pStandardInfo =
(PFILE_STANDARD_INFORMATION)Params.QueryFileInformation.InfoBuffer;

pStandardInfo->EndOfFile = MyEOF;
pStandardInfo->AllocationSize = AllocationSize;

MyDrvTrace(My_TRACELEVEL_HIGH,
(“Got %ws for File : %ws. EndOfFile = 0x%I64x,
AllocSize = 0x%I64x\n”,

pQueryInfoClasses[Params.QueryFileInformation.FileInformationClass],
oNamePointer,
pStandardInfo->EndOfFile.QuadPart,
pStandardInfo->AllocationSize.QuadPart));

break;

}
case FileAllInformation:{

// For All Info, we need to change the following :
// 1. StandardInformation.EndOfFile
// 2. PositionInformation.CurrentByteOffset

PFILE_ALL_INFORMATION pAllInfo =
(PFILE_ALL_INFORMATION)Params.QueryFileInformation.InfoBuffer;

pAllInfo->StandardInformation.EndOfFile = MyEOF;
pAllInfo->StandardInformation.AllocationSize = AllocationSize;

PFILE_OBJECT pFO = FltObjects->FileObject;

pAllInfo->PositionInformation.CurrentByteOffset =
pFO->CurrentByteOffset;

MyDrvTrace(My_TRACELEVEL_HIGH,
(“Got %ws for File : %ws. Set EndOfFile = 0x%I64x,
AllocSize = 0x%I64x, CurrentByteOffset = 0x%I64x\n”,

pQueryInfoClasses[Params.QueryFileInformation.FileInformationClass],
oNamePointer,
pAllInfo->StandardInformation.EndOfFile.QuadPart,

pAllInfo->StandardInformation.AllocationSize.QuadPart,
pAllInfo->PositionInformation.CurrentByteOffset));

break;

}
case FileNetworkOpenInformation:{

// For Network Open Info, we need to change the EOF location to
our own…
PFILE_NETWORK_OPEN_INFORMATION pNwopenInfo =
(PFILE_NETWORK_OPEN_INFORMATION)Params.QueryFileInformation.InfoBuffer;

pNwopenInfo->EndOfFile = MyEOF;
pNwopenInfo->AllocationSize = AllocationSize;

MyDrvTrace(My_TRACELEVEL_HIGH,
(“Got %ws for File : %ws. EndOfFile = 0x%I64x,
AllocSize = 0x%I64x\n”,

pQueryInfoClasses[Params.QueryFileInformation.FileInformationClass],
oNamePointer,
pNwopenInfo->EndOfFile.QuadPart,
pNwopenInfo->AllocationSize.QuadPart));

break;
}

default: {
MyDrvTrace(My_TRACELEVEL_HIGH,
(“Got %ws for File : %ws\n”,

pQueryInfoClasses[Params.QueryFileInformation.FileInformationClass],
oNamePointer));

break;
}
}

Exit:

if(CompletionContext){

MyMmFreeMemory(CompletionContext, MyLAT_QUERYOP_POOL_TAG);
}

return FLT_POSTOP_FINISHED_PROCESSING;

}

next i paste Nw Query Open

FLT_PREOP_CALLBACK_STATUS
myNwQueryOpenPreOp (
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__deref_out_opt PVOID *CompletionContext
)

{
UNREFERENCED_PARAMETER (Data);
UNREFERENCED_PARAMETER (FltObjects);
UNREFERENCED_PARAMETER (CompletionContext);

return FLT_PREOP_DISALLOW_FASTIO;
}

I mean the FileInformationClass.

What does the subroutine ProcessRequest do? Why do you cast the SafeBuffer
pointer based on the O/S release?

FileBothDirectoryInformation uses FILE_BOTH_DIR_INFORMATION and
FileIdBothDirectoryInformation uses FILE_ID_BOTH_DIR_INFORMATION, regardless
of O/S release.

-scott
OSR

“A P” wrote in message news:xxxxx@ntfsd…
the list manager keeps rejecting the msg stating it is too large, so i will
break my email into two back to back messages…

PART#1

Scott, peter,
thank you for your interest in the topic. i cannot say how glad i am that
someone is trying to help me learn.
answering all the questions one by one:
[Peter] File size information is retrieved either through the fastIO calls
for NetworkQueryOpen or the querystandard or through the irp based requests
for a directory query or file_query_info with the FileAllInfo,
FileNetworkOpenInfo or FileStandardInfo class.
[AP] I hope I have handled all of them, I have posted relevant code
sections below in this same email for your guidance.

[Scott]If you’re leaking the actual size at any point then your filter is
broken. Applications can get very confused if you leak the wrong size to
them.
[AP] right you are, my english grammer and vocabulary is not so good,
perhaps i use worng words sometimes.
[Scott]Note that Process Monitor does not indicate the enumeration level on
the directory query, so either or both of these can return size information.
[AP] This I did not understand, can you please elaborate ‘level’?
[Scott]Do you properly handle directory queries with a filter mask
specified? For example, does “dir foo.txt” show the correct size for your
file?
[AP]yes, dir ., dir, dir .ext, dir foo. dir foor.ext all work from
cmd.exe

CODE
--------
First this is registration section:
CONST FLT_OPERATION_REGISTRATION MyOpCallbacks = {
{ IRP_MJ_CREATE, // Listen to File Create calls
0,
MyCreatePreOp, // preoperation for Create
MyCreatePostOp }, // postoperation for Create
{ IRP_MJ_READ, // Listen to File Read calls
0,
MyReadPreOp, // preoperation for read
MyReadPostOp }, // postoperation for read
{ IRP_MJ_FAST_IO_CHECK_IF_POSSIBLE,
0,
MyFastIoCheckPreOp,
MyFastIoCheckPostOp },
{ IRP_MJ_QUERY_INFORMATION,
0,
MyQueryPreOp,
MyQueryPostOp },
{ IRP_MJ_SET_INFORMATION,
0,
MySetPreOp,
MySetPostOp },
{ IRP_MJ_DIRECTORY_CONTROL,
0,
MyDirCtrlPreOp,
MyDirCtrlPostOp },
{ IRP_MJ_NETWORK_QUERY_OPEN,
0,
MyNwQueryOpenPreOp,
NULL },
{ IRP_MJ_OPERATION_END }
};

const FLT_CONTEXT_REGISTRATION Contexts = {
{ FLT_INSTANCE_CONTEXT,
0,
MyInstanceCtxCleanup, // Destructor function
pointer
sizeof(MY_INSTANCE_CONTEXT),
MY_INSTANCE_CONTEXT_TAG },
{ FLT_STREAM_CONTEXT,
0,
MyStreamCtxCleanup,
My_STREAM_CONTEXT_SIZE,
MY_STREAMCTX_POOL_TAG },

{ FLT_CONTEXT_END }
};

CONST FLT_REGISTRATION MyRegistration = {
sizeof(FLT_REGISTRATION), // Size
FLT_REGISTRATION_VERSION, // Version
0, // Flags
Contexts, // Context
MyOpCallbacks, // Operation callbacks
MyUnload, // Unload Handler
MyInstanceSetup, // InstanceSetup
MyQueryTeardown, // InstanceQueryTeardown
MyInstanceTeardownStart, // InstanceTeardownStart
MyInstanceTeardownComplete, // InstanceTeardownComplete
NULL, // GenerateFileName
NULL, // GenerateDestinationFileName
NULL // NormalizeNameComponent
};

Next is DirCtl handling Code:
FLT_PREOP_CALLBACK_STATUS
MyDirCtrlPreOp (
inout PFLT_CALLBACK_DATA Data,
in PCFLT_RELATED_OBJECTS FltObjects,
__deref_out_opt PVOID *CompletionContext
)
{
FLT_PREOP_CALLBACK_STATUS returnStatus =
FLT_PREOP_SUCCESS_NO_CALLBACK;
NTSTATUS status;
PMy_STREAM_CONTEXT pMyStreamCtx = NULL;
BOOLEAN bStreamCtxCreated = FALSE;

ASSERT(Data->Iopb->MajorFunction == IRP_MJ_DIRECTORY_CONTROL);

if (IRP_MN_QUERY_DIRECTORY == Data->Iopb->MinorFunction) {

// Now we try to locate a stream context for this Operation. A
stream context
// should have been allocated for a File of our interest in Create
Post-Op
status = MyFindOrCreateStreamContext(Data,
FALSE, //
do not create if one does not exist
&pMyStreamCtx,
&bStreamCtxCreated);
if (!NT_SUCCESS( status )) {

// This failure will most likely be because stream contexts
are not supported
// on the object we are trying to assign a context to or the
object is being
// deleted
goto Exit; // Fall back to Pass
through Mode
}
returnStatus = FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
Exit:
if (pMyStreamCtx != NULL) {
FltReleaseContext( pMyStreamCtx );
}
return returnStatus;
}

FLT_POSTOP_CALLBACK_STATUS
MyDirCtrlPostOp (
__inout PFLT_CALLBACK_DATA Data,
in PCFLT_RELATED_OBJECTS FltObjects,
in PVOID CompletionContext,
__in FLT_POST_OPERATION_FLAGS Flags
)
{
PFLT_IO_PARAMETER_BLOCK Iopb = Data->Iopb;
ASSERT(Iopb->MajorFunction == IRP_MJ_DIRECTORY_CONTROL);
if (IRP_MN_QUERY_DIRECTORY == Iopb->MinorFunction) {
MyModifyPostDirCtrl(Data,
FltObjects,
CompletionContext,
Flags);
}
return FLT_POSTOP_FINISHED_PROCESSING;
}

FLT_POSTOP_CALLBACK_STATUS
MyModifyPostDirCtrl (
__inout PFLT_CALLBACK_DATA Data,
in PCFLT_RELATED_OBJECTS FltObjects,
in_opt PVOID CompletionContext,
__in FLT_POST_OPERATION_FLAGS Flags)
{
ULONG nextOffset = 0;
PVOID SafeBuffer = NULL;
PFLT_IO_PARAMETER_BLOCK Iopb = Data->Iopb;
FLT_PARAMETERS Parameters = Iopb->Parameters;
NTSTATUS status = Data->IoStatus.Status;
PFLT_CONTEXT pFltContext = NULL;
UNREFERENCED_PARAMETER (FltObjects);
UNREFERENCED_PARAMETER (CompletionContext);

if (FlagOn (Flags, FLTFL_POST_OPERATION_DRAINING)) {
return FLT_POSTOP_FINISHED_PROCESSING;
}
if(Iopb->MinorFunction != IRP_MN_QUERY_DIRECTORY){
// we are only interested in Query Directory at the moment…
goto Exit;
}
if(Parameters.DirectoryControl.QueryDirectory.MdlAddress != NULL) {
SafeBuffer = MmGetSystemAddressForMdlSafe
(Parameters.DirectoryControl.QueryDirectory.MdlAddress,
NormalPagePriority);
}
else {
SafeBuffer =
Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer;
}
if (SafeBuffer == NULL) {
// Nothing much we can do here…
goto Exit;
}
if((status != STATUS_SUCCESS )){

goto Exit;
}
if(Parameters.DirectoryControl.QueryDirectory.Length == 0){
goto Exit;
}

status = FltGetInstanceContext(FltObjects->Instance,
&pFltContext);
if (!NT_SUCCESS( status ) && (status == STATUS_NOT_FOUND)){
// every time we attach to a volume we create an instance context,
// so if one isnt found we need not proceed as we are not interested
// in this volume at all
goto Exit;
}

switch (Parameters.DirectoryControl.QueryDirectory.FileInformationClass){
case FileBothDirectoryInformation:
case FileIdBothDirectoryInformation:
#if FLT_MGR_LONGHORN
status = ProcessRequest((PFILE_ID_BOTH_DIR_INFORMATION)
SafeBuffer, (PMy_INSTANCE_CONTEXT)pFltContext);
#else
status =ProcessRequest((PFILE_BOTH_DIR_INFORMATION)
SafeBuffer, (PMy_INSTANCE_CONTEXT)pFltContext);
#endif
break;
case FileFullDirectoryInformation:
status =ProcessRequest((PFILE_FULL_DIR_INFORMATION) SafeBuffer,
(PMy_INSTANCE_CONTEXT)pFltContext);
break;
default: {
MyDrvTrace(My_TRACELEVEL_HIGH,
(“Got %ws, Bypassing…\n”,
pQueryInfoClasses[Parameters.DirectoryControl.QueryDirectory.FileInformationClass]));
break;
}
}
if(status == STATUS_INSUFFICIENT_RESOURCES){ // Our memory
allocation failed
// We should fail this request and complain to IO Manager
Data->IoStatus.Status = status;
Data->IoStatus.Information = 0;
FltSetCallbackDataDirty( Data );
goto Exit;
}

Exit:
if(pFltContext){
FltReleaseContext(pFltContext);
}
return FLT_POSTOP_FINISHED_PROCESSING;
}

On Wed, Jun 5, 2013 at 2:15 AM, Scott Noone wrote:
“A P” wrote in message news:xxxxx@ntfsd…

this bug is as of now cosmetic, but irritating

If you’re leaking the actual size at any point then your filter is broken.
Applications can get very confused if you leak the wrong size to them.

The application has to get the size from somewhere. For my sanity I just ran
a quick check and I see fast I/O network query opens, fast I/O query
informations for standard information, as well as two directory
enumerations. Note that Process Monitor does not indicate the enumeration
level on the directory query, so either or both of these can return size
information.

Do you properly handle directory queries with a filter mask specified? For
example, does “dir foo.txt” show the correct size for your file?

-scott
OSR

“A P” wrote in message news:xxxxx@ntfsd…

hi scott,

thank you for your reply. i have already tried procmon and it doesnt show
any operation which queries the file size, are are few FileBasicInfo,
FileNameInfo calls but nothing which either queries EOF or allocsize. this
is on Win2k8r2

actually reads are handled in the driver already, the so is write, this bug
is as of now cosmetic, but irritating, and i need to get to bottom of it.

On Tue, Jun 4, 2013 at 9:02 PM, Scott Noone wrote:
Process Monitor should show you which operation(s) you’re missing (I suggest
enabling Advanced Output).

Where do you plan on going from here? Note that things can become
significantly more complicated if you want to support I/O to the file.

-scott
OSR

“A P” wrote in message news:xxxxx@ntfsd…

Greetings everyone,

I am trying to create a zero byte file on a disk using win32 createfile api
and then in my mini filter, I want to show a legitimate size for this file.
so far I have done the following:

captured irp_mj_query_info and in the classes which use file allocation size
and eof i have patched the output in post operation, I do this in post
operation because the other members of that class needs to be populated and
since mine is a legitimate file on the disk i let the FS handle it.

I have captured irp_mj_dir_ctl/irp_mn_query_dir and in the post op i have
again patched the file size (thank you don, peter for your inputs there
related to stream contexts)

i have also temporarily disabled network_query_open so that it falls back to
default paths.

after doing this, i see that both explorer and cmd.exe show file sizes
properly, even network shares work, GetfileSize api also works and I a, able
to achieve 90% of my target.

problem happens when someone right clicks on the file and does ‘properties’,
there the file size shows is 0 bytes. i am unable to fool this properties. i
have read here in osr that not all queries for size is sent to the kernel,
ntset/queryinfo does some optimizations. but then how do i get my goal with
drivers? i cannot hook this api as it is illegal. is there some flag i can
pass while creating file in createfile() which will force ntquery to always
send query to driver? is there any other better approach where no matter
what flags are used in createfile driver always gets all requests?


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

[SN]I mean the FileInformationClass.

[AP]But it shows ‘QueryBasicInformaton’, ‘QueryNameInformation’, isn’t that the user firendly name of the actual class? If not, I wud have to use mini spy to see actual names.

[SN]What does the subroutine ProcessRequest do? Why do you cast the SafeBuffer
pointer based on the O/S release

[AP]It is a template function, here is the code:

template
NTSTATUS ProcessRequest(TYPE *pCurrFInfoObj,
PMY_INSTANCE_CONTEXT pFltContext)
{

TYPE *pNextFInfoObj = NULL;
ULONG nextOffset = 0;
NTSTATUS status = STATUS_SUCCESS;
KIRQL Irql;

Irql = KeGetCurrentIrql();

if(Irql >= DISPATCH_LEVEL) {

MyDrvTrace(My_TRACELEVEL_HIGH,
(“IRQL too High to Process request…\n”));

goto Exit;

}

do {

// Byte offset of the next entry
nextOffset = pCurrFInfoObj -> NextEntryOffset;

pNextFInfoObj = (TYPE *) ((PCHAR) (pCurrFInfoObj) + nextOffset);

My_DRV_DATA SData;
NTSTATUS statusOfCM;
PWCHAR pFName = NULL;

pFName = (PWCHAR)MyMmAllocateMemory(NonPagedPool,
pCurrFInfoObj->FileNameLength + sizeof(WCHAR), // The length doesn’t contain the NULL character space
MyLAT_DIRCTLOP_POOL_TAG);

if(pFName == NULL){

// Nothing much we can do at this time…
status = STATUS_INSUFFICIENT_RESOURCES;
MyDrvTrace(My_TRACELEVEL_HIGH, (“Allocation Failed\n”));
goto Exit;
}

MyMmZeroMemory(pFName, pCurrFInfoObj->FileNameLength + sizeof(WCHAR));
// We need a copy of this file name because it doesn’t always come NULL terminated…
MyMmCopyMemory(pFName,
pCurrFInfoObj->FileName,
pCurrFInfoObj->FileNameLength); // notice that we copy only required data and not the uLen size…

MyMmZeroMemory(&SData, sizeof(My_DRV_DATA));

statusOfCM = g_MyDrvData.MyCMGetData(pFName, &SData);

if(NT_SUCCESS(statusOfCM)){ // Okay so the name is a match, lets modify the contents

pCurrFInfoObj->EndOfFile = SData.EmulationSize;
pCurrFInfoObj->AllocationSize.QuadPart = ROUND_UP(SData.EmulationSize.QuadPart, pFltContext->VolInfo.FSClusterSize);
MyDrvTrace(My_TRACELEVEL_MED,
(“File : %ws Located, Modifying EOF to : 0x%I64x, AllocSize : 0x%I64x\n”,
pFName,
pCurrFInfoObj->EndOfFile.QuadPart,
pCurrFInfoObj->AllocationSize.QuadPart));

}

// We need to free this immediately, as the next file name will need fresh allocation
MyMmFreeMemory(pFName, MyLAT_DIRCTLOP_POOL_TAG);

// Move the current pointer
pCurrFInfoObj = pNextFInfoObj;
}while (nextOffset !=0);

Exit:

return status;
}

The level is shown for _QUERY_INFORMATION calls, but not for
_DIRECTORY_CONTROL/_QUERY_DIRECTORY requests.

That still doesn’t explain why you cast to the wrong type?

-scott
OSR

wrote in message news:xxxxx@ntfsd…

[SN]I mean the FileInformationClass.

[AP]But it shows ‘QueryBasicInformaton’, ‘QueryNameInformation’, isn’t that
the user firendly name of the actual class? If not, I wud have to use mini
spy to see actual names.

[SN]What does the subroutine ProcessRequest do? Why do you cast the
SafeBuffer
pointer based on the O/S release

[AP]It is a template function, here is the code:

template
NTSTATUS ProcessRequest(TYPE *pCurrFInfoObj,
PMY_INSTANCE_CONTEXT pFltContext)
{

TYPE *pNextFInfoObj = NULL;
ULONG nextOffset = 0;
NTSTATUS status = STATUS_SUCCESS;
KIRQL Irql;

Irql = KeGetCurrentIrql();

if(Irql >= DISPATCH_LEVEL) {

MyDrvTrace(My_TRACELEVEL_HIGH,
(“IRQL too High to Process request…\n”));

goto Exit;

}

do {

// Byte offset of the next entry
nextOffset = pCurrFInfoObj -> NextEntryOffset;

pNextFInfoObj = (TYPE *) ((PCHAR) (pCurrFInfoObj) + nextOffset);

My_DRV_DATA SData;
NTSTATUS statusOfCM;
PWCHAR pFName = NULL;

pFName = (PWCHAR)MyMmAllocateMemory(NonPagedPool,
pCurrFInfoObj->FileNameLength +
sizeof(WCHAR), // The length doesn’t contain the NULL character space
MyLAT_DIRCTLOP_POOL_TAG);

if(pFName == NULL){

// Nothing much we can do at this time…
status = STATUS_INSUFFICIENT_RESOURCES;
MyDrvTrace(My_TRACELEVEL_HIGH, (“Allocation Failed\n”));
goto Exit;
}

MyMmZeroMemory(pFName, pCurrFInfoObj->FileNameLength +
sizeof(WCHAR));
// We need a copy of this file name because it doesn’t always come
NULL terminated…
MyMmCopyMemory(pFName,
pCurrFInfoObj->FileName,
pCurrFInfoObj->FileNameLength); // notice that we
copy only required data and not the uLen size…

MyMmZeroMemory(&SData, sizeof(My_DRV_DATA));

statusOfCM = g_MyDrvData.MyCMGetData(pFName, &SData);

if(NT_SUCCESS(statusOfCM)){ // Okay so the name is a match, lets
modify the contents

pCurrFInfoObj->EndOfFile = SData.EmulationSize;
pCurrFInfoObj->AllocationSize.QuadPart =
ROUND_UP(SData.EmulationSize.QuadPart, pFltContext->VolInfo.FSClusterSize);
MyDrvTrace(My_TRACELEVEL_MED,
(“File : %ws Located, Modifying EOF to : 0x%I64x,
AllocSize : 0x%I64x\n”,
pFName,
pCurrFInfoObj->EndOfFile.QuadPart,
pCurrFInfoObj->AllocationSize.QuadPart));

}

// We need to free this immediately, as the next file name will
need fresh allocation
MyMmFreeMemory(pFName, MyLAT_DIRCTLOP_POOL_TAG);

// Move the current pointer
pCurrFInfoObj = pNextFInfoObj;
}while (nextOffset !=0);

Exit:

return status;
}

[SN]That still doesn’t explain why you cast to the wrong type?

[AP] my CVS file history tells me that the original writer copied some code from this link, though it does something different. i guess this is where it came from?

http://www.cnblogs.com/js2854/archive/2010/11/03/HideDir.html

That code is wrong. The FileName field is at different offsets in these two
structures, so you’re not getting the right name if you use the wrong
structure. IIRC Vista did start using FileIdBothDirectoryInformation more
heavily, though it’s still possible to see FileBothDirectoryInformation.

-scott
OSR

wrote in message news:xxxxx@ntfsd…

[SN]That still doesn’t explain why you cast to the wrong type?

[AP] my CVS file history tells me that the original writer copied some code
from this link, though it does something different. i guess this is where it
came from?

http://www.cnblogs.com/js2854/archive/2010/11/03/HideDir.html

[SN]That code is wrong. The FileName field is at different offsets in these two structures, so you’re not getting the right name if you use the wrong structure. IIRC Vista did start using FileIdBothDirectoryInformation more heavily, though it’s still possible to see FileBothDirectoryInformation.

[AP] Yes indeed that was the problem!!! Thank you so much for your patience, and for helping me! I am grateful.