/************************************************ * 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; }
/************************************************* * 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; }
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); } }
int main(int argc, char* argv[]) { if (argc < 2) { printf("Usage:SwitchDesktop <Desktop Name>\n"); } HDESK desk = OpenDesktop(argv[1], 0, FALSE, DESKTOP_SWITCHDESKTOP); if (desk == NULL) { printf("切换桌面失败:%d\n", GetLastError()); getchar(); return 1; } if (SwitchDesktop(desk)) { printf("切换桌面成功"); } else { printf("切换桌面失败:%d\n", GetLastError()); } getchar(); }
int _tmain(int argc, _TCHAR* argv[]) { if(argc != 2) { printf("Usage : SwitchDesktop [DesktopName]\n"); return -1; } HDESK dsk = OpenDesktop(argv[1],0,FALSE,GENERIC_ALL); if(!dsk) { printf("OpenDesktop Error! Error Code: %d\n",GetLastError()); return -1; } _TCHAR wallpaper[MAX_PATH]; lstrcpy(wallpaper,argv[1]); lstrcat(wallpaper,L".bmp"); SetDesktopWallPaper(wallpaper); BOOL ret = SwitchDesktop(dsk); if(!ret) { printf("SwitchDesktop Error! Error Code: %d\n",GetLastError()); } CloseDesktop(dsk); return 0; }
void CClientDlg::OnBnClickedSs() { HDESK hSecondDesktop=CreateDesktopW(L"SecondDesktop",NULL,NULL,DF_ALLOWOTHERACCOUNTHOOK,GENERIC_ALL,NULL); if(hSecondDesktop == NULL) { DWORD err = GetLastError(); WCHAR msg[100]; wsprintf(&msg[0], L"CreateDesktop ERROR: %d", err); MessageBoxW(&msg[0]); //DbgMsgW(L"ClientDlg.cpp", err, L"ERROR"); } /*HDESK hDesktop_cur = GetThreadDesktop(GetCurrentThreadId()); if(hDesktop_cur != hSecondDesktop && hDesktop_cur != NULL) hFirstDesktop = hDesktop_cur;*/ HDESK hCurrDesk = GetThreadDesktop(GetCurrentThreadId()); SwitchDesktop(hSecondDesktop); Sleep(5000); SwitchDesktop(hCurrDesk); }
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; }
/* * @implemented */ int WINAPI WlxSwitchDesktopToWinlogon( HANDLE hWlx) { PWLSESSION Session = (PWLSESSION)hWlx; TRACE("WlxSwitchDesktopToWinlogon()\n"); return (int)SwitchDesktop(Session->WinlogonDesktop); }
/* * @implemented */ int WINAPI WlxSwitchDesktopToUser( HANDLE hWlx) { PWLSESSION Session = (PWLSESSION)hWlx; TRACE("WlxSwitchDesktopToUser()\n"); return (int)SwitchDesktop(Session->ApplicationDesktop); }
void Desktops::SwitchToDesktop(int idx) { if (_current_desktop == idx) return; DesktopPtr& desktop = (*this)[idx]; DesktopThread* pThread = NULL; if (desktop.get()) { if (desktop->_hdesktop) if (!SwitchDesktop(desktop->_hdesktop)) return; } else { FmtString desktop_name(TEXT("Desktop %d"), idx); SECURITY_ATTRIBUTES saAttr = {sizeof(SECURITY_ATTRIBUTES), 0, TRUE}; /* HWINSTA hwinsta = CreateWindowStation(TEXT("ExplorerWinStation"), 0, GENERIC_ALL, &saAttr); if (!SetProcessWindowStation(hwinsta)) return; */ HDESK hdesktop = CreateDesktop(desktop_name, NULL, NULL, 0, GENERIC_ALL, &saAttr); if (!hdesktop) return; desktop = DesktopPtr(new Desktop(hdesktop/*, hwinsta*/)); pThread = new DesktopThread(*desktop); } _current_desktop = idx; if (pThread) { desktop->_pThread = DesktopThreadPtr(pThread); pThread->Start(); } }
static void test_foregroundwindow(void) { HWND hwnd, hwnd_test, partners[2], hwnds[2]; HDESK hdesks[2]; int thread_desk_id, input_desk_id, hwnd_id; WNDCLASSA wclass; wnd_param param; DWORD ret, timeout, timeout_old; char win_text[1024]; #define DESKTOPS 2 memset( &wclass, 0, sizeof(wclass) ); wclass.lpszClassName = "test_class"; wclass.lpfnWndProc = WndProc; RegisterClassA(&wclass); param.wnd_name = "win_name"; hdesks[0] = GetThreadDesktop(GetCurrentThreadId()); ok(hdesks[0] != NULL, "OpenDesktop failed!\n"); SetLastError(0xdeadbeef); hdesks[1] = CreateDesktopA("desk2", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL); ret = GetLastError(); ok(hdesks[1] != NULL || ret == ERROR_ACCESS_DENIED, "CreateDesktop failed (%u)\n", ret); if(!hdesks[1]) { win_skip("Not enough privileges for CreateDesktop\n"); return; } ret = SystemParametersInfoA(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &timeout_old, 0); if(!ret) { win_skip("Skip tests on NT4\n"); CloseDesktop(hdesks[1]); return; } trace("old timeout %d\n", timeout_old); timeout = 0; ret = SystemParametersInfoA(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); ok(ret, "set foreground lock timeout failed!\n"); ret = SystemParametersInfoA(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &timeout, 0); ok(ret, "get foreground lock timeout failed!\n"); ok(timeout == 0, "unexpected timeout %d\n", timeout); for (thread_desk_id = 0; thread_desk_id < DESKTOPS; thread_desk_id++) { param.hdesk = hdesks[thread_desk_id]; param.hevent = CreateEventA(NULL, TRUE, FALSE, NULL); CreateThread(NULL, 0, create_window, ¶m, 0, NULL); ret = WaitForSingleObject(param.hevent, INFINITE); ok(ret == WAIT_OBJECT_0, "wait failed!\n"); hwnds[thread_desk_id] = param.hwnd; } for (thread_desk_id = 0; thread_desk_id < DESKTOPS; thread_desk_id++) { param.hdesk = hdesks[thread_desk_id]; param.hevent = CreateEventA(NULL, TRUE, FALSE, NULL); CreateThread(NULL, 0, create_window, ¶m, 0, NULL); ret = WaitForSingleObject(param.hevent, INFINITE); ok(ret == WAIT_OBJECT_0, "wait failed!\n"); partners[thread_desk_id] = param.hwnd; } trace("hwnd0 %p hwnd1 %p partner0 %p partner1 %p\n", hwnds[0], hwnds[1], partners[0], partners[1]); for (hwnd_id = 0; hwnd_id < DESKTOPS; hwnd_id++) for (thread_desk_id = 0; thread_desk_id < DESKTOPS; thread_desk_id++) for (input_desk_id = 0; input_desk_id < DESKTOPS; input_desk_id++) { trace("testing thread_desk %d input_desk %d hwnd %d\n", thread_desk_id, input_desk_id, hwnd_id); hwnd_test = hwnds[hwnd_id]; ret = SetThreadDesktop(hdesks[thread_desk_id]); ok(ret, "set thread desktop failed!\n"); ret = SwitchDesktop(hdesks[input_desk_id]); ok(ret, "switch desktop failed!\n"); set_foreground(partners[0]); set_foreground(partners[1]); hwnd = GetForegroundWindow(); ok(hwnd != hwnd_test, "unexpected foreground window %p\n", hwnd); ret = set_foreground(hwnd_test); hwnd = GetForegroundWindow(); GetWindowTextA(hwnd, win_text, 1024); trace("hwnd %p name %s\n", hwnd, win_text); if (input_desk_id == hwnd_id) { if (input_desk_id == thread_desk_id) { ok(ret, "SetForegroundWindow failed!\n"); ok(hwnd == hwnd_test , "unexpected foreground window %p\n", hwnd); } else { todo_wine ok(ret, "SetForegroundWindow failed!\n"); todo_wine ok(hwnd == 0, "unexpected foreground window %p\n", hwnd); } } else { if (input_desk_id == thread_desk_id) { ok(!ret, "SetForegroundWindow should fail!\n"); ok(hwnd == partners[input_desk_id] , "unexpected foreground window %p\n", hwnd); } else { todo_wine ok(!ret, "SetForegroundWindow should fail!\n"); todo_wine ok(hwnd == 0, "unexpected foreground window %p\n", hwnd); } } } /* Clean up */ for (thread_desk_id = DESKTOPS - 1; thread_desk_id >= 0; thread_desk_id--) { ret = SetThreadDesktop(hdesks[thread_desk_id]); ok(ret, "set thread desktop failed!\n"); SendMessageA(hwnds[thread_desk_id], WM_DESTROY, 0, 0); SendMessageA(partners[thread_desk_id], WM_DESTROY, 0, 0); } ret = SwitchDesktop(hdesks[0]); ok(ret, "switch desktop failed!\n"); CloseDesktop(hdesks[1]); ret = SystemParametersInfoA(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UlongToPtr(timeout_old), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); ok(ret, "set foreground lock timeout failed!\n"); ret = SystemParametersInfoA(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &timeout, 0); ok(ret, "get foreground lock timeout failed!\n"); ok(timeout == timeout_old, "unexpected timeout %d\n", timeout); }
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"); }
static NTSTATUS HandleLogoff( IN OUT PWLSESSION Session, IN UINT Flags) { PLOGOFF_SHUTDOWN_DATA LSData; PSECURITY_ATTRIBUTES psa; HANDLE hThread; DWORD exitCode; NTSTATUS Status; /* Prepare data for logoff thread */ LSData = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGOFF_SHUTDOWN_DATA)); if (!LSData) { ERR("Failed to allocate mem for thread data\n"); return STATUS_NO_MEMORY; } LSData->Flags = Flags; LSData->Session = Session; Status = CreateLogoffSecurityAttributes(&psa); if (!NT_SUCCESS(Status)) { ERR("Failed to create a required security descriptor. Status 0x%08lx\n", Status); HeapFree(GetProcessHeap(), 0, LSData); return Status; } /* Run logoff thread */ hThread = CreateThread(psa, 0, LogoffShutdownThread, (LPVOID)LSData, 0, NULL); if (!hThread) { ERR("Unable to create logoff thread, error %lu\n", GetLastError()); DestroyLogoffSecurityAttributes(psa); HeapFree(GetProcessHeap(), 0, LSData); return STATUS_UNSUCCESSFUL; } WaitForSingleObject(hThread, INFINITE); if (!GetExitCodeThread(hThread, &exitCode)) { ERR("Unable to get exit code of logoff thread (error %lu)\n", GetLastError()); CloseHandle(hThread); DestroyLogoffSecurityAttributes(psa); HeapFree(GetProcessHeap(), 0, LSData); return STATUS_UNSUCCESSFUL; } CloseHandle(hThread); if (exitCode == 0) { ERR("Logoff thread returned failure\n"); DestroyLogoffSecurityAttributes(psa); HeapFree(GetProcessHeap(), 0, LSData); return STATUS_UNSUCCESSFUL; } SwitchDesktop(Session->WinlogonDesktop); // TODO: Play logoff sound! SetWindowStationUser(Session->InteractiveWindowStation, &LuidNone, NULL, 0); // DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_LOGGINGOFF); // FIXME: Closing network connections! // DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_CLOSINGNETWORKCONNECTIONS); /* Kill remaining COM apps. Only at logoff! */ hThread = CreateThread(psa, 0, KillComProcesses, (LPVOID)LSData, 0, NULL); if (hThread) { WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); } /* We're done with the SECURITY_DESCRIPTOR */ DestroyLogoffSecurityAttributes(psa); psa = NULL; HeapFree(GetProcessHeap(), 0, LSData); DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_SAVEYOURSETTINGS); UnloadUserProfile(Session->UserToken, Session->hProfileInfo); CallNotificationDlls(Session, LogoffHandler); CloseHandle(Session->UserToken); UpdatePerUserSystemParameters(0, FALSE); Session->LogonState = STATE_LOGGED_OFF; Session->UserToken = NULL; return STATUS_SUCCESS; }
static BOOL HandleLogon( IN OUT PWLSESSION Session) { PROFILEINFOW ProfileInfo; BOOL ret = FALSE; /* Loading personal settings */ DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_LOADINGYOURPERSONALSETTINGS); ProfileInfo.hProfile = INVALID_HANDLE_VALUE; if (0 == (Session->Options & WLX_LOGON_OPT_NO_PROFILE)) { if (Session->Profile == NULL || (Session->Profile->dwType != WLX_PROFILE_TYPE_V1_0 && Session->Profile->dwType != WLX_PROFILE_TYPE_V2_0)) { ERR("WL: Wrong profile\n"); goto cleanup; } /* Load the user profile */ ZeroMemory(&ProfileInfo, sizeof(PROFILEINFOW)); ProfileInfo.dwSize = sizeof(PROFILEINFOW); ProfileInfo.dwFlags = 0; ProfileInfo.lpUserName = Session->MprNotifyInfo.pszUserName; ProfileInfo.lpProfilePath = Session->Profile->pszProfile; if (Session->Profile->dwType >= WLX_PROFILE_TYPE_V2_0) { ProfileInfo.lpDefaultPath = Session->Profile->pszNetworkDefaultUserProfile; ProfileInfo.lpServerName = Session->Profile->pszServerName; ProfileInfo.lpPolicyPath = Session->Profile->pszPolicy; } if (!LoadUserProfileW(Session->UserToken, &ProfileInfo)) { ERR("WL: LoadUserProfileW() failed\n"); goto cleanup; } } /* Create environment block for the user */ if (!CreateUserEnvironment(Session)) { WARN("WL: SetUserEnvironment() failed\n"); goto cleanup; } CallNotificationDlls(Session, LogonHandler); DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGYOURPERSONALSETTINGS); UpdatePerUserSystemParameters(0, TRUE); /* Set default user language */ if (!SetDefaultLanguage(Session)) { WARN("WL: SetDefaultLanguage() failed\n"); goto cleanup; } AllowWinstaAccess(Session); /* Connect remote resources */ RestoreAllConnections(Session); if (!StartUserShell(Session)) { //WCHAR StatusMsg[256]; WARN("WL: WlxActivateUserShell() failed\n"); //LoadStringW(hAppInstance, IDS_FAILEDACTIVATEUSERSHELL, StatusMsg, sizeof(StatusMsg) / sizeof(StatusMsg[0])); //MessageBoxW(0, StatusMsg, NULL, MB_ICONERROR); goto cleanup; } CallNotificationDlls(Session, StartShellHandler); if (!InitializeScreenSaver(Session)) WARN("WL: Failed to initialize screen saver\n"); Session->hProfileInfo = ProfileInfo.hProfile; /* Logon has succeeded. Play sound. */ PlayLogonSound(Session); ret = TRUE; cleanup: if (Session->Profile) { HeapFree(GetProcessHeap(), 0, Session->Profile->pszProfile); HeapFree(GetProcessHeap(), 0, Session->Profile); } Session->Profile = NULL; if (!ret && ProfileInfo.hProfile != INVALID_HANDLE_VALUE) { UnloadUserProfile(Session->UserToken, ProfileInfo.hProfile); } RemoveStatusMessage(Session); if (!ret) { SetWindowStationUser(Session->InteractiveWindowStation, &LuidNone, NULL, 0); CloseHandle(Session->UserToken); Session->UserToken = NULL; } if (ret) { SwitchDesktop(Session->ApplicationDesktop); Session->LogonState = STATE_LOGGED_ON; } return ret; }
int WINAPI WinMain(IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpCmdLine, IN int nShowCmd) { #if 0 LSA_STRING ProcessName, PackageName; HANDLE LsaHandle; LSA_OPERATIONAL_MODE Mode; BOOLEAN Old; ULONG AuthenticationPackage; NTSTATUS Status; #endif ULONG HardErrorResponse; MSG Msg; UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); UNREFERENCED_PARAMETER(nShowCmd); hAppInstance = hInstance; if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE)) { ERR("WL: Could not register logon process\n"); NtShutdownSystem(ShutdownNoReboot); ExitProcess(0); } WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), 0, sizeof(WLSESSION)); if (!WLSession) { ERR("WL: Could not allocate memory for winlogon instance\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); ExitProcess(1); } ZeroMemory(WLSession, sizeof(WLSESSION)); WLSession->DialogTimeout = 120; /* 2 minutes */ if (!CreateWindowStationAndDesktops(WLSession)) { ERR("WL: Could not create window station and desktops\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); ExitProcess(1); } LockWorkstation(WLSession); /* Load default keyboard layouts */ if (!InitKeyboardLayouts()) { ERR("WL: Could not preload keyboard layouts\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); ExitProcess(1); } if (!StartServicesManager()) { ERR("WL: Could not start services.exe\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); ExitProcess(1); } if (!StartLsass()) { ERR("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError()); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, OptionOk, &HardErrorResponse); ExitProcess(1); } /* Wait for the LSA server */ WaitForLsass(); /* Load and initialize gina */ if (!GinaInit(WLSession)) { ERR("WL: Failed to initialize Gina\n"); DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), GetDesktopWindow(), GinaLoadFailedWindowProc, (LPARAM)L""); HandleShutdown(WLSession, WLX_SAS_ACTION_SHUTDOWN_REBOOT); ExitProcess(1); } DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP); #if 0 /* Connect to NetLogon service (lsass.exe) */ /* Real winlogon uses "Winlogon" */ RtlInitUnicodeString((PUNICODE_STRING)&ProcessName, L"Winlogon"); Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode); if (Status == STATUS_PORT_CONNECTION_REFUSED) { /* Add the 'SeTcbPrivilege' privilege and try again */ Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, TRUE, &Old); if (!NT_SUCCESS(Status)) { ERR("RtlAdjustPrivilege() failed with error %lu\n", LsaNtStatusToWinError(Status)); return 1; } Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode); } if (!NT_SUCCESS(Status)) { ERR("LsaRegisterLogonProcess() failed with error %lu\n", LsaNtStatusToWinError(Status)); return 1; } RtlInitUnicodeString((PUNICODE_STRING)&PackageName, MICROSOFT_KERBEROS_NAME_W); Status = LsaLookupAuthenticationPackage(LsaHandle, &PackageName, &AuthenticationPackage); if (!NT_SUCCESS(Status)) { ERR("LsaLookupAuthenticationPackage() failed with error %lu\n", LsaNtStatusToWinError(Status)); LsaDeregisterLogonProcess(LsaHandle); return 1; } #endif /* Create a hidden window to get SAS notifications */ if (!InitializeSAS(WLSession)) { ERR("WL: Failed to initialize SAS\n"); ExitProcess(2); } //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS); //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGCOMPUTERSETTINGS); /* Display logged out screen */ WLSession->LogonState = STATE_LOGGED_OFF; RemoveStatusMessage(WLSession); /* Check for pending setup */ if (GetSetupType() != 0) { TRACE("WL: Setup mode detected\n"); /* Run setup and reboot when done */ SwitchDesktop(WLSession->ApplicationDesktop); RunSetup(); } else PostMessageW(WLSession->SASWindow, WLX_WM_SAS, WLX_SAS_TYPE_TIMEOUT, 0); /* Tell kernel that CurrentControlSet is good (needed * to support Last good known configuration boot) */ NtInitializeRegistry(CM_BOOT_FLAG_ACCEPTED | 1); /* Message loop for the SAS window */ while (GetMessageW(&Msg, WLSession->SASWindow, 0, 0)) { TranslateMessage(&Msg); DispatchMessageW(&Msg); } /* We never go there */ return 0; }
BOOL CreateWindowStationAndDesktops( IN OUT PWLSESSION Session) { BYTE LocalSystemBuffer[SECURITY_MAX_SID_SIZE]; BYTE InteractiveBuffer[SECURITY_MAX_SID_SIZE]; PSID pLocalSystemSid = (PSID)&LocalSystemBuffer; PSID pInteractiveSid = (PSID)InteractiveBuffer; DWORD SidSize, AclSize; PACL pDefaultAcl = NULL; PACL pUserDesktopAcl = NULL; SECURITY_DESCRIPTOR DefaultSecurityDescriptor; SECURITY_ATTRIBUTES DefaultSecurity; SECURITY_DESCRIPTOR UserDesktopSecurityDescriptor; SECURITY_ATTRIBUTES UserDesktopSecurity; BOOL ret = FALSE; /* * Prepare information for ACLs we will apply */ SidSize = SECURITY_MAX_SID_SIZE; if (!CreateWellKnownSid(WinLocalSystemSid, NULL, pLocalSystemSid, &SidSize)) { ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError()); goto cleanup; } SidSize = SECURITY_MAX_SID_SIZE; if (!CreateWellKnownSid(WinInteractiveSid, NULL, pInteractiveSid, &SidSize)) { ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError()); goto cleanup; } AclSize = sizeof(ACL) + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(pLocalSystemSid) + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(pInteractiveSid); pDefaultAcl = HeapAlloc(GetProcessHeap(), 0, AclSize); pUserDesktopAcl = HeapAlloc(GetProcessHeap(), 0, AclSize); if (!pDefaultAcl || !pUserDesktopAcl) { ERR("WL: HeapAlloc() failed\n"); goto cleanup; } if (!InitializeAcl(pDefaultAcl, AclSize, ACL_REVISION) || !InitializeAcl(pUserDesktopAcl, AclSize, ACL_REVISION)) { ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError()); goto cleanup; } /* * Create default ACL (window station, winlogon desktop, screen saver desktop) */ if (!AddAccessAllowedAce(pDefaultAcl, ACL_REVISION, GENERIC_ALL, pLocalSystemSid) || !AddAccessAllowedAce(pDefaultAcl, ACL_REVISION, GENERIC_READ, pInteractiveSid)) { ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError()); goto cleanup; } /* * Create the default security descriptor */ if (!InitializeSecurityDescriptor(&DefaultSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) { ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError()); goto cleanup; } if (!SetSecurityDescriptorDacl(&DefaultSecurityDescriptor, TRUE, pDefaultAcl, FALSE)) { ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError()); goto cleanup; } DefaultSecurity.nLength = sizeof(SECURITY_ATTRIBUTES); DefaultSecurity.lpSecurityDescriptor = &DefaultSecurityDescriptor; DefaultSecurity.bInheritHandle = TRUE; /* * Create user desktop ACL */ if (!AddAccessAllowedAce(pUserDesktopAcl, ACL_REVISION, GENERIC_ALL, pLocalSystemSid) || !AddAccessAllowedAce(pUserDesktopAcl, ACL_REVISION, GENERIC_ALL, pInteractiveSid)) { ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError()); goto cleanup; } /* * Create the user desktop security descriptor */ if (!InitializeSecurityDescriptor(&UserDesktopSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) { ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError()); goto cleanup; } if (!SetSecurityDescriptorDacl(&UserDesktopSecurityDescriptor, TRUE, pUserDesktopAcl, FALSE)) { ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError()); goto cleanup; } UserDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES); UserDesktopSecurity.lpSecurityDescriptor = &UserDesktopSecurityDescriptor; UserDesktopSecurity.bInheritHandle = TRUE; /* * Create the interactive window station */ Session->InteractiveWindowStationName = L"WinSta0"; Session->InteractiveWindowStation = CreateWindowStationW( Session->InteractiveWindowStationName, 0, MAXIMUM_ALLOWED, &DefaultSecurity); if (!Session->InteractiveWindowStation) { ERR("WL: Failed to create window station (%lu)\n", GetLastError()); goto cleanup; } if (!SetProcessWindowStation(Session->InteractiveWindowStation)) { ERR("WL: SetProcessWindowStation() failed (error %lu)\n", GetLastError()); goto cleanup; } /* * Create the application desktop */ Session->ApplicationDesktop = CreateDesktopW( L"Default", NULL, NULL, 0, /* FIXME: Add DF_ALLOWOTHERACCOUNTHOOK flag? */ MAXIMUM_ALLOWED, &UserDesktopSecurity); if (!Session->ApplicationDesktop) { ERR("WL: Failed to create Default desktop (%lu)\n", GetLastError()); goto cleanup; } /* * Create the winlogon desktop */ Session->WinlogonDesktop = CreateDesktopW( L"Winlogon", NULL, NULL, 0, MAXIMUM_ALLOWED, &DefaultSecurity); if (!Session->WinlogonDesktop) { ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError()); goto cleanup; } /* * Create the screen saver desktop */ Session->ScreenSaverDesktop = CreateDesktopW( L"Screen-Saver", NULL, NULL, 0, MAXIMUM_ALLOWED, &DefaultSecurity); if(!Session->ScreenSaverDesktop) { ERR("WL: Failed to create Screen-Saver desktop (%lu)\n", GetLastError()); goto cleanup; } /* * Switch to winlogon desktop */ if (!SetThreadDesktop(Session->WinlogonDesktop) || !SwitchDesktop(Session->WinlogonDesktop)) { ERR("WL: Cannot switch to Winlogon desktop (%lu)\n", GetLastError()); goto cleanup; } ret = TRUE; cleanup: if (!ret) { if (Session->ApplicationDesktop) { CloseDesktop(Session->ApplicationDesktop); Session->ApplicationDesktop = NULL; } if (Session->WinlogonDesktop) { CloseDesktop(Session->WinlogonDesktop); Session->WinlogonDesktop = NULL; } if (Session->ScreenSaverDesktop) { CloseDesktop(Session->ScreenSaverDesktop); Session->ScreenSaverDesktop = NULL; } if (Session->InteractiveWindowStation) { CloseWindowStation(Session->InteractiveWindowStation); Session->InteractiveWindowStation = NULL; } } HeapFree(GetProcessHeap(), 0, pDefaultAcl); HeapFree(GetProcessHeap(), 0, pUserDesktopAcl); return ret; }
void ThreadInit(LPVOID tData) { MSG msg; HWND hWnd; HDC hTemp; int width; // window width USEROBJECTFLAGS uof; // To set Desktop attributes uof.fInherit = FALSE; // If an app inherits multiple desktop handles, // it could run on any one of those desktops uof.fReserved = FALSE; // // Let other account processes hook this desktop // uof.dwFlags = DF_ALLOWOTHERACCOUNTHOOK; SetUserObjectInformation (((ThreadData*)tData)->hDesk, UOI_FLAGS, (LPVOID)&uof, sizeof(uof)); // // Make sure the handle is valid // if (gDeskArray[((ThreadData*)tData)->index]) { // // Assign new desktop to this thread // SetThreadDesktop (((ThreadData*)tData)->hDesk); // create the cool switcher window if ((gMaxIndex+1) * gWidth > MINWINDOWWIDTH) { width = (gMaxIndex+1) * gWidth; } else { width = MINWINDOWWIDTH; } hWnd = CreateWindow (szClassName, szAppName, WS_MINIMIZEBOX|WS_OVERLAPPED|WS_VISIBLE|WS_BORDER|WS_CAPTION|WS_SYSMENU, 0, 0, width, 30+gHeight + CONTROLHEIGHT, NULL, NULL, ghInst, tData); if (!hWnd) // bag it { gDeskArray[((ThreadData*)tData)->index] = NULL; GlobalFree (tData); return; } // //update the global window array // hWndArray[((ThreadData*)tData)->index] = hWnd; } else { GlobalFree (tData); return; } // // Acquire and dispatch messages until a WM_QUIT message is received. // while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg);// Translates virtual key codes DispatchMessage(&msg); // Dispatches message to window } // // Switch back to the default desktop and close the user-created one // SetThreadDesktop (DEFAULT_DESKTOP); SwitchDesktop (DEFAULT_DESKTOP); CloseDesktop (((ThreadData*)tData)->hDesk); // // NULL out the global array entry so other threads won't try to switch to // this desktop // gDeskArray[((ThreadData*)tData)->index] = NULL; // // cleanup // hTemp = gHDCArray[((ThreadData*)tData)->index]; gHDCArray[((ThreadData*)tData)->index] = NULL; DeleteObject (hTemp); GlobalFree (tData); }
LONG APIENTRY WndProc( HWND hWnd, UINT message, // type of message WPARAM wParam, // additional information LPARAM lParam) // additional information { int newThread; // Thread index to switch to int i; ThreadData *ptd; static HWND hShowing = NULL; // which preview window is being shown static LONG fntHeight = CONTROLHEIGHT; // height for the edit control switch (message) { case WM_CREATE: { HDC hDC; HBITMAP hBmp; // Create edit control, button, and label at the bottom of the window // This will allow the user to input a program to run SetWindowLong (hWnd, GWL_USERDATA, (LONG)((CREATESTRUCT *)lParam)->lpCreateParams); ptd = (ThreadData *)GetWindowLong (hWnd, GWL_USERDATA); CreateControls (ptd, hWnd); fntHeight = GetFontHeight (hWnd); // // initialize the DC array entry // hDC = CreateDC (TEXT("DISPLAY"), NULL, NULL, NULL); gHDCArray[ptd->index] = CreateCompatibleDC (hDC); // // Halftone is the best stretching algorithm // SetStretchBltMode (gHDCArray[ptd->index], HALFTONE); SetBrushOrgEx (gHDCArray[ptd->index], 0, 0, NULL); // // Use a bitmap the same size as the desktop preview rectangles // hBmp = CreateCompatibleBitmap (hDC, gWidth*2, gHeight*2); SelectObject (gHDCArray[ptd->index], hBmp); DeleteDC (hDC); SaveScreen (ptd->index); TitleWindow (hWnd); // // Register hot keys // for (i=0;i<10;i++) { RegisterHotKey (hWnd, VK_F1+i, MOD_CONTROL, VK_F1+i); } return 0; } case WM_SIZE: { // // Put the child controls at the right places // #define PADDING 5 RECT rect; ThreadData *ptd; if (GetClientRect (hWnd, &rect)) { ptd = (ThreadData *)GetWindowLong (hWnd, GWL_USERDATA); MoveWindow (ptd->hWndStatic, 0, rect.bottom - CONTROLHEIGHT, gStaticWidth, fntHeight + PADDING, TRUE); MoveWindow (ptd->hWndEdit, gStaticWidth + 5, rect.bottom - fntHeight - PADDING, gEditWidth, fntHeight+PADDING, TRUE); MoveWindow (ptd->hWndBtn, gStaticWidth + gEditWidth + 10, rect.bottom - fntHeight - PADDING, gBtnWidth, fntHeight+PADDING, TRUE); MoveWindow (ptd->hWndNew, gStaticWidth+gEditWidth+gBtnWidth+15, rect.bottom - fntHeight- PADDING, gNewWidth, fntHeight+PADDING, TRUE); } return 0; } case WM_PAINT: PaintMainWnd (hWnd); return 0; case WM_RBUTTONDOWN: { // // Find the rectangle in which the button was pressed // POINTS pts; ThreadData *ptd; ptd = (ThreadData *)GetWindowLong(hWnd, GWL_USERDATA); pts = MAKEPOINTS (lParam); if (pts.y > gHeight) { return 1; } newThread = pts.x/gWidth; // // Get a snapshot of the current desktop // SaveScreen (ptd->index); // // Switch to the selected desktop // if (!gDeskArray[newThread]) { StartNewDesktop (newThread); } if (!SwitchDesktop (gDeskArray[newThread])) MessageBox (hWnd, PSZ(IDS_BADDESKTOP), PSZ(IDS_ERRCAPTION), MB_OK); return 0; } case WM_LBUTTONDOWN: // // show the preview window // { POINTS pts; POINT ptl; int *index; pts = MAKEPOINTS (lParam); if (pts.y > gHeight) { return 1; } newThread = pts.x/gWidth; index = GlobalAlloc (GMEM_FIXED, sizeof(int)); if (!index) { return 1; } *index = newThread; // // Want to show the preview window where the button was clicked. // Map the given points to screen coords. // ClientToScreen is expecting a POINT structure, not a POINTS // ptl.x = (LONG)pts.x; ptl.y = (LONG)pts.y; ClientToScreen (hWnd, &ptl); hShowing = CreateWindow (szPreviewClass, TEXT(""), WS_POPUP | WS_VISIBLE | WS_BORDER, ptl.x+3, ptl.y+3, gWidth*2, gHeight*2, hWnd, (HMENU)0, ghInst, (LPVOID)index); return 0; } case WM_CHAR: if (wParam == VK_RETURN) { PostMessage (hWnd, WM_COMMAND, (WPARAM)IDC_RUNMEBTN, 0); } return 0; case WM_SYSCHAR: { ThreadData *ptd; ptd = (ThreadData *)GetWindowLong(hWnd, GWL_USERDATA); switch (wParam) { // alt+r == focus on the edit control case TEXT('r'): case TEXT('R'): if (GetKeyState (VK_MENU)) { SetFocus (ptd->hWndEdit); } return 0; // alt+n = create a new desktop case TEXT('n'): case TEXT('N'): if (GetKeyState (VK_MENU)) { PostMessage (hWnd, WM_COMMAND, (WPARAM)IDC_NEWDSKBTN, 0); } } return 0; } case WM_HOTKEY: case WM_KEYDOWN: // // F1-F9 switches to corresponding desktop // if ((wParam >= VK_F1 && wParam <= VK_F10) && (wParam - VK_F1 <= (UINT)gMaxIndex)) { LONG x, y; x = (wParam - VK_F1) * gWidth + 2; y = gHeight - 4; PostMessage (hWnd, WM_RBUTTONDOWN, 0, MAKELPARAM (x, y)); } return 0; case WM_SETFOCUS: case WM_NCLBUTTONUP: case WM_LBUTTONUP: // // destroy the preview window // if (hShowing) { DestroyWindow (hShowing); hShowing = NULL; } return 0; case WM_CLOSE: // // to be safe, check for a preview window // if (hShowing) { DestroyWindow (hShowing); hShowing = NULL; } // // go to the default desktop so the DestroyWindow calls all succeed // SwitchDesktop (DEFAULT_DESKTOP); // // kill the window on this desktop // all the windows will be destroyed if this is the default desktop // for (i=gMaxIndex;i>=0;i--) { DestroyWindow (hWndArray[i]); } // // Unregister the hot keys // for (i=0;i<10;i++) { UnregisterHotKey (hWnd,VK_F1+i); } return 0; case WM_DESTROY: // message: window being destroyed PostQuitMessage(0); return 0; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_RUNMEBTN: { RunApp (hWnd); return 0; } case IDC_NEWDSKBTN: // // Create a new desktop and resize the windows to show it. // { RECT rect; int i; if (gMaxIndex + 1 < MAX_THREADS) { gMaxIndex++; StartNewDesktop (gMaxIndex); GetWindowRect (hWnd,&rect); for (i=0;i<gMaxIndex;i++) { MoveWindow (hWndArray[i], rect.left, rect.top, rect.right + gWidth, rect.bottom-rect.top, TRUE); } } return 0; } default: return DefWindowProc (hWnd, message, wParam, lParam); } } default: // Passes it on if unprocessed return (DefWindowProc (hWnd, message, wParam, lParam)); } }
BOOL ZSwitchDesktop(HDESK hDesktop) { return SwitchDesktop(hDesktop) ; }
static VOID DoGenericAction( IN OUT PWLSESSION Session, IN DWORD wlxAction) { switch (wlxAction) { case WLX_SAS_ACTION_LOGON: /* 0x01 */ if (Session->LogonState == STATE_LOGGED_OFF_SAS) { if (!HandleLogon(Session)) { Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context); CallNotificationDlls(Session, LogonHandler); } } break; case WLX_SAS_ACTION_NONE: /* 0x02 */ if (Session->LogonState == STATE_LOGGED_OFF_SAS) { Session->LogonState = STATE_LOGGED_OFF; Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context); } else if (Session->LogonState == STATE_LOGGED_ON_SAS) { Session->LogonState = STATE_LOGGED_ON; } else if (Session->LogonState == STATE_LOCKED_SAS) { Session->LogonState = STATE_LOCKED; Session->Gina.Functions.WlxDisplayLockedNotice(Session->Gina.Context); } break; case WLX_SAS_ACTION_LOCK_WKSTA: /* 0x03 */ if (Session->Gina.Functions.WlxIsLockOk(Session->Gina.Context)) { SwitchDesktop(Session->WinlogonDesktop); Session->LogonState = STATE_LOCKED; Session->Gina.Functions.WlxDisplayLockedNotice(Session->Gina.Context); CallNotificationDlls(Session, LockHandler); } break; case WLX_SAS_ACTION_LOGOFF: /* 0x04 */ case WLX_SAS_ACTION_SHUTDOWN: /* 0x05 */ case WLX_SAS_ACTION_SHUTDOWN_POWER_OFF: /* 0x0a */ case WLX_SAS_ACTION_SHUTDOWN_REBOOT: /* 0x0b */ if (Session->LogonState != STATE_LOGGED_OFF) { if (!Session->Gina.Functions.WlxIsLogoffOk(Session->Gina.Context)) break; if (!NT_SUCCESS(HandleLogoff(Session, EWX_LOGOFF))) { RemoveStatusMessage(Session); break; } Session->Gina.Functions.WlxLogoff(Session->Gina.Context); } if (WLX_SHUTTINGDOWN(wlxAction)) { // FIXME: WlxShutdown should be done from inside HandleShutdown, // after having displayed "ReactOS is shutting down" message. Session->Gina.Functions.WlxShutdown(Session->Gina.Context, wlxAction); if (!NT_SUCCESS(HandleShutdown(Session, wlxAction))) { RemoveStatusMessage(Session); Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context); } } else { RemoveStatusMessage(Session); Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context); } break; case WLX_SAS_ACTION_TASKLIST: /* 0x07 */ SwitchDesktop(Session->ApplicationDesktop); Session->LogonState = STATE_LOGGED_ON; StartTaskManager(Session); break; case WLX_SAS_ACTION_UNLOCK_WKSTA: /* 0x08 */ SwitchDesktop(Session->ApplicationDesktop); Session->LogonState = STATE_LOGGED_ON; CallNotificationDlls(Session, UnlockHandler); break; default: WARN("Unknown SAS action 0x%lx\n", wlxAction); } }
BOOL InitializeSAS( IN OUT PWLSESSION Session) { WNDCLASSEXW swc; BOOL ret = FALSE; if (!SwitchDesktop(Session->WinlogonDesktop)) { ERR("WL: Failed to switch to winlogon desktop\n"); goto cleanup; } /* Register SAS window class */ swc.cbSize = sizeof(WNDCLASSEXW); swc.style = CS_SAVEBITS; swc.lpfnWndProc = SASWindowProc; swc.cbClsExtra = 0; swc.cbWndExtra = 0; swc.hInstance = hAppInstance; swc.hIcon = NULL; swc.hCursor = NULL; swc.hbrBackground = NULL; swc.lpszMenuName = NULL; swc.lpszClassName = WINLOGON_SAS_CLASS; swc.hIconSm = NULL; if (RegisterClassExW(&swc) == 0) { ERR("WL: Failed to register SAS window class\n"); goto cleanup; } /* Create invisible SAS window */ Session->SASWindow = CreateWindowExW( 0, WINLOGON_SAS_CLASS, WINLOGON_SAS_TITLE, WS_POPUP, 0, 0, 0, 0, 0, 0, hAppInstance, Session); if (!Session->SASWindow) { ERR("WL: Failed to create SAS window\n"); goto cleanup; } /* Register SAS window to receive SAS notifications */ if (!SetLogonNotifyWindow(Session->SASWindow)) { ERR("WL: Failed to register SAS window\n"); goto cleanup; } if (!SetDefaultLanguage(NULL)) return FALSE; ret = TRUE; cleanup: if (!ret) UninitializeSAS(Session); return ret; }