информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Все любят медАтака на InternetЗа кого нас держат?
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Бэкдор в xz/liblzma, предназначенный... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
На faqmakers доступ не для всех.. Надо попросить dl-я, чтобы выложил уже, если замечаний нет. 24.05.04 18:36  Число просмотров: 1670
Автор: !mm <Ivan Ch.> Статус: Elderman
<"чистая" ссылка>
<programming>
[Win32] Безоконное приложение Win32 05.05.04 21:50   [ZloyShaman, amirul]
Автор: Lutien Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Просветите плиз дуру грешную ;)

Собственно, как написать прогу под windows которая не открывает никаких окон?

А то вот все пишу и пишу, и все с окноми, но ведь наверняка есть возможность работы без окон?
[Win32] В продолжение темы: сервисы 14.05.04 15:08  
Автор: Lutien Статус: Незарегистрированный пользователь
<"чистая" ссылка>
В продолжение темы:
А чем отличаются сервисы, от обычнх приложений?
Наскоко трудно переделать обычную прогу в сервис - наверно нужно поддерживать некий специфический интерфейс?

Кстати, наскоко я понимаю запускать приложения в качестве сервиса пожет токо супер пользователь?
О супер пользователе. 15.05.04 01:27  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
> Кстати, наскоко я понимаю запускать приложения в качестве
> сервиса пожет токо супер пользователь?

Терминологически неверно.
"...супер пользователь ...", это термин, который определяет полномочия пользователя в Российских, как правило, сертифицированных ГТК приложениях, типа сикретнет, аккорд и т.д., которые при определённых обстоятельствах и требованиях могут устанавливаются в том числе и на W2k.
В NT и W2k пользуются другой терминологией.
[Win32] Хых, руки у мадемуазель зачесались ;-) 14.05.04 19:47  
Автор: HandleX <Александр М.> Статус: The Elderman
Отредактировано 18.05.04 08:04  Количество правок: 5
<"чистая" ссылка>
> В продолжение темы:
> А чем отличаются сервисы, от обычнх приложений?
> Наскоко трудно переделать обычную прогу в сервис - наверно
> нужно поддерживать некий специфический интерфейс?
Итак, службы... Да, поддерживают они особый интерфейс для "общения" с Service Control Manager'ом.
SCM их и запускает, исходя из того, какие параметры имеются в записи реестра об этой службе. Между
прочим, SCM запускает также и драйверы, поэтому "захват власти" над SCM является лакомой добычей
хакеров и вирусов, поскольку именно оттуда они могут запустить драйвер ядра. А драйвер ядра может
поиметь абсолютно полный контроль над системой.
Но написание драйверов ядра задача не для слабонервных. И не всякий компилятор сможет это
сделать. К примеру, Delphi даже при создании простейшего *.exe, который запускается и тут же
выходит, запихивает в него некий run-time, который использует user-mode API, и запуск
такого "драйвера" вызовет ошибку. Вообще, я не слышал, чтобы драйверы компилировали на
чём-нибудь отличном от M$ VC.

Однако вернёмся к user-mode службам. Сперва службу нужно написать ;-) Там всё просто, в MSDN есть
примеры ;-) Поскольку службу запускает SCM, он некоторое время ждёт, когда служба вызовет
StartServiceCtrlDispatcher(), параметром этой функции является массив из записей вида
"Имя службы-Точка входа в MainServiceProc), из чего делаем вывод, что в одном исполняемом файле
службы может "содержаться" несколько служб. Интересно, что возврат из StartServiceCtrlDispatcher()
происходит только после остановки всех прописанных в этом вызове служб. Если
StartServiceCtrlDispatcher() возвращает false, значит что-то не так, и поможет GetLastError() ;-)

Итак, если всё в порядке, SCM запускает новый поток и в конце концов передаёт управление на
ServiceMain(). В этой функции программист должен первым делать зарегистрировать свою функцию
ServiceControlHandler(), в которую SCM будет "кидать" сообщения о том, что нужно делать службе -
запуститься, перейти в паузу, выйти из паузы, остановиться и проч. Необходимо сказать о
многопоточности. ServiceControlHandler() и ServiceMain() исполняются в отдельных потоках, это нужно
учитывать. Но это и кое-что облегчает... Часто программисты для перевода службы в "паузу" просто
исполняют SuspendThread() для потока ServiceMain(), а с помощью ResumeThread восстанавливают
работу службы. Сервис может "отчитываться" SCM о своём состоянии, докладывать ему об ошибках
во время запуска, "говорить" SCM о том, какие "команды" он может в данный момент воспринимать.
В частности, службу можно запрограммировать так, что остановить её после запуска, или загнать в
паузу, будет невозможно, эдакий "неубиваемый" сервис... Единственное, его можно грохнуть через
TerminateProcess(), но это отдельная история...

И вот, "скелет" службы создан, и руки чешутся нажать на кнопку "Run" компилятора... Однако спешка
нужна сами знаете где... Теперь службу нужно "прописать" в систему. Нужно или в самой программе
службы встроить реакцию на скажем, параметр командной строки типа -install либо написать
программу-установщик, которая зарегистрирует службу в системе. Делается это при помощи вызова
функций API OpenSCManager() и CreateService(), внимательное изучение параметров этих двух функций
поможет понять как управлять и инсталлировать службы, а также какие они бывают и когда SCM будет
их запускать. К примеру, можно указать SCM автоматический запуск службы во время старта OS, или
ручной, или вообще отключить службу...

Ну и наконец, после того, как служба инсталлирована в систему, можно попробовать её запустить...
Делается это встроенным в OS "запускателем" командной строки net start ИмяСлужбы или через
оснастку управления службами.
Отладка служб тоже занятие не для слабонервных ;-) Однако есть подсказки от M$ о том, как это делается.

> Кстати, наскоко я понимаю запускать приложения в качестве
> сервиса пожет токо супер пользователь?
При вызове функции OpenSCManager() одним из параметров является уровень доступа к службам...
По умолчанию обычный пользователь не может установить службу. А вот дальше доступ
(сможет ли пользователь запустить, остановить или даже удалить уже прописанную службу) задаётся
после создании службы при помощи функции SetServiceObjectSecurity(), иныим словами для каждой
службы можно сконфигурировать любой Список Контроля Доступа для любых пользователей и групп в системе.

Ну как, после всего вышесказанного не отпало желание написать службу? ;-)
Для интересующихся и начинающих изучать программирование приведу пример простейшей службы на
Delphi, которая может себя устанавливать и удалять, при запуске "пикает" в системный спикер, может
войти в паузу и быть остановлена.

Успехов.

program SimpleServ;
{$APPTYPE CONSOLE}
uses Windows, WinSVC; //Не используем SysUtils и прочий хлам - размер екзешника у нас будет всего ~25 килобайт

  Function IsWin2KorHigher: BOOL;
  Var aVer: OSVERSIONINFO;
  Begin
    ZeroMemory(@aVer, SizeOf(aVer));
    aVer.dwOSVersionInfoSize := SizeOf(aVer);
    GetVersionEx(aVer);
    Result := (aVer.dwPlatformId = VER_PLATFORM_WIN32_NT) And (aVer.dwMajorVersion >= 5);
  End;

Const
  ServicesCount = 1;
  ServiceName = 'SimpleServ';
  DisplayName = 'Simple Service';
  ServiceType = SERVICE_WIN32_OWN_PROCESS;
  ServiceDescription = 'SimpleServ from Handlex ;-))) This simple program will help you to understand WinNT Services. Mail to alex_wh@mail.ru.';

Var
  ServThrHndl: THandle = 0;
  StopEvent: THandle = 0;
  aServHndl: DWord = 0;
  aServStatus: SERVICE_STATUS;

  Function IntToStr(Value: Integer): String; //Included because we don't use SysUtils
  Var aSign: Bool;
  Begin
    Result := '';

    aSign := Value >= 0;
    If Not aSign Then Value := -Value;

    Repeat
      Result := Char(Value - (Value Div 10) * 10 + Byte('0')) + Result;
      Value := Value Div 10;
    Until Value = 0;

    If Not aSign Then Result := '-' + Result;
  End;

  // Helper function for windows error strings
  function SysErrorMessage(ErrorCode: Integer): string; //Included because we don't use SysUtils
  var
    Len: Integer;
    Buffer: array[0..255] of Char;
  begin
    Len := FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or
      FORMAT_MESSAGE_ARGUMENT_ARRAY, nil, ErrorCode, 0, Buffer,
      SizeOf(Buffer), nil);
    while (Len > 0) and (Buffer[Len - 1] in [#0..#32]) do Dec(Len);
    SetString(Result, Buffer, Len);
    UniqueString(Result);
    ANSItoOEM(PChar(Result), PChar(Result));
    If Result <> '' Then
      Result := '(' + IntToStr(ErrorCode) + ') ' + Result;
  end;

  Procedure ShowInfo;
  Begin
    WriteLn;
    WriteLn('                    -=* SIMPLE TRAINING SERVICE BY HandleX *=-');
  End;

  Procedure ProcessStartupParams; //Реакция на install, uninstall

    Function SetServiceDescription(aSHndl: THandle; aDesc: String): Bool; //Устанавливает "описание" для службы, Win2k и выше
    Const SERVICE_CONFIG_DESCRIPTION: DWord = 1;
    Var
      DynChangeServiceConfig2: Function(
        hService: SC_HANDLE;                    // handle to service
        dwInfoLevel: DWORD;                     // information level
        lpInfo: Pointer): Bool; StdCall;        // new data
      aLibHndl: THandle;
      TempP: PChar;
    Begin
      aLibHndl := GetModuleHandle(advapi32);
      Result := aLibHndl <> 0; If Not Result Then Exit;
      DynChangeServiceConfig2 := GetProcAddress(aLibHndl, 'ChangeServiceConfig2A');
      Result := @DynChangeServiceConfig2 <> Nil; If Not Result Then Exit;
      TempP := PChar(aDesc); //ChangeServiceConfig2 хочет вместо строки указатель на указатель ;-)
      Result := DynChangeServiceConfig2(aSHndl, SERVICE_CONFIG_DESCRIPTION, @TempP);
    End;

  Type
    TToDo = (tdError, tdInstall, tdUninstall);
    TToDo_s = Set of TToDo;
  Const
    ParamStrings: Array[tdInstall..tdUninstall] of String = ('install', 'uninstall');

  Function MapParam(aParam: String): TToDo; //Узнаёт из параметра о вашем желании ;-)
  Var
    J: TToDo;
    TempStr: String;
  Begin
    Result := tdError;
    TempStr := aParam;
    If TempStr[1] In ['/', '-'] Then
      TempStr := Copy(TempStr, 2, Length(TempStr) - 1);
    UniqueString(TempStr);
      CharLower(PChar(TempStr));
    For J := Low(ParamStrings) to High(ParamStrings) Do
      If ParamStrings[J] = TempStr Then
      Begin
        Result := J;
        Exit;
      End;
  End;

  Var
    J: Integer;
    scHndl, sHndl: THandle;
    aStatus: TServiceStatus;
    toDo: TTodo_s;
  Begin
    toDo := [];
    For J := 1 to ParamCount Do
    Begin
      Include(ToDo, MapParam(ParamStr(J)));
      If tdError in toDo Then
      Begin
        ExitCode := ERROR_INVALID_PARAMETER;
        WriteLn('Unknown parameter - ' + ParamStr(J) + '. RTFM, please...');
        Exit;
      End;
    End;

    If [tdInstall, tdUninstall] <= toDo Then
    Begin
      ExitCode := ERROR_INVALID_PARAMETER;
      WriteLn('Error: you can not install and uninstall service simultaniosly. Check params.');
      Exit;
    End;

    If tdInstall in toDo Then //Устанавливаем сервис
    Begin
      Write('Connecting Service Control Manager...');
      scHndl := OpenSCManager(Nil, Nil, SC_MANAGER_CREATE_SERVICE);
      If scHndl = 0 Then
      Begin
        ExitCode := GetLastError;
        WriteLn('Failed!'); WriteLn('Error: ', SysErrorMessage(ExitCode));
        Exit;
      End;
      Try
        WriteLn('Ok');
        Write('Creating service database record...');
        sHndl := CreateService(
          SCHndl, ServiceName, DisplayName,
          SERVICE_QUERY_CONFIG Or SERVICE_CHANGE_CONFIG, ServiceType, SERVICE_DEMAND_START,
          SERVICE_ERROR_NORMAL, PChar(ParamStr(0)), Nil, Nil, Nil, Nil, Nil);

        If sHndl = 0 Then
        Begin
          ExitCode := GetLastError;
          WriteLn('Failed!'); WriteLn('Error: ', SysErrorMessage(ExitCode));
          Exit;
        End;
        Try
          WriteLn('Ok');
          If ServiceDescription <> '' Then
          Begin
            Write('Setting service description...');
            If Not SetServiceDescription(sHndl, ServiceDescription) Then
            Begin
              WriteLn('Failed!');
              WriteLn('Warning: ', SysErrorMessage(GetLastError));
              WriteLn('Warning: SetServiceDesc() failed, but service is installed!');
            End;
            WriteLn('Ok');
          End;
        Finally
          CloseServiceHandle(sHndl);
        End;
      Finally
        CloseServiceHandle(SCHndl);
      End;
      WriteLn('Service "', DisplayName, '" install success.');
    End;

    If tdUninstall in toDo Then //Удаляем сервис...
    Begin
      Write('Connecting Service Control Manager...');
      scHndl := OpenSCManager(Nil, Nil, GENERIC_EXECUTE);
      If scHndl = 0 Then
      Begin
        ExitCode := GetLastError;
        WriteLn('Failed!');
        WriteLn('Error: ', SysErrorMessage(ExitCode));
        Exit;
      End;
      Try
        WriteLn('Ok');

        Write('Opening and Quering Service...');
        sHndl := OpenService(SCHndl, ServiceName, STANDARD_RIGHTS_REQUIRED Or SERVICE_QUERY_STATUS Or SERVICE_STOP);
        If sHndl = 0 Then
        Begin
          ExitCode := GetLastError;
          WriteLn('Failed!'); WriteLn('Error: ', SysErrorMessage(ExitCode));
          Exit;
        End;
        Try
          If Not QueryServiceStatus(sHndl, aStatus) Then
          Begin
            ExitCode := GetLastError;
            WriteLn('Failed!'); WriteLn('Error: ', SysErrorMessage(ExitCode));
            Exit;
          End;
          WriteLn('Ok');

          If aStatus.dwCurrentState <> SERVICE_STOPPED Then
          Begin
            Write('Service is running, wait until stopped...');
            If Not ControlService(sHndl, SERVICE_CONTROL_STOP, aStatus) Then
            Begin
              ExitCode := GetLastError;
              WriteLn('Failed!'); WriteLn('Error: ', SysErrorMessage(ExitCode));
              Exit;
            End;
            While aStatus.dwCurrentState <> SERVICE_STOPPED Do
            Begin
              Sleep(250); Write('.');
              If Not QueryServiceStatus(sHndl, aStatus) Then
              Begin
                ExitCode := GetLastError;
                WriteLn('Failed!'); WriteLn('Error: ', SysErrorMessage(ExitCode));
                Exit;
              End;
            End;
            WriteLn('Stopped');
          End;

          Write('Deleting Service...');
          If Not DeleteService(sHndl) Then
          Begin
            ExitCode := GetLastError;
            WriteLn('Failed!'); WriteLn('Error: ', SysErrorMessage(ExitCode));
            Exit;
          End;
          WriteLn('Ok');
        Finally
          CloseServiceHandle(sHndl);
        End;
      Finally
        CloseServiceHandle(SCHndl);
      End;
      WriteLn('Service uninstall success.');
    End;

  End;

    Function SetState(aState: DWORD): DWORD;
    Begin
      aServStatus.dwCurrentState := aState;
      If aServHndl <> 0 Then
        SetServiceStatus(aServHndl, aServStatus);
      Result := aServStatus.dwCurrentState;
    End;

    Procedure ServiceHandler(fdwControl: DWORD); StdCall;
    Begin
      Case fdwControl Of
        SERVICE_CONTROL_STOP: Begin           //Requests the service to stop.
          SetState(SERVICE_STOP_PENDING);
          SetEvent(StopEvent);
          ResumeThread(ServThrHndl); //Если сервис был в паузе, то рабочий поток надо возобновить
        End;
        SERVICE_CONTROL_PAUSE: Begin          //Requests the service to pause.
          SetState(SERVICE_PAUSE_PENDING);
          SuspendThread(ServThrHndl); //Останавливаем рабочий поток сервиса
          SetState(SERVICE_PAUSED);
        End;
        SERVICE_CONTROL_CONTINUE: Begin       //Requests the paused service to resume.
          SetState(SERVICE_CONTINUE_PENDING);
          ResumeThread(ServThrHndl); //Восстанавливаем рабочий поток сервиса
          SetState(SERVICE_RUNNING);
        End;
        SERVICE_CONTROL_INTERROGATE: Begin    //Requests the service to update immediately its current status information to the service control manager.
          SetState(aServStatus.dwCurrentState); //Говорим SCM о том, в каком состоянии находится наша служба
        End;
        128..255: Begin                       //The service defines the action associated with the control code.
          SuspendThread(ServThrHndl);         //Протяжно пищим в спикер, потому что кто-то послал USER DEFINED CONTROL CODE ;-)
          Windows.Beep(1000, 500);
          ResumeThread(ServThrHndl);
        End;
      End;
    End;
  Procedure MainServiceProc(      // Каждая служба может иметь параметры своего запуска. У нас не используется ;-)
    dwArgc: DWORD;                // number of arguments
    lpszArgv: Pointer); StdCall   // array of arguments
  Begin
    aServHndl := RegisterServiceCtrlHandler(ServiceName, @ServiceHandler);
    If aServHndl = 0 Then
    Begin
      ExitCode := GetLastError;
      Exit; //Какая-то ошибка, срочно выходим, SCM будет ругаться, но сообщить мы ему ничего не можем...
    End;
    ZeroMemory(@aServStatus, SizeOf(aServStatus));
    aServStatus.dwServiceType := ServiceType;
    aServStatus.dwControlsAccepted := SERVICE_ACCEPT_STOP Or SERVICE_ACCEPT_PAUSE_CONTINUE;
    //aServStatus.dwWaitHint := 500; //Здесь может быть подсказка для небыстрых служб о том, как долго она реагирует на команды
    SetState(SERVICE_START_PENDING); //Извещаем SCM, что мы начали стартовать именно этот сервис...

    // Тут идёт рутина инициализации...

    If Not DuplicateHandle(GetCurrentProcess, GetCurrentThread, GetCurrentProcess, @ServThrHndl, 0, FALSE, DUPLICATE_SAME_ACCESS) Then
    Begin //Нам нужен реальный дескриптор потока службы, делаем его...
      aServStatus.dwWin32ExitCode := GetLastError;
      SetState(SERVICE_STOPPED);
      Exit;
    End;

    //Нам нужен unnamed event для реагирования на останов из ControlHandler...
    StopEvent := CreateEvent(Nil, True, False, Nil);
    If StopEvent = 0 Then //Какая-то ошибка - срочно останавливаемся и выходим...
    Begin
      aServStatus.dwWin32ExitCode := GetLastError;
      SetState(SERVICE_STOPPED);
      Exit;
    End;

    // Инит прошёл, пошла работа сервиса...

    SetState(SERVICE_RUNNING); //Момент истины - извещаем SCM что мы работаем!!!

    While WaitForSingleObject(StopEvent, 500) = WAIT_TIMEOUT Do
      Windows.Beep(10000, 10); //Крутим цикл, бипаем по таймауту, иначе выходим...

    // Выполняем остановку сервиса - вычищаемся и выходим...
    CloseHandle(ServThrHndl);
    ServThrHndl := 0;
    CloseHandle(StopEvent);
    StopEvent := 0;

    SetState(SERVICE_STOPPED); // Работа сервиса закончена...

  End;

Var
  ServTableEntryArray: Array[0..ServicesCount] Of TServiceTableEntryA;

begin
{$R *.res}

  //Старт программы...

  If ParamCount > 0 Then //От нас что-то хотят...
  Begin
    ShowInfo;
    ProcessStartupParams; //Выясняем что и выходим...
    Exit;
  End;

  //Готовимся к вызову StartServiceCtrlDispatcher
  ZeroMemory(@ServTableEntryArray, SizeOf(ServTableEntryArray));
  ServTableEntryArray[0].lpServiceName := ServiceName;
  ServTableEntryArray[0].lpServiceProc := @MainServiceProc;

  If Not StartServiceCtrlDispatcher(ServTableEntryArray[0]) Then
  Begin
    ExitCode := GetLastError;
    ShowInfo; //Какой-то косяк, поэтому выводим в консоль сообщение и выходим...
    WriteLn('Error: ', SysErrorMessage(ExitCode));
    WriteLn('This program is Windows NT Service, so it CAN NOT be run from command prompt.');
    WriteLn('You can install it with "/install" parameter.');
    Exit;
  End;

  // Все сервисы завершили свою работу, выходим...
end.

---
Ешё раз спасибо за код!!! Да пашет, классно. ;-))) 24.05.04 06:57  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
Ешё раз спасибо за код!!! Да пашет, классно. ;-)))
Чё я сразу не посмотрел? ;))))
Не за что... FAQ почитай! 8-)) (Ссылка фнутри) 24.05.04 08:04  
Автор: HandleX <Александр М.> Статус: The Elderman
Отредактировано 24.05.04 08:07  Количество правок: 1
<"чистая" ссылка>
Я туда кстати, специально для тебя про Security целый абзац + пример программы привёл... Дерзай! ;-)

FAQ по службам NT
Не открывается ссылка. :( 24.05.04 18:11  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
> Я туда кстати, специально для тебя про Security целый абзац
> + пример программы привёл... Дерзай! ;-)
Не открывается ссылка. :(
А у тебя есть FAQ Makers в списке досок? Зайди туда, там про службы должен быть он последним... dl пообещал скоро в FAQ выложить... 24.05.04 18:22  
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
О, вот теперь появилось. Спасибо ;) Читаю уже ;)) 25.05.04 02:59  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
На faqmakers доступ не для всех.. Надо попросить dl-я, чтобы выложил уже, если замечаний нет. 24.05.04 18:36  
Автор: !mm <Ivan Ch.> Статус: Elderman
<"чистая" ссылка>
Хороший постинг. Думаю, если подчистить, так и статья... 18.05.04 23:44  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
Хороший постинг. Думаю, если подчистить, так и статья неплохая получилась бы. Код есть, что привлекательно.
Один вопрос. Может ли интерактивный сервис создать окно (конечно, что бы туду что-нибудь написать в ответ на ControlService() ) на рабочем столе удалённой рабочей станции интерактивного пользователя.
Спрашиваю, потому, как не уверен. Буквально день назад тема немного обсуждалась на одном из форумов. По своей некомпетентности я , дай, да пропостил следующее:

[quote]Думаю, что нет. По крайней мере без гимора. Но могу ошибаться.
Интерактивный сервис имеет доступ к рабочему столу интерактивного пользователя для рабочей станции Winsta0, если она пущена под учётной записью LocalSystem и имеет флаг SERVICE_INTERACTIVE_PROCESS. Известно, что даже для служб к которым пользователь интерактится при помощи Terminal Services W2k - глючно. То, что ты удалённо можешь посылать коды пользовательских команд - понятно (хотя даже здесь в общем случае не так всё розово. могу ошибаться поскольку я как всегда несколько передёргиваю задачу). Но вот писать, как ты хочешь, служба будет .... куда? Думаю, никуда. Нет у неё доступа к твоему рабочему столу. Она ничего не знает про твой рабочий стол и процессы на нём. Она знает только рабочие столы своего компа. Служба не сможет по твоей команде (она-то доедет) создать на твоём рабочем столе окно и написать туда чего-нибудь. [/quote]

Вопрос - прав я, или мне всю жизнь теперь жить с этим позором.

Второе. Не могли бы Вы указать ссылку на примеры назначения прав группам пользователей на доступ к служдам при помощи SetServiceObjectSecurity(). В MSDN есть описание интерфейса функции. Примеров не обнаруживается.

Спасибо.
Если я правильно понимаю суть проблемы, то при наличии... 19.05.04 09:22  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> Один вопрос. Может ли интерактивный сервис создать окно
> (конечно, что бы туду что-нибудь написать в ответ на
> ControlService() ) на рабочем столе удалённой рабочей
> станции интерактивного пользователя.
Если я правильно понимаю суть проблемы, то при наличии нужных привелегий, установить для удаленной станции и десктопа нужные права проблем не составит.
Собственно вот даже пример есть:
http://msdn.microsoft.com/library/en-us/security/security/starting_an_interactive_client_process_in_c__.asp
Тут правда открывается WinSta0 и ее десктоп, но что мешает заменить ее любой другой?
Проблема в другом. Человек хотел узнать, может ли сервис вывести GUI на рабочий стол пользователя, который конролирует этот сервис при помощи ControlService() с удалённой машины. Однозначно не может... Пользователь слишком далеко ;-) 19.05.04 19:18  
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
Да, Вы совершенно правильно поняли мой вопрос. И меня... 19.05.04 20:39  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
Да, Вы совершенно правильно поняли мой вопрос. И меня радует, что несмотря на практическое полное отсутствие знаний у меня, я случайно пропосил на том форуме верно ;))) Повезло ;)))

Но, вот меня смутил ответ amirul, которому я верю, как себе ;))) Без иронии. Он сказал и указал пример MSDN, что принципиально сервис на удалённом хосте 1 может получить доступ к объекту рабочей станции WinSta0 и ёе рабочему столу интерактивного пользователя на хосте 2:
(HOST1-> servce) -> (HOST2-> WinSta0->DeskTop).

Вопрос, если это так, то может ли тогда ?:
1) сервис хоста1 создать процесс на хосте 2 , затем в этом процессе создать окно (CreateWindow) и туда чего-нибудь пропостить. Грубо говоря удалённый пользователь увидит на десктопе своего компа новое окно, созданное сервисом удалённого хоста.
2) сервис хоста1 посылать сообщения в очередь сообщений windows хоста 2 с тем, чтобы некая програ хоста 2 анализировала эти wParam, lParam сообщения

Спасибо.
Я думаю, что amirul другое имел ввиду... 20.05.04 10:03  
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
> (HOST1-> servce) -> (HOST2-> WinSta0->DeskTop).
Нет, так нельзя.

А по ссылке пример того, как подключится к оконной станции интерактивного пользователя... Но код исполняется _на той же машине_. Т.е. рабочая станция и оконная станция разные вещи ;-)

> Вопрос, если это так, то может ли тогда ?:
> 1) сервис хоста1 создать процесс на хосте 2 , затем в этом
> процессе создать окно (CreateWindow) и туда чего-нибудь
> пропостить. Грубо говоря удалённый пользователь увидит на
> десктопе своего компа новое окно, созданное сервисом
> удалённого хоста.
Нет. На той другой удалённой станции уже что-то должно быть запущено, чтобы "подчинятся".

> 2) сервис хоста1 посылать сообщения в очередь сообщений
> windows хоста 2 с тем, чтобы некая програ хоста 2
> анализировала эти wParam, lParam сообщения
Я думаю проще сделать GUI в отдельной программе, а «квинтэссенцию мудрости» работы этой программы передавать или через ControlService, или через NamedPipe, открытой сервисом.
Да, конечно, описался (виндовс стайшен). Имелось ввиду... 20.05.04 16:05  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
> же машине_. Т.е. рабочая станция и оконная станция разные
> вещи ;-)

Да, конечно, описался (виндовс стайшен). Имелось ввиду воркстайшен--виндовсстатйшен--десктоп :)))
Спасибо за ответ. Для меня это было важно, чтобы в в будущем не пойти по неверному пути.
ControlSirvices не поможет, т.к. нужно не только посылать сообщения пользователя сервису, но и получать удалённо некоторую информацию.
Конечно, именоваными каналами здорово, Вы правы. Но, можно было б и с сокетами. Это было б более универсально, устойчиво и для разных сеток, в которых сервис и управляющий клиент расположены по разные стороны межсетевого экрана. Могу ошибаться, конечно. Проже были б ACL. Нет? Но вот беда, с аунитнификацией в случае сокетов придётся всё самому делать. Как думаете?

Спасибо.
[Win32] еще gcc вроде умеет дрова виндовые компилить 17.05.04 19:44  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
Под mingw есть даже собственные хедеры (и platform sdk и ddk)
эх, вот бы мне так подробно отвечали.. 15.05.04 07:27  
Автор: zelych Статус: Member
<"чистая" ссылка>
services 14.05.04 17:23  
Автор: cb <cb> Статус: Member
Отредактировано 14.05.04 17:24  Количество правок: 1
<"чистая" ссылка>
> В продолжение темы:
> А чем отличаются сервисы, от обычнх приложений?

[skip]

наверное будет правильней обратиться к первоисточникам чем ждать ответов в форуме..

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/services.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndllpro/html/msdn_ntservic.asp
http://www.win2000mag.com/Articles/Index.cfm?ArticleID=8723

cb.
Короче много трепа тут вокруг милой дамы. 13.05.04 20:05  
Автор: Serge Статус: Незарегистрированный пользователь
<"чистая" ссылка>
> Просветите плиз дуру грешную ;)
>
> Собственно, как написать прогу под windows которая не
> открывает никаких окон?
>
> А то вот все пишу и пишу, и все с окноми, но ведь наверняка
> есть возможность работы без окон?
Короче много трепа тут вокруг милой дамы.


#include <windows.h>

int PASCAL WinMain(HINSTANCE hinst,HINSTANCE hprev, LPSTR param,int cmdShow)
{
return(0);
}

и погнали наши городских.
1  |  2  |  3 >>  »  




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


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