├── CreateDesktop └── main.c ├── EnumDesktops └── main.c └── README.md /CreateDesktop/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | HDESK CreateHiddenDesktop(const char *desktop_name, HDESK *default_desktop) 5 | { 6 | HDESK hidden_desktop = NULL, original_desktop; 7 | STARTUPINFOA si = { 0 }; 8 | PROCESS_INFORMATION pi = { 0 }; 9 | 10 | hidden_desktop = CreateDesktopA(desktop_name, NULL, NULL, 0, GENERIC_ALL, NULL); 11 | if (!hidden_desktop) { 12 | printf("CreateDesktopA() failed, error: %d\n", GetLastError()); 13 | return NULL; 14 | } 15 | 16 | original_desktop = GetThreadDesktop(GetCurrentThreadId()); 17 | if (!original_desktop) { 18 | printf("GetThreadDesktop() failed, error: %d\n", GetLastError()); 19 | goto cleanup; 20 | } 21 | 22 | if (!SetThreadDesktop(hidden_desktop)) { 23 | printf("SetThreadDesktop() failed, error: %d\n", GetLastError()); 24 | goto cleanup; 25 | } 26 | 27 | si.cb = sizeof(si); 28 | si.lpDesktop = (char *)desktop_name; 29 | 30 | if (!CreateProcessA("C:\\windows\\explorer.exe", NULL, NULL, 31 | NULL, FALSE, 0, NULL, 32 | NULL, &si, &pi)) { 33 | printf("CreateProcessA() failed, error: %d\n", GetLastError()); 34 | goto cleanup; 35 | } 36 | 37 | CloseHandle(pi.hThread); 38 | CloseHandle(pi.hProcess); 39 | 40 | SetThreadDesktop(original_desktop); 41 | 42 | *default_desktop = original_desktop; 43 | 44 | return hidden_desktop; 45 | 46 | cleanup: 47 | if(hidden_desktop) 48 | CloseDesktop(hidden_desktop); 49 | 50 | return FALSE; 51 | } 52 | 53 | void main() { 54 | HDESK hidden_desktop, original_desktop; 55 | MSG msg = { 0 }; 56 | 57 | hidden_desktop = CreateHiddenDesktop("TestHiddenDesktop123", &original_desktop); 58 | if (!hidden_desktop) 59 | return; 60 | 61 | if (!SetThreadDesktop(hidden_desktop)) { 62 | printf("SetThreadDesktop() failed, error: %d\n", GetLastError()); 63 | goto cleanup; 64 | } 65 | 66 | if (!RegisterHotKey(NULL, 1, MOD_CONTROL | MOD_ALT | MOD_NOREPEAT, 'E')) { 67 | printf("RegisterHotKey() failed, error: %d\n", GetLastError()); 68 | goto cleanup; 69 | } 70 | 71 | printf("Use CTRL + ALT + E to switch back to default desktop.\n"); 72 | printf("Hit enter to switch into hidden desktop\n"); 73 | 74 | getchar(); 75 | 76 | SwitchDesktop(hidden_desktop); 77 | 78 | while (GetMessage(&msg, NULL, 0, 0) != 0) 79 | { 80 | if (msg.message == WM_HOTKEY) 81 | { 82 | printf("Exited hidden desktop\n"); 83 | SwitchDesktop(original_desktop); 84 | break; 85 | } 86 | } 87 | 88 | cleanup: 89 | if(hidden_desktop) 90 | CloseDesktop(hidden_desktop); 91 | } 92 | -------------------------------------------------------------------------------- /EnumDesktops/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | BOOL GetProcessName(DWORD process_id, char *process_name, size_t name_length) { 6 | HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process_id); 7 | if (process == NULL) { 8 | printf("OpenProcess() failed, error: %d\n", GetLastError()); 9 | return FALSE; 10 | } 11 | 12 | if (!GetModuleBaseNameA(process, NULL, process_name, name_length)) { 13 | printf("GetModuleFileNameExA() failed, error: %d\n", GetLastError()); 14 | CloseHandle(process); 15 | return FALSE; 16 | } 17 | 18 | CloseHandle(process); 19 | return TRUE; 20 | } 21 | 22 | BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { 23 | DWORD process_id = NULL; 24 | HANDLE process; 25 | PDWORD process_ids = (PDWORD)lParam; 26 | char process_name[MAX_PATH]; 27 | 28 | if (!GetWindowThreadProcessId(hwnd, &process_id)) { 29 | printf("GetWindowThreadProcessId() failed, error: %d\n", GetLastError()); 30 | return FALSE; 31 | } 32 | 33 | for (int i = 0; i < 1024 && process_ids[i] != process_id; i++) { 34 | if (process_ids[i] == 0) { 35 | process_ids[i] = process_id; 36 | 37 | if (GetProcessName(process_id, process_name, MAX_PATH)) { 38 | printf("\tFound Process: %s\n", process_name); 39 | } 40 | 41 | break; 42 | } 43 | } 44 | 45 | return TRUE; 46 | } 47 | 48 | BOOL CALLBACK EnumDesktopProc(LPSTR lpszDesktop, LPARAM lParam) { 49 | DWORD desktop_pids[1024] = { 0 }; 50 | 51 | if (_stricmp(lpszDesktop, "Default") != 0) { 52 | printf("Found Desktop: %s\n", lpszDesktop); 53 | 54 | HDESK desktop = OpenDesktopA(lpszDesktop, 0, FALSE, GENERIC_ALL); 55 | 56 | EnumDesktopWindows(desktop, EnumWindowsProc, (LPARAM)&desktop_pids); 57 | 58 | CloseDesktop(desktop); 59 | } 60 | 61 | return TRUE; 62 | } 63 | 64 | BOOL SwitchToDesktop(char* desktop_name) { 65 | BOOL success = FALSE; 66 | HDESK desktop = NULL; 67 | 68 | desktop = OpenDesktopA(desktop_name, 0, FALSE, GENERIC_ALL); 69 | if (!desktop) { 70 | printf("OpenDesktopA() failed, error: %d\n", GetLastError()); 71 | goto cleanup; 72 | } 73 | 74 | if (!SetThreadDesktop(desktop)) { 75 | printf("SetThreadDesktop() failed, error: %d\n", GetLastError()); 76 | goto cleanup; 77 | } 78 | 79 | if (!SwitchDesktop(desktop)) { 80 | printf("SwitchDesktop() failed, error: %d\n", GetLastError()); 81 | goto cleanup; 82 | } 83 | 84 | success = TRUE; 85 | 86 | cleanup: 87 | if (desktop) 88 | CloseDesktop(desktop); 89 | 90 | return success; 91 | } 92 | 93 | 94 | void main() { 95 | char desktop_name[MAX_PATH]; 96 | MSG msg = { 0 }; 97 | 98 | EnumDesktopsA(GetProcessWindowStation(), EnumDesktopProc, NULL); 99 | 100 | if (!RegisterHotKey(NULL, 1, MOD_CONTROL | MOD_ALT | MOD_NOREPEAT, 'E')) { 101 | printf("RegisterHotKey('E') failed, error: %d\n", GetLastError()); 102 | return; 103 | } 104 | 105 | HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId()); 106 | if (!old_desktop) { 107 | printf("GetThreadDesktop() failed, error: %d\n", GetLastError()); 108 | return; 109 | } 110 | 111 | while (TRUE) { 112 | printf("Note: Use CTRL + ALT + E to switch back to the default desktop\r\n"); 113 | printf("Enter desktop to switch to: "); 114 | scanf_s("%s", desktop_name, MAX_PATH); 115 | 116 | if (SwitchToDesktop(desktop_name)) { 117 | 118 | while (GetMessage(&msg, NULL, 0, 0) != 0) 119 | { 120 | if (msg.message == WM_HOTKEY) 121 | { 122 | printf("Exiting desktop %s\r\n", desktop_name); 123 | SwitchDesktop(old_desktop); 124 | break; 125 | } 126 | } 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HiddenDesktop 2 | Create and enumerate hidden desktops. 3 | 4 | CreateDesktop - Create a hidden desktop using CreateDesktop() then launch explorer into it. 5 | EnumDesktop - List hidden desktops created using CreateDesktop(). 6 | --------------------------------------------------------------------------------