Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to make undocumented API Calls

Status
Not open for further replies.

sggaunt

Programmer
Jul 4, 2001
8,620
GB
Can anyone make this work in Delphi ??

This Extract from
PCPLUS magazine May 2000 Dave Jewel, C++ Workshop 'How to make undocumented API calls'

Use of GetProcAddress
Unfortunately the import libraries supplied with C++ (or Delphi sgg) don't contain entries for the undocumented API calls and that's why we need to make use of GetProcAddress, enabling us to track down the unwanted routine for ourselves. As you will probably realise, most of the routines exported from a DLL are exported by name, in other words you only need the name of the target routine to in order to retrieve its address using getprocaddress. However Microsoft was a little sneaky when it came to implementing the undocumented API routines, rather than exporting these routine by name, they are exported by ordinal, in other words by number.
Most of the time when you see other programmers using getprocaddress they will pass a routine by name as the second parameter. This won't work for us because the routines we want are only accessible by number.
But how to pass a number to a routine that expects a string,? This is when we use another classic programmers trick in the shape of MAKEINTRESOURCE macro This enable us to take the number (62 in the case of PickIconDlg) and transmogrify it into a form which the C++ compiler will accept as a number.
You will also notice that the routine address returned from GetProcAddress has to be cast into to the procedural type that we want to work with - in this case PICKICONDLGPROC If we don't do this the compiler will complain that it cannot convert from one procedural type to another.

Steve.
 
Can you not just look up the entry point using an application such as Dependancy Walker, for example

in Shell32.dll

Ordinal = 62 (0x003E)
EntryPoint = 0x00065574

Ordinal = 98 (0x0062)
EntryPoint = 0x00077E13


X-)
Billy H

bhogar@acxiom.co.uk
 
Steve:

I dont know if this will help you, but here are two fuctions that do the same thing - with one difference the first function access the the Shell32 method via its function name the second access the same function via the ordinal.


Ordinal = 235 (0x00EB)
Function = SHAddToRecentDocs


Code:
procedure TForm1.Button1Click(Sender: TObject);
const
  SHARD_PIDL = 1;
  SHARD_PATH = 2;
type
   TSHAddToRecentDocs = function (Wnd: HWND;LPCTSTR: PChar): integer; stdcall;
var
   SHAddToRecentDocs: TSHAddToRecentDocs;
   LibHandle: THandle;
begin
   LibHandle := LoadLibrary(PChar('Shell32.dll'));
   if LibHandle <> 0 then
      @SHAddToRecentDocs := GetProcAddress(LibHandle, 'SHAddToRecentDocs')
   else
   begin
      MessageDlg('Failed to load Shell32.dll.', mtError, [mbOK], 0);
      Exit;
   end;
   if @SHAddToRecentDocs <> nil then
   SHAddToRecentDocs(SHARD_PATH,'C:\MyDocs\report.txt');
   FreeLibrary(LibHandle);
    @SHAddToRecentDocs := nil;
end;


procedure TForm1.Button2Click(Sender: TObject);
const
  SHARD_PIDL = 1;
  SHARD_PATH = 2;
type
   TSHAddToRecentDocs = function (Wnd: HWND;LPCTSTR: PChar): integer; stdcall;
var
   SHAddToRecentDocs: TSHAddToRecentDocs;
   LibHandle: THandle;
begin
   LibHandle := LoadLibrary(PChar('Shell32.dll'));
   if LibHandle <> 0 then
      @SHAddToRecentDocs := GetProcAddress(LibHandle, pchar(235))
   else
   begin
      MessageDlg('Failed to load Shell32.dll.', mtError, [mbOK], 0);
      Exit;
   end;
   if @SHAddToRecentDocs <> nil then
   SHAddToRecentDocs(SHARD_PATH,'C:\MyDocs\report2.txt');
   FreeLibrary(LibHandle);
    @SHAddToRecentDocs := nil;
end;
Billy H

bhogar@acxiom.co.uk
 
Will
My original code conversion (from C++ Builder)was not unlike
the second example you give.
However, some tweaking to bring my code into line with this still results in an unholy crash.
So I am giving up on this one.
It was just an attempt on my part to prove that what ever can be done in Builder can be done in Delphi (I still belive this).
anyway as you say you can duplicate the icon picker dialog using a draw grid.

Thanks for bearing with me on this one.
Steve ....
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top