Захват экрана Winlogon в Windows 7/10

Мне нужно захватить экран winlogon в WinXP / Win7 / 10.
Для WinXP я использую зеркальный драйвер и стандартную методику, подобную этой:

...
extern "C" __declspec(dllexport) void SetActiveDesktop() {
if ( currentDesk != NULL )
CloseDesktop( currentDesk );

currentDesk = OpenInputDesktop( 0, FALSE, GENERIC_ALL );
BOOL ret = SetThreadDesktop( currentDesk );
int LASTeRR = GetLastError();
}

extern "C" __declspec(dllexport) HBITMAP CaptureAnImage(
int width,
int height,
int bitsPerPixel )
{
HBITMAP hbmScreen;
LPTSTR bih = NULL;
HDC hdcMemDC = NULL;

int colorDepth = GetCurrentColorDepth();

if ( bitsPerPixel > colorDepth && colorDepth > 0 )
bitsPerPixel = colorDepth;

// Checks a current HDC
if ( currHdc == NULL ) {
SetActiveDesktop();
currHdc = GetDcMirror();
}

if ( prevHdc != currHdc ) {
prevHdc = currHdc;
}

// Check an application instance handler
if ( appInstance == NULL )
appInstance = GetModuleHandle(NULL);

// Creates a compatible DC which is used in a BitBlt from the window DC
hdcMemDC = CreateCompatibleDC( currHdc );

if( hdcMemDC == NULL )
{
return NULL;
}

// Defines bitmap parameters
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = width;
bi.bmiHeader.biHeight = height;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = bitsPerPixel;

// Creates a bitmap with defined parameters
hbmScreen = CreateDIBSection( hdcMemDC, &bi, DIB_RGB_COLORS, (VOID**)&lpBitmapBits, NULL, 0 );

if ( hbmScreen == NULL ) {
return NULL;
}

// Select the compatible bitmap into the compatible memory DC.
SelectObject(hdcMemDC,hbmScreen);

// Bit block transfer into our compatible memory DC.
if(!BitBlt(hdcMemDC,
0,0,
width, height,
currHdc,
0,0,
SRCCOPY))
{
SetActiveDesktop();
currHdc = GetDC(NULL);//GetDcMirror();
hdcMemDC = CreateCompatibleDC( currHdc );

// Creates a bitmap with defined parameters
hbmScreen = CreateDIBSection( hdcMemDC, &bi, DIB_RGB_COLORS, (VOID**)&lpBitmapBits, NULL, 0 );

if(!BitBlt(hdcMemDC,
0,0,
width, height,
currHdc,
0,0,
SRCCOPY ))
{
DeleteDC( hdcMemDC );
return hbmScreen;
}
}

if (DeleteDC( hdcMemDC ) == FALSE ) {
return NULL;
}

return hbmScreen;
}

И, к счастью, это работает на WinXP. Но в случае с win7 / win10 у меня совсем другая ситуация:

Функция SetThreadDesktop после переключения на winlogon всегда возвращает FALSE с ошибкой 5 (доступ запрещен)
Я пытался изменить стратегию:

  • В первую очередь программа создает список всех существующих оконных станций и их рабочих столов.
  • После этого программа опрашивает все WINSTA и HDESK и сохраняет скриншоты на диске.

    Я пытался запустить эту программу в 3 режимах:

    • как администратор
    • как сервис с включенным взаимодействием с рабочим столом.
    • на рабочем столе winlogon с использованием флагов CreateProcess (в этом случае программа просто падает)

И результат был тот же.
Что я делаю не так? Должен ли я попробовать Desktop Duplication API?

Заранее спасибо за ваши ответы!

1

Решение

Как Winlogon это безопасный рабочий стол Вы должны запустить приложение под учетной записью LOCAL_SYSTEM, чтобы получить к нему доступ.

Пример: служба Windows, которая работает под LOCAL_SYSTEM, которая запускает пользовательское приложение (которое захватывает экран) в сеансе консоли.

В вашем коде нет проверки для возвращаемого значения OpenInputDesktop, которое может быть NULL с кодом ошибки 5 (доступ запрещен).

Проверьте этот ответ а также для получения дополнительной информации

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]