Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.11.2013, 15:54   #1
al-tom
Новичок
Джуниор
 
Регистрация: 29.11.2013
Сообщений: 1
По умолчанию Службы и GDI

Приветствую всех.
Есть Windows служба:

Код:
  SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
  if(!hSCManager) {
    return false;
  }
  
  GetModuleFileName(NULL, servicePath, MAX_PATH);
  DWORD wver = LOWORD(GetVersion());
  wver = (LOBYTE(wver) << 8) + HIBYTE(wver);
  DWORD stype = SERVICE_WIN32_OWN_PROCESS;
  if (wver < 0x0600) {
    stype |= SERVICE_INTERACTIVE_PROCESS;
  }
  SC_HANDLE hService = CreateService(
     hSCManager,
     serviceName,
     serviceName,
     SERVICE_ALL_ACCESS,
     stype,
     SERVICE_AUTO_START,
     SERVICE_ERROR_NORMAL,
     servicePath,
     NULL, NULL, NULL, NULL, NULL
  );

  CloseServiceHandle(hService);
  CloseServiceHandle(hSCManager);
Служба запускает другой процесс:

Код:
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  memset(&si, 0, sizeof(si));
  si.cb = sizeof(si);
  memset(&pi, 0, sizeof(pi));
  
  HANDLE proc = GetCurrentProcess();
  HANDLE cur_token, new_token;
  DWORD session = WTSGetActiveConsoleSessionId();
  
  if (!OpenProcessToken(proc, TOKEN_DUPLICATE, &cur_token)) {
    return false;
  }
  if (!DuplicateTokenEx(cur_token, TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, &new_token)) {
    return false;
  }
  if (!SetTokenInformation(new_token, (TOKEN_INFORMATION_CLASS) TokenSessionId, &session, sizeof(session))) {
    return false;
  }

  CreateProcessAsUser(new_token, NULL, "program.exe scr", NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);

  CloseHandle(token);
  CloseHandle(userToken);
Этот процесс занимается снятием скриншотов:

Код:
  HDC winDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
  HDC bmpDC = CreateCompatibleDC(winDC);
 
  int width = GetDeviceCaps(winDC, HORZRES);
  int height = GetDeviceCaps(winDC, VERTRES);
 
  BITMAPINFOHEADER bmpInfoHeader;
  BITMAPFILEHEADER bmpFileHeader;
 
  bmpFileHeader.bfType = 0x4d42;
  bmpFileHeader.bfSize = 0;
  bmpFileHeader.bfReserved1 = 0;
  bmpFileHeader.bfReserved2 = 0;
  bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
 
  bmpInfoHeader.biSize = sizeof(bmpInfoHeader);
  bmpInfoHeader.biWidth = width;
  bmpInfoHeader.biHeight = height;
  bmpInfoHeader.biPlanes = 1;
  bmpInfoHeader.biBitCount = 24;
  bmpInfoHeader.biCompression = BI_RGB;
  bmpInfoHeader.biSizeImage = width * height * 3;
  bmpInfoHeader.biXPelsPerMeter = 0;
  bmpInfoHeader.biYPelsPerMeter = 0;
  bmpInfoHeader.biClrUsed = 0;
  bmpInfoHeader.biClrImportant = 0;
  
  BITMAPINFO info;
  info.bmiHeader = bmpInfoHeader;
 
  void* memory;
  HBITMAP bitmap;
  bitmap = CreateDIBSection(winDC, &info, DIB_RGB_COLORS, &memory, NULL, 0);
  SelectObject(bmpDC, bitmap);
  if (!BitBlt(bmpDC, 0, 0, width, height, winDC, 0, 0, SRCCOPY | CAPTUREBLT)) {
    return false;
  }

  FILE *f = fopen("scrsht.bmp", "wb");
  fwrite(&bmpFileHeader, 1, sizeof(BITMAPFILEHEADER), f);
  fwrite(&bmpInfoHeader, 1, sizeof(BITMAPINFOHEADER), f);
  fwrite(memory, 1, bmpInfoHeader.biSizeImage, f);
  fclose(f);
Проблема заключается в том, что при работе под Windows XP приходится делать службу интерактивной
(иначе на скриншоте получаем черный прямоугольник), а интерактивные службы могут быть запрещены на машине клиента.
Но, коль скоро скриншоты делает не служба, а запущенный процесс, напрашивается вывод о том, что процесс
наследует какие-то права службы, которые мешают ему получить доступ к консоли.
При этом, даже в случае интерактивной службы, при отображении экрана приветствия получается черный прямоугольник.
По некоторым причинам служба и дочерний процесс представлены одним exe файлом, но непосредственно функционал
(запуск дочернего процесса и снятие скриншотов) расположен в dll (общей). Было сомнение по поводу того, что
проблема может быть связана с загрузкой этой dll из сервиса и последующим использованием ее же в дочернем
процессе, но разнесение функционала по разным dll не помогло.
Возможно, я не стал бы биться над решением этой задачи, списал бы это на ограничения винды, если бы не TightVNC,
которая производит аналогичные манипуляции, при этом не регистрируя сервис как интерактивный.
Собственно, отсюда 2 вопроса:
1. Какие права нужно добавить/отобрать у процесса, чтобы его работа не зависела от настроек службы (если проблема в правах)?
2. Что может мешать получению скриншота с экрана приветствия?
al-tom вне форума Ответить с цитированием
Старый 01.12.2013, 01:57   #2
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

Неинтерактивный сервис выполняется на другом десктопе, возможно проблема именно в этом. Попробуйте запускать процесс заданным параметром:
Код:
si.lpDesktop = "WinSta0\Default";
Возможно наведет на мысль Windows Stations.
counter вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
GDI+ Dimarik Общие вопросы .NET 4 03.05.2010 20:54
Службы Bat{CMD}_Men Общие вопросы Delphi 0 04.10.2009 14:50
GDI EdNovice Win Api 4 12.02.2008 09:14
службы bloood Общие вопросы C/C++ 1 02.04.2007 02:04