[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Api / TypeCasting problem?

Posted on 2006-10-19
15
Medium Priority
?
1,061 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
Technology Partners: 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 2000 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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Suggested Courses

650 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