Einzelnen Beitrag anzeigen

-Amazeroth-
(Gast)

n/a Beiträge
 
#2

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

  Alt 30. Jul 2003, 23: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