Autor Beitrag
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Mi 13.06.18 13:35 
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:
ausblenden 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:

ausblenden 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 ?

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mi 13.06.18 13:56 
Zunächst muss noch stdcall eingebaut werden:
ausblenden Delphi-Quelltext
1:
function SQLGetInstalledDriversW(lpszBuf:PChar; cbufMax: word; pcbBufOut: PWord): boolean; stdcallexternal 'ODBCCP32.DLL';					

Danach wie folgt:
ausblenden 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);
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 14.06.18 01:28 
- Nachträglich durch die Entwickler-Ecke gelöscht -
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: 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:

ausblenden 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 !

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 14.06.18 19:31 
- Nachträglich durch die Entwickler-Ecke gelöscht -
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: 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.
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 15.06.18 15:10 
- Nachträglich durch die Entwickler-Ecke gelöscht -
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: 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.
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 18.06.18 08:53 
- Nachträglich durch die Entwickler-Ecke gelöscht -
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: 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:
www.pinvoke.net/defa...GetInstalledDriversW
Das war übrigens der erste Treffer in der Liste.