IPC в Vista (сервис и приложение)

Я создаю приложение в Vista, которое включает службу и консольное приложение. Оба они работают под одной учетной записью.

В сервисе я создаю событие и жду этого события. В консольном приложении я открываю то же событие (здесь начинается проблема) и вызываю функцию SetEvent. Я не могу открыть событие (ошибка 5, доступ запрещен) в консольном приложении. Я поискал в сети и увидел кое-что об уровне целостности (я не уверен, что проблема связана с уровнем целостности). и приложение имеет разные уровни целостности.

вот часть кода, где происходит IPC

служба

DWORD
WINAPI IpcThread(LPVOID lpParam)
{
HANDLE ghRequestEvent = NULL ;

ghRequestEvent = CreateEvent(NULL, FALSE,
FALSE, "Global\Event1") ; //creating the event

if (NULL == ghRequestEvent)
{
//error
}
while(1)
{
WaitForSingleObject(ghRequestEvent, INFINITE) //waiting for the event
//here some action related to event
}
}

Консольное приложение

Здесь, в приложении, открытие события и установка события

unsigned int
event_notification()
{
HANDLE ghRequestEvent = NULL ;



 ghRequestEvent = OpenEvent(SYNCHRONIZE|EVENT_MODIFY_STATE, FALSE, "Global\Event1") ;

if (NULL == ghRequestEvent)
{
//error
}
SetEvent(ghRequestEvent) ;
} 

Я запускаю оба приложения (сервисное и консольное) с правами администратора (я вошел в систему как администратор и запустил консольное приложение, щелкнув правой кнопкой мыши и используя опцию «запуск от имени администратора»).

Ошибка, которую я получаю в консольном приложении (где я открываю событие), - это ошибка № 5 (доступ запрещен).

Так что будет очень полезно, если вы расскажете, как сделать IPC между службой и приложением в Vista.

заранее спасибо

Navaneeth

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
3 559
5

Ответы 5

Служба и приложение работают от имени одного пользователя с разными уровнями целостности или от имени разных пользователей?

Если первое, то эта статья из MSDN который говорит об уровнях целостности, может помочь. У них есть пример кода для понижения уровня целостности файла. Я не уверен, что это может иметь отношение к мероприятию.

#include <sddl.h>
#include <AccCtrl.h>
#include <Aclapi.h>

void SetLowLabelToFile()
{
  // The LABEL_SECURITY_INFORMATION SDDL SACL to be set for low integrity 
  #define LOW_INTEGRITY_SDDL_SACL_W L"S:(ML;;NW;;;LW)"
  DWORD dwErr = ERROR_SUCCESS;
  PSECURITY_DESCRIPTOR pSD = NULL;    

  PACL pSacl = NULL; // not allocated
  BOOL fSaclPresent = FALSE;
  BOOL fSaclDefaulted = FALSE;
  LPCWSTR pwszFileName = L"Sample.txt";

  if (ConvertStringSecurityDescriptorToSecurityDescriptorW(
         LOW_INTEGRITY_SDDL_SACL_W, SDDL_REVISION_1, &pSD;, NULL)) 
  {
    if (GetSecurityDescriptorSacl(pSD, &fSaclPresent;, &pSacl;, 
         &fSaclDefaulted;))
    {
      // Note that psidOwner, psidGroup, and pDacl are 
      // all NULL and set the new LABEL_SECURITY_INFORMATION
      dwErr = SetNamedSecurityInfoW((LPWSTR) pwszFileName, 
                 SE_FILE_OBJECT, LABEL_SECURITY_INFORMATION, 
                 NULL, NULL, NULL, pSacl);
    }
    LocalFree(pSD);
  }
}

Если это последнее, вы можете посмотреть на эту ссылку, которая предлагает создать NULL ACL и связать ее с объектом (в примере это именованный канал, но подход аналогичен для события, которое я уверен:

BYTE sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
SECURITY_ATTRIBUTES sa;

sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = &sd;

InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, (PACL) 0, FALSE);

CreateNamedPipe(..., &sa);

Где можно найти описание использованной выше строки LOW_INTEGRITY_SDDL_SACL_W? Я видел это только в образце кода, но никогда не определялся официально.

Clay 09.11.2008 17:22

Здесь определяется язык определения дескрипторов безопасности (SDDL) msdn.microsoft.com/en-us/library/aa379567(VS.85).aspx

1800 INFORMATION 09.11.2008 21:12

Во-первых, важно концептуально понять, что требуется. Как только это будет понято, мы сможем взять это оттуда.

На сервере это должно выглядеть примерно так:

{
   HANDLE hEvent;
   hEvent = CreateEvent(null, true, false, TEXT("MyEvent"));
   while (1)
   {
       WaitForSingleObject (hEvent);
       ResetEvent (hEvent);
       /* Do something -- start */
       /* Processing 1 */
       /* Processing 2 */
       /* Do something -- end */
   }
}

На клиенте:

{
   HANDLE hEvent;
   hEvent = OpenEvent(0, false, TEXT("MyEvent"));
   SetEvent (hEvent);
}

Несколько замечаний:

  • ResetEvent должен быть как можно раньше, сразу после WaitForSingleObject или WaitForMultipleObjects. Если несколько клиентов используют сервер и обработка первого клиента требует времени, второй клиент может установить событие, и оно может не быть обнаружено, пока сервер обрабатывает первый запрос.
  • Вы должны реализовать какой-то механизм, который будет уведомлять клиента о завершении обработки сервером.
  • Прежде чем выполнять какую-либо службу win32 mumbo-jumbo, запустите сервер как простое приложение. Это устранит любые проблемы, связанные с безопасностью.

Вам следует использовать событие автоматического сброса (второй параметр CreateEvent имеет значение false), а не беспокоиться о состоянии гонки, которое вы описываете.

1800 INFORMATION 09.11.2008 21:15

Я заметил, что вы создаете объект в «глобальном» пространстве имен, но пытаетесь открыть его в локальном пространстве имен. Помогает ли добавление "Global \" к имени в открытом вызове?

Кроме того, есть ли что-нибудь в области // ошибки, чтобы вы знали, что оно не было создано?

@Navaneeth:

Отличная обратная связь. Поскольку ваша ошибка - Доступ запрещен, я бы изменил желаемый доступ с EVENT_ALL_ACCESS, который вам действительно не нужен, на

(SYNCHRONIZE | EVENT_MODIFY_STATE)

SYNCHRONIZE позволяет ждать события, а EVENT_MODIFY_STATE позволяет вызывать SetEvent, ResetEvent и PulseEvent.

Возможно, вам понадобится больше доступа, но это очень необычно.

«1800 ИНФОРМАЦИЯ» правильно - это проблема UIPI; в любом случае не используйте события в новом коде, сигнал события может быть потерян, если целевая блокировка события происходит в коде APC пользовательского режима, когда оно запускается. Канонический способ написания службы / приложения в Win32 - использовать вызовы RPC для пересечения границы UIPI.

Другие вопросы по теме