3

When using the following line code in Delphi 2010, a'm getting an "Access Violation" error, but the same code working fine in VC++.

The Delphi 2010 code is

var
  hMyInf : HINF;
begin
hMyInf := SetupOpenInfFile('.\\DIGIMHID.INF','Mouse', INF_STYLE_WIN4,Nil);

The VC++ code is

hMyInf = SetupOpenInfFile(".\\DigimHID.inf", "Mouse", INF_STYLE_WIN4, NULL);

Please help me to solve this issue. Thanks All.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Able Alias
  • 3,824
  • 11
  • 58
  • 87
  • Show the Delphi declaration of SetupOpenInfFile. – kludg Feb 13 '11 at 08:06
  • `TSetupOpenInfFileW = function(const FileName: PWideChar; const InfClass: PWideChar; InfStyle: DWORD; ErrorLine: PUINT): HINF; stdcall;` – Able Alias Feb 13 '11 at 08:11
  • 1
    One issue's with the double-backslash in the Delphi call: The C++ version uses that to escape the `\` so the final text only contains one; The Delphi version doesn't use '\' as an escape char, so you actually get two backslashes. But that's usually not a problem, apparently Windows tolerates that; Even if it didn't, the error would not be an AV. Where did you find that TSetupOpenInfFileW definition? I wanted to try your code, but I can't find it. – Cosmin Prund Feb 13 '11 at 08:20
  • The above is not enough - I don't see an error. Show the Delphi code example that can be compiled. – kludg Feb 13 '11 at 08:23
  • Since you're getting an AV I suspect the invalid memory access is done on the Delphi side (before control is passed to the `SetupOpeninfFile` routine); Based on your declaration I suspect `SetupOpenInfFile` is not a simple imported method, it's an function pointer and it's not initialized. Put this before your function call: `if not Assigned(SetupOpenInfFile) then raise Exception.Create('It''s a function pointer and it''s not initialized');`. If the exception is raized do a search for the function name in the unit you're using, look for assignments. You probably need to call something to init. – Cosmin Prund Feb 13 '11 at 08:23
  • this code is from "SetupApi.pas" providing by Project JEDI – Able Alias Feb 13 '11 at 08:29

2 Answers2

4

Call LoadSetupAPI before using any methods in the SetupAPI.pas

Edit, to provide some background: As simultaneously wrote by David in his answer and by me in my comment, the error is probably caused by calling an uninitialized method pointer. For me the first tip was the error message, an Access Violation: If the equivalent of an Access Violation came from Windows itself, it'd be called a Runtime Error 216. The code is very simple, only uses constants and a method call. Constants can't generate AV's so the error had to come from the method itself, or from calling the method.

Since the Delphi declaration supplied showed a "function type", I suspected SetupOpenInfFile is actually an method pointer, not an import method. Those pointers need to somehow be initialized. Searching SetupAPI.pas (thanks google for providing a link, because I don't use JEDI libraries) I quickly found that it's being assigned from LoadSetupAPI. My first thought: isn't LoadSetupAPI called from the initialization section? It's not, so it needs to be called from code. Problem solved.

Cosmin Prund
  • 25,498
  • 2
  • 60
  • 104
  • +1 That's going to get the job done!! I'd assumed that would be done by `initialization` section - don't have much experience of the JEDI code. – David Heffernan Feb 13 '11 at 08:47
  • Thanks All, I just call `LoadSetupAPI` function just before calling the `SetupOpenInfFile`. Now its working fine. It was method pointer issue. Thanks a lot my friends. – Able Alias Feb 13 '11 at 08:52
  • @David, I don't juse any JEDI units; I googled the code, search the function name and noticed it's assigned from `LoadSetupAPI`. Nothing is called from the Initialization section and there's also an `UnloadSetupAPI` method, maybe the JEDI guys had a reason not to call `LoadSetupAPI` from initialization. – Cosmin Prund Feb 13 '11 at 08:52
  • @Cosmin I guess the reasoning is to allow the caller the option of never calling it. – David Heffernan Feb 13 '11 at 08:54
  • @Able Please accept the answer!! You have not accepted any answers yet on Stack Overflow! That feels a little ungrateful to us. – David Heffernan Feb 13 '11 at 09:04
  • @David, Able asked 5 questions: 2 have 0 answers, 1 was closed, 1 has a good answer but Able left a comment stipulating it's not solving his problem, and then there's this question. In my opinion he's not abusing SO, since this is the first time he actually *should* tick the answer mark. – Cosmin Prund Feb 13 '11 at 09:13
  • @Cosmin @Able Sorry, my mistake. Now I see you have accepted this answer so I am suitably placated! For what it's worth, doing it with implicit linking the way I suggest is cleaner but even if you do it that way please leave the accept with Cosmin! – David Heffernan Feb 13 '11 at 09:23
2

Your filename is wrong in the Delphi version. You don't escape \ in Delphi, a single one will do. But that wouldn't lead to an access violation.

My guess is that your GetProcAddress call is failing. But that is a guess. I'd like to see more code and the full error message.

EDIT

It seems that we were on the right track. Cosmin's answer will solve the problem for you. An alternative would be to switch to inplicit linking by removing the definition of the condition SETUPAPI_LINKONREQUEST in SetupApi.pas.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490