Entwickler-Ecke

Windows API - SQLGetInstalledDrivers in Delphi


OlafSt - Mi 13.06.18 13:35
Titel: SQLGetInstalledDrivers in Delphi
Hallo Freunde,

ich versuche gerade, die Liste an installierten ODBC-Treibern auszulesen. Dazu gibt es in ODBCCP32.DLL die prima Routine

BOOL SQLGetInstalledDrivers(
LPTSTR lpszBuf,
WORD cbBufMax,
WORD * pcbBufOut);

Meine Delphi-Übersetzung:

Delphi-Quelltext
1:
function SQLGetInstalledDriversW(lpszBuf:PChar; cbufMax: word; pcbBufOut: PWord): boolean; external 'ODBCCP32.DLL';                    


Rufe ich das nun auf, gibt es einen Stack Overflow:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
var
   Buf: string;
   Res: Word;
begin
     Setlength(Buf, 2000);
     Res:=0;
     SQLGetInstalledDriversW(PChar(Buf), 2000, Res);
end;

Auch wenn ich @Res als letzten Parameter nehme, wenn ich PAnsiChar verwende etcpp... Stets gibts einen Stack Overflow.

Was mache ich falsch ?


jasocul - Mi 13.06.18 13:56

Zunächst muss noch stdcall eingebaut werden:

Delphi-Quelltext
1:
function SQLGetInstalledDriversW(lpszBuf:PChar; cbufMax: word; pcbBufOut: PWord): boolean; stdcallexternal 'ODBCCP32.DLL';                    

Danach wie folgt:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var
   Buf: PChar; //string;
   Res: Cardinal;
begin
  GetMem(Buf, 2000);
  Res:=0;
  SQLGetInstalledDriversW(Buf, 2000, @Res);


Delete - Do 14.06.18 01:28

- Nachträglich durch die Entwickler-Ecke gelöscht -


jasocul - Do 14.06.18 09:31

Sehr interessant, dass es SQLGetInstalledDriversW nicht geben soll.
Ich frage mich dann, wieso mein Beispiel-Code ein sinnvolles Ergebnis geliefert hat.


OlafSt - Do 14.06.18 15:51

SQLGetInstalledDrivers() liefert die Ergebnisse als AnsiChar zurück. Für Unicode wurde dann SQLGetInstalledDriversW() dazugefügt.

Darum bekam ich auch bei @Frühlingsrolle's Beispiel einen Haufen chinesische Zeichen zurück, die keinen Sinn ergaben (ja, ich kann das in begrenztem Umfang lesen). An sich hatte ich es schon fast, auf das stdcall; kam ich nur nicht.

Das ganze sieht also fertig so aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
uses Winapi.Windows, Vcl.Dialogs, System.SysUtils;

function SQLGetInstalledDriversW(lpszBuf:PChar; cbufMax: word; pcbBufOut: PWord): boolean; stdcallexternal 'ODBCCP32.DLL';

procedure GetODBCDriver;
var
   Buf: array[0..2000of Char;
   bufSize: word;
   Res: Cardinal;
begin
     ZeroMemory(@buf, Length(buf));
     bufSize:=0;
     SQLGetInstalledDriversW(@Buf, Length(buf), @bufSize);
     ShowMessage(IntToStr(bufSize));
     ShowMessage(buf);
end;


Das ganze liefert eine Liste der installierten ODBC-Treiber zurück. Jeder ODBC-Treibername ist mit einem 0-Byte abgeschlossen, das Ende der Liste mit zwei 0-Bytes in Folge. Ergo wird MAXPATH, das IIRC 260 beträgt, bei weitem nicht reichen (ich habe hier bereits 844 Bytes).

Aber: Frage beantwortet, danke für die Hilfe !


Delete - Do 14.06.18 19:31

- Nachträglich durch die Entwickler-Ecke gelöscht -


jasocul - Fr 15.06.18 07:26

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
In der Doku steht nichts über eine Unicode Version (SQLGetInstalledDriversW)! Und explizit danach gesucht, komm ich auf kein Suchergebnis! Daher bin ich ausgegangen, dass es diese Funktion nicht gibt. Verlinkt sie mir, solltet ihr sie finden.

In der MSDN-Doku kann ich auch nichts dazu finden. Aber Tante Google spuckt einiges dazu aus.


Delete - Fr 15.06.18 15:10

- Nachträglich durch die Entwickler-Ecke gelöscht -


jasocul - Mo 18.06.18 07:21

Ich glaube, du bist schon groß und kannst das ganz alleine.
Aber zwei kleine Tipps:
1. "Meintest Du: SQLGetInstalledDrivers" ignorieren.
2. Bei den Ergebnissen nicht nur die Überschriften lesen.


Delete - Mo 18.06.18 08:53

- Nachträglich durch die Entwickler-Ecke gelöscht -


jasocul - Mo 18.06.18 09:11

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
welches ungleich diesem Topic entspricht.

Meinst du, weil das Topic "SQLGetInstalledDrivers in Delphi" heißt?
Ich habe mich halt eher an den Source im ersten Beitrag gehalten. Dort geht es dann doch um SQLGetInstalledDriversW.
Aber hier mal ein Link, der sich mit der WideChar-Variante auseinandersetzt:
https://www.pinvoke.net/default.aspx/odbccp32.SQLGetInstalledDriversW
Das war übrigens der erste Treffer in der Liste.