информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Сетевые кракеры и правда о деле ЛевинаГде водятся OGRы
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Очередное исследование 19 миллиардов... 
 Оптимизация ввода-вывода как инструмент... 
 Зловреды выбирают Lisp и Delphi 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
если вы видите этот текст, отключите в настройках форума использование JavaScript
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
[Win32 Delphi 5] У кого мозги не засохли — нужна помощь ;-) 19.10.02 19:21  
Автор: HandleX <Александр М.> Статус: The Elderman
Отредактировано 19.10.02 19:47  Количество правок: 3
<"чистая" ссылка>
Не понимаю, почему я не могу взять строки lpRebootMsg или lpCommand из структуры... Это указатель, но указывает на какую-то хрень... Помогите, pls...
Прогу наваял специально для тестирования этого случая, думаю проблем скомпилить не составит, у кого Delphi 5.


program Main;
{$APPTYPE CONSOLE}
uses
  SysUtils, Windows, WinSvc;

  Function forCons(aStr: String): String;
  Begin
    Result := aStr; UniqueString(Result);
    ANSItoOEM(PChar(Result), PChar(Result));
  End;

  Function QueryServiceConfig2A(
    hService: SC_HANDLE;   // handle to service
    dwInfoLevel: DWORD;    // information level
    lpInfo: Pointer;       // new data
    cbBufSize: DWORD;      // size of buffer
    Var pcbBytesNeeded: DWORD // bytes needed
  ): BOOL; StdCall; External AdvApi32;

Type
  _SERVICE_DESCRIPTION = Record
    lpDescription: LPTSTR;
  End;
  SERVICE_DESCRIPTION = _SERVICE_DESCRIPTION;
  PSERVICE_DESCRIPTION = ^SERVICE_DESCRIPTION;

  _SC_ACTION_TYPE = (SC_ACTION_NONE, SC_ACTION_RESTART, SC_ACTION_REBOOT, SC_ACTION_RUN_COMMAND);
  SC_ACTION_TYPE = _SC_ACTION_TYPE;

  _SC_ACTION = Record
    aType: SC_ACTION_TYPE;
    Delay: DWORD;
  End;
  TSC_ACTION = _SC_ACTION;
  PSC_ACTION = ^TSC_ACTION;

  TSC_ACTION_Array = Array[0..0] Of TSC_ACTION;
  PSC_ACTION_Array = ^TSC_ACTION_Array;

  _SERVICE_FAILURE_ACTIONS = Record
    dwResetPeriod: DWORD;
    lpRebootMsg: LPTSTR;
    lpCommand: LPTSTR;
    cActions: DWORD;
    lpsaActions: PSC_ACTION_Array;
  End;
  TSERVICE_FAILURE_ACTIONS = _SERVICE_FAILURE_ACTIONS;
  PSERVICE_FAILURE_ACTIONS = ^TSERVICE_FAILURE_ACTIONS;

Const
  SERVICE_CONFIG_DESCRIPTION = 1;
  SERVICE_CONFIG_FAILURE_ACTIONS = 2;

  ActionTypeStrings: Array[SC_ACTION_NONE..SC_ACTION_RUN_COMMAND] Of String = (
    'SC_ACTION_NONE', 'SC_ACTION_RESTART', 'SC_ACTION_REBOOT', 'SC_ACTION_RUN_COMMAND'
  );

  Function GetServiceDescription(sHndl: THandle): String;
  Var
    BytesNeeded: DWord;
    OutBuff: PSERVICE_DESCRIPTION;
  Begin
    QueryServiceConfig2A(sHndl, SERVICE_CONFIG_DESCRIPTION, Nil, 0, BytesNeeded);
    If GetLastError <> ERROR_INSUFFICIENT_BUFFER Then
      RaiseLastWin32Error;
    GetMem(OutBuff, BytesNeeded);
    Try
      Win32Check(QueryServiceConfig2A(sHndl, SERVICE_CONFIG_DESCRIPTION, OutBuff, BytesNeeded, BytesNeeded));
      Result := OutBuff.lpDescription;
    Finally
      FreeMem(OutBuff);
    End;
  End;

  Function GetServiceFailureActions(sHndl: THandle): PSERVICE_FAILURE_ACTIONS;
  Var
    BytesNeeded: DWord;
  Begin
    QueryServiceConfig2A(sHndl, SERVICE_CONFIG_DESCRIPTION, Nil, 0, BytesNeeded);
    If GetLastError <> ERROR_INSUFFICIENT_BUFFER Then
      RaiseLastWin32Error;
    GetMem(Result, BytesNeeded);
    Try
      Win32Check(QueryServiceConfig2A(sHndl, SERVICE_CONFIG_FAILURE_ACTIONS, Result, BytesNeeded, BytesNeeded));
    Except
      FreeMem(Result);
      Raise;
    End;
  End;

Var
  scHndl, sHndl: THandle;
  anActions: PSERVICE_FAILURE_ACTIONS;
  J: Integer;
begin
  Try
    WriteLn;
    WriteLn('Hello, this test application will show work of some API functions, wait...');
    Write('Try to open SC Manager...');
    scHndl := OpenSCManager(Nil, Nil, MAXIMUM_ALLOWED);
    Win32Check(scHndl <> 0);
    Try
      WriteLn('Ok');

      Write('Try to open "WinMgmt" Service...');
      sHndl := OpenService(scHndl, 'WinMgmt', MAXIMUM_ALLOWED);
      Win32Check(sHndl <> 0);
      Try
        WriteLn('Ok');

        Write('Getting Service Description...');
        WriteLn('Ok'#$A'Service Description is: "' + forCons(GetServiceDescription(sHndl)) + '";');

        Write('Getting Service Failure Actions...');

        anActions := GetServiceFailureActions(sHndl);
        Try
          WriteLn('Ok');

          If anActions = Nil Then
            Raise EAbort.Create('Very strange error... Exiting!');

          WriteLn('Reset Period, seconds: ', anActions.dwResetPeriod);
          WriteLn('Reboot message: "', String(anActions.lpRebootMsg), '";');
          WriteLn('Command action: "', String(anActions.lpCommand), '";');
          WriteLn('Actions count: ', anActions.cActions, ';');

          For J := 0 To anActions.cActions - 1 Do
          Begin
            WriteLn;
            WriteLn(J, ' action type: ', ActionTypeStrings[anActions.lpsaActions[J].aType]);
            WriteLn(J, ' action delay, msec: ', anActions.lpsaActions[J].Delay);
          End;

          WriteLn;
          WriteLn('End of actions enumeration.');

        Finally
          FreeMem(anActions);
        End;
      Finally
        CloseServiceHandle(sHndl);
      End;
    Finally
      CloseServiceHandle(scHndl);
    End;

  Except
    on E: Exception Do
    Begin
      WriteLn; WriteLn;
      If E Is EAbort Then WriteLn(forCons(E.Message))
      Else Begin
        WriteLn('Exception occured, apllication will be terminated!');
        WriteLn('Exception class: "' + E.ClassName + '";');
        WriteLn('Exception message: "' + ForCons(E.Message) + '".');
      End;
    End;
  End;

  Write('Press Enter to exit...');
  ReadLn;
end.

---
Тестировать надо под Win2k, что понятно ввиду специфики API. Нужно открыть консоль MMC, для сервиса «Инструментарий управления Windows», выбрать вкладку «Восстановление», потом сказать, что при последующих сбоях надо перезагружать компьютер, нажать на кнопку «Параметры перезагрузки компьютера», там закрыжить, что нужно слать сообщение, и набрать некое сообщение. После чего запустить прогу.

К сожалению, не могу добиться того, чтобы извлечь это сообщение программно.
Всем заранее огромное спасибо!
Всем спасибо за мозговой штурм, сам разобрался. ;-) и вам на заметку — ansi версия queryserviceconfig2a работает криво при вызове с параметром service_config_failure_actions. не конвертит, сволочь уникод в анси, да и ладно, а то ещё и память портит! ;-) 20.10.02 13:34  
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2025 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach