Screen goes black upon receiving message from driver [using FilterGetMessage]?

Well i have made a simple minifilter driver that monitors filesystem
activity, and registry activity and reports it to a rudimentary usermode
application. This is the send message function:

NTSTATUS
SfSendMessage(
__in PCWSTR processID, __in PCWSTR action, __in PUNICODE_STRING fullPath,
__in PUNICODE_STRING name
)
{
NTSTATUS status;
PSF_MESSAGE message = NULL;
int count, totalCount = 0;

message = (PSF_MESSAGE)ExAllocatePoolWithTag(NonPagedPool,
sizeof(SF_MESSAGE), SF_USR_MSG_POOL_TAG);
if(message == NULL)
return STATUS_INSUFFICIENT_RESOURCES;

for(totalCount = 0; processID[totalCount] != ‘\0’; totalCount++)
message->Contents[totalCount] = processID[totalCount];

message->Contents[totalCount++] = ‘#’;

for(count = 0; action[count] != ‘\0’; count++, totalCount++)
message->Contents[totalCount] = action[count];

message->Contents[totalCount++] = ‘#’;

for(count = 0; count < ((fullPath->Length) / 2) ; count++, totalCount++)
message->Contents[totalCount] = fullPath->Buffer[count];

if((name != NULL) && ((action == keyValueCreated) ||
(action == keyValueDeleted) ||
(action == keyValueModified) ||
(action == keyRenamed)))
{
if(action == keyRenamed)
message->Contents[totalCount++] = ‘#’;
else
message->Contents[totalCount++] = ‘\’;

for(count = 0; count < ((name->Length) / 2); count++, totalCount++)
message->Contents[totalCount] = name->Buffer[count];
}

message->Contents[totalCount++] = ‘#’;
message->Contents[totalCount] = ‘\0’;

if(totalCount >= 1536)
{
ExFreePoolWithTag(message, SF_USR_MSG_POOL_TAG);
return STATUS_INSUFFICIENT_RESOURCES;
}

status = FltSendMessage(SfData.FilterHandle,
&SfData.ClientPort,
message,
sizeof(SF_MESSAGE),
NULL,
NULL,
NULL);
ExFreePoolWithTag(message, SF_USR_MSG_POOL_TAG);

return status;
}

This function has been called at various places, to report the relevant
filesystem and registry activity. Now this is the rudimentary code for the
user mode application, where it recieves these messages:

int __cdecl main()
{
HRESULT hr;
HANDLE hComPort;
PSIMPLE_MESSAGE MessageEnvelop = NULL;

MessageEnvelop = (PSIMPLE_MESSAGE)malloc(sizeof(SIMPLE_MESSAGE));

cout<<“Client waiting to connect to the filter…\n”;

do
{
hr = FilterConnectCommunicationPort(SimplePortName, 0, NULL, 0, NULL,
&hComPort);
}
while(IS_ERROR(hr));
cout<<“Connected successfully!\n”;

while(1)
{
hr = FilterGetMessage(hComPort, &MessageEnvelop->MessageHeader,
sizeof(SIMPLE_MESSAGE), NULL);
if(!IS_ERROR(hr))
printf(“%ls\n\n”, MessageEnvelop->Message.Contents);
}

getchar();
return 0;
}

As you can see, it is very basic and only for the purpose of testing. Now
the situation is that the code runs fine, the driver runs fine, my exact
specified filesystem and registry activity is reported just how i want it
to. The only problem occurs that whenever i run an application that asks
for admin privileges (UAC turned on; windows 7 32-bit), the screen goes
black. I have connected WinDbg to the target windows 7 instance on VMWare
that i am deploying this driver on, but it shows no signs of error or
anything. Anyhow so i narrowed down the cause of the problem to this line:

while(1)
{
hr = FilterGetMessage(hComPort, &MessageEnvelop->MessageHeader,
sizeof(SIMPLE_MESSAGE), NULL);
if(!IS_ERROR(hr))
printf(“%ls\n\n”, MessageEnvelop->Message.Contents); //this line
}

The printf statement to be precise, if i comment it out, the screen does
not go black/get stuck, upon running an application with admin privileges
and everything always runs fine, except for the fact that i can’t display
my the reports through the usermode application offcourse. Although i can
obviously print them to debug, and thus everything runs fine.

So here is the obvious question, what is wrong here? what am i doing wrong?
Is it that FilterGetMessage recieves a message, but it hasn’t actually
received a message, or received a correct message, so that when i try to
access MessageEnvelop->Message.Contents, or rather display it, the screen
goes black, and it gets stuck and i have to power off and restart the
VMWare instance. Even though that the driver is obviously running fine,
there are no signs of errors on WinDbg either. The problem lies with
receiving the message from the driver and then trying to display it. And
only happens when Admin access is attempted for ANY program on the system.

Kindly help me out with this!

Okay so first off, as it turns out this isn’t a ntfsd related problem as
i’ll explain below. Though when i originally posted the query i had no
idea. Still if someone has any knowledge of this please help me out. The
problem has to do with registry filtering/monitoring via a minifilter.

Well i digged a bit futher into it and i found that everytime admin
priveleges are requested, these registry key values are accessed and
modified/written to, in this exact order:

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-08002BE10318}\0000\ActiveMonitors

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-08002BE10318}\0000\VidPNSource0Flags

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-08002BE10318}\0000\VidPNSource0Width

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-08002BE10318}\0000\VidPNSource0Height

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-08002BE10318}\0000\VidPNSource0X

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-08002BE10318}\0000\VidPNSource0Y

The problem starts when the minifilter intercepts this registry operation,
“RegNtPreSetValueKey” for this particular key:

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-08002BE10318}\0000\VidPNSource0Flags

This key operation notification is unable to reach the user mode
application via the FilterGetMessage function. Instead the screen goes
black, and the rest of the 4 notifications are also not received by the
usermode application:

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-08002BE10318}\0000\VidPNSource0Width

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-08002BE10318}\0000\VidPNSource0Height

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-08002BE10318}\0000\VidPNSource0X

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-08002BE10318}\0000\VidPNSource0Y

I am assuming this has something to do with, when UAC is turned on and
admin privileges are requested, and the screen grays down a bit, and a
Yes/No dialogue is displayed in the middle. Probably has something to do
with graphics. I know this has drifted away from the ntfsd topic, but
still if anyone has a workaround, or an exact reason for why this is
happening please let me know. I could always check and set the VidPNSource
keys to be skipped, but that just seems like a hack and not an actual
solution.

Regards

On Tue, 12 Feb 2013 06:36:37 +0500, Muhammad Umair
wrote:

> Well i have made a simple minifilter driver that monitors filesystem
> activity, and registry activity and reports it to a rudimentary usermode
> application. This is the send message function:
>
> NTSTATUS
> SfSendMessage(
> in PCWSTR processID, in PCWSTR action, in PUNICODE_STRING fullPath,
>
in PUNICODE_STRING name
> )
> {
> NTSTATUS status;
> PSF_MESSAGE message = NULL;
> int count, totalCount = 0;
>
> message = (PSF_MESSAGE)ExAllocatePoolWithTag(NonPagedPool,
> sizeof(SF_MESSAGE), SF_USR_MSG_POOL_TAG);
> if(message == NULL)
> return STATUS_INSUFFICIENT_RESOURCES;
>
> for(totalCount = 0; processID[totalCount] != ‘\0’; totalCount++)
> message->Contents[totalCount] = processID[totalCount];
>
> message->Contents[totalCount++] = ‘#’;
>
> for(count = 0; action[count] != ‘\0’; count++, totalCount++)
> message->Contents[totalCount] = action[count];
>
> message->Contents[totalCount++] = ‘#’;
>
> for(count = 0; count < ((fullPath->Length) / 2) ; count++, totalCount++)
> message->Contents[totalCount] = fullPath->Buffer[count];
>
> if((name != NULL) && ((action == keyValueCreated) ||
> (action == keyValueDeleted) ||
> (action == keyValueModified) ||
> (action == keyRenamed)))
> {
> if(action == keyRenamed)
> message->Contents[totalCount++] = ‘#’;
> else
> message->Contents[totalCount++] = ‘\’;
>
> for(count = 0; count < ((name->Length) / 2); count++, totalCount++)
> message->Contents[totalCount] = name->Buffer[count];
> }
>
> message->Contents[totalCount++] = ‘#’;
> message->Contents[totalCount] = ‘\0’;
>
> if(totalCount >= 1536)
> {
> ExFreePoolWithTag(message, SF_USR_MSG_POOL_TAG);
> return STATUS_INSUFFICIENT_RESOURCES;
> }
>
> status = FltSendMessage(SfData.FilterHandle,
> &SfData.ClientPort,
> message,
> sizeof(SF_MESSAGE),
> NULL,
> NULL,
> NULL);
> ExFreePoolWithTag(message, SF_USR_MSG_POOL_TAG);
>
> return status;
> }
>
> This function has been called at various places, to report the relevant
> filesystem and registry activity. Now this is the rudimentary code for
> the
> user mode application, where it recieves these messages:
>
> int __cdecl main()
> {
> HRESULT hr;
> HANDLE hComPort;
> PSIMPLE_MESSAGE MessageEnvelop = NULL;
>
> MessageEnvelop = (PSIMPLE_MESSAGE)malloc(sizeof(SIMPLE_MESSAGE));
>
> cout<<“Client waiting to connect to the filter…\n”;
>
> do
> {
> hr = FilterConnectCommunicationPort(SimplePortName, 0, NULL, 0, NULL,
> &hComPort);
> }
> while(IS_ERROR(hr));
> cout<<“Connected successfully!\n”;
>
> while(1)
> {
> hr = FilterGetMessage(hComPort, &MessageEnvelop->MessageHeader,
> sizeof(SIMPLE_MESSAGE), NULL);
> if(!IS_ERROR(hr))
> printf(“%ls\n\n”, MessageEnvelop->Message.Contents);
> }
>
> getchar();
> return 0;
> }
>
> As you can see, it is very basic and only for the purpose of testing. Now
> the situation is that the code runs fine, the driver runs fine, my exact
> specified filesystem and registry activity is reported just how i want it
> to. The only problem occurs that whenever i run an application that asks
> for admin privileges (UAC turned on; windows 7 32-bit), the screen goes
> black. I have connected WinDbg to the target windows 7 instance on VMWare
> that i am deploying this driver on, but it shows no signs of error or
> anything. Anyhow so i narrowed down the cause of the problem to this
> line:
>
> while(1)
> {
> hr = FilterGetMessage(hComPort, &MessageEnvelop->MessageHeader,
> sizeof(SIMPLE_MESSAGE), NULL);
> if(!IS_ERROR(hr))
> printf(“%ls\n\n”, MessageEnvelop->Message.Contents); //this line
> }
>
> The printf statement to be precise, if i comment it out, the screen does
> not go black/get stuck, upon running an application with admin privileges
> and everything always runs fine, except for the fact that i can’t display
> my the reports through the usermode application offcourse. Although i can
> obviously print them to debug, and thus everything runs fine.
>
> So here is the obvious question, what is wrong here? what am i doing
> wrong?
> Is it that FilterGetMessage recieves a message, but it hasn’t actually
> received a message, or received a correct message, so that when i try to
> access MessageEnvelop->Message.Contents, or rather display it, the screen
> goes black, and it gets stuck and i have to power off and restart the
> VMWare instance. Even though that the driver is obviously running fine,
> there are no signs of errors on WinDbg either. The problem lies with
> receiving the message from the driver and then trying to display it. And
> only happens when Admin access is attempted for ANY program on the
> system.
>
> Kindly help me out with this!


Using Opera’s mail client: http://www.opera.com/mail/

Have you considered using an asynchronous messaging model? I would, for example, just build a message and stick it in a queue. KeInsertQueue works well, though I found the annotation in the WDK on Windows 8 is broken but easily fixed. Then have a thread or two that pick the messages out of the queue and send them to the user mode service. The only reason to stick with a synchronous model is if you need an answer back. FltSendMessage, however, cannot be used to send from completion routines (elevated IRQL) AND it blocks the calling thread until a UM thread picks up the message. Blocking kernel operations is best avoided when possible.

So using an asynchronous message queue, you wouldn’t be blocking things and you should be able to progress.

Tony
OSR

Thankyou so much for the help. I am having this problem now, and the thing
is that i have to get it done today, like in a few hours actually. Anyhow,
i tried to do like you said (i am new at this):

I prepare my message and queue it like so

typedef struct _SF_MESSAGE {
WCHAR Contents[1536];
LIST_ENTRY ListEntry;
} SF_MESSAGE, *PSF_MESSAGE;

NTSTATUS
DriverEntry(
__in PDRIVER_OBJECT DriverObject,
__in PUNICODE_STRING RegistryPath
)
{
.
.
.
messageQueue = (PRKQUEUE)ExAllocatePoolWithTag(NonPagedPool,
sizeof(KQUEUE), SF_QUEUE_TAG);
KeInitializeQueue(messageQueue, NULL);

InitializeObjectAttributes(&oa,
NULL,
OBJ_KERNEL_HANDLE,
NULL,
NULL);

status = PsCreateSystemThread(&messageQueueHandle, //Thread creation
THREAD_ALL_ACCESS,
&oa,
NULL,
NULL,
(PKSTART_ROUTINE)SfSendMessageThread,
messageQueue);
.
.
}

NTSTATUS
SfQueueMessage(
__in PCHAR processName, __in PCWSTR action, __in PUNICODE_STRING
fullPath, __in PUNICODE_STRING name
)
{
.
.
.
KeInsertQueue(messageQueue, &message->ListEntry);
.
}

And this is the message sending thread routine:

VOID
SfSendMessageThread(
__in PVOID queue
)
{
PSF_MESSAGE message;

for(;:wink:
{
DbgPrint(“ThreadWorking\n”);

message = (PSF_MESSAGE)KeRemoveQueue((PRKQUEUE)queue,
KernelMode,
0);

message = CONTAINING_RECORD(message, SF_MESSAGE, ListEntry);

if( !(((NTSTATUS)message) == STATUS_TIMEOUT ||
((NTSTATUS)message) == STATUS_USER_APC ||
((NTSTATUS)message) == STATUS_ABANDONED) )
{
FltSendMessage(SfData.FilterHandle,
&SfData.ClientPort,
message,
sizeof(SF_MESSAGE),
NULL,
NULL,
NULL);

ExFreePoolWithTag(message, SF_USR_MSG_POOL_TAG);
}

if(DriverShuttingDown)
return;
}
}

This is the driver unload routine:

NTSTATUS
SimpleUnload(
__in FLT_FILTER_UNLOAD_FLAGS Flags
)
{
.
.
.

DriverShuttingDown = TRUE;

while((message = (PSF_MESSAGE)KeRundownQueue(messageQueue)) != NULL)
{
message = CONTAINING_RECORD(message, SF_MESSAGE, ListEntry);
ExFreePoolWithTag(message, SF_USR_MSG_POOL_TAG);
}

ExFreePoolWithTag(messageQueue, SF_QUEUE_TAG);

.
.
}

but the problem is that now, the FltSendMessage function blocks, (even
though it has a valid message to send, i checked by setting breakpoints).
Its as if the user mode application is not picking up the message, even
though FilterGetMessage is set on a loop in the UM application like i
showed in the code in my previous posts. It picked up messages fine
before, but not even a single message is going through now. Does it have
something to do with the fact that FltSendMessage is being called on a
different thread, than the one in which the connection was initiated? …i
am kind of stumped, and have VERY few time on my hands right now.

What am i doing wrong here, what am i missing? Kindy help me out here

Regards,
Muhammad Umair.

On Tue, 12 Feb 2013 09:30:49 +0500, Tony Mason wrote:

> Have you considered using an asynchronous messaging model? I would, for
> example, just build a message and stick it in a queue. KeInsertQueue
> works well, though I found the annotation in the WDK on Windows 8 is
> broken but easily fixed. Then have a thread or two that pick the
> messages out of the queue and send them to the user mode service. The
> only reason to stick with a synchronous model is if you need an answer
> back. FltSendMessage, however, cannot be used to send from completion
> routines (elevated IRQL) AND it blocks the calling thread until a UM
> thread picks up the message. Blocking kernel operations is best avoided
> when possible.
>
> So using an asynchronous message queue, you wouldn’t be blocking things
> and you should be able to progress.
>
> Tony
> OSR
>


Using Opera’s mail client: http://www.opera.com/mail/

Okay so now i setup the connection to the UM application, in the same
thread as i am send the messages from, still no message is going through
and FltSendMessage just blocks. The code is:

VOID
SfSendMessageThread(
__in PVOID queue
)
{
PSF_MESSAGE message;
PSECURITY_DESCRIPTOR sd;
OBJECT_ATTRIBUTES oa;
UNICODE_STRING uniString;
NTSTATUS status;

const PCWSTR SimplePortName = L"\SimplePort";

RtlInitUnicodeString(&uniString, SimplePortName);

status = FltBuildDefaultSecurityDescriptor(&sd, FLT_PORT_ALL_ACCESS);

if(NT_SUCCESS(status))
{
InitializeObjectAttributes(&oa,
&uniString,
OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
NULL,
sd);

status = FltCreateCommunicationPort(SfData.FilterHandle,
&SfData.ServerPort,
&oa,
NULL,
SfPortConnect,
SfPortDisconnect,
NULL,
1);

FltFreeSecurityDescriptor(sd);

if(!NT_SUCCESS(status))
DbgPrint(“Could not create ComPort\n”);
else
DbgPrint(“ComPort created successfully\n”);

}

for(;:wink:
{

message = (PSF_MESSAGE)KeRemoveQueue((PRKQUEUE)queue,
KernelMode,
0);

message = CONTAINING_RECORD(message, SF_MESSAGE, ListEntry);

if( !(((NTSTATUS)message) == STATUS_TIMEOUT ||
((NTSTATUS)message) == STATUS_USER_APC ||
((NTSTATUS)message) == STATUS_ABANDONED) )
{
FltSendMessage(SfData.FilterHandle,
&SfData.ClientPort,
message,
sizeof(SF_MESSAGE),
NULL,
NULL,
NULL);

ExFreePoolWithTag(message, SF_USR_MSG_POOL_TAG);
}

if(DriverShuttingDown)
return;
}
}

What am i doing wrong here?

On Tue, 12 Feb 2013 09:30:49 +0500, Tony Mason wrote:

> Have you considered using an asynchronous messaging model? I would, for
> example, just build a message and stick it in a queue. KeInsertQueue
> works well, though I found the annotation in the WDK on Windows 8 is
> broken but easily fixed. Then have a thread or two that pick the
> messages out of the queue and send them to the user mode service. The
> only reason to stick with a synchronous model is if you need an answer
> back. FltSendMessage, however, cannot be used to send from completion
> routines (elevated IRQL) AND it blocks the calling thread until a UM
> thread picks up the message. Blocking kernel operations is best avoided
> when possible.
>
> So using an asynchronous message queue, you wouldn’t be blocking things
> and you should be able to progress.
>
> Tony
> OSR
>


Using Opera’s mail client: http://www.opera.com/mail/

I’m not sure what you’re doing wrong. Are you seeing a connection notify callback? I’ve used this technique successfully in the past, so there’s something specific about your implementation.

Perhaps others can see something.

Tony
OSR

Did you tried to analyse your driver by SDV (Static Driver Verifier from
WDK) and by Driver Verifier (verifier.exe)?
I haven’t read all of posted code, but I see some potential buffer overrun,
like testing “if(totalCount >= 1536)” after writing to buffer…
This one is probably not a direct cause of problems, but I would start with
this SDV and verifier.

You can also look for ‘scanner’ example in WDK, it uses filter
communication port, and on UM receiving messages are by IOCP.

Best regards,
Krystian Bigaj

“Krystian Bigaj” wrote in message
news:xxxxx@ntfsd…
>Did you tried to analyse your driver by SDV (Static Driver Verifier from
>WDK)

This is definitely a good suggestion in general, but unfortunately SDV does
not currently support analyzing file systems or file system filter drivers.
Hopefully this is addressed in the future as its usefulness has grown
exponentially in the Win 8 WDK (being able to launch it from within VS is a
beautiful thing).

Definitely Driver Verifier though and PREfast/OACR (Win7 WDK) or Code
Analysis (Win8 WDK) are worth checking.

-scott
OSR

“Krystian Bigaj” wrote in message
news:xxxxx@ntfsd…
Did you tried to analyse your driver by SDV (Static Driver Verifier from
WDK) and by Driver Verifier (verifier.exe)?
I haven’t read all of posted code, but I see some potential buffer overrun,
like testing “if(totalCount >= 1536)” after writing to buffer…
This one is probably not a direct cause of problems, but I would start with
this SDV and verifier.

You can also look for ‘scanner’ example in WDK, it uses filter communication
port, and on UM receiving messages are by IOCP.

Best regards,
Krystian Bigaj

I was thinking about PREfast/OACR (used it 3y ago), when I wrote about
the SDV (never used it :slight_smile:
I thought that they are same thing, but I was wrong, thanks!

http://www.osronline.com/showThread.CFM?link=112892

Best regards,
Krystian Bigaj

On 15 February 2013 15:47, Scott Noone wrote:

> “Krystian Bigaj” wrote in message
> news:xxxxx@ntfsd…
>
> Did you tried to analyse your driver by SDV (Static Driver Verifier from
>> WDK)
>>
>
> This is definitely a good suggestion in general, but unfortunately SDV
> does not currently support analyzing file systems or file system filter
> drivers. Hopefully this is addressed in the future as its usefulness has
> grown exponentially in the Win 8 WDK (being able to launch it from within
> VS is a beautiful thing).
>
> Definitely Driver Verifier though and PREfast/OACR (Win7 WDK) or Code
> Analysis (Win8 WDK) are worth checking.
>
> -scott
> OSR

I am so sorry for replying to this so late, i was away from the internet
so to speak. Actually i had to get it done that very same day, and what a
hectic day it was! …anyhow i did solve the problem, and yes it was
specific to my implementation. Anyhow, it all got to work fine in the end.
Thankyou so much for all your help everyone!

On Thu, 14 Feb 2013 19:50:37 +0500, Tony Mason wrote:

> I’m not sure what you’re doing wrong. Are you seeing a connection
> notify callback? I’ve used this technique successfully in the past, so
> there’s something specific about your implementation.
>
> Perhaps others can see something.
>
> Tony
> OSR
>
>


Using Opera’s mail client: http://www.opera.com/mail/

Can you share with us what the issue was so that if someone runs into the problem in the future we can suggest a corrective action?

Tony
OSR

Well, the solution was exactly what you had suggested actually, using an
asynchronous messaging model.

When admin privileges are requested while UAC is turned on, the screen
normally turns dim and the yes/no dialog box pops up. For this purpose,
the OS modifies some registry key values with the “VidPN” prefix (along
with the ActiveMonitors one). These keys to be exact:

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-080
02BE10318}\0000\ActiveMonitors

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-080
02BE10318}\0000\VidPNSource0Flags

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-080
02BE10318}\0000\VidPNSource0Width

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-080
02BE10318}\0000\VidPNSource0Height

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-080
02BE10318}\0000\VidPNSource0X

\REGISTRY\MACHINE\SYSTEM\ControlSet001\Control\Class{4D36E968-E325-11CE-BFC1-080
02BE10318}\0000\VidPNSource0Y

I don’t know their exact purpose, but they have something to do with the
GPU/VGA device drivers. Anyhow, so basically the driver was filtering
“RegNtPreSetValueKey”. Now in the callback, a message was being sent to
the usermode application. The usermode application was recieving the
message like so:

for(;:wink:
{
hr = FilterGetMessage(hComPort, &MessageEnvelop->MessageHeader,
sizeof(SIMPLE_MESSAGE), NULL);
if(!IS_ERROR(hr))
printf(“%ls\n\n”, MessageEnvelop->Message.Contents);
}

This made the screen go black, whenever the yes/no dialog box with the
gray/dim background was supposed to pop up. And the “black screen”
problem/error went away if i changed the code in the UM application from
above to:

for(;:wink:
{
hr = FilterGetMessage(hComPort, &MessageEnvelop->MessageHeader,
sizeof(SIMPLE_MESSAGE), NULL);
}

So basically, the screen goes black, because of the small delay from the
first FilterGetMessage call to the next FilterGetMessage call, caused by
the UM application executing the printf statment. The VidPN keys are not
all modified at the exact moment that they are required to (probably by
the GPU/VGA driver), because FltSendMessage is blocking the registry
operation, while the UM application is executing the printf. (Although i
must say that this is just my amateur opinion)

Anyhow, thus removing the printf statement “temporarily” fixed the
problem. And using the asynchronous messaging model that you suggested,
permanently fixed the problem.

Now, the second problem, (of the message not going through to the UM
application using the asynchronous model) was actually my carelessness
(time constraint made me rush the code). I did everything right, only that
while modifying the code to send messages asynchronously, i forgot to
change the message structure of the UM application to match that of the
driver.

Driver message structure:

typedef struct _SF_MESSAGE {
WCHAR Contents[1536];
LIST_ENTRY ListEntry;
} SF_MESSAGE, *PSF_MESSAGE;

UM application message structure:

typedef struct _SF_MESSAGE {
WCHAR Contents[1536];
} SF_MESSAGE, *PSF_MESSAGE;

I hadn’t used a single common header file for both the driver and the UM
application, so there you go. The structures being different is the reason
the UM application wasn’t receiving the messages that were being sent from
the driver.

Anyhow, i apologize for my carelessness and once again thankyou all for
your help!

Regards,
Muhammad Umair.

On Sun, 24 Feb 2013 01:49:04 +0500, Tony Mason wrote:

> Can you share with us what the issue was so that if someone runs into
> the problem in the future we can suggest a corrective action?
>
> Tony
> OSR
>
>


Using Opera’s mail client: http://www.opera.com/mail/