Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Treiber installieren, starten, stoppen, deinstallieren (https://www.delphipraxis.net/53496-treiber-installieren-starten-stoppen-deinstallieren.html)

Neotracer64 17. Sep 2005 19:47


Treiber installieren, starten, stoppen, deinstallieren
 
Zuerst einmal: Ich weiss, dass man keine Treiber mit Delphi programmieren kann.

Darum geht es auch NICHT.

Ich habe schon einen Treiber in Form einer sys-Datei. (geschrieben in C++ und kompiliert mit dem DDK)

Diese möchte ich mit Delphi installieren, starten, stoppen und deinstallieren können.

Komischerweise habe ich dazu nichts gefunden hier im Forum. Aber es müsste doch eigentlich möglich sein oder ? Funktioniert das so ähnlich wie bei Diensten ?

Ach ja:
Damit das hier nicht in die Falsche Richtung läuft. Ich möchte keinerlei Alternativen sehen. Ich möchte nur wissen ob es in Delphi geht und wenn ja wie.
Ich bin also in der Lage ein klares Nein zu akzeptieren. (Natürlich nur wenn es wahrheitsgemäss ist)

Danke schonmal :)

:dp:

Olli 17. Sep 2005 19:52

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Zitat:

Zitat von Neotracer64
(geschrieben in C++ und kompiliert mit dem DDK)

Respekt. Manche würden dich dafür steinigen, wenn du dank überladenem new und delete den Speicher verschwendest :lol:

Guck mal in mein Service Tut: http://assarbad.net/en/stuff/tutorials/ntsvc/

Dienste und Treiber werden auf die gleiche Art und Weise installiert, gestartet und gestoppt usw.

Neotracer64 17. Sep 2005 19:58

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Zitat:

Respekt. Manche würden dich dafür steinigen, wenn du dank überladenem new und delete den Speicher verschwendest
Hmm versteh ich nicht ganz. Kann es sein, dass ich mich etwas falsch ausgedrückt hab ? Von Treiberprogrammierung versteh ich noch nicht viel, deswegen hatte ich auch kompetente Hilfe, die im Moment nicht erreichbar ist. Gut, dass die DP so schnell ist :thumb:

Danke für das TUT, Olli :cyclops:

Olli 17. Sep 2005 20:04

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Zitat:

Zitat von Neotracer64
Hmm versteh ich nicht ganz. Kann es sein, dass ich mich etwas falsch ausgedrückt hab ?

Nee, es ging darum, daß du sagtest, dein Treiber sei mit C++ programmiert. Suche mal mit Google nach dem Streitthema ob C++ oder C verwendet werden soll ;) ... dann weißt du was ich meine. Ist aber auch nicht trivial mit C++ einen Treiber zu programmieren.

MagicAndre1981 17. Sep 2005 20:08

Re: Treiber installieren, starten, stoppen, deinstallieren
 
[quote="Olli"]
Zitat:

Zitat von Neotracer64
Ist aber auch nicht trivial mit C++ einen Treiber zu programmieren.

Dafür gibts extra DriverProgrammingKits, mitdenen man Treiber auch mit C++ schreiben kann.

Olli 17. Sep 2005 20:11

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Zitat:

Zitat von MagicAndre1981
Zitat:

Zitat von Olli
Ist aber auch nicht trivial mit C++ einen Treiber zu programmieren.

Dafür gibts extra DriverProgrammingKits, mitdenen man Treiber auch mit C++ schreiben kann.

Nee, ehrlich? Wenn du dir sowas leisten kannst, Glückwunsch. Ich steige erst in die Riege der Großverdiener auf :mrgreen:

bigg 17. Sep 2005 20:36

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Schau mal hier:
http://www.nirsoft.net/utils/serviwin.html

Es sollte sich also über die allbekannte und von vielen gehasste Registry realisieren lassen.
(ot: hasse sie nicht, finde sie sehr sinnvoll)

Olli 17. Sep 2005 20:39

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Zitat:

Zitat von bigg
Es sollte sich also über die allbekannte und von vielen gehasste Registry realisieren lassen.

Über die SCM-APIs greifst du implizit auf die Registry zu. Allerdings wirst du ohne Beteiligung des SCM nicht einen Eintrag in die Registry machen und dann ohne Neustart deinen Treiber/Dienst starten können. Daher ist eben der SCM immer der Weg, den man gehen sollte. Auch wenn man es über ein Registry-Script (.REG) oder sonstwas lösen könnte!

Neotracer64 17. Sep 2005 23:22

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Ich habe noch eine Quick&Dirty Variante gefunden. Leider lässt sich der Treiber ohne Neustart nicht mehr entladen.

Und geklappt hat es auch noch nicht, da ich wahrscheinlich zu blöd bin C++ in Delphi zu übersetzen. Ich habs trotzdem ma versucht:

Original C-Code:

Zitat:

//----------------------------------------------------------------
// load a sys file as a driver using undocumented method
//----------------------------------------------------------------
bool load_sysfile()
{
SYSTEM_LOAD_AND_CALL_IMAGE GregsImage;

WCHAR daPath[] = L"\\??\\C:\\HELLOWORLD.SYS";

//////////////////////////////////////////////////////////////
// get DLL entry points
//////////////////////////////////////////////////////////////
if( !(RtlInitUnicodeString = (RTLINITUNICODESTRING)
GetProcAddress( GetModuleHandle("ntdll.dll")
,"RtlInitUnicodeString"
)))
{
return false;
}

if(!(ZwSetSystemInformation = (ZWSETSYSTEMINFORMATION)
GetProcAddress(
GetModuleHandle("ntdll.dll")
,"ZwSetSystemInformation" )))
{
return false;
}

RtlInitUnicodeString(
&(GregsImage.ModuleName)
,daPath
);

if(
!NT_SUCCESS(
ZwSetSystemInformation(
SystemLoadAndCallImage
,&GregsImage
,sizeof(SYSTEM_LOAD_AND_CALL_IMAGE))))
{
return false;
}

return true;
}
Delphi-Quellcode:
uses ...JwaNative, JwaNTStatus;
...
function load_sysfile: boolean;
var
  GregsImage: SYSTEM_LOAD_AND_CALL_IMAGE;
  daPath: PWideChar;
begin
  daPath := 'HelloWorld.sys';
  RtlInitUnicodeString(@GregsImage.ModuleName,daPath);
  if ZwSetSystemInformation(SystemLoadAndCallImage,@GregsImage,sizeof(SYSTEM_LOAD_AND_CALL_IMAGE))= STATUS_SUCCESS
    Then result := True
    Else result := false;
end;
Es kommt leider immer false raus :(

Olli 17. Sep 2005 23:43

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Wozu das gut sein soll, wirst du wohl selber wissen, denn es existiert ja "nur" eine dokumentierte Methode. Da ist es mehr als logisch zur undokumentierten zu greifen *kopfschüttel*

Die Native API zeigt Fehler an, indem der Wert negativ ist. Nur weil der Rückgabewert ungleich STATUS_SUCCESS sagt das nicht, daß es einen Fehler gab. Wir haben in JwaNative.pas ja durchaus auch die Makros als Funktionen drin, wenn ich mich recht entsinne. Ansonsten checkst du eben selber auf ">= STATUS_SUCCESS".

Aber mal ehrlich, wozu fragst du eigentlich, wenn du dann doch eine andere (und zumal unzuverlässige) Methode benutzt?

EDIT:
Ach ja, ob ein Treiber entladen werden kann, hängt a.) vom Typ des Treibers und b.) von seiner Konzeption ab. Also selbst wenn der Treibertyp es erlaubt entladen zu werden, muß es der Treiber noch nicht erlauben.

Der Code enthält übrigens keinerlei C++-Features, sondern nur C. Außerdem ist Greg Hoglund eine Koryphäe auf dem Gebiet und weiß was er mit undokumentierten Aufrufen erreichen kann (und will) und was nicht. Genau das fehlt dir (offensichtlich!)

Neotracer64 18. Sep 2005 00:19

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Zitat:

Da ist es mehr als logisch zur undokumentierten zu greifen *kopfschüttel*
Heisst ja nicht, dass ich die jetz unbedingt benutzen will. Ich bin nur im Moment ein bisschen am rumexperimentieren. Dass ich da schnell an meine Grenzen stosse, ist vielleicht ein bisschen nervig, wenn ich dann eine "dumme" Frage stelle. Ich gebs ja zu.... :cry:

Zitat:

Aber mal ehrlich, wozu fragst du eigentlich, wenn du dann doch eine andere (und zumal unzuverlässige) Methode benutzt?
siehe oben. Ich möcht halt nicht dumm sterben, mal so gesagt. *g*. Wenn ich Primzahlen rausfinden will, dann probier ich auch mehrere Methoden aus. Vlt hat die eine ja seine Vorzüge, wo jedoch ein Feature nicht dabei ist, was ich dann auch nicht brauche. Probier ich doch halt, spass wie es macht, alle Methoden mal aus.


Zitat:

Außerdem ist Greg Hoglund eine Koryphäe auf dem Gebiet und weiß was er mit undokumentierten Aufrufen erreichen kann (und will) und was nicht. Genau das fehlt dir (offensichtlich!)
Kann doch sein, dass es mit meinem krüppeligen HelloWorld-Treiber funktioniert oder nich :)
Ja es fehlt mir. Aber vlt hätte ich ja früher oder später entdeckt warum genau diese MEthode nicht so gut funktioniert. Aber wenn sie nichtmal funktioniert, dann bin ich auf andere angewiesen, ich alte Nervensäge :wall:

Dann entschuldige ich mich und gebe Ruhe :wink:

Neotracer64 18. Sep 2005 17:05

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Da ich Schuldgefühle habe, dass ich eine "fiese" Methode benutzen wollte habe ich es auf normale Art und Weise versucht.
Dabei habe ich wieder Greg Hoglunds C-Code übersetzt.

Aber Guess What. Er funktioniert noch nicht so ganz ;(
Er scheitert schon beim öffnen des SC_Managers. (Ja ich hab Admin-Rechte).

Delphi-Quellcode:
uses ...,WinSvc;

...

function load_sysfile(DriverPath: String):boolean;
var
  sh, rh                 : SC_HANDLE;
  aPath,dummy,DriverName : PChar;
begin
  dummy := '';
  sh := OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
  if not sh > 0 Then
    begin
      MessageBox(0,'Fehler beim öffnen des SC_MANAGERS! ','Error Handling',MB_ICONERROR);
      result := false;
      Exit;
    end;
  aPath := Pchar(DriverPath);
  DriverName := Pchar(ExtractFileName(DriverPath));
  rh :=CreateService(sh,
                     DriverName,
                     DriverName,
                     SERVICE_ALL_ACCESS,
                     SERVICE_KERNEL_DRIVER,
                     SERVICE_DEMAND_START,
                     SERVICE_ERROR_NORMAL,
                     aPath,
                     nil,
                     nil,
                     nil,
                     nil,
                     nil);

  if not rh > 0 Then
    begin
      if GetLastError = ERROR_SERVICE_EXISTS Then
        begin
          MessageBox(0,'Service existiert schon!','Error Handling',MB_ICONERROR);
          rh := OpenService(sh, Pchar(DriverName),SERVICE_ALL_ACCESS);
          if not rh > 0 Then
            begin
              MessageBox(0,'Vorhandener Service kann nicht geöffnet werden!','Error Handling',MB_ICONERROR);
              CloseServiceHandle(sh);
              result := false;
              Exit;
            end;
        end else
          begin
            MessageBox(0,'Fehler beim erstellen des Services!','Error Handling',MB_ICONERROR);
            CloseServiceHandle(sh);
            result := false;
            Exit;
          end;
    end;
  if rh > 0 Then
    begin
      if StartService(rh,0,dummy) Then
        begin
         if GetLastError = ERROR_SERVICE_ALREADY_RUNNING Then
           begin
             MessageBox(0,'Service läuft schon!','Error Handling',MB_ICONINFORMATION);
             result := True;
           end else
             begin
               MessageBox(0,'Service lässt sich nicht starten!','Error Handling',MB_ICONERROR);
               CloseServiceHandle(rh);
               CloseServiceHandle(sh);
               result := false;
               Exit;
             end;
        end;
      result := True;
    end;
Habt ihr eine Idee ?

Olli 18. Sep 2005 19:32

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Zitat:

Zitat von Neotracer64
Da ich Schuldgefühle habe, dass ich eine "fiese" Methode benutzen wollte habe ich es auf normale Art und Weise versucht.
Dabei habe ich wieder Greg Hoglunds C-Code übersetzt.

Die Methode ist ja okay ;)

Kannst du mir mal sagen, ob das entsprechende Privileg zum Laden von Treibern/Diensten aktiviert ist?

Neotracer64 18. Sep 2005 20:26

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Muss ich mir das in meinem Programm extra holen ? Mit token oder so ?
Weil ich kann mit dem programm INSTDRV.EXE eins installieren. Also ich habe das als Privileg.

Muss man vlt das SeDebugPrivlieg haben ? Oder wie heisst das da ?

Danke für deine Hilfe

Olli 18. Sep 2005 20:28

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Zitat:

Zitat von Neotracer64
Muss man vlt das SeDebugPrivlieg haben ? Oder wie heisst das da ?

SE_LOAD_DRIVER_NAME = 'SeLoadDriverPrivilege'

Robert Marquardt 18. Sep 2005 20:52

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Treiber werden ueber Setup API bzw. Config Manager API gehandhabt.
Zusaetzlich gibt es noch die zentrale Funktion UpdateDriverForPlugAndPlayDevices, die merkwuerdigerweise keinem Teil-API zugeordnet ist.

Grundsaetzlich muss man erst mal verstehen was Setup-Klassen sind und was sie von Device-Klassen unterscheidet.
Die gesamte Treiberinstallation geschieht ueber INF-Files.

Olli 18. Sep 2005 20:59

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Zitat:

Zitat von Robert Marquardt
Treiber werden ueber Setup API bzw. Config Manager API gehandhabt.
Zusaetzlich gibt es noch die zentrale Funktion UpdateDriverForPlugAndPlayDevices, die merkwuerdigerweise keinem Teil-API zugeordnet ist.

Grundsaetzlich muss man erst mal verstehen was Setup-Klassen sind und was sie von Device-Klassen unterscheidet.
Die gesamte Treiberinstallation geschieht ueber INF-Files.

Wenn der Treiber ein virtueller Treiber ist, dürfte all dies ziemlich egal sein. Im Endeffekt reicht die SCM-API dann auch völlig aus, weil sie ursprünglich dafür konzipiert wurde. Die von dir genannten APIs kamen ja quasi erst später (2000) hinzu.

Neotracer64 18. Sep 2005 21:09

Re: Treiber installieren, starten, stoppen, deinstallieren
 
So. Ich habe die Funktion etwas erweitert.

Die Funktion EnablePrivileg habe ich aus :

http://www.delphipraxis.net/internal...light=privileg

Delphi-Quellcode:
function load_sysfile(DriverPath: String):boolean;
var
  sh, rh                 : SC_HANDLE;
  aPath,dummy,DriverName : PChar;
  PreviousState          : Boolean;
begin
  If not EnablePrivilege('SeLoadDriverPrivilege',False,PreviousState) = ERROR_SUCCESS Then
    begin
      MessageBox(0,'Fehler beim akquirieren des SeLoadDriverPrivileges!','Error Handling',MB_ICONERROR);
      result := false;
      Exit;
    end;
  dummy := '';
  sh := OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
  if not sh > 0 Then
    begin
      MessageBox(0,'Fehler beim öffnen des SC_MANAGERS! ','Error Handling',MB_ICONERROR);
      result := false;
      Exit;
    end;
  aPath := Pchar(DriverPath);
  DriverName := Pchar(ExtractFileName(DriverPath));
  rh :=CreateService(sh,
                     DriverName,
                     DriverName,
                     SERVICE_ALL_ACCESS,
                     SERVICE_KERNEL_DRIVER,
                     SERVICE_DEMAND_START,
                     SERVICE_ERROR_NORMAL,
                     aPath,
                     nil,
                     nil,
                     nil,
                     nil,
                     nil);

  if not rh > 0 Then
    begin
      if GetLastError = ERROR_SERVICE_EXISTS Then
        begin
          MessageBox(0,'Service existiert schon!','Error Handling',MB_ICONERROR);
          rh := OpenService(sh, Pchar(DriverName),SERVICE_ALL_ACCESS);
          if not rh > 0 Then
            begin
              MessageBox(0,'Vorhandener Service kann nicht geöffnet werden!','Error Handling',MB_ICONERROR);
              CloseServiceHandle(sh);
              result := false;
              Exit;
            end;
        end else
          begin
            MessageBox(0,'Fehler beim erstellen des Services!','Error Handling',MB_ICONERROR);
            CloseServiceHandle(sh);
            result := false;
            Exit;
          end;
    end;
  if rh > 0 Then
    begin
      if StartService(rh,0,dummy) Then
        begin
         if GetLastError = ERROR_SERVICE_ALREADY_RUNNING Then
           begin
             MessageBox(0,'Service läuft schon!','Error Handling',MB_ICONINFORMATION);
             result := True;
           end else
             begin
               MessageBox(0,'Service lässt sich nicht starten!','Error Handling',MB_ICONERROR);
               CloseServiceHandle(rh);
               CloseServiceHandle(sh);
               result := false;
               Exit;
             end;
        end;
      result := True;
    end;

Dann habe ich getestet ob ich auch wirklich das privileg danach habe:

Delphi-Quellcode:
var
Luid: TLargeInteger;
...
load_sysfile('HelloWorld.sys');
If LookupPrivilegeValue(nil, 'SeLoadDriverPrivilege', Luid) Then ShowMessage('ja');
Es kommt immernoch:Fehler beim öffnen des SC_MANAGERS!
Und danach kommt die ShowMessage mit "ja". Also müsste ich das privileg doch haben oder ?

Olli 18. Sep 2005 21:14

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Sorry, nicht eher gesehen. Auf jeden Fall gibt es einen kleinen Fehler. So ists richtig:

Delphi-Quellcode:
  sh := OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
  if (sh = 0) then
    begin
      MessageBox(0,'Fehler beim öffnen des SC_MANAGERS! ','Error Handling',MB_ICONERROR);
      // Hier kannste mit GetLastError() testen!!!
      result := false;
      Exit;
    end;

Neotracer64 18. Sep 2005 21:24

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Gute Idee! :)

Aber nach dem ich dieses Stück wie folgt geändert habe war ich verwirrter als vorher :

Delphi-Quellcode:
sh := OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
  if not sh > 0 Then
    begin
      MessageBox(0,Pchar('OpenSCManager : '+SyserrorMessage(GetLastError)),'Error Handling',MB_ICONERROR);
      result := false;
      Exit;
    end;
Die MessageBox sagt : " OpenSCManager : Der Vorgang wurde erfolgreich beendet "

Wie kann der Vorgang erfolgreich beendet worden sein, wenn der Handle leer ist ? :S

Olli 18. Sep 2005 21:29

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Könntest du bitte mal genau hinschauen und meine IF-Bedingung übernehmen statt deine Bedingung weiter zu nutzen. Danke! :roll:

Neotracer64 18. Sep 2005 22:08

Re: Treiber installieren, starten, stoppen, deinstallieren
 
Autsch. Sorry, jetz hab ich nicht genau hingeguckt.
Ich habe deswegen jetzt selber noch etwas genauer hingeschaut und ein paar Sachen verbessert.

Es klappt jetz :D

ich weiss es nicht ob es überhaupt nochmal nützlich für jemanden sein könnte. Vlt wäre ein Post in der CodeLibrary nicht verkehrt ?
Naja wens interessiert hier:

Delphi-Quellcode:
function load_sysfile(DriverPath: String):boolean;
var
  sh, rh                 : SC_HANDLE;
  aPath,dummy,DriverName : PChar;
  PreviousState          : Boolean;
begin
  If not EnablePrivilege('SeLoadDriverPrivilege',False,PreviousState) = ERROR_SUCCESS Then
    begin
      MessageBox(0,'Fehler beim akquirieren des SeLoadDriverPrivileges!','Error Handling',MB_ICONERROR);
      result := false;
      Exit;
    end;
  dummy := '';
  sh := OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);
  if (sh = 0) then
    begin
      MessageBox(0,Pchar('OpenSCManager : '+SyserrorMessage(GetLastError)),'Error Handling',MB_ICONERROR);
      result := false;
      Exit;
    end;
  aPath := Pchar(DriverPath);
  DriverName := Pchar(ExtractFileName(DriverPath));
  rh :=CreateService(sh,
                     DriverName,
                     DriverName,
                     SERVICE_ALL_ACCESS,
                     SERVICE_KERNEL_DRIVER,
                     SERVICE_DEMAND_START,
                     SERVICE_ERROR_NORMAL,
                     aPath,
                     nil,
                     nil,
                     nil,
                     nil,
                     nil);

  if (rh=0) Then
    begin
      if GetLastError = ERROR_SERVICE_EXISTS Then
        begin
          MessageBox(0,'Service existiert schon!','Error Handling',MB_ICONERROR);
          rh := OpenService(sh, Pchar(Drivername),SERVICE_ALL_ACCESS);
          if (rh=0) Then
            begin
              MessageBox(0,Pchar('Vorhandener Service kann nicht geöffnet werden! : ' + SysErrorMessage(GetLastError)),'Error Handling',MB_ICONERROR);
              CloseServiceHandle(sh);
              result := false;
              Exit;
            end;
        end else
          begin
            MessageBox(0,'Fehler beim erstellen des Services!','Error Handling',MB_ICONERROR);
            CloseServiceHandle(sh);
            result := false;
            Exit;
          end;
    end;
  if not (rh=0) Then
    begin
      if not StartService(rh,0,dummy) Then
        begin
         if GetLastError = ERROR_SERVICE_ALREADY_RUNNING Then
           begin
             MessageBox(0,'Service läuft schon!','Error Handling',MB_ICONINFORMATION);
             result := True;
           end else
             begin
               MessageBox(0,Pchar('Service lässt sich nicht starten: ' + SysErrorMessage(GetLastError)),'Error Handling',MB_ICONERROR);
               CloseServiceHandle(rh);
               CloseServiceHandle(sh);
               result := false;
               Exit;
             end;
        end;
      result := True;
    end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:05 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz