paging i/o problem

I saw some posts about how (and why) unsafe is paging i/o pending, but due to initial architecture decision I am stuck with a minifilter filesystem driver.
My driver is “fooling” the system that there are some files on the drive, that are not actually there (Processing post Query directory). The actual files are on remote server. So what I need to do is when I detect READ request I pend it and request the download of the file form user level application. It works fine with normal reads. But applications such as notepad rely only on paging reads. So my question: Is there a way to do the same thing with paging i/o reads without causing locks or impacting system performance (like using FltSendMessage to stop the processing until the user application notifies of successful file download).

P.S. If the thread was created twice please excuse me, but I waited some hours the first time and it didn’t appear

If you need to download the files completely, you can do it at create time.
Otherwise, considering the fact that you control the Cc on these files, you can correctly control the locks, it’s not the same as when the FS below you controls the Cc on a file. The only caveat is whether FltMgr will send the message from a paging read.

xxxxx@abv.bg wrote:

I saw some posts about how (and why) unsafe is paging i/o pending, but due to initial architecture decision I am stuck with a minifilter filesystem driver.
My driver is “fooling” the system that there are some files on the drive, that are not actually there (Processing post Query directory). The actual files are on remote server. So what I need to do is when I detect READ request I pend it and request the download of the file form user level application. It works fine with normal reads. But applications such as notepad rely only on paging reads. So my question: Is there a way to do the same thing with paging i/o reads without causing locks or impacting system performance (like using FltSendMessage to stop the processing until the user application notifies of successful file download).


Kind regards, Dejan
http://www.alfasp.com
File system audit, security and encryption kits.

Thanks for the reply. The initial implementation was downloading the files on Create , but it impacted performance and also the system generates way too many creates even if it actually doesn’t read the file. As far as I can see I am receiving the paging read requests. So i was wondering if there can be a problem if i try to download only the bytes requested from the read IRP before releasing it, not the whole file.This way only the data that is really needed will be downloaded.

I’ve got a similar project going here, and it sounds like you’re running
into the same problems I’m trying to work around. The version I
inherited did the restore on the creates, and every time you browsed a
directory containing a stub file, it got downloaded.

An additional problem with downloading the file on creates occurs in
this situation: A client connects to a file share on a file server and
the file server needs to retrieve the file from somewhere else. If it’s
a big file, and the create spends too much time (around 10 minutes?)
pended, the Server service locks up on the file server. Not only does
it lock it up for the client that requested the file, it locks up
completely. Nobody else can connect to the share, or any other share on
the file server. Whoops.

For this reason, and for the reason you mentioned, the MS approved way
is to do the download on reads/writes. Apparently keeping a create
pended for an extended length of time is not a kosher thing to do.

By the way, I’m still waiting for an answer from MS to your original
question.

~Eric

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@abv.bg
Sent: Tuesday, September 18, 2007 1:31 AM
To: Windows File Systems Devs Interest List
Subject: RE:[ntfsd] paging i/o problem

Thanks for the reply. The initial implementation was downloading the
files on Create , but it impacted performance and also the system
generates way too many creates even if it actually doesn’t read the
file. As far as I can see I am receiving the paging read requests. So i
was wondering if there can be a problem if i try to download only the
bytes requested from the read IRP before releasing it, not the whole
file.This way only the data that is really needed will be downloaded.


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars (including our new
fs mini-filter seminar) visit:
http://www.osr.com/seminars

You are currently subscribed to ntfsd as: xxxxx@edsiohio.com To
unsubscribe send a blank email to xxxxx@lists.osr.com

Actually the problems with the CREATE flood was partially solved by adding the FILE_ATTRIBUTE_OFFLINE on processing directory listing. This way the file recieves creates only when it is opened for read (as far as I can see although right click seems also to generate create some times ). It deals with another big problem also: thumbnails - non are generated this way you don’t have to download 700mb movie when someone opens the directory.
Currently I am trying to capture the first read for the file, but I only capture one create from notepad and many reading and writing paging i/os but none in reference with the .txt file. Probably that is because I have created it before that with zero size and the file is already cached in which case I still havn’t found a way to find if it is read from the cache. I am most probably doing something wrong. Can someone direct me?
Also it will be vary helpful to me if you can tell me what was MS’s answer when it comes
10x in advnce.

> Actually the problems with the CREATE flood was partially solved by

adding the FILE_ATTRIBUTE_OFFLINE on processing directory listing. This
way the file recieves creates only when it is opened for read (as far
as I can see although right click seems also to generate create some
times ). It deals with another big problem also: thumbnails - non are
generated this way you don’t have to download 700mb movie when someone
opens the directory.
Currently I am trying to capture the first read for the file, but I
only capture one create from notepad and many reading and writing
paging i/os but none in reference with the .txt file. Probably that is
because I have created it before that with zero size and the file is
already cached in which case I still havn’t found a way to find if it
is read from the cache. I am most probably doing something wrong. Can
someone direct me?
[Edouard A.]

That is because the PAGING IO may not occur on the same handle. A while ago (when I was young and crazy), I wrote a filter driver to cipher an arbitrary file (especially pagefile.sys) and I had that same problem.

The problem is that the OS may give you handles different from the one you have as it creates objects on his own. Every time you get a read/write request you need to check the FCB of the file and see if it matches one file you’re working on. If yes you need to add it to a structure in your driver that maintain the associations. This could be a hash table of list (std::hash_map>> to speak C++).

Don’t forget to remove the object from your association when it is closed, or you will have a leak as long as your driver is running.

Hope this answers your question.



Edouard A.

> a hash table of list (std::hash_map> boost::shared_ptrstd::list>> to speak C++).

[Edouard A.]

Sorry the structure is wrong I typed too fast. :slight_smile: It must not be based on a HANDLE. Instead, use the path that you can get from the FCB.



Edouard A.</std::list>

Edouard,
This is sounds familiar :wink: I’m doing my stuff in a minifilter and
using FLT_CALLBACK_DATA.Iopb->TargetFileObject as the key into the hash
table (with linked list chaining) and the other data I need to download
the file as the value. The problem with this is that the TFO pointer
may be the same between two files provided the first has been closed and
the second has been created. This presents some nasty issues with
synchronization so that the cache data is correct at all times. If the
FCB is unique on a per-file basis, is there a way to get at it from the
FLT_CALLBACK_DATA structure? That would help address some of the
issues.

~Eric

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Edouard A.
Sent: Tuesday, September 18, 2007 2:00 PM
To: Windows File Systems Devs Interest List
Subject: RE: [ntfsd] paging i/o problem

Actually the problems with the CREATE flood was partially solved by
adding the FILE_ATTRIBUTE_OFFLINE on processing directory listing.
This way the file recieves creates only when it is opened for read (as

far as I can see although right click seems also to generate create
some times ). It deals with another big problem also: thumbnails - non

are generated this way you don’t have to download 700mb movie when
someone opens the directory.
Currently I am trying to capture the first read for the file, but I
only capture one create from notepad and many reading and writing
paging i/os but none in reference with the .txt file. Probably that is

because I have created it before that with zero size and the file is
already cached in which case I still havn’t found a way to find if it
is read from the cache. I am most probably doing something wrong. Can
someone direct me?
[Edouard A.]

That is because the PAGING IO may not occur on the same handle. A while
ago (when I was young and crazy), I wrote a filter driver to cipher an
arbitrary file (especially pagefile.sys) and I had that same problem.

The problem is that the OS may give you handles different from the one
you have as it creates objects on his own. Every time you get a
read/write request you need to check the FCB of the file and see if it
matches one file you’re working on. If yes you need to add it to a
structure in your driver that maintain the associations. This could be a
hash table of list (std::hash_mapboost::shared_ptrstd::list>> to speak C++).

Don’t forget to remove the object from your association when it is
closed, or you will have a leak as long as your driver is running.

Hope this answers your question.



Edouard A.


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars (including our new
fs mini-filter seminar) visit:
http://www.osr.com/seminars

You are currently subscribed to ntfsd as: unknown lmsubst tag argument:
‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com</std::list>

Yes I am aware of the different handles problem. I was hoping that this would solve it:
DbgPrint( “\nI/O Paging PreCreate: FileObject: 0x%08X, PID:0x%08X %wZ\n”, Data->Iopb->TargetFileObject, hCurrentProcessID, &FltObjects->FileObject->FileName );
giving me the associated filename via &FltObjects->FileObject->FileName ,but i guess I am totally wrong Never the less I still observe strange behaviour like for an example create being done and then cleanup on the file handle of the .txt with absolutely no reads between neither standard nor paging. Another thing is that after i delete the file restart the driver and try to open the virtual file again , the second time there are absolutely no paging reads i/os whatsoever (until I restart the machine). This made me think that I am somehow filtering caching I/Os . I have this code:
if (IoGetTopLevelIrp())
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
Now I know that sometimes this function returns PIRP, sometimes it reterns a flag. I think that my problems is something around:
if(IoGetTopLevelIrp()==FSRTL_CACHE_TOP_LEVEL_IRP)

DbgPrint( “\nPreRead FSRTL_CACHE_TOP_LEVEL_IRP: FileObject: 0x%08X, PID:0x%08X %wZ\n”, Data->Iopb->TargetFileObject, hCurrentProcessID, &FltObjects->FileObject->FileName );
When I add this lines, there are no dumps either. It is really strange for me. I think that once cached notepad always tries to read it from the cache and I can’t recieve reads about that. I am lost help will be appreciated.

> Yes I am aware of the different handles problem. I was hoping that

this would solve it:
DbgPrint( “\nI/O Paging PreCreate: FileObject: 0x%08X, PID:0x%08X
%wZ\n”, Data->Iopb->TargetFileObject, hCurrentProcessID, &FltObjects-
>FileObject->FileName );
giving me the associated filename via &FltObjects->FileObject-
>FileName ,but i guess I am totally wrong Never the less I still
observe strange behaviour like for an example create being done and
then cleanup on the file handle of the .txt with absolutely no reads
between neither standard nor paging. Another thing is that after i
delete the file restart the driver and try to open the virtual file
again , the second time there are absolutely no paging reads i/os
whatsoever (until I restart the machine). This made me think that I am
somehow filtering caching I/Os . I have this code:

[Edouard A.]

If this is paging IO, then this not cached IO… You can check the presence of IRP_NOCACHE to be sure.

AFAIK you cannot have IRP_PAGING_IO without IRP_NOCACHE.
Unless you have several VMM on your operating system I don’t think you want to cache a paging IO. :wink:

if (IoGetTopLevelIrp())
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
Now I know that sometimes this function returns PIRP, sometimes it
reterns a flag. I think that my problems is something around:
if(IoGetTopLevelIrp()==FSRTL_CACHE_TOP_LEVEL_IRP)

DbgPrint( “\nPreRead FSRTL_CACHE_TOP_LEVEL_IRP:
FileObject: 0x%08X, PID:0x%08X %wZ\n”, Data->Iopb->TargetFileObject,
hCurrentProcessID, &FltObjects->FileObject->FileName );
When I add this lines, there are no dumps either. It is really strange
for me. I think that once cached notepad always tries to read it from
the cache and I can’t recieve reads about that. I am lost help will be
appreciated.

[Edouard A.]

Your intuition is correct. Requests from the cache will not be apparent to you (unless you be specific about it), but you shouldn’t care. Again, back to my previous experience, I would get the first IRP_MJ_READ and then no more. This was not a problem as the decrypted data would be in the cache. The only problem is for testing.

In your case you only need to take action the first time (copy the file to the machine). When the cache is read, well, it’s not really your business as you cannot read data from the cache if the file wasn’t there in the first place, can you?

To test you can write an user program that does memory allocation until exhaustion and then exits. Make sure all buffers are written otherwise the VMM might not commit everything (the knave!).

This generally resets all caches and make your machine crawls for few minutes as well. Ultra violence at its finest.

You can also work on a different file at each test.

EA

> Edouard,

This is sounds familiar :wink: I’m doing my stuff in a minifilter and
using FLT_CALLBACK_DATA.Iopb->TargetFileObject as the key into the hash
table (with linked list chaining) and the other data I need to download
the file as the value. The problem with this is that the TFO pointer
may be the same between two files provided the first has been closed
and
the second has been created. This presents some nasty issues with
synchronization so that the cache data is correct at all times. If the
FCB is unique on a per-file basis, is there a way to get at it from the
FLT_CALLBACK_DATA structure? That would help address some of the
issues.
[Edouard A.]

Is that what you are looking for:

FSRTL_ADVANCED_FCB_HEADER *pMyFcb =
(FSRTL_ADVANCED_FCB_HEADER)FLT_CALLBACK_DATA.Iopb->TargetFileObject->FsConte
xt;

?

Edouard

Unless you are dealing with the paging file proper, you can do this with a
FLT_STREAM_CONTEXT


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply

“Edouard A.” wrote in message news:xxxxx@ntfsd…
>> Edouard,
>> This is sounds familiar :wink: I’m doing my stuff in a minifilter and
>> using FLT_CALLBACK_DATA.Iopb->TargetFileObject as the key into the hash
>> table (with linked list chaining) and the other data I need to download
>> the file as the value. The problem with this is that the TFO pointer
>> may be the same between two files provided the first has been closed
>> and
>> the second has been created. This presents some nasty issues with
>> synchronization so that the cache data is correct at all times. If the
>> FCB is unique on a per-file basis, is there a way to get at it from the
>> FLT_CALLBACK_DATA structure? That would help address some of the
>> issues.
> [Edouard A.]
>
> Is that what you are looking for:
>
> FSRTL_ADVANCED_FCB_HEADER *pMyFcb =
> (FSRTL_ADVANCED_FCB_HEADER)FLT_CALLBACK_DATA.Iopb->TargetFileObject->FsConte
> xt;
>
> ?
>
> –
>
> Edouard
>
>
>

Prane:

The FltObjects->FileObject->FileName is only valid during the create
(http://msdn2.microsoft.com/en-us/library/ms793823.aspx). I tried to go
down that path too *rueful grin*. If you only need the file name in the
preop callback, you could use FltGetFileNameInformation, with the caveat
that there has been a lot of discussion lately about this having risks
of its own. If you need to check the irp in the postop callback, you’ll
need to look at something else in the callbackdata, which is what lead
me to the TargetFileObject pointer.

Edouard:

Thanks, I totally missed that. Are you suggesting using the whole FCB
(hashed somehow, I assume) as the key, or some member of the FCB? I
haven’t looked at the header file (fcb.h >6000 lines, yikes!) in depth
yet, so if this is a dumb question feel free to say so and redirect me
to the code :wink:

~Eric

Edouard -
I don’t know if this is already answered, but it looks like you want to implement functionality similar to HSM filter drivers: a file is marked offline, sparsed, with no allocation. But on the first i/o you want to bring the contents back. Yes marking it with the bit is a good hint to explorer to suppress a bunch of i/o activity. A note of caution that not all applications and shell extensions honor the bit necessarily, but it can go a long way.

If that is indeed the case then you are seeing paging i/o’s before you see any top-level i/o’s from notepad because notepad memory maps the file. So notepad does not any i/o’s directly - but the memory manager will page in pages that are touched (directly) by notepad, and page out the pages that were dirtied.

Since trying to recall the file back at the time you see the mm paging i/o involves stepping through a minefield of deadlocks, a much simpler, safer alternative is to recall the file when the section is being created. Effectively - you are going to recall when the memory mapping section is created. Given that doesn’t happen unless there is intent to read/write, you hook the acquire for create section in your minifilter, and bring back the contents there as you would on a top-level non-paging read/write. Just make sure that you are cancellable there as well in the sense if the thread is being terminated, you would abort that operation.
Ravi


From: xxxxx@lists.osr.com [xxxxx@lists.osr.com] On Behalf Of Edouard A. [xxxxx@fausse.info]
Sent: Tuesday, September 18, 2007 11:00 AM
To: Windows File Systems Devs Interest List
Subject: RE: [ntfsd] paging i/o problem

Actually the problems with the CREATE flood was partially solved by
adding the FILE_ATTRIBUTE_OFFLINE on processing directory listing. This
way the file recieves creates only when it is opened for read (as far
as I can see although right click seems also to generate create some
times ). It deals with another big problem also: thumbnails - non are
generated this way you don’t have to download 700mb movie when someone
opens the directory.
Currently I am trying to capture the first read for the file, but I
only capture one create from notepad and many reading and writing
paging i/os but none in reference with the .txt file. Probably that is
because I have created it before that with zero size and the file is
already cached in which case I still havn’t found a way to find if it
is read from the cache. I am most probably doing something wrong. Can
someone direct me?
[Edouard A.]

That is because the PAGING IO may not occur on the same handle. A while ago (when I was young and crazy), I wrote a filter driver to cipher an arbitrary file (especially pagefile.sys) and I had that same problem.

The problem is that the OS may give you handles different from the one you have as it creates objects on his own. Every time you get a read/write request you need to check the FCB of the file and see if it matches one file you’re working on. If yes you need to add it to a structure in your driver that maintain the associations. This could be a hash table of list (std::hash_map>> to speak C++).

Don’t forget to remove the object from your association when it is closed, or you will have a leak as long as your driver is running.

Hope this answers your question.



Edouard A.


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars
(including our new fs mini-filter seminar) visit:
http://www.osr.com/seminars

You are currently subscribed to ntfsd as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

Thanks a lot for the answer but you’re talking to the wrong person. :stuck_out_tongue:

Le Tue, 18 Sep 2007 18:10:25 -0700, Ravi Pudipeddi
a ecrit:
> Edouard -
> I don’t know if this is already answered, but it looks like you want to
> implement functionality similar to HSM filter drivers: a file is marked
> offline, sparsed, with no allocation. But on the first i/o you want to
> bring the contents back. Yes marking it with the bit is a good hint to
> explorer to suppress a bunch of i/o activity. A note of caution that not
> all applications and shell extensions honor the bit necessarily, but it
> can go a long way.
>
> If that is indeed the case then you are seeing paging i/o’s before you
see
> any top-level i/o’s from notepad because notepad memory maps the file. So
> notepad does not any i/o’s directly - but the memory manager will page in
> pages that are touched (directly) by notepad, and page out the pages that
> were dirtied.
>
> Since trying to recall the file back at the time you see the mm paging
i/o
> involves stepping through a minefield of deadlocks, a much simpler, safer
> alternative is to recall the file when the section is being created.
> Effectively - you are going to recall when the memory mapping section is
> created. Given that doesn’t happen unless there is intent to read/write,
> you hook the acquire for create section in your minifilter, and bring
back
> the contents there as you would on a top-level non-paging read/write.
Just
> make sure that you are cancellable there as well in the sense if the
> thread is being terminated, you would abort that operation.
> Ravi
>
> ________________________________________
> From: xxxxx@lists.osr.com [xxxxx@lists.osr.com]
> On Behalf Of Edouard A. [xxxxx@fausse.info]
> Sent: Tuesday, September 18, 2007 11:00 AM
> To: Windows File Systems Devs Interest List
> Subject: RE: [ntfsd] paging i/o problem
>
>> Actually the problems with the CREATE flood was partially solved by
>> adding the FILE_ATTRIBUTE_OFFLINE on processing directory listing. This
>> way the file recieves creates only when it is opened for read (as far
>> as I can see although right click seems also to generate create some
>> times ). It deals with another big problem also: thumbnails - non are
>> generated this way you don’t have to download 700mb movie when someone
>> opens the directory.
>> Currently I am trying to capture the first read for the file, but I
>> only capture one create from notepad and many reading and writing
>> paging i/os but none in reference with the .txt file. Probably that is
>> because I have created it before that with zero size and the file is
>> already cached in which case I still havn’t found a way to find if it
>> is read from the cache. I am most probably doing something wrong. Can
>> someone direct me?
> [Edouard A.]
>
> That is because the PAGING IO may not occur on the same handle. A while
> ago (when I was young and crazy), I wrote a filter driver to cipher an
> arbitrary file (especially pagefile.sys) and I had that same problem.
>
> The problem is that the OS may give you handles different from the one
> you have as it creates objects on his own. Every time you get a
read/write
> request you need to check the FCB of the file and see if it matches one
> file you’re working on. If yes you need to add it to a structure in your
> driver that maintain the associations. This could be a hash table of list
> (std::hash_map>> to
> speak C++).
>
> Don’t forget to remove the object from your association when it is
closed,
> or you will have a leak as long as your driver is running.
>
> Hope this answers your question.
>
> –
>
> Edouard A.
>
>
> —
> NTFSD is sponsored by OSR
>
> For our schedule debugging and file system seminars
> (including our new fs mini-filter seminar) visit:
> http://www.osr.com/seminars
>
> You are currently subscribed to ntfsd as: unknown lmsubst tag argument:
‘’
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
> —
> NTFSD is sponsored by OSR
>
> For our schedule debugging and file system seminars
> (including our new fs mini-filter seminar) visit:
> http://www.osr.com/seminars
>
> You are currently subscribed to ntfsd as: unknown lmsubst tag argument:
‘’
> To unsubscribe send a blank email to xxxxx@lists.osr.com


EA

Le Tue, 18 Sep 2007 17:42:39 -0400, “Eric Diven”
a ecrit:

> Edouard:
>
> Thanks, I totally missed that. Are you suggesting using the whole FCB
> (hashed somehow, I assume) as the key, or some member of the FCB? I
> haven’t looked at the header file (fcb.h >6000 lines, yikes!) in depth
> yet, so if this is a dumb question feel free to say so and redirect me
> to the code :wink:

If I recall correctly the FCB pointer is enough to distinguish. Please
double check that different files indeed point to the same FCB block.

If not why not use the PFAST_MUTEX… I don’t think different FCB share the
same mutex…



EA

Thanks for all the replies, they were really. So for the problem with detecting the first paging i/o read I am using the code:

RtlZeroMemory( &fsFilterCallbacks,
sizeof(FS_FILTER_CALLBACKS) );

fsFilterCallbacks.SizeOfFsFilterCallbacks = sizeof( FS_FILTER_CALLBACKS );
fsFilterCallbacks.PreAcquireForSectionSynchronization = drvPreAcquireForSectionSynchronization;
/*
fsFilterCallbacks.PostAcquireForSectionSynchronization = NULL;
fsFilterCallbacks.PreReleaseForSectionSynchronization = NULL;
fsFilterCallbacks.PostReleaseForSectionSynchronization = NULL;
fsFilterCallbacks.PreAcquireForCcFlush = NULL;
fsFilterCallbacks.PostAcquireForCcFlush = NULL;
fsFilterCallbacks.PreReleaseForCcFlush = NULL;
fsFilterCallbacks.PostReleaseForCcFlush = NULL;
fsFilterCallbacks.PreAcquireForModifiedPageWriter = NULL;
fsFilterCallbacks.PostAcquireForModifiedPageWriter = NULL;
fsFilterCallbacks.PreReleaseForModifiedPageWriter = NULL;
fsFilterCallbacks.PostReleaseForModifiedPageWriter = NULL;
*/

DbgPrint(“Registering Filter driver callbacks”);
status = FsRtlRegisterFileSystemFilterCallbacks(DriverObject,&fsFilterCallbacks);
if (!NT_SUCCESS( status ))
{
DbgPrint(“FsRtlRegisterFileSystemFilterCallbacks fails”);
}
The function returns success, but I don’t receive any events. Any clue what I am doing wrong?

Quick question: does your callback registration occur in the DriverEntry of
your filter driver?

EA

Yes it is in DriverEntry since the documentation says it has to be there and the examples in the SDK say it has to be there could this be the problem? Since in another driver i had this kind of problem with a function that has to be called only outside DriverEntry

Le Fri, 21 Sep 2007 09:37:56 -0400 (EDT), xxxxx@abv.bg a ecrit:

Yes it is in DriverEntry since the documentation says it has to be there
and the examples in the SDK say it has to be there could this be the
problem? Since in another driver i had this kind of problem with a
function that has to be called only outside DriverEntry

On the contrary, I wanted to eliminate a trivial problem of mislocation.

When you place a breakpoint on your callback, you never stop, right?

EA