bool InputDesktopSelected() { DWORD dummy; char threadname[256]; char inputname[256]; HDESK threaddesktop = GetThreadDesktop(GetCurrentThreadId()); HDESK inputdesktop = OpenInputDesktop(0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); if (inputdesktop == NULL) return FALSE; if (!GetUserObjectInformation(threaddesktop, UOI_NAME, &threadname, 256, &dummy)) { CloseDesktop(inputdesktop); return FALSE; } if (!GetUserObjectInformation(inputdesktop, UOI_NAME, &inputname, 256, &dummy)) { CloseDesktop(inputdesktop); return FALSE; } CloseDesktop(inputdesktop); if (strcmp(threadname, inputname) != 0) { //if (strcmp(inputname, "Screen-saver") == 0) { return SelectDesktop(); } return FALSE; } return TRUE; }
/************************************************ * Create a new Desktop and run a Thread in it. * * (Win NT+). * ************************************************/ int DLL_EXP_IMP WINAPI Thread_Desktop(LPTHREAD_START_ROUTINE ThreadFunc, THREAD_DATA *td) { HDESK hOriginalThread; HDESK hOriginalInput; HDESK hNewDesktop; // Save original ... hOriginalThread = GetThreadDesktop(GetCurrentThreadId()); hOriginalInput = OpenInputDesktop(0, FALSE, DESKTOP_SWITCHDESKTOP); // Create a new Desktop and switch to it hNewDesktop = CreateDesktop(td->szDesktopName, NULL, NULL, 0, GENERIC_ALL, NULL); SetThreadDesktop(hNewDesktop); SwitchDesktop(hNewDesktop); // Execute thread in new desktop td->hDesk = hNewDesktop; StartThread(ThreadFunc, td); // Restore original ... SwitchDesktop(hOriginalInput); SetThreadDesktop(hOriginalThread); // Close the Desktop CloseDesktop(hNewDesktop); return 0; }
bool SwitchInputDesktop() { BOOL bRet = false; DWORD dwLengthNeeded; HDESK hOldDesktop, hNewDesktop; char strCurrentDesktop[256], strInputDesktop[256]; hOldDesktop = GetThreadDesktop(GetCurrentThreadId()); memset(strCurrentDesktop, 0, sizeof(strCurrentDesktop)); GetUserObjectInformation(hOldDesktop, UOI_NAME, &strCurrentDesktop, sizeof(strCurrentDesktop), &dwLengthNeeded); hNewDesktop = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED); memset(strInputDesktop, 0, sizeof(strInputDesktop)); GetUserObjectInformation(hNewDesktop, UOI_NAME, &strInputDesktop, sizeof(strInputDesktop), &dwLengthNeeded); if (lstrcmpi(strInputDesktop, strCurrentDesktop) != 0) { SetThreadDesktop(hNewDesktop); bRet = true; } CloseDesktop(hOldDesktop); CloseDesktop(hNewDesktop); return bRet; }
LRESULT CIdlePreventDlg::SendWakeEvent(WPARAM wparam, LPARAM lparam) { // This ensures we only send wake events while the machine isn't locked. Seems Windows queues some events and sometimes they happen at once as soon as you unlock the computer. HDESK test = OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, TRUE,DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |DESKTOP_SWITCHDESKTOP |GENERIC_WRITE); if (test != NULL) { if(RDPFriendlyWakeEnabled) { keybd_event(VK_RSHIFT,0xB6, KEYEVENTF_KEYUP, 0); } else { INPUT mouseInput[1]; mouseInput[0].mi.dx = 0; mouseInput[0].mi.dy = 0; mouseInput[0].mi.mouseData = 0; mouseInput[0].mi.dwFlags = MOUSEEVENTF_MOVE; mouseInput[0].mi.time = 0; mouseInput[0].mi.dwExtraInfo = NULL; SendInput(1, mouseInput, sizeof(mouseInput)); SetThreadExecutionState(ES_DISPLAY_REQUIRED); } } CloseDesktop(test); return 0; }
bool SelectDesktop() { HDESK desktop; HDESK old_desktop; DWORD dummy; char new_name[256]; desktop = OpenInputDesktop(0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); if (desktop == NULL) return FALSE; old_desktop = GetThreadDesktop(GetCurrentThreadId()); if (!GetUserObjectInformation(desktop, UOI_NAME, &new_name, 256, &dummy)) { CloseDesktop(desktop); return FALSE; } if(!SetThreadDesktop(desktop)) { CloseDesktop(desktop); return FALSE; } CloseDesktop(old_desktop); return TRUE; }
/************************************************* * Create a new Desktop and run a Process in it. * * (Win NT+). * *************************************************/ int DLL_EXP_IMP WINAPI Process_Desktop(char *szDesktopName, char *szPath) { HDESK hOriginalThread; HDESK hOriginalInput; HDESK hNewDesktop; // Save original ... hOriginalThread = GetThreadDesktop(GetCurrentThreadId()); hOriginalInput = OpenInputDesktop(0, FALSE, DESKTOP_SWITCHDESKTOP); // Create a new Desktop and switch to it hNewDesktop = CreateDesktop(szDesktopName, NULL, NULL, 0, GENERIC_ALL, NULL); SetThreadDesktop(hNewDesktop); SwitchDesktop(hNewDesktop); // Execute process in new desktop StartProcess(szDesktopName, szPath); // Restore original ... SwitchDesktop(hOriginalInput); SetThreadDesktop(hOriginalThread); // Close the Desktop CloseDesktop(hNewDesktop); return 0; }
// - SelectDesktop(char *) // Switches the current thread into a different desktop, by name // Calling with a valid desktop name will place the thread in that desktop. // Calling with a NULL name will place the thread in the current input desktop. BOOL vncService::SelectDesktop(char *name, HDESK *new_desktop) { //return false; // Are we running on NT? if (IsWinNT()) { HDESK desktop; vnclog.Print(LL_INTERR, VNCLOG("SelectDesktop \n")); if (name != NULL) { vnclog.Print(LL_INTERR, VNCLOG("OpenInputdesktop2 named\n")); // Attempt to open the named desktop desktop = OpenDesktop(name, 0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); } else { vnclog.Print(LL_INTERR, VNCLOG("OpenInputdesktop2 NULL\n")); // No, so open the input desktop desktop = OpenInputDesktop(0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); } // Did we succeed? if (desktop == NULL) { vnclog.Print(LL_INTERR, VNCLOG("OpenInputdesktop2 \n")); return FALSE; } else vnclog.Print(LL_INTERR, VNCLOG("OpenInputdesktop2 OK\n")); // Switch to the new desktop if (!SelectHDESK(desktop)) { // Failed to enter the new desktop, so free it! if (!CloseDesktop(desktop)) vnclog.Print(LL_INTERR, VNCLOG("SelectDesktop failed to close desktop\n")); return FALSE; } if (new_desktop) { if (*new_desktop) CloseDesktop(*new_desktop); *new_desktop = desktop; } // We successfully switched desktops! return TRUE; } return (name == NULL); }
BOOL COpenDesktop::_OpenDesktop(LPCWSTR szName) { WCHAR pvInfo[128] = {0}; if(szName != NULL) { lstrcpy((LPSTR)pvInfo, (LPCSTR)szName); } else { HDESK hActiveDesktop; DWORD dwLen; hActiveDesktop = OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, FALSE, MAXIMUM_ALLOWED); GetUserObjectInformation(hActiveDesktop, UOI_NAME, pvInfo, sizeof(pvInfo), &dwLen); CloseDesktop(hActiveDesktop); } m_hwinstaCurrent = GetProcessWindowStation(); CheckPointer(m_hwinstaCurrent,FALSE); m_hdeskCurrent = GetThreadDesktop(GetCurrentThreadId()); CheckPointer(m_hdeskCurrent,FALSE); // ´ò¿ªwinsta0 m_hwinsta = OpenWindowStation(_T("winsta0"), FALSE, WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES); CheckPointer(m_hwinsta,FALSE); if (!SetProcessWindowStation(m_hwinsta)) { return FALSE; } // ´ò¿ªdesktop m_hdesk = OpenDesktop((LPSTR)pvInfo, 0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS); CheckPointer(m_hdesk,FALSE); SetThreadDesktop(m_hdesk); return TRUE; }
void Desktops::init() { resize(DESKTOP_COUNT); #ifdef _USE_HDESK DesktopPtr& desktop = (*this)[0]; desktop = DesktopPtr(new Desktop(OpenInputDesktop(0, FALSE, DESKTOP_SWITCHDESKTOP))); #endif }
HDESK DesktopSelector::getInputDesktop() { return OpenInputDesktop(0, TRUE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); }
// get the current input desktop name and compare with // the desktop the call thread attached ,if not equal, // then switch to the input desktop BOOL SwitchInputDesktop() { HDESK threaddesk = GetThreadDesktop(GetCurrentThreadId()); HDESK inputdesk = OpenInputDesktop(0, DF_ALLOWOTHERACCOUNTHOOK,GENERIC_ALL); if (inputdesk == NULL) { DebugOutF(filelog::log_error,("OpenInputDesktop failed with %d"),GetLastError()); return FALSE; } DWORD len=0; TCHAR szThread[MAX_PATH]; TCHAR szInput[MAX_PATH]; szThread[0] = _T('\0'); szInput[0] = _T('\0'); BOOL res = FALSE; try { // get desktop name if(!GetUserObjectInformation(threaddesk, UOI_NAME, szThread, MAX_PATH, &len)){ DebugOutF(filelog::log_error,("GetUserObjectInformation failed with %d"),GetLastError()); throw FALSE; } if (!GetUserObjectInformation(inputdesk, UOI_NAME, szInput, MAX_PATH, &len)) { DebugOutF(filelog::log_error,("GetUserObjectInformation failed with %d"),GetLastError()); throw FALSE; } //compare,if not equal,then switch to the input desktop if (_tcsicmp(szThread, szInput) != 0) { if(!SetThreadDesktop(inputdesk)){ DebugOutF(filelog::log_error,("SetThreadDesktop %s failed with %d"),szInput,GetLastError()); throw FALSE; } DebugOutF(filelog::log_info,("switch input desktop %s"),szInput); res = TRUE; } } catch(BOOL b1) { res = b1; } if(threaddesk)CloseDesktop(threaddesk); if(inputdesk)CloseDesktop(inputdesk); return res; }
static BOOL is_desktop_hidden(void) { HDESK desk; /* We cannot get current desktop. But we can try to open the current desktop, which will most likely be a secure desktop (if it isn't ours), and will thus fail. */ desk = OpenInputDesktop(0, FALSE, GENERIC_READ); if (desk) CloseDesktop(desk); return desk == NULL; }
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { try { wchar_t* desktop = L"NewDesktop"; HDESK hThreadDT = GetThreadDesktop(GetCurrentThreadId()); HDESK hInputDT = OpenInputDesktop(0, FALSE, DESKTOP_SWITCHDESKTOP); HDESK hNewDT = CreateDesktop(desktop, NULL, NULL, 0, GENERIC_ALL, NULL); SetThreadDesktop(hNewDT); SwitchDesktop(hNewDT); PROCESS_INFORMATION pi; STARTUPINFO si; memset(&pi, 0, sizeof(pi)); memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.lpDesktop = desktop; wchar_t cmdline[MAX_PATH]; wsprintf(cmdline, L"%s %s", L"NAMCredentialWizard.exe", L"/u"); if (CreateProcess(L"NAMCredentialWizard.exe", cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { WaitForSingleObject(pi.hProcess, INFINITE); } else { wchar_t msg[1000]; wsprintf(msg,L"CreateProcess failed (%d)",GetLastError()); MessageBox(NULL,msg,NULL,MB_OK); } SwitchDesktop(hInputDT); SetThreadDesktop(hThreadDT); CloseDesktop(hNewDT); return 0; } catch(...) { MessageBox(NULL,L"Caught Exception",NULL,MB_OK); } }
BOOL vncService::SelectDesktop(char *name) { // Are we running on NT? if (IsWinNT()) { HDESK desktop; if (name != NULL) { // Attempt to open the named desktop desktop = OpenDesktop(name, 0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); } else { // No, so open the input desktop desktop = OpenInputDesktop(0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); } // Did we succeed? if (desktop == NULL) { vnclog.Print(LL_INTERR, VNCLOG("unable to open desktop, error=%d\n"), GetLastError()); return FALSE; } // Switch to the new desktop if (!SelectHDESK(desktop)) { // Failed to enter the new desktop, so free it! vnclog.Print(LL_INTERR, VNCLOG("SelectDesktop() failed to select desktop\n")); if (!CloseDesktop(desktop)) vnclog.Print(LL_INTERR, VNCLOG("SelectDesktop failed to close desktop, error=%d\n"), GetLastError()); return FALSE; } // We successfully switched desktops! return TRUE; } return (name == NULL); }
DWORD WINAPI BlackWindow(LPVOID lpParam) { // TODO: Place code here. HDESK desktop; desktop = OpenInputDesktop(0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE ); if (desktop == NULL) vnclog.Print(LL_INTERR, VNCLOG("OpenInputdesktop Error \n")); else vnclog.Print(LL_INTERR, VNCLOG("OpenInputdesktop OK\n")); HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId()); DWORD dummy; char new_name[256]; if (desktop) { if (!GetUserObjectInformation(desktop, UOI_NAME, &new_name, 256, &dummy)) { vnclog.Print(LL_INTERR, VNCLOG("!GetUserObjectInformation \n")); } vnclog.Print(LL_INTERR, VNCLOG("SelectHDESK to %s (%x) from %x\n"), new_name, desktop, old_desktop); if (!SetThreadDesktop(desktop)) { vnclog.Print(LL_INTERR, VNCLOG("SelectHDESK:!SetThreadDesktop \n")); } } create_window(); MSG msg; while (GetMessage(&msg,0,0,0) != 0) { TranslateMessage(&msg); DispatchMessage(&msg); } vnclog.Print(LL_INTERR, VNCLOG("end BlackWindow \n")); SetThreadDesktop(old_desktop); if (desktop) CloseDesktop(desktop); return 0; }
BOOL vncService::InputDesktopSelected() { // Are we running on NT? if (IsWinNT()) { // Get the input and thread desktops HDESK threaddesktop = GetThreadDesktop(GetCurrentThreadId()); HDESK inputdesktop = OpenInputDesktop(0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); if (inputdesktop == NULL) { // Returning TRUE on ERROR_BUSY fixes the bug #1109102. // FIXME: Probably this is not the most correct way to do it. return (GetLastError() == ERROR_BUSY) ? TRUE : FALSE; } DWORD dummy; char threadname[256]; char inputname[256]; if (!GetUserObjectInformation(threaddesktop, UOI_NAME, &threadname, 256, &dummy)) { if (!CloseDesktop(inputdesktop)) vnclog.Print(LL_INTWARN, VNCLOG("failed to close input desktop\n")); return FALSE; } _ASSERT(dummy <= 256); if (!GetUserObjectInformation(inputdesktop, UOI_NAME, &inputname, 256, &dummy)) { if (!CloseDesktop(inputdesktop)) vnclog.Print(LL_INTWARN, VNCLOG("failed to close input desktop\n")); return FALSE; } _ASSERT(dummy <= 256); if (!CloseDesktop(inputdesktop)) vnclog.Print(LL_INTWARN, VNCLOG("failed to close input desktop\n")); if (strcmp(threadname, inputname) != 0) return FALSE; } return TRUE; }
int DesktopThread::Run() { if (!SetThreadDesktop(_desktop._hdesktop)) return -1; HDESK hDesk_old = OpenInputDesktop(0, FALSE, DESKTOP_SWITCHDESKTOP); if (!SwitchDesktop(_desktop._hdesktop)) return -1; if (!_desktop._hwndDesktop) _desktop._hwndDesktop = DesktopWindow::Create(); int ret = Window::MessageLoop(); SwitchDesktop(hDesk_old); return ret; }
String MSWindowsSession::getActiveDesktopName() { String result; try { HDESK hd = OpenInputDesktop(0, TRUE, GENERIC_READ); if (hd != NULL) { DWORD size; GetUserObjectInformation(hd, UOI_NAME, NULL, 0, &size); TCHAR* name = (TCHAR*)alloca(size + sizeof(TCHAR)); GetUserObjectInformation(hd, UOI_NAME, name, size, &size); result = name; CloseDesktop(hd); } } catch (std::exception error) { LOG((CLOG_ERR "failed to get active desktop name: %s", error.what())); } return result; }
bool AttachToWorkstation() { DWORD dwThreadId; // Ensure connection to service window station and desktop, and // save their handles. hwinstaSave = GetProcessWindowStation(); dwThreadId = GetCurrentThreadId(); hdeskSave = GetThreadDesktop(dwThreadId); // connect to the User's window station and desktop. //RpcImpersonateClient(h); hwinstaUser = OpenWindowStation("WinSta0", TRUE, MAXIMUM_ALLOWED); if (hwinstaUser == NULL) { //RpcRevertToSelf(); err_printf("AttachToWorkstation:OpenWindowStation failed, error %d.\n", GetLastError()); return false; } SetProcessWindowStation(hwinstaUser); hdeskUser = OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, TRUE, MAXIMUM_ALLOWED); /* DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS); */ //RpcRevertToSelf(); if (hdeskUser == NULL) { SetProcessWindowStation(hwinstaSave); CloseWindowStation(hwinstaUser); err_printf("AttachToWorkstation:OpenInputDesktop failed, error %d\n", GetLastError()); return false; } SetThreadDesktop(hdeskUser); return true; }
/* * Switch to the input desktop and set it as this threads desktop. */ HDESK vncdll_getinputdesktop( BOOL bSwitchStation ) { DWORD dwResult = ERROR_ACCESS_DENIED; HWINSTA hWindowStation = NULL; HDESK hInputDesktop = NULL; HWND hDesktopWnd = NULL; do { if( bSwitchStation ) { // open the WinSta0 as some services are attached to a different window station. hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS ); if( !hWindowStation ) { if( RevertToSelf() ) hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS ); } // if we cant open the defaut input station we wont be able to take a screenshot if( !hWindowStation ) BREAK_WITH_ERROR( "[VNCDLL] vncdll_getinputdesktop: Couldnt get the WinSta0 Window Station", ERROR_INVALID_HANDLE ); // set the host process's window station to this sessions default input station we opened if( !SetProcessWindowStation( hWindowStation ) ) BREAK_ON_ERROR( "[VNCDLL] vncdll_getinputdesktop: SetProcessWindowStation failed" ); } // grab a handle to the default input desktop (e.g. Default or WinLogon) hInputDesktop = OpenInputDesktop( 0, FALSE, MAXIMUM_ALLOWED ); if( !hInputDesktop ) BREAK_ON_ERROR( "[VNCDLL] vncdll_getinputdesktop: OpenInputDesktop failed" ); // set this threads desktop to that of this sessions default input desktop on WinSta0 SetThreadDesktop( hInputDesktop ); } while( 0 ); return hInputDesktop; }
BOOL vncService::IsWSLocked() { if (!IsWinNT()) return false; bool bLocked = false; HDESK hDesk; BOOL bRes; DWORD dwLen; char sName[200]; hDesk = OpenInputDesktop(0, FALSE, 0); if (hDesk == NULL) { bLocked = true; } else { bRes = GetUserObjectInformation(hDesk, UOI_NAME, sName, sizeof(sName), &dwLen); if (bRes) sName[dwLen]='\0'; else sName[0]='\0'; if (_stricmp(sName,"Default") != 0) bLocked = true; // WS is locked or screen saver active else bLocked = false ; } if (hDesk != NULL) CloseDesktop(hDesk); return bLocked; }
BOOL SelectDesktop(char *name) { HDESK desktop; if (name != NULL) { // Attempt to open the named desktop desktop = OpenDesktop(name, 0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); } else { // No, so open the input desktop desktop = OpenInputDesktop(0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); } // Did we succeed? if (desktop == NULL) { return FALSE; } // Switch to the new desktop if (!SelectHDESK(desktop)) { // Failed to enter the new desktop, so free it! CloseDesktop(desktop); return FALSE; } // We successfully switched desktops! return TRUE; }
DWORD MessageBoxSecure(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType) { DWORD retunvalue; if (m_fRunningFromExternalService) { HDESK desktop=NULL; HDESK old_desktop; desktop = OpenInputDesktop(0, FALSE,DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); old_desktop = GetThreadDesktop(GetCurrentThreadId()); if (desktop && old_desktop && old_desktop!=desktop) { SetThreadDesktop(desktop); retunvalue=MessageBox(hWnd,lpText,lpCaption,uType); SetThreadDesktop(old_desktop); CloseDesktop(desktop); } else retunvalue=0; } else { retunvalue=MessageBox(hWnd,lpText,lpCaption,uType); } return retunvalue; }
void vncVideoDriver::Deactivate_NT50() { HDESK hdeskInput; HDESK hdeskCurrent; // it is important to us to be able to deactivate // even what we have never activated. thats why we look it up, all over // if (!m_devname[0]) // return; // ... and forget the name *m_devname = 0; DISPLAY_DEVICE dd; INT devNum = 0; if (!LookupVideoDeviceAlt(szDriverString, szDriverStringAlt, devNum, &dd)) { vnclog.Print(LL_INTERR, VNCLOG("No '%s' or '%s' found.\n"), szDriverString, szDriverStringAlt); return; } DEVMODE devmode; FillMemory(&devmode, sizeof(DEVMODE), 0); devmode.dmSize = sizeof(DEVMODE); devmode.dmDriverExtra = 0; BOOL change = EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devmode); devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; devmode.dmDeviceName[0] = '\0'; HKEY hKeyDevice = CreateDeviceKey(szMiniportName); if (hKeyDevice == NULL) return; DWORD one = 0; if (RegSetValueEx(hKeyDevice,("Attach.ToDesktop"), 0, REG_DWORD, (unsigned char *)&one,4) != ERROR_SUCCESS) { vnclog.Print(LL_INTERR, VNCLOG("Can't set Attach.ToDesktop to 0x1\n")); } // reverting to default behavior RegDeleteValue(hKeyDevice, ("Cap.DfbBackingMode")); RegDeleteValue(hKeyDevice, ("Order.BltCopyBits.Enabled")); pChangeDisplaySettingsEx pCDS = NULL; HINSTANCE hInstUser32 = LoadNImport("User32.DLL", "ChangeDisplaySettingsExA", pCDS); if (!hInstUser32) return; // Save the current desktop hdeskCurrent = GetThreadDesktop(GetCurrentThreadId()); if (hdeskCurrent != NULL) { hdeskInput = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED); if (hdeskInput != NULL) SetThreadDesktop(hdeskInput); } // 24 bpp screen mode is MUNGED to 32 bpp. see vncDesktop::ThunkBitmapInfo() if (devmode.dmBitsPerPel==24) devmode.dmBitsPerPel = 32; // Add 'Default.*' settings to the registry under above hKeyProfile\mirror\device (*pCDS)((TCHAR *)dd.DeviceName, &devmode, NULL, CDS_UPDATEREGISTRY, NULL); // Reset desktop SetThreadDesktop(hdeskCurrent); // Close the input desktop CloseDesktop(hdeskInput); RegCloseKey(hKeyDevice); FreeLibrary(hInstUser32); }
// outType = 1 : console, 2: file, 3: buffer bool Screen::takeScreenshot(const int outType, const char *filename, char **buffer, DWORD &size) { if (outType < 1 || outType > 3) { return false; } bool result = false; HBITMAP handleBitmapScreen = 0; HDC handleMemoryDC = 0; HWND hWnd = 0; HDC handleDeviceContextOfWindow = 0; // open the WinSta0 as some services are attached to a different window station. HWINSTA hWindowStation = hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS ); if( !hWindowStation ) { if( RevertToSelf() ) hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS ); } // if we cant open the defaut input station we wont be able to take a screenshot if( !hWindowStation ) { MYPRINTF( "[SCREENSHOT] screenshot: Couldnt get the WinSta0 Window Station"); return false; } // get the current process's window station so we can restore it later on. HWINSTA hOrigWindowStation = GetProcessWindowStation(); // set the host process's window station to this sessions default input station we opened if( !SetProcessWindowStation( hWindowStation ) ) { MYPRINTF( "[SCREENSHOT] screenshot: SetProcessWindowStation failed" ); return false; } // grab a handle to the default input desktop (e.g. Default or WinLogon) //HDESK hInputDesktop = OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED ); HDESK hInputDesktop = OpenInputDesktop( 0, FALSE, MAXIMUM_ALLOWED ); if( !hInputDesktop ) { MYPRINTF( "[SCREENSHOT] screenshot: OpenInputDesktop failed" ); return false; } //if (SwitchDesktop(hInputDesktop) == 0){ // MYPRINTF( "[SCREENSHOT] screenshot: SwitchDesktop failed" ); // return false; //} // get the threads current desktop so we can restore it later on HDESK hOrigDesktop = GetThreadDesktop( GetCurrentThreadId() ); // set this threads desktop to that of this sessions default input desktop on WinSta0 SetThreadDesktop( hInputDesktop ); // and now we can grab a handle to this input desktop HWND hDesktopWnd = GetDesktopWindow(); int screenWidth = GetSystemMetrics (SM_CXSCREEN); int screenHeight = GetSystemMetrics (SM_CYSCREEN); MYPRINTF("width: %d, height: %d\n", screenWidth, screenHeight); // Retrieve the handle to a display device context for the client // area of the window. HDC handleDeviceContextOfScreen = GetDC(hDesktopWnd); //HDC handleDeviceContextOfScreen = CreateDC("DISPLAY",NULL,NULL,NULL); if (handleDeviceContextOfScreen == 0) { MYPRINTF("GetDC(0) has failed: %d", GetLastError()); goto done; } if (outType == 1) { // print to console //The source DC is the entire screen and the destination DC is the current window (HWND) // Get the client area for size calculation HWND hWnd = GetForegroundWindow(); HDC handleDeviceContextOfWindow = GetDC(hWnd); if (handleDeviceContextOfScreen == 0) { MYPRINTF("GetDC(hWnd) has failed: %d", GetLastError()); goto done; } RECT rcClient; GetClientRect(hWnd, &rcClient); //This is the best stretch mode SetStretchBltMode(handleDeviceContextOfWindow, HALFTONE); if(!StretchBlt(handleDeviceContextOfWindow, 0,0, rcClient.right, rcClient.bottom, handleDeviceContextOfScreen, 0,0, screenWidth, screenHeight, SRCCOPY)) { MYPRINTF("StretchBlt has failed: %d", GetLastError()); goto done; } result = true; } else { // Create a compatible DC which is used in a BitBlt from the window DC handleMemoryDC = CreateCompatibleDC(handleDeviceContextOfScreen); if(!handleMemoryDC) { MYPRINTF("CreateCompatibleDC has failed: %d", GetLastError()); goto done; } BITMAPINFO bmpinfo; ZeroMemory(&bmpinfo,sizeof(bmpinfo)); LONG dwWidth = GetDeviceCaps(handleDeviceContextOfScreen, HORZRES); LONG dwHeight = GetDeviceCaps(handleDeviceContextOfScreen, VERTRES); //dwBPP = GetDeviceCaps(hScreen, BITSPIXEL); LONG dwBPP = 24; LONG dwNumColors = GetDeviceCaps(handleDeviceContextOfScreen, NUMCOLORS); LPVOID pBits; bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpinfo.bmiHeader.biWidth = dwWidth; bmpinfo.bmiHeader.biHeight = dwHeight; bmpinfo.bmiHeader.biPlanes = 1; bmpinfo.bmiHeader.biBitCount = (WORD) dwBPP; bmpinfo.bmiHeader.biCompression = BI_RGB; bmpinfo.bmiHeader.biSizeImage = 0; bmpinfo.bmiHeader.biXPelsPerMeter = 0; bmpinfo.bmiHeader.biYPelsPerMeter = 0; bmpinfo.bmiHeader.biClrUsed = dwNumColors; bmpinfo.bmiHeader.biClrImportant = dwNumColors; handleBitmapScreen = CreateDIBSection(handleDeviceContextOfScreen, &bmpinfo, DIB_PAL_COLORS, &pBits, NULL, 0); /** // Create a compatible bitmap from the Window DC handleBitmapScreen = CreateCompatibleBitmap(handleDeviceContextOfScreen, screenWidth, screenHeight); if(!handleBitmapScreen) { MYPRINTF("CreateCompatibleBitmap Failed: %d", GetLastError()); goto done; } */ // Select the compatible bitmap into the compatible memory DC. if (SelectObject(handleMemoryDC, handleBitmapScreen) == 0) { MYPRINTF("SelectObject Failed: %d", GetLastError()); goto done; } // Bit block transfer into our compatible memory DC. if(!BitBlt(handleMemoryDC, 0, 0, screenWidth, screenHeight, handleDeviceContextOfScreen, 0, 0, SRCCOPY)) { MYPRINTF("BitBlt has failed: %d", GetLastError()); goto done; } BITMAP bmpScreen; // Get the BITMAP from the HBITMAP if (GetObject(handleBitmapScreen, sizeof(BITMAP), &bmpScreen) == 0) { MYPRINTF("GetObject has failed: %d", GetLastError()); goto done; } BITMAPFILEHEADER bmfHeader; BITMAPINFOHEADER bi; bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = bmpScreen.bmWidth; bi.biHeight = bmpScreen.bmHeight; bi.biPlanes = 1; bi.biBitCount = 32; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight; HANDLE hData = GlobalAlloc(GHND,dwBmpSize); char *bmpdata = (char *)GlobalLock(hData); // Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that // call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc // have greater overhead than HeapAlloc. HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize); char *lpbitmap = (char *)GlobalLock(hDIB); // Gets the "bits" from the bitmap and copies them into a buffer // which is pointed to by lpbitmap. //GetDIBits(handleDeviceContextOfWindow, handleBitmapScreen, 0, GetDIBits(handleDeviceContextOfScreen, handleBitmapScreen, 0, (UINT)bmpScreen.bmHeight, lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS); // Add the size of the headers to the size of the bitmap to get the total file size DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); //Offset to where the actual bitmap bits start. bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); //Size of the file bmfHeader.bfSize = dwSizeofDIB; //bfType must always be BM for Bitmaps bmfHeader.bfType = 0x4D42; //BM DWORD dwBytesWritten = 0; UINT mybmpsize = dwBmpSize + sizeof(bi) + sizeof(bmfHeader); // put headers together to make a .bmp in memory memcpy(bmpdata, &bmfHeader, sizeof(bmfHeader)); memcpy(bmpdata + sizeof(bmfHeader), &bi, sizeof(bi)); memcpy(bmpdata + sizeof(bmfHeader) + sizeof(bi), lpbitmap, dwBmpSize); if (outType == 2) { // Now convert to JPEG if (bmp2jpegtofile((PBYTE)bmpdata, 70, filename ) == 0) { MYPRINTF("unable to write jpg"); } else { result = true; } } else { if (bmp2jpegtomemory((PBYTE)bmpdata, 70, (BYTE **)buffer, &size) == 0) { MYPRINTF("unable to write jpg"); } else { result = true; } } //Unlock and Free the DIB from the heap GlobalUnlock(hDIB); GlobalFree(hDIB); GlobalUnlock(hData); GlobalFree(hData); } //Clean up done: // restore the origional process's window station if( hOrigWindowStation ) SetProcessWindowStation( hOrigWindowStation ); // restore the threads origional desktop if( hOrigDesktop ) SetThreadDesktop( hOrigDesktop ); // close the WinSta0 window station handle we opened if( hWindowStation ) CloseWindowStation( hWindowStation ); // close this last to avoid a handle leak... if( hInputDesktop ) CloseDesktop( hInputDesktop ); DeleteObject(handleBitmapScreen); DeleteObject(handleMemoryDC); ReleaseDC(NULL,handleDeviceContextOfScreen); ReleaseDC(hWnd,handleDeviceContextOfWindow); return result; }
/* * Take a screenshot of this sessions default input desktop on WinSta0 * and send it as a JPEG image to a named pipe. */ DWORD screenshot( int quality, DWORD dwPipeName ) { DWORD dwResult = ERROR_ACCESS_DENIED; HWINSTA hWindowStation = NULL; HWINSTA hOrigWindowStation = NULL; HDESK hInputDesktop = NULL; HDESK hOrigDesktop = NULL; HWND hDesktopWnd = NULL; HDC hdc = NULL; HDC hmemdc = NULL; HBITMAP hbmp = NULL; BYTE * pJpegBuffer = NULL; OSVERSIONINFO os = {0}; char cNamedPipe[MAX_PATH] = {0}; // If we use SM_C[X|Y]VIRTUALSCREEN we can screenshot the whole desktop of a multi monitor display. int xmetric = SM_CXVIRTUALSCREEN; int ymetric = SM_CYVIRTUALSCREEN; DWORD dwJpegSize = 0; int sx = 0; int sy = 0; do { _snprintf( cNamedPipe, MAX_PATH, "\\\\.\\pipe\\%08X", dwPipeName ); os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); if( !GetVersionEx( &os ) ) BREAK_ON_ERROR( "[SCREENSHOT] screenshot: GetVersionEx failed" ) // On NT we cant use SM_CXVIRTUALSCREEN/SM_CYVIRTUALSCREEN. if( os.dwMajorVersion <= 4 ) { xmetric = SM_CXSCREEN; ymetric = SM_CYSCREEN; } // open the WinSta0 as some services are attached to a different window station. hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS ); if( !hWindowStation ) { if( RevertToSelf() ) hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS ); } // if we cant open the defaut input station we wont be able to take a screenshot if( !hWindowStation ) BREAK_WITH_ERROR( "[SCREENSHOT] screenshot: Couldnt get the WinSta0 Window Station", ERROR_INVALID_HANDLE ); // get the current process's window station so we can restore it later on. hOrigWindowStation = GetProcessWindowStation(); // set the host process's window station to this sessions default input station we opened if( !SetProcessWindowStation( hWindowStation ) ) BREAK_ON_ERROR( "[SCREENSHOT] screenshot: SetProcessWindowStation failed" ); // grab a handle to the default input desktop (e.g. Default or WinLogon) hInputDesktop = OpenInputDesktop( 0, FALSE, MAXIMUM_ALLOWED ); if( !hInputDesktop ) BREAK_ON_ERROR( "[SCREENSHOT] screenshot: OpenInputDesktop failed" ); // get the threads current desktop so we can restore it later on hOrigDesktop = GetThreadDesktop( GetCurrentThreadId() ); // set this threads desktop to that of this sessions default input desktop on WinSta0 SetThreadDesktop( hInputDesktop ); // and now we can grab a handle to this input desktop hDesktopWnd = GetDesktopWindow(); // and get a DC from it so we can read its pixels! hdc = GetDC( hDesktopWnd ); if( !hdc ) BREAK_ON_ERROR( "[SCREENSHOT] screenshot. GetDC failed" ); // back up this DC with a memory DC hmemdc = CreateCompatibleDC( hdc ); if( !hmemdc ) BREAK_ON_ERROR( "[SCREENSHOT] screenshot. CreateCompatibleDC failed" ); // calculate the width and height sx = GetSystemMetrics( xmetric ); sy = GetSystemMetrics( ymetric ); // and create a bitmap hbmp = CreateCompatibleBitmap( hdc, sx, sy ); if( !hbmp ) BREAK_ON_ERROR( "[SCREENSHOT] screenshot. CreateCompatibleBitmap failed" ); // this bitmap is backed by the memory DC if( !SelectObject( hmemdc, hbmp ) ) BREAK_ON_ERROR( "[SCREENSHOT] screenshot. SelectObject failed" ); // BitBlt the screenshot of this sessions default input desktop on WinSta0 onto the memory DC we created if( !BitBlt( hmemdc, 0, 0, sx, sy, hdc, 0, 0, SRCCOPY ) ) BREAK_ON_ERROR( "[SCREENSHOT] screenshot. BitBlt failed" ); // finally convert the BMP we just made into a JPEG... if( bmp2jpeg( hbmp, hmemdc, quality, &pJpegBuffer, &dwJpegSize ) != 1 ) BREAK_WITH_ERROR( "[SCREENSHOT] screenshot. bmp2jpeg failed", ERROR_INVALID_HANDLE ); // we have succeded dwResult = ERROR_SUCCESS; } while( 0 ); // if we have successfully taken a screenshot we send it back via the named pipe // but if we have failed we send back a zero byte result to indicate this failure. if( dwResult == ERROR_SUCCESS ) screenshot_send( cNamedPipe, pJpegBuffer, dwJpegSize ); else screenshot_send( cNamedPipe, NULL, 0 ); if( hdc ) ReleaseDC( hDesktopWnd, hdc ); if( hmemdc ) DeleteDC( hmemdc ); if( hbmp ) DeleteObject( hbmp ); // free the jpeg images buffer if( pJpegBuffer ) free( pJpegBuffer ); // restore the origional process's window station if( hOrigWindowStation ) SetProcessWindowStation( hOrigWindowStation ); // restore the threads origional desktop if( hOrigDesktop ) SetThreadDesktop( hOrigDesktop ); // close the WinSta0 window station handle we opened if( hWindowStation ) CloseWindowStation( hWindowStation ); // close this last to avoid a handle leak... if( hInputDesktop ) CloseDesktop( hInputDesktop ); return dwResult; }
DWORD WINAPI imp_desktop_thread(LPVOID lpParam) { vncServer *server = (vncServer *)lpParam; HDESK desktop; //vnclog.Print(LL_INTERR, VNCLOG("SelectDesktop \n")); //vnclog.Print(LL_INTERR, VNCLOG("OpenInputdesktop2 NULL\n")); desktop = OpenInputDesktop(0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE ); if (desktop == NULL) vnclog.Print(LL_INTERR, VNCLOG("OpenInputdesktop Error \n")); else vnclog.Print(LL_INTERR, VNCLOG("OpenInputdesktop OK\n")); HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId()); DWORD dummy; char new_name[256]; if (!GetUserObjectInformation(desktop, UOI_NAME, &new_name, 256, &dummy)) { vnclog.Print(LL_INTERR, VNCLOG("!GetUserObjectInformation \n")); } vnclog.Print(LL_INTERR, VNCLOG("SelectHDESK to %s (%x) from %x\n"), new_name, desktop, old_desktop); if (!SetThreadDesktop(desktop)) { vnclog.Print(LL_INTERR, VNCLOG("SelectHDESK:!SetThreadDesktop \n")); } // ImpersonateCurrentUser_(); char m_username[UNLEN+1]; HWINSTA station = GetProcessWindowStation(); if (station != NULL) { DWORD usersize; GetUserObjectInformation(station, UOI_USER_SID, NULL, 0, &usersize); DWORD dwErrorCode = GetLastError(); SetLastError(0); if (usersize != 0) { DWORD length = sizeof(m_username); if (GetUserName(m_username, &length) == 0) { UINT error = GetLastError(); if (error != ERROR_NOT_LOGGED_ON) { vnclog.Print(LL_INTERR, VNCLOG("getusername error %d\n"), GetLastError()); SetThreadDesktop(old_desktop); CloseDesktop(desktop); Sleep(500); return FALSE; } } } } vnclog.Print(LL_INTERR, VNCLOG("Username %s \n"),m_username); // Create tray icon and menu vncMenu *menu = new vncMenu(server); if (menu == NULL) { vnclog.Print(LL_INTERR, VNCLOG("failed to create tray menu\n")); PostQuitMessage(0); } // This is a good spot to handle the old PostAdd messages if (PostAddAutoConnectClient_bool) vncService::PostAddAutoConnectClient( pszId_char ); if (PostAddAutoConnectClient_bool_null) vncService::PostAddAutoConnectClient( NULL ); if (PostAddConnectClient_bool) vncService::PostAddConnectClient( pszId_char ); if (PostAddConnectClient_bool_null) vncService::PostAddConnectClient( NULL ); if (PostAddNewClient_bool) { PostAddNewClient_bool=false; vnclog.Print(LL_INTERR, VNCLOG("PostAddNewClient IIIII\n")); vncService::PostAddNewClient(address_vcard, port_int); } //adzm 2009-06-20 if (PostAddNewRepeaterClient_bool) { PostAddNewRepeaterClient_bool=false; vnclog.Print(LL_INTERR, VNCLOG("PostAddNewRepeaterClient II\n")); vncService::PostAddNewRepeaterClient(); } bool Runonce=false; MSG msg; while (GetMessage(&msg,0,0,0) != 0) { TranslateMessage(&msg); DispatchMessage(&msg); if (fShutdownOrdered && !Runonce) { Runonce=true; if (menu) menu->Shutdown(true); } if (hShutdownEvent) { // vnclog.Print(LL_INTERR, VNCLOG("****************** SDTimer tic\n")); DWORD result = WaitForSingleObject(hShutdownEvent, 1); if (WAIT_OBJECT_0 == result) { ResetEvent(hShutdownEvent); fShutdownOrdered = true; vnclog.Print(LL_INTERR, VNCLOG("****************** WaitForSingleObject - Shutdown server\n")); } } } // sf@2007 - Close all (vncMenu,tray icon, connections...) if (menu != NULL) delete menu; //vnclog.Print(LL_INTERR, VNCLOG("GetMessage stop \n")); SetThreadDesktop(old_desktop); CloseDesktop(desktop); // RevertToSelf(); return 0; }
BOOL vncDesktop::InitWindow() { vnclog.Print(LL_INTERR, VNCLOG("InitWindow called\n")); HDESK desktop; desktop = OpenInputDesktop(0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE ); if (desktop == NULL) vnclog.Print(LL_INTERR, VNCLOG("InitWindow:OpenInputdesktop Error \n")); else vnclog.Print(LL_INTERR, VNCLOG("InitWindow:OpenInputdesktop OK\n")); HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId()); DWORD dummy; char new_name[256]; if (!GetUserObjectInformation(desktop, UOI_NAME, &new_name, 256, &dummy)) { vnclog.Print(LL_INTERR, VNCLOG("InitWindow:!GetUserObjectInformation \n")); } vnclog.Print(LL_INTERR, VNCLOG("InitWindow:SelectHDESK to %s (%x) from %x\n"), new_name, desktop, old_desktop); if (!SetThreadDesktop(desktop)) { vnclog.Print(LL_INTERR, VNCLOG("InitWindow:SelectHDESK:!SetThreadDesktop \n")); } HMODULE hUser32 = LoadLibrary("user32.dll"); CHANGEWINDOWMESSAGEFILTER pfnFilter = NULL; pfnFilter =(CHANGEWINDOWMESSAGEFILTER)GetProcAddress(hUser32,"ChangeWindowMessageFilter"); if (pfnFilter) pfnFilter(RFB_SCREEN_UPDATE, MSGFLT_ADD); if (pfnFilter) pfnFilter(RFB_COPYRECT_UPDATE, MSGFLT_ADD); if (pfnFilter) pfnFilter(RFB_MOUSE_UPDATE, MSGFLT_ADD); if (pfnFilter) pfnFilter(WM_QUIT, MSGFLT_ADD); if (pfnFilter) pfnFilter(WM_SHUTDOWN, MSGFLT_ADD); if (m_wndClass == 0) { // Create the window class WNDCLASSEX wndclass; wndclass.cbSize = sizeof(wndclass); wndclass.style = 0; wndclass.lpfnWndProc = &DesktopWndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hAppInstance; wndclass.hIcon = NULL; wndclass.hCursor = NULL; wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = (const char *) NULL; wndclass.lpszClassName = szDesktopSink; wndclass.hIconSm = NULL; // Register it m_wndClass = RegisterClassEx(&wndclass); if (!m_wndClass) { vnclog.Print(LL_INTERR, VNCLOG("failed to register window class\n")); SetEvent(restart_event); return FALSE; } } // And create a window m_hwnd = CreateWindow(szDesktopSink, "WinVNC", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 200, NULL, NULL, hAppInstance, NULL); if (m_hwnd == NULL) { vnclog.Print(LL_INTERR, VNCLOG("failed to create hook window\n")); SetEvent(restart_event); return FALSE; } SetTimer(m_hwnd,1001,1000,NULL); // Set the "this" pointer for the window helper::SafeSetWindowUserData(m_hwnd, (LONG_PTR)this); // Enable clipboard hooking // adzm - 2010-07 - Fix clipboard hangs m_settingClipboardViewer = true; m_hnextviewer = SetClipboardViewer(m_hwnd); m_settingClipboardViewer = false; StopDriverWatches=false; DrvWatch mywatch; mywatch.stop=&StopDriverWatches; mywatch.hwnd=m_hwnd; if (VideoBuffer()) { DWORD myword; HANDLE T1=NULL; T1=CreateThread(NULL,0,Driverwatch,m_hwnd,0,&myword); if (T1) CloseHandle(T1); } vnclog.Print(LL_INTERR, VNCLOG("OOOOOOOOOOOO load hookdll's\n")); //////////////////////// hModule=NULL; char szCurrentDir[MAX_PATH]; if (GetModuleFileName(NULL, szCurrentDir, MAX_PATH)) { char* p = strrchr(szCurrentDir, '\\'); if (p == NULL) return 0; *p = '\0'; strcat (szCurrentDir,"\\vnchooks.dll"); } hSCModule=NULL; char szCurrentDirSC[MAX_PATH]; if (GetModuleFileName(NULL, szCurrentDirSC, MAX_PATH)) { char* p = strrchr(szCurrentDirSC, '\\'); if (p == NULL) return 0; *p = '\0'; #ifdef _X64 strcat (szCurrentDirSC,"\\schook64.dll"); #else strcat (szCurrentDirSC,"\\schook.dll"); #endif } hW8Module=NULL; char szCurrentDirW8[MAX_PATH]; if (WIN8) { if (GetModuleFileName(NULL, szCurrentDirW8, MAX_PATH)) { char* p = strrchr(szCurrentDirW8, '\\'); if (p == NULL) return 0; *p = '\0'; #ifdef _X64 strcat (szCurrentDirW8,"\\w8hook64.dll"); #else strcat (szCurrentDirW8,"\\w8hook.dll"); #endif } } UnSetHooks=NULL; SetMouseFilterHook=NULL; SetKeyboardFilterHook=NULL; SetMouseFilterHooks=NULL; SetKeyboardFilterHooks=NULL; SetHooks=NULL; UnSetHook=NULL; SetHook=NULL; hModule = LoadLibrary(szCurrentDir); hSCModule = LoadLibrary(szCurrentDirSC);//TOFIX resource leak if (WIN8) hW8Module = LoadLibrary(szCurrentDirW8); if (hModule) { strcpy_s(g_hookstring,"vnchook"); UnSetHooks = (UnSetHooksFn) GetProcAddress( hModule, "UnSetHooks" ); SetMouseFilterHook = (SetMouseFilterHookFn) GetProcAddress( hModule, "SetMouseFilterHook" ); SetKeyboardFilterHook = (SetKeyboardFilterHookFn) GetProcAddress( hModule, "SetKeyboardFilterHook" ); SetHooks = (SetHooksFn) GetProcAddress( hModule, "SetHooks" ); } if (hSCModule) { UnSetHook = (UnSetHookFn) GetProcAddress( hSCModule, "UnSetHook" ); SetHook = (SetHookFn) GetProcAddress( hSCModule, "SetHook" ); SetMouseFilterHooks = (SetMouseFilterHookFn) GetProcAddress( hSCModule, "SetMouseFilterHook" ); SetKeyboardFilterHooks = (SetKeyboardFilterHookFn) GetProcAddress( hSCModule, "SetKeyboardFilterHook" ); } startw8=NULL; stopw8=NULL; capturew8=NULL; if (hW8Module) { startw8=(StartW8)GetProcAddress(hW8Module,"StartW8"); stopw8=(StopW8)GetProcAddress(hW8Module,"StopW8"); capturew8=(CaptureW8)GetProcAddress(hW8Module,"CaptureW8"); } /////////////////////////////////////////////// vnclog.Print(LL_INTERR, VNCLOG("OOOOOOOOOOOO start dispatch\n")); MSG msg; SetEvent(restart_event); while (TRUE) { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { vnclog.Print(LL_INTERR, VNCLOG("OOOOOOOOOOOO %i %i\n"),msg.message,msg.hwnd); if (msg.message==WM_TIMER) { if(msg.wParam==1001) keepalive(); } if (msg.message==WM_QUIT || fShutdownOrdered) { vnclog.Print(LL_INTERR, VNCLOG("OOOOOOOOOOOO called wm_quit\n")); DestroyWindow(m_hwnd); SetEvent(trigger_events[5]); break; } else if (msg.message==WM_SHUTDOWN) { vnclog.Print(LL_INTERR, VNCLOG("OOOOOOOOOOOO called wm_user+4\n")); DestroyWindow(m_hwnd); break; } else if (msg.message==RFB_SCREEN_UPDATE) { if (can_be_hooked) { vnclog.Print(LL_INTERR, VNCLOG("RFB_SCREEN_UPDATE \n")); rfb::Rect rect; rect.tl = rfb::Point((SHORT)LOWORD(msg.wParam), (SHORT)HIWORD(msg.wParam)); rect.br = rfb::Point((SHORT)LOWORD(msg.lParam), (SHORT)HIWORD(msg.lParam)); //Buffer coordinates rect.tl.x-=m_ScreenOffsetx; rect.br.x-=m_ScreenOffsetx; rect.tl.y-=m_ScreenOffsety; rect.br.y-=m_ScreenOffsety; vnclog.Print(LL_INTERR, VNCLOG("REct3 %i %i %i %i \n"),rect.tl.x,rect.br.x,rect.tl.y,rect.br.y); rect = rect.intersect(m_Cliprect); if (!rect.is_empty()) { while (lock_region_add) Sleep(5); rgnpump.assign_union(rect); SetEvent(trigger_events[1]); } } } else if (msg.message==RFB_MOUSE_UPDATE) { if (can_be_hooked) { vnclog.Print(LL_INTERR, VNCLOG("RFB_MOUSE_UPDATE \n")); SetCursor((HCURSOR) msg.wParam); SetEvent(trigger_events[2]); } } else { if (msg.message==WM_USER+3 )vnclog.Print(LL_INTERR, VNCLOG("OOOOOOOOOOOO called wm_user+3\n")); TranslateMessage(&msg); DispatchMessage(&msg); } } else WaitMessage(); } KillTimer(m_hwnd,1001); if (hModule)FreeLibrary(hModule); if (hSCModule)FreeLibrary(hSCModule); if (hW8Module)FreeLibrary(hW8Module); SetThreadDesktop(old_desktop); CloseDesktop(desktop); /////////////////////// vnclog.Print(LL_INTERR, VNCLOG("OOOOOOOOOOOO end dispatch\n")); m_hwnd = NULL; return TRUE; }
static void test_inputdesktop2(void) { HWINSTA w1, w2; HDESK thread_desk, new_desk, input_desk, hdesk; DWORD ret; thread_desk = GetThreadDesktop(GetCurrentThreadId()); ok(thread_desk != NULL, "GetThreadDesktop failed!\n"); w1 = GetProcessWindowStation(); ok(w1 != NULL, "GetProcessWindowStation failed!\n"); SetLastError(0xdeadbeef); w2 = CreateWindowStationA("winsta_test", 0, WINSTA_ALL_ACCESS, NULL); ret = GetLastError(); ok(w2 != NULL || ret == ERROR_ACCESS_DENIED, "CreateWindowStation failed (%u)\n", ret); if (!w2) { win_skip("Not enough privileges for CreateWindowStation\n"); return; } ret = EnumDesktopsA(GetProcessWindowStation(), desktop_callbackA, 0); ok(!ret, "EnumDesktopsA failed!\n"); input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(input_desk != NULL, "OpenInputDesktop failed!\n"); ret = CloseDesktop(input_desk); ok(ret, "CloseDesktop failed!\n"); ret = SetProcessWindowStation(w2); ok(ret, "SetProcessWindowStation failed!\n"); hdesk = GetThreadDesktop(GetCurrentThreadId()); ok(hdesk != NULL, "GetThreadDesktop failed!\n"); ok(hdesk == thread_desk, "thread desktop should not change after winstation changed!\n"); ret = EnumDesktopsA(GetProcessWindowStation(), desktop_callbackA, 0); new_desk = CreateDesktopA("desk_test", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL); ok(new_desk != NULL, "CreateDesktop failed!\n"); ret = EnumDesktopsA(GetProcessWindowStation(), desktop_callbackA, 0); ok(!ret, "EnumDesktopsA failed!\n"); SetLastError(0xdeadbeef); input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(input_desk == NULL, "OpenInputDesktop should fail on non default winstation!\n"); ok(GetLastError() == ERROR_INVALID_FUNCTION || broken(GetLastError() == 0xdeadbeef), "last error %08x\n", GetLastError()); hdesk = OpenDesktopA("desk_test", 0, TRUE, DESKTOP_ALL_ACCESS); ok(hdesk != NULL, "OpenDesktop failed!\n"); SetLastError(0xdeadbeef); ret = SwitchDesktop(hdesk); todo_wine ok(!ret, "Switch to desktop belong to non default winstation should fail!\n"); todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED || broken(GetLastError() == 0xdeadbeef), "last error %08x\n", GetLastError()); ret = SetThreadDesktop(hdesk); ok(ret, "SetThreadDesktop failed!\n"); /* clean side effect */ ret = SetThreadDesktop(thread_desk); todo_wine ok(ret, "SetThreadDesktop should success even desktop is not belong to process winstation!\n"); ret = SetProcessWindowStation(w1); ok(ret, "SetProcessWindowStation failed!\n"); ret = SetThreadDesktop(thread_desk); ok(ret, "SetThreadDesktop failed!\n"); ret = CloseWindowStation(w2); ok(ret, "CloseWindowStation failed!\n"); ret = CloseDesktop(new_desk); ok(ret, "CloseDesktop failed!\n"); ret = CloseDesktop(hdesk); ok(ret, "CloseDesktop failed!\n"); }
static void test_inputdesktop(void) { HDESK input_desk, old_input_desk, thread_desk, old_thread_desk, new_desk; DWORD ret; CHAR name[1024]; INPUT inputs[1]; inputs[0].type = INPUT_KEYBOARD; U(inputs[0]).ki.wVk = 0; U(inputs[0]).ki.wScan = 0x3c0; U(inputs[0]).ki.dwFlags = KEYEVENTF_UNICODE; /* OpenInputDesktop creates new handles for each calls */ old_input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(old_input_desk != NULL, "OpenInputDesktop failed!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(old_input_desk, UOI_NAME, name, 1024, NULL); ok(ret, "GetUserObjectInformation failed!\n"); ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name); input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(input_desk != NULL, "OpenInputDesktop failed!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(input_desk, UOI_NAME, name, 1024, NULL); ok(ret, "GetUserObjectInformation failed!\n"); ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name); ok(old_input_desk != input_desk, "returned the same handle!\n"); ret = CloseDesktop(input_desk); ok(ret, "CloseDesktop failed!\n"); /* by default, GetThreadDesktop is the input desktop, SendInput should succeed. */ old_thread_desk = GetThreadDesktop(GetCurrentThreadId()); ok(old_thread_desk != NULL, "GetThreadDesktop faile!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(old_thread_desk, UOI_NAME, name, 1024, NULL); ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name); SetLastError(0xdeadbeef); ret = SendInput(1, inputs, sizeof(INPUT)); ok(GetLastError() == 0xdeadbeef, "unexpected last error %08x\n", GetLastError()); ok(ret == 1, "unexpected return count %d\n", ret); /* Set thread desktop to the new desktop, SendInput should fail. */ new_desk = CreateDesktopA("new_desk", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL); ok(new_desk != NULL, "CreateDesktop failed!\n"); ret = SetThreadDesktop(new_desk); ok(ret, "SetThreadDesktop failed!\n"); thread_desk = GetThreadDesktop(GetCurrentThreadId()); ok(thread_desk == new_desk, "thread desktop doesn't match!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(thread_desk, UOI_NAME, name, 1024, NULL); ok(!strcmp(name, "new_desk"), "unexpected desktop %s\n", name); SetLastError(0xdeadbeef); ret = SendInput(1, inputs, sizeof(INPUT)); if(broken(GetLastError() == 0xdeadbeef)) { SetThreadDesktop(old_thread_desk); CloseDesktop(old_input_desk); CloseDesktop(input_desk); CloseDesktop(new_desk); win_skip("Skip tests on NT4\n"); return; } todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "unexpected last error %08x\n", GetLastError()); ok(ret == 1 || broken(ret == 0) /* Win64 */, "unexpected return count %d\n", ret); /* Set thread desktop back to the old thread desktop, SendInput should success. */ ret = SetThreadDesktop(old_thread_desk); ok(ret, "SetThreadDesktop failed!\n"); thread_desk = GetThreadDesktop(GetCurrentThreadId()); ok(thread_desk == old_thread_desk, "thread desktop doesn't match!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(thread_desk, UOI_NAME, name, 1024, NULL); ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name); SetLastError(0xdeadbeef); ret = SendInput(1, inputs, sizeof(INPUT)); ok(GetLastError() == 0xdeadbeef, "unexpected last error %08x\n", GetLastError()); ok(ret == 1, "unexpected return count %d\n", ret); /* Set thread desktop to the input desktop, SendInput should success. */ ret = SetThreadDesktop(old_input_desk); ok(ret, "SetThreadDesktop failed!\n"); thread_desk = GetThreadDesktop(GetCurrentThreadId()); ok(thread_desk == old_input_desk, "thread desktop doesn't match!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(thread_desk, UOI_NAME, name, 1024, NULL); ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name); SetLastError(0xdeadbeef); ret = SendInput(1, inputs, sizeof(INPUT)); ok(GetLastError() == 0xdeadbeef, "unexpected last error %08x\n", GetLastError()); ok(ret == 1, "unexpected return count %d\n", ret); /* Switch input desktop to the new desktop, SendInput should fail. */ ret = SwitchDesktop(new_desk); ok(ret, "SwitchDesktop failed!\n"); input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(input_desk != NULL, "OpenInputDesktop failed!\n"); ok(input_desk != new_desk, "returned the same handle!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(input_desk, UOI_NAME, name, 1024, NULL); ok(ret, "GetUserObjectInformation failed!\n"); todo_wine ok(!strcmp(name, "new_desk"), "unexpected desktop %s\n", name); ret = CloseDesktop(input_desk); ok(ret, "CloseDesktop failed!\n"); SetLastError(0xdeadbeef); ret = SendInput(1, inputs, sizeof(INPUT)); todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "unexpected last error %08x\n", GetLastError()); ok(ret == 1 || broken(ret == 0) /* Win64 */, "unexpected return count %d\n", ret); /* Set thread desktop to the new desktop, SendInput should success. */ ret = SetThreadDesktop(new_desk); ok(ret, "SetThreadDesktop failed!\n"); thread_desk = GetThreadDesktop(GetCurrentThreadId()); ok(thread_desk == new_desk, "thread desktop doesn't match!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(thread_desk, UOI_NAME, name, 1024, NULL); ok(!strcmp(name, "new_desk"), "unexpected desktop %s\n", name); SetLastError(0xdeadbeef); ret = SendInput(1, inputs, sizeof(INPUT)); ok(GetLastError() == 0xdeadbeef, "unexpected last error %08x\n", GetLastError()); ok(ret == 1, "unexpected return count %d\n", ret); /* Switch input desktop to the old input desktop, set thread desktop to the old * thread desktop, clean side effects. SendInput should success. */ ret = SwitchDesktop(old_input_desk); input_desk = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(input_desk != NULL, "OpenInputDesktop failed!\n"); ok(input_desk != old_input_desk, "returned the same handle!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(input_desk, UOI_NAME, name, 1024, NULL); ok(ret, "GetUserObjectInformation failed!\n"); ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name); ret = SetThreadDesktop(old_thread_desk); ok(ret, "SetThreadDesktop failed!\n"); thread_desk = GetThreadDesktop(GetCurrentThreadId()); ok(thread_desk == old_thread_desk, "thread desktop doesn't match!\n"); memset(name, 0, sizeof(name)); ret = GetUserObjectInformationA(thread_desk, UOI_NAME, name, 1024, NULL); ok(!strcmp(name, "Default"), "unexpected desktop %s\n", name); SetLastError(0xdeadbeef); ret = SendInput(1, inputs, sizeof(INPUT)); ok(GetLastError() == 0xdeadbeef, "unexpected last error %08x\n", GetLastError()); ok(ret == 1, "unexpected return count %d\n", ret); /* free resources */ ret = CloseDesktop(input_desk); ok(ret, "CloseDesktop failed!\n"); ret = CloseDesktop(old_input_desk); ok(ret, "CloseDesktop failed!\n"); ret = CloseDesktop(new_desk); ok(ret, "CloseDesktop failed!\n"); }