Solved

Api / TypeCasting problem?

Posted on 2006-10-19
15
1,039 Views
Last Modified: 2012-05-05
Hi all,

Still stuggling along here in Delphi; hoping someone could help me get the usage of the api
FilterReplyMessage working... I can use it with no problem in C; just can't get it right in
Delphi.

In the WDK(formally known as the DDK), this function is prototyped as follows:

        HRESULT
        WINAPI
        FilterReplyMessage(
          IN HANDLE  hPort,
          IN PFILTER_REPLY_HEADER  lpReplyBuffer,
          IN DWORD  dwReplyBufferSize
        );

In C, this function works fine for me, below is how I call it:

        hr = FilterReplyMessage( hPort,
                                 (PFILTER_REPLY_HEADER) &replyMessage, //<-notice the typecast
                                 sizeof( replyMessage ) );

replyMessage is a seperate structure that contains my own data along with a FILTER_REPLY_HEADER
with the correct fields initiallized.

However, in Delphi I'm not having any luck.... Here is how I prototyped the function:
---

function FilterReplyMessage(hPort: THANDLE; lpReplyBuffer: Pointer; dwReplyBufferSize: DWORD):HRESULT; stdcall; external 'fltlib.dll';
---
And within a thread I created, I'm doing this:
--------------------------------------------------------------------------------------------------------------------------------------
var
  msg: ^Filter_Message;
  replyMessage: ^Filter_Reply_Message;
  replySize: Integer;

Begin

Repeat
Getmem(msg, 600); //<-more than enough
GetMem(replyMessage, 400);

errr := FilterGetMessage(hPort, @msg.MessageHeader, 600, nil); //<-success
ShowMessage(msg.Notification.filename);  //<-displays name of file attempting to be opened

replyMessage.ReplyHeader.Status := 0;
replyMessage.ReplyHeader.MessageId := msg.MessageHeader.MessageId;
replyMessage.Reply.SafeToOpen := False;

replySize := sizeof(@replyMessage);

errr := FilterReplyMessage(hPort, @replyMessage.ReplyHeader, replySize); //<-thinking problem, I don't think I //can typecast in Delphi like above in C

FreeMem(msg);
FreeMem(replyMessage);

until False;
end;
-----------------------------------------------------------------------------------------------

So what do I need to do too make this work? I'm able too open a communication port with the driver
and send and receive messages, I just can't reply too them.... Stepping threw with a kernel debugger,
I see nothing is being received, and since I'm using synchronous IO and fltSendMessage blocks untill
it receives a reply (timeout set too NULL) - I'm having some lovely hangs here.

This function wants a pointer too a caller allocated buffer, and I 'think' I've done this right...
I'm thinking since I'm not typecasting above, fltmgr doesn't read the struct correctly. Am I right in
assuming this is the problem, and if so, how do I fix this?

Thanks and sorry for such a novice question.

m.

[function link]

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IFSK_r/hh/IFSK_r/FltWin32ApiRef_f89f529e-8396-4f15-ae63-6497c92aab1a.xml.asp
0
Comment
Question by:mugman21
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 7
15 Comments
 
LVL 28

Expert Comment

by:2266180
ID: 17764758
actually, the problem lies here:
replySize := sizeof(@replyMessage);
so replace it with
replySize := sizeof(Filter_Reply_Message);
because sizeof(@replyMessage) will return sizeof pointer. you don't want that.
also replyMessage is already a  pointer so there is no need for the "@".
0
 
LVL 8

Author Comment

by:mugman21
ID: 17765495
Right, I have no idea what I was thinking with the sizeof thing....

I'm still not able to get this too work... It feels like I've called this function in every concievable way, I've been
trying all night, and a part of last night....

If you were trying too call this function, how would you prototype it? How would you call it?

I'd be very grateful if you could show me how this is done, I'm beyond fustrated.

Thanks for pointing out my errors so far.

m.



0
 
LVL 8

Author Comment

by:mugman21
ID: 17765513
If you, or anyone  else could give it a shot, here are the structs I've ported over.

//Filter Manager's structs
type
  FILTER_MESSAGE_HEADER = record

  ReplyLength: ULONG;
  MessageId: Int64;
end;

type
  FILTER_REPLY_HEADER = record
  Status: LongInt;
  MessageId: Int64;
end;

//My Structs

type FILTER_NOTIFICATION = record
    filename: Array[0..255] of widechar;
end;

type FILTER_REPLY = record
   SafeToOpen: Boolean;
end;

type  FILTER_MESSAGE = record
    MessageHeader: FILTER_MESSAGE_HEADER;
    Notification: FILTER_NOTIFICATION;
end;

type FILTER_REPLY_MESSAGE = record
    ReplyHeader: FILTER_REPLY_HEADER ;
    Reply: FILTER_REPLY;
end;
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 28

Expert Comment

by:2266180
ID: 17765545
well, for starters I would preserve the api prototype, though that shouldn't make any difference since both prototypes assume a pointer in the middle parameter.
then, I would definetly check the err vaule and see in teh documentation what it means. after that, it's just about getting the problem solved, since usually err will hold the problem.
so  my suggestion is see hwat does err hold. if it holds success, then there is no coding error,but maybe a logical error or attention error :)
0
 
LVL 28

Accepted Solution

by:
2266180 earned 500 total points
ID: 17765563
can you also post the C ones? because at frist glance I see
type FILTER_REPLY = record
   SafeToOpen: Boolean;
end;
and from my experience this would be a longbool. (boolean is byte)
0
 
LVL 8

Author Comment

by:mugman21
ID: 17765893
typedef struct _FILTER_MESSAGE_HEADER {

    //
    //  OUT
    //
    //  Total buffer length in bytes, including the FILTER_REPLY_HEADER, of
    //  the expected reply.  If no reply is expected, 0 is returned.
    //

    ULONG ReplyLength;

    //
    //  OUT
    //
    //  Unique Id for this message.  This will be set when the kernel message
    //  satifies this FilterGetMessage or FilterInstanceGetMessage request.
    //  If replying to this message, this is the MessageId that should be used.
    //

    ULONGLONG MessageId;

    //
    //  General filter-specific buffer data follows...
    //

} FILTER_MESSAGE_HEADER, *PFILTER_MESSAGE_HEADER;

typedef struct _FILTER_REPLY_HEADER {

    //
    //  IN.
    //
    //  Status of this reply. This status will be returned back to the filter
    //  driver who is waiting for a reply.
    //

    NTSTATUS Status;

    //
    //  IN
    //
    //  Unique Id for this message.  This id was returned in the
    //  FILTER_MESSAGE_HEADER from the kernel message to which we are replying.
    //

    ULONGLONG MessageId;

    //
    //  General filter-specific buffer data follows...
    //

} FILTER_REPLY_HEADER, *PFILTER_REPLY_HEADER;


typedef struct _FILTER_NOTIFICATION {
    WCHAR filename[255];
} FILTER_NOTIFICATION, *PFILTER_NOTIFICATION;

typedef struct _FILTER_REPLY {
    BOOLEAN SafeToOpen;  
} FILTER_REPLY, *PFILTER_REPLY;

typedef struct _FILTER_MESSAGE {
    FILTER_MESSAGE_HEADER MessageHeader;
    FILTER_NOTIFICATION Notification;
} FILTER_MESSAGE, *PFILTER_MESSAGE;

typedef struct _FILTER_REPLY_MESSAGE {
    FILTER_REPLY_HEADER ReplyHeader;
    FILTER_REPLY Reply;
} FILTER_REPLY_MESSAGE, *PFILTER_REPLY_MESSAGE;






0
 
LVL 8

Author Comment

by:mugman21
ID: 17765947
In the driver I'm getting a 0x80000005 (buffer overflow) and in the app I'm getting -2147024662 which from what I can tell, is 'more data avaliable'... Like that makes a lot of sense.
0
 
LVL 28

Expert Comment

by:2266180
ID: 17766149
I think I know where the problem lies.

in C you call the function with
(PFILTER_REPLY_HEADER) &replyMessag

and I assuem that replyMessage is of type FILTER_REPLY_MESSAGE
what happens. you need that cast because that is how the function prototype is written so the cast makes sure that the code compiles. what happens behind it?
well, the replyMessage consisting of a header and a reply, in this exact order, can be casted to a header only and it will seem that only the header is passed on, BUT, the function knows that after teh header there is a reply, because that is what is expecting.

so that is what you need to do in delphi as well: pass the reference to the header, and not the reply itself.
so the following shoudl work:
errr := FilterReplyMessage(hPort, @replyMessage, replySize);
0
 
LVL 8

Author Comment

by:mugman21
ID: 17766393
Sorry, tried that already...Just tried it again. That gives an err code of 2145452000 which I can't find a def for...

m.



0
 
LVL 28

Expert Comment

by:2266180
ID: 17766473
I have to leave the office now.

can you post a complete test app for me? I never played with this thing before and don't want to waste time tryint to figure out how na dhwich functions to call ;)

I will get back to you in about 3-4 hours

btwm I'm on winxp SP1. hope that it's ok.
0
 
LVL 8

Author Comment

by:mugman21
ID: 17766608
I also have too go, need a little sleep.

Regarding a test app, fltmgr requires w2k sp4 roll-up 1, xp sp2, srv'03 sp1 or vista/longhorn. The second two have the same kernel.... :-) amazing what people pay for...

Second, if you still want too play with it, I hope you have a test machine. Although this driver hasn't yet blown up my file system, I can't make any promises about yours.  

m.
0
 
LVL 28

Expert Comment

by:2266180
ID: 17769540
I see. I have some virtual machines at the office, not exactly sure which OS though. guess you can post a small test app and I'll see if I can make ti work.
0
 
LVL 8

Author Comment

by:mugman21
ID: 17773243
ok... The source of the problem seems too be buffer alignment. With all records packed, the message gets too the filter 90% of the time, and I get a nice access denied error on the file I was trying too open. This is correct...

about 10% of the time, the filter does not interpret the FALSE flag I'm sending it telling it to deny access too the file; it gets garbage instead. This keeps happening with the same files. The only files this filter looks at are ones with the .txt extension.

With all records packed, now the message received in the app that uses ShowMessage wont display, however I can see the filename and volume guid in the string.

Still not 100%, but I'm pretty sure I'm on the right track now.

m.

 
0
 
LVL 8

Author Comment

by:mugman21
ID: 17787805
ciuly,

Just want to say thank you for your time and attentiveness the other morning. I've finally solved the problem, it was indeed a misaligned buffer. I'm now having 100% success in allowing and denying file access while using a delphi app to control the filter.

Thanks again,

m.



 
0
 
LVL 28

Expert Comment

by:2266180
ID: 17787811
glad you solved it.
can you also post which buffer was not aligned correctly and how it should have been? it will probably help others in the future ;)
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…

729 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question