[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 348
  • Last Modified:

Question about GetOpenFileNameA API

In my application I hooked GetOpenFileNameA API expecting that the OpengFile dialog won't appear but returns with a desired filename. The application raises an error when calling this API, can anyone help me? Thank you.

uses madCodeHook
var
GetOpenFilenameANextHook: function (var OpenFile: TOpenFilenameA): Bool; stdcall;

HookAPI('Comdlg32.dll', 'GetOpenFileNameA',@myGetOpenFileNameA, @GetOpenFilenameANextHook);

function myGetOpenFileNameA(var OpenFile: TOpenFilenameA): Bool; stdcall;
var
szFile:PCHAR;
begin
  showmsg('HOoked');
  GetMem(szFile,260);
  ZeroMemory(szFile,260);
  szFile:='c:\1.txt';

  ZeroMemory(@OpenFile, sizeof(TOpenFilenameA));
  OpenFile.lStructSize := sizeof(TOpenFilenameA);
  OpenFile.hwndOwner := Hinstance;
  OpenFile.lpstrFile := szFile;
  OpenFile.nMaxFile := 260;
  OpenFile.lpstrFilter := pchar('All'#0'*.*'#0'Text'#0'*.TXT'#0);
  OpenFile.nFilterIndex := 1;
  OpenFile.lpstrFileTitle := nil;
  OpenFile.nMaxFileTitle := 0;
  OpenFile.lpstrInitialDir := nil;
  OpenFile.Flags := OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST;
  result:=true;
end;
0
klemperer
Asked:
klemperer
  • 9
  • 6
1 Solution
 
Slick812Commented:
I do not have time now to try and use the HookAPI of madCodeHook, but I can see some things in your code that do not seem right to me, I do not think that you need to do all of that code to place entries in the OpenFile record, aren't those entrys already there, you are doing this like you are going to do a regular call to create an Open dialog, aren't you intercepting the system call for GetOpenFileNameA( ) ? ?
I am guessing this may be more of the code needed, but I do NOT try and evaluate the Flags sent in and change anything -

function myGetOpenFileNameA(var OpenFile: TOpenFilenameA): Bool; stdcall;

begin
if OpenFile.nMaxFile > 8 then
  result := true
  else
  begin
  result := False;
  Exit;
  end;
  StrCopy(OpenFile.lpstrFile, 'c:\1.txt');
// I'm not sure if you have access to the memory at OpenFile.lpstrFile ?
// but I beleive you just need to return a result with the a change of the OpenFile.lpstrFile
 
end;
0
 
Slick812Commented:
what is it you are trying to do?
0
 
klempererAuthor Commented:
Thank you for your answer.
Consider an application with the following procedure: Click "Open File" button-->Open File Dialog appears-->Select a File and Click "OK"-->The application reads the file and adds its content to a listview

Now I would like to change its procedure as follows: Click "Open File" button-->The application reads the desired file "c:\1.txt" and adds its content to a listview.

So I wrote a dll and injected it into the application and HOOK GetOpenFilenameA API (The application calls GetOpenFilenameA to show an open file dialog).

The code is:

var
 GetOpenFilenameANextHook: function (var OpenFile: TOpenFilenameA): Bool; stdcall;

function myGetOpenFileNameA(var OpenFile: TOpenFilenameA): Bool; stdcall;
begin
  showmsg('HOoked');
  lstrcpy(OpenFile.lpstrFile,'c:\1.txt');
  result:=true;
end;

.......
HookAPI('Comdlg32.dll', 'GetOpenFileNameA',@myGetOpenFileNameA, @GetOpenFilenameANextHook);
......

Now the problem is, when I click on "open file" button, the "HOoked" dialog appears, but the content of desired file doesn't show in a listview.
I am quite puzzled now~
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
klempererAuthor Commented:
The hooking is process wide and won't intercept the system call for GetOpenFilenameA
0
 
Slick812Commented:
the system API  GetOpenFilenameA( ) is not so simple, it takes a complex record TOpenFilenameA with 20 members . . . and the Flags member can have more than 22 flag bits (even more for win 200 and XP), I would guess that the calling program requires more than just the OpenFile.lpstrFile  to be filled with the file name, you may need to set the  OpenFile.nFileOffset  or the  OpenFile.nFileExtension or maybe the  OpenFile.lpstrFileTitle                                                          ? ?. . .
 or maybe if it has a  OpenFile.lpfnHook it will need some dialog box input to confirm the acceptance of the file?,
you do not test for any of the flag bits, if I tested for them , I am not sure what to do for some of them like the  OFN_ENABLEHOOK

I am guessing that the file - 'c:\1.txt'  does exist, the program may check for it's existance, or may check for the folder location, or may check for many other things for a file path sent to it. . .
0
 
klempererAuthor Commented:
Sounds difficult. Now there are still two questions.
1. Can I spy the members of TOpenFilename while its open file dialog appears?

2. What if I let the open file dialog shows, then I PostMessage(Hinstance,WM_KEYDOWN,VK_RETURN,0) to return?

function myGetOpenFileNameA(var OpenFile: TOpenFilenameA): Bool; stdcall;
var
flag:boolean;
begin
   result:=GetOpenFilenameANextHook(OpenFile);
end;
0
 
klempererAuthor Commented:
The two functions below lead to different results?

function myGetOpenFileNameA(var OpenFile: TOpenFilenameA): Bool; stdcall;
var
flag:boolean;
begin
   flag:=GetOpenFilenameANextHook(OpenFile);
   result:=flag;
end;

function myGetOpenFileNameA(var OpenFile: TOpenFilenameA): Bool; stdcall;
begin
   result:=GetOpenFilenameANextHook(OpenFile);
end;
0
 
klempererAuthor Commented:
sorry, I have made a mistake--the difference between bool and boolean :)
0
 
Slick812Commented:
What I would do is to call the -
  GetOpenFilenameANextHook( )
in your  myGetOpenFileNameA( ), and then analize the returned   OpenFile  for the members and use this data to set your returned   OpenFile  members to reflect the data returned of  members in the  OpenFile   from the GetOpenFilenameANextHook, , , ,

is the  OFN_ENABLEHOOK  flag bit in the Flags of the sent  OpenFile  record ? if it does not have this it may be eaysier


function myGetOpenFileNameA(var OpenFile: TOpenFilenameA): Bool; stdcall;
begin
result:=GetOpenFilenameANextHook(OpenFile);
showmsg(IntToStr(OpenFile.Flags));
showmsg(IntToStr(Integer(OpenFile.lpstrFileTitle)));
//more OpenFile member data analysis
end;
0
 
klempererAuthor Commented:
I got the members.
The flags include:

OFN_HIDEREADONLY
OFN_ENABLEHOOK
OFN_PATHMUSTEXIST
OFN_FILEMUSTEXIST
OFN_EXPLORBER
OFN_SHATEWARN

including OFN_ENABLEHOOK. Sounds more difficulty now.

By the way, the result of  GetOpenFilenameANextHook(OpenFile) is a longbool variable with value "01 00 00 00".
If I didn't call GetOpenFilenameANextHook, How can I set a longbool variable with the value I just said?
0
 
Slick812Commented:
a BOOL value is just a 32 bit memory block used as a Boolean value, in Delphi you can just set a BOOL value to True or False, the compilier will know to set the value to cardinal 1 . . . which I beleive is   "01 00 00 00"  for true, if for some reason you need to use all four bytes, I believe you can typecate it to a Cardinal

Cardinal(Result) := 1; // true

you could test it with
if Cardinal(Result) = 1 then



since it has the OFN_ENABLEHOOK, there may be complications, it may read the user's seletions with the CDN_SELCHANGE notifycation message and do some internal data changes? or Not

0
 
klempererAuthor Commented:
//The following code got the desired result
var
flag:bool;
....
flag:=GetOpenFilenameANextHook(OpenFile);
if Cardinal(flag) = 1 then   //true
showmsg('True');
result:=flag;

//but the following code can't get the desired result
var
flag:bool;
....
flag:=GetOpenFilenameANextHook(OpenFile);
flag:=true;
if Cardinal(flag) = 1 then   //false
showmsg('True');
result:=flag;

0
 
Slick812Commented:
I do not know, I have used this code many many many times -

if GetOpenFileName(OFName) then
    Str1 := FileName;

and the GetOpenFileName( )  ( which calles the GetOpenFileNameA( ) ) will give a True result if the open dialog is not canceled, as far as I know
one is true and 0 is false, even in a normal Boolean (which just uses one Byte), the 32 bit Bool is more efficient 32 bit code and works faster, I have changed many of my Boolean to BOOL variables in my code
0
 
klempererAuthor Commented:
Well, while you use "if GetOpenFileName(OFName) then", the result will be auto type casted to boolean, and some bits will be lost.
0
 
klempererAuthor Commented:
I got it:)

integer(flag):=1;  //it works

Thank you for your help all the time:)
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 9
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now