Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перехват сообщений в сервисе 
:(
    Опции темы
Mosian
Дата 17.7.2009, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 17.7.2009

Репутация: нет
Всего: нет



Сервис написан без форм на APi
Необходимо получить системное сообщение об изменении конфигурации Windows (wm_devicechange)

В главном потоке сервиса подписываюсь на получение сообщений
Registerdevicenotification (handlService, @структура на то что хочу получать,  Flag);

Где flag = device_notify_window_handle если 1 параметр Окно
                   device_notify_service_handle  если 1 параметр сервис (мой случай).

Проблема первая (device_notify_service_handle) – пишет Undeclared , а (device_notify_window_handle) проходит объявление в Windows

ГДЕ ВЗЯТЬ device_notify_service_handle?

Проблема вторая, чем перехватывать эти сообщения? (Может создать поток и вызывать в нём GetMessage)
                              
Сильно не судите чайник.

PM MAIL   Вверх
Virtuals
Дата 17.7.2009, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 476
Регистрация: 27.11.2006

Репутация: 4
Всего: 11



Mosian, 
2. wm_devicechange сообщение оконное, соответственно и ловят его окна smile

PM MAIL ICQ   Вверх
kami
Дата 17.7.2009, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



DEVICE_NOTIFY_SERVICE_HANDLE = 1 (гугл рулит).


Цитата(Mosian @  17.7.2009,  12:17 Найти цитируемый пост)
чем перехватывать эти сообщения?

Перекрыть DoCustomControl сервиса.
Только насколько я понял из других ссылок (пока искал значение DEVICE_NOTIFY_SERVICE_HANDLE), там не обойтись им, потому что в DoCustomControl передается только msg.WParam.

У себя я давно обошел это, если в сервис устанавливается на Win2k или более новую винду, то вызывается не RegisterServiceCtrlHandler, а RegisterServiceCtrlHandlerEx, что позволяет получать дополнительные уведомления от системы. Правда, для этого пришлось влезть в генофонд, ну да ладно - оно того стоило.
HandlerEx callback function

Добавлено через 1 минуту и 35 секунд
Цитата(Virtuals @  17.7.2009,  13:01 Найти цитируемый пост)
wm_devicechange сообщение оконное, соответственно и ловят его окна

неправда ваша.

Добавлено через 4 минуты и 9 секунд
Вариант 2:
читаем внимательно RegisterDeviceNotification Function:

Цитата

hRecipient [in] 
A handle to the window or service that will receive device events for the devices specified in the NotificationFilter parameter. The same window handle can be used in multiple calls to RegisterDeviceNotification. 

Services can specify either a window handle or service status handle.


Вывод: создаем в сервисе окошко (AllocateHWND) и пользуем его.
PM MAIL WWW   Вверх
Mosian
Дата 17.7.2009, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 17.7.2009

Репутация: нет
Всего: нет



Через AllocateHWND пробовал молчит окошко;
Возможно я неправильно передаю в RegisterServiceCtrlHandle  Handle сервиса
беру его из registerServiceCtrlHandler либо необходимо OpenService?
И где правильно вызывать RegisterServiceCtrlHandle в основном потоке либо без разницы

PM MAIL   Вверх
Mosian
Дата 17.7.2009, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 17.7.2009

Репутация: нет
Всего: нет



Kami а где взять RegisterServiceCtrlHandlerEx
PM MAIL   Вверх
kami
Дата 17.7.2009, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(Mosian @  17.7.2009,  14:14 Найти цитируемый пост)
Через AllocateHWND пробовал молчит окошко;

и при этом указывал DEVICE_NOTIFY_WINDOW_HANDLE ?

Цитата(Mosian @  17.7.2009,  15:42 Найти цитируемый пост)
где взять RegisterServiceCtrlHandlerEx

Код

type
  TRegisterServiceCtrlHandlerEx=function (lpServiceName:PChar;
    lpHandlerProc: TFarProc; lpContext:DWORD):SERVICE_STATUS_HANDLE; stdcall;
  TRegisterServiceCtrlHandlerExW=function (lpServiceName:PWideChar;
    lpHandlerProc: TFarProc; lpContext:DWORD):SERVICE_STATUS_HANDLE; stdcall;

var
  advapi32:THandle;
  RegisterServiceCtrlHandlerEx:TRegisterServiceCtrlHandlerEx;
  //RegisterServiceCtrlHandlerExA:TRegisterServiceCtrlHandlerEx;
  //RegisterServiceCtrlHandlerExW:TRegisterServiceCtrlHandlerExW;

initialization
  advapi32 := LoadLibrary('advapi32.dll');
  if advapi32 <> 0 then
    begin
      RegisterServiceCtrlHandlerEx:=GetProcAddress(advapi32, 'RegisterServiceCtrlHandlerExA');
      //RegisterServiceCtrlHandlerExA:=GetProcAddress(advapi32, 'RegisterServiceCtrlHandlerExA');
      //RegisterServiceCtrlHandlerExW:=GetProcAddress(advapi32, 'RegisterServiceCtrlHandlerExW');
    end;
 ................
finalization
  FreeLibrary(advapi32);
................


Добавлено через 12 минут и 13 секунд
Цитата(Mosian @  17.7.2009,  14:14 Найти цитируемый пост)
Возможно я неправильно передаю в RegisterServiceCtrlHandle  Handle сервиса
беру его из registerServiceCtrlHandler

Читаем еще раз:
Цитата

RegisterDeviceNotification
hRecipient [in] 
A handle to the window or service that will receive device events for the devices specified in the NotificationFilter parameter. The same window handle can be used in multiple calls to RegisterDeviceNotification. 

Services can specify either a window handle or service status handle.

Смотрим, что возвращает RegisterServiceCtrlHandler:
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerEx(
  __in      LPCTSTR lpServiceName,
  __in      LPHANDLER_FUNCTION_EX lpHandlerProc,
  __in_opt  LPVOID lpContext
);

то есть, параметр передан правильно.
Теперь смотрим на
HandlerEx Callback Function

Цитата

This parameter can also be one of the following extended control codes. Note that these control codes are not supported by the Handler function.

Control Code Meaning 
SERVICE_CONTROL_DEVICEEVENT

 
Вывод - если нужно получать не через оконную функцию, а через callback функцию сервиса, то Hander (который регистрируется через RegisterServiceCtrlHandler) ничего не получит, как бы ни старался, тогда только HandlerEx.
PM MAIL WWW   Вверх
Mosian
Дата 20.7.2009, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 17.7.2009

Репутация: нет
Всего: нет



Люди что я делаю не так HendlerEx не получает сообщения SERVICE_CONTROL_DEVICEEVENT да и другие доп. параметры введённые для данной функции.
Сервис должен реагировать на вкл. выкл. USB

Ниже я привёл код, где происходит рег. Функции обработчика сообщ.

Код

Type
    _DEV_BROADCAST_DEVICEINTERFACE = record
       dbcc_size:DWORD;
       dbcc_devicetype:DWORD;
       dbcc_reserved:DWORD;
       dbcc_classguid:TGUID;
       dbcc_name:array[0..0] of char;
   end;
   TDEV_BROADCAST_DEVICEINTERFACE = _DEV_BROADCAST_DEVICEINTERFACE;
   DBT_DEVTYP_DEVICEINTERFACE = 5;


//************ Далее в основном потоке сервиса пишу *******************

  SERV_STATUS.dwServiceType           := SERVICE_WIN32_OWN_PROCESS; 
  SERV_STATUS.dwCurrentState           := SERVICE_START_PENDING;     
  SERV_STATUS.dwControlsAccepted := SERVICE_ACCEPT_STOP;
  SERV_STATUS.dwWin32ExitCode    := NO_ERROR;
  SERV_STATUS.dwServiceSpecificExitCode := 0;
  SERV_STATUS.dwCheckPoint            := 0;
  SERV_STATUS.dwWaitHint                := 5000;


   SERV_Handle := RegisterServiceCtrlHandlerEx(c_ServiceName,@ServiceCtrlHandler,0); 
   //Регистрация проходит успешно и ServiceCtrlHandler реагирует на SERVICE_CONTROL_STOP

   if SERV_Handle <> 0 then
    begin
        SERV_STATUS.dwCurrentState :=SERVICE_RUNNING; 
        SERV_STATUS.dwCheckPoint   :=0;
        SERV_STATUS.dwWaitHint     :=0;
        SetServiceStatus(SERV_Handle,SERV_STATUS);    

        NF.dbcc_size:=sizeof(TDEV_BROADCAST_DEVICEINTERFACE);
        NF.dbcc_devicetype:=DBT_DEVTYP_DEVICEINTERFACE;
        RegDN := Registerdevicenotification(SERV_Handle,@NF,1 and 4);

        // RegDN вроде тоже успешна <>nil
    end


//****************** Сам обработчик ******************
//Он реагирует только на стандартные сообщения 

ServiceCtrlHandler(Opcode:Cardinal;dwEventType:DWORD;lpEventData:Pointer;lpContext:Pointer);stdcall;
 begin
   //ErrortoFile(inttostr(Opcode));
   case Opcode of
    SERVICE_CONTROL_CONTINUE:
      if SERV_STATUS.dwCurrentState <> SERVICE_RUNNING then
       begin
         SERV_STATUS.dwCurrentState := SERVICE_RUNNING;
         SERV_STATUS.dwCheckPoint    := 0;
         SERV_STATUS.dwWaitHint      := 0;
         SetServiceStatus (SERV_Handle,SERV_STATUS);
       end;
    SERVICE_CONTROL_STOP:
      if SERV_STATUS.dwCurrentState <> SERVICE_STOPPED then
        begin
          SERV_STATUS.dwCurrentState  := SERVICE_STOPPED;
          SERV_STATUS.dwCheckPoint    := 0;
          SERV_STATUS.dwWaitHint      := 0;
          SetServiceStatus (SERV_Handle,SERV_STATUS);
        end;
    SERVICE_CONTROL_INTERROGATE :;
   end;
 end;


M
Rrader
Mosian, пользуйтесь подсветкой кода!





Это сообщение отредактировал(а) Rrader - 20.7.2009, 14:56
PM MAIL   Вверх
kami
Дата 20.7.2009, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(Mosian @  20.7.2009,  14:32 Найти цитируемый пост)
ServiceCtrlHandler(Opcode: Cardinal; dwEventType: WORD; lpEventData: Pointer; lpContext: Pointer);stdcall;

Неверное объявление.
Должно быть:
Код

function ServiceCtrlHandler(dwControl: DWORD; dwEventType: DWORD; lpEventData, lpContext: pointer): BOOL; stdcall;


Цитата(Mosian @  20.7.2009,  14:32 Найти цитируемый пост)
//Он реагирует только на стандартные сообщения 

А в этом коде не видно, что обрабатываются коды SERVICE_CONTROL_DEVICEEVENT

Хочу еще обратить внимание на DEV_BROADCAST_DEVICEINTERFACE:
Цитата

dbcc_name 
A null-terminated string that specifies the name of the device.
When this structure is returned to a window through the WM_DEVICECHANGE message, the dbcc_name string is converted to ANSI as appropriate. Services always receive a Unicode string, whether they call RegisterDeviceNotificationW or RegisterDeviceNotificationA.

Это во-первых.
А во-вторых, нужно учитывать, что dbcc_name:array[0..0] of char; (для сервиса - WideChar) - это сишная структура, которая не мешает обращаться по другим индексам этого массива. В Delphi с этим могут возникнуть проблемы. (меня самого как-то "ткнули носом" в это на другом форуме).

Это сообщение отредактировал(а) kami - 20.7.2009, 20:51
PM MAIL WWW   Вверх
Mosian
Дата 21.7.2009, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 17.7.2009

Репутация: нет
Всего: нет



В ServiceCtrlHandler приходят только стандартные сообщенки сервиса (stop start)
Но SERVICE_CONTROL_DEVICEEVENT так и не работает
Что может быть  smile 


Код

function ServiceCtrlHandler(dwControl: DWORD; dwEventType: DWORD; lpEventData, lpContext: LParam): BOOL; stdcall;
 begin
     ErrortoFile(inttostr(dwControl));
   ......
 end;

{************************ Оснавная Функция сервиса ****************************}
procedure ServiceProc(argc : DWORD;var argv : array of PChar);stdcall;
var RegDN :pointer;
      dbi         :dev_broadcast_deviceinterface;
      size       :integer;
 begin
   RegDeregLog_Service;                                         //Подцепляем лог файл к службе если удачно fEventLog<>0
   SERV_STATUS.dwServiceType      := SERVICE_WIN32_OWN_PROCESS; //тип сервиса
   SERV_STATUS.dwCurrentState     := SERVICE_START_PENDING;     //Сервис находится в процессе запуска
   SERV_STATUS.dwControlsAccepted := SERVICE_ACCEPT_STOP;       //Сервис может быть остановлен.
   SERV_STATUS.dwWin32ExitCode           := NO_ERROR;
   SERV_STATUS.dwServiceSpecificExitCode := 0;
   SERV_STATUS.dwCheckPoint              := 0;
   SERV_STATUS.dwWaitHint                := 5000;           //Время необх. для полной рег. службы
   advapi32 := LoadLibrary('advapi32.dll');
   RegisterServiceCtrlHandlerEx:=GetProcAddress(advapi32, 'RegisterServiceCtrlHandlerExA');

   SERV_Handle := RegisterServiceCtrlHandlerEx(c_ServiceName,@ServiceCtrlHandler,1); //Регистрируем службу

   if SERV_Handle <> 0 then
    begin
      SERV_STATUS.dwCurrentState :=SERVICE_RUNNING; //меняем статус на запуск
      SERV_STATUS.dwCheckPoint   :=0;
      SERV_STATUS.dwWaitHint     :=0;
      SetServiceStatus(SERV_Handle,SERV_STATUS);    //Запуск сервиса

      size := sizeof(dev_broadcast_deviceinterface);
      zeromemory(@dbi, size);
      dbi.dbcc_size := size;
      dbi.dbcc_devicetype := dbt_devtyp_deviceinterface;
      dbi.dbcc_reserved := 0;
      dbi.dbcc_classguid := guid_devinterface_usb_device;
      dbi.dbcc_name := 0;
      RegDN := Registerdevicenotification(SERV_Handle,@dbi,1);

      //ОСНОВНОЙ КОД ПРОГРАММЫ
      repeat
        sleep(200);
      until SERV_STATUS.dwCurrentState = SERVICE_STOPPED;

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0504 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.