Solved

Api / TypeCasting problem?

Posted on 2006-10-19
15
1,019 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
  • 8
  • 7
15 Comments
 
LVL 28

Expert Comment

by:ciuly
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 28

Expert Comment

by:ciuly
Comment Utility
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:
ciuly earned 500 total points
Comment Utility
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
Comment Utility
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
Comment Utility
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
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 28

Expert Comment

by:ciuly
Comment Utility
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
Comment Utility
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:ciuly
Comment Utility
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
Comment Utility
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:ciuly
Comment Utility
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
Comment Utility
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
Comment Utility
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:ciuly
Comment Utility
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

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Suggested Solutions

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

762 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now