AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi NT-Dienste, Fehler im Code...nur wo?
Thema durchsuchen
Ansicht
Themen-Optionen

NT-Dienste, Fehler im Code...nur wo?

Ein Thema von LeoDD · begonnen am 30. Jul 2003 · letzter Beitrag vom 31. Jul 2003
Antwort Antwort
LeoDD

Registriert seit: 30. Jul 2003
43 Beiträge
 
Delphi 2010 Professional
 
#1

NT-Dienste, Fehler im Code...nur wo?

  Alt 30. Jul 2003, 18:14
Hallo

Ich sitz derzeit an nem kleinen Programm, was den Status und die Config für einen bestimmten Dienst ("Messenger") abfragen soll und auch ändern soll (später).

Während die Statusabfrage problemlos läuft, verzweifel ich an der Konfigurationsabfrage. Zunächst mal der Codeschnipsel:

Code:
procedure GetMessengerInfo(var ServiceStatus: TServiceStatus; var ServiceConfig: TQueryServiceConfig);
var
   SMH, MH: THandle;
   NeededBytes: dword;
   R: boolean;

begin
SMH:=OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if SMH = null then begin
   ShowMessage(SysErrorMessage(GetLastError));
   Application.Terminate;
end;

MH:=OpenService(SMH, PChar('Messenger'), SC_MANAGER_ALL_ACCESS);

if MH = null then begin
   ShowMessage(SysErrorMessage(GetLastError));
end;

if not QueryServiceStatus(MH, ServiceStatus) then begin
   ShowMessage(SysErrorMessage(GetLastError));
end;

NeededBytes:=0;

R:=QueryServiceConfig(MH, @ServiceConfig, sizeof(ServiceConfig), NeededBytes);

if not R then begin
   if GetLastError = ERROR_INSUFFICIENT_BUFFER then begin
      if not QueryServiceConfig(MH, @ServiceConfig, sizeof(ServiceConfig) + NeededBytes, NeededBytes) then begin
         ShowMessage(SysErrorMessage(GetLastError));
      end;
   end else begin
      ShowMessage(SysErrorMessage(GetLastError));
   end;
end;

CloseServiceHandle(MH);
CloseServiceHandle(SMH);
end;
Diese Funktion soll also den Status und die Config in die übergebenen Parameter ablegen. Dabei erscheint auch keine Fehlermeldung. Aber beim Beenden des Programms kommt eine "access violation".

Kann sich bitte einer von euch mal der Sache annehmen und mir einen Hinweis geben was ich falsch mache?

Gruß
Leo
Erst wenn man dreimal auf Holz klopfen will, stellt man fest, dass die Welt nur noch aus Plastik und Aluminium besteht.
  Mit Zitat antworten Zitat
-Amazeroth-
(Gast)

n/a Beiträge
 
#2

Re: NT-Dienste, Fehler im Code...nur wo?

  Alt 31. Jul 2003, 00:31
In deinem Code schreibst du ÜBER deinen Speicher hinaus. Daher die AV.
Du hast nur den Speicher für eine TQueryServiceConfig-Struktur reserviert. Allerdings willst du im zweiten Aufruf "QueryServiceConfig(MH, @ServiceConfig, sizeof(ServiceConfig) + NeededBytes, NeededBytes)" plötzlich mehr Bytes geschrieben haben, als du reserviert hast. Es geht nicht so simpel. Du mußt mit Pointern arbeiten!
Hier eine Lösung. Allerdings verlangt sie, daß du per GetMemory() vorher Speicher reservierst und danach per FreeMemory() wieder freigibst.

Delphi-Quellcode:
procedure GetMessengerInfo(var ServiceStatus: TServiceStatus; var ServiceConfig: PQueryServiceConfig);
var
  SMH, MH: THandle;
  NeededBytes: dword;
  R: boolean;
begin
  SMH := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if SMH <> 0 then // NULL <> 0!!!
  try
    MH := OpenService(SMH, 'Messenger', SC_MANAGER_ALL_ACCESS); // Literale gehen auch so!
    if MH <> 0 then
    try
      if not QueryServiceStatus(MH, ServiceStatus) then
        ShowMessage(SysErrorMessage(GetLastError));
      NeededBytes := 0;
      R := QueryServiceConfig(MH, ServiceConfig^, sizeof(ServiceConfig^), NeededBytes);
      if not R then
        (
          if GetLastError = ERROR_INSUFFICIENT_BUFFER then
          begin
            FreeMemory(ServiceConfig);
            ServiceConfig := GetMemory(NeededBytes);
            if Assigned(ServiceConfig) then
              if not QueryServiceConfig(MH, ServiceConfig^, NeededBytes, NeededBytes) then
                ShowMessage(SysErrorMessage(GetLastError));
          end
          else
            ShowMessage(SysErrorMessage(GetLastError))
              )
    finally
      CloseServiceHandle(MH);
    end
    else
      ShowMessage(SysErrorMessage(GetLastError));
  finally
    CloseServiceHandle(SMH);
  end
  else
  begin
    ShowMessage(SysErrorMessage(GetLastError));
    Application.Terminate;
  end;
end;
Aufruf ca so ...

Delphi-Quellcode:
var
  ServiceStatus: TServiceStatus;
  ServiceConfig: PQueryServiceConfig;
begin
  ServiceConfig := GetMemory(sizeof(ServiceConfig^));
  if Assigned(ServiceConfig) then
  try
    ZeroMemory(ServiceConfig, sizeof(ServiceConfig^));
    GetMessengerInfo(ServiceStatus, ServiceConfig);
// Hier wird die Konfiguration ausgewertet
// ...
  finally
// Freigegeben des Speichers
    FreeMemory(ServiceConfig);
  end;
end;
  Mit Zitat antworten Zitat
LeoDD

Registriert seit: 30. Jul 2003
43 Beiträge
 
Delphi 2010 Professional
 
#3

Re: NT-Dienste, Fehler im Code...nur wo?

  Alt 31. Jul 2003, 09:48
Ein ganz dickes Dankeschön

Ich werds gleich mal testen

Nachtrag:
Der Compiler sagt:
Zitat:
[Fehler] MainUnit.pas(48): Inkompatible Typen: '_QUERY_SERVICE_CONFIGA' und 'PQueryServiceConfigA'
[Fehler] MainUnit.pas(56): Inkompatible Typen: '_QUERY_SERVICE_CONFIGA' und 'PQueryServiceConfigA'
Nachtrag2:

habs gelöst und es läuft Nochmal vielen Dank
Erst wenn man dreimal auf Holz klopfen will, stellt man fest, dass die Welt nur noch aus Plastik und Aluminium besteht.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:15 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz