1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Console Server DLL 4 * FILE: win32ss/user/winsrv/consrv/frontendctl.c 5 * PURPOSE: Terminal Front-Ends Control 6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) 7 */ 8 9 /* INCLUDES *******************************************************************/ 10 11 #include "consrv.h" 12 13 #define NDEBUG 14 #include <debug.h> 15 16 /* PUBLIC SERVER APIS *********************************************************/ 17 18 /********************************************************************** 19 * HardwareStateProperty 20 * 21 * DESCRIPTION 22 * Set/Get the value of the HardwareState and switch 23 * between direct video buffer ouput and GDI windowed 24 * output. 25 * ARGUMENTS 26 * Client hands us a CONSOLE_GETSETHWSTATE object. 27 * We use the same object to Request. 28 * NOTE 29 * ConsoleHwState has the correct size to be compatible 30 * with NT's, but values are not. 31 */ 32 #if 0 33 static NTSTATUS 34 SetConsoleHardwareState(PCONSRV_CONSOLE Console, ULONG ConsoleHwState) 35 { 36 DPRINT1("Console Hardware State: %d\n", ConsoleHwState); 37 38 if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState) 39 ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState)) 40 { 41 if (Console->HardwareState != ConsoleHwState) 42 { 43 /* TODO: implement switching from full screen to windowed mode */ 44 /* TODO: or back; now simply store the hardware state */ 45 Console->HardwareState = ConsoleHwState; 46 } 47 48 return STATUS_SUCCESS; 49 } 50 51 return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */ 52 } 53 #endif 54 55 /* API_NUMBER: ConsolepGetHardwareState */ 56 CSR_API(SrvGetConsoleHardwareState) 57 { 58 #if 0 59 NTSTATUS Status; 60 PCONSOLE_GETSETHWSTATE HardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HardwareStateRequest; 61 PCONSOLE_SCREEN_BUFFER Buff; 62 PCONSRV_CONSOLE Console; 63 64 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 65 HardwareStateRequest->OutputHandle, 66 &Buff, 67 GENERIC_READ, 68 TRUE); 69 if (!NT_SUCCESS(Status)) 70 { 71 DPRINT1("Failed to get console handle in SrvGetConsoleHardwareState\n"); 72 return Status; 73 } 74 75 Console = Buff->Header.Console; 76 HardwareStateRequest->State = Console->HardwareState; 77 78 ConSrvReleaseScreenBuffer(Buff, TRUE); 79 return Status; 80 #else 81 UNIMPLEMENTED; 82 return STATUS_NOT_IMPLEMENTED; 83 #endif 84 } 85 86 /* API_NUMBER: ConsolepSetHardwareState */ 87 CSR_API(SrvSetConsoleHardwareState) 88 { 89 #if 0 90 NTSTATUS Status; 91 PCONSOLE_GETSETHWSTATE HardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HardwareStateRequest; 92 PCONSOLE_SCREEN_BUFFER Buff; 93 PCONSRV_CONSOLE Console; 94 95 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 96 HardwareStateRequest->OutputHandle, 97 &Buff, 98 GENERIC_WRITE, 99 TRUE); 100 if (!NT_SUCCESS(Status)) 101 { 102 DPRINT1("Failed to get console handle in SrvSetConsoleHardwareState\n"); 103 return Status; 104 } 105 106 DPRINT("Setting console hardware state.\n"); 107 Console = Buff->Header.Console; 108 Status = SetConsoleHardwareState(Console, HardwareStateRequest->State); 109 110 ConSrvReleaseScreenBuffer(Buff, TRUE); 111 return Status; 112 #else 113 UNIMPLEMENTED; 114 return STATUS_NOT_IMPLEMENTED; 115 #endif 116 } 117 118 /* API_NUMBER: ConsolepGetDisplayMode */ 119 CSR_API(SrvGetConsoleDisplayMode) 120 { 121 NTSTATUS Status; 122 PCONSOLE_GETDISPLAYMODE GetDisplayModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetDisplayModeRequest; 123 PCONSRV_CONSOLE Console; 124 125 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 126 &Console, TRUE); 127 if (!NT_SUCCESS(Status)) return Status; 128 129 GetDisplayModeRequest->DisplayMode = TermGetDisplayMode(Console); 130 131 ConSrvReleaseConsole(Console, TRUE); 132 return STATUS_SUCCESS; 133 } 134 135 /* API_NUMBER: ConsolepSetDisplayMode */ 136 CSR_API(SrvSetConsoleDisplayMode) 137 { 138 NTSTATUS Status; 139 PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetDisplayModeRequest; 140 PCONSRV_CONSOLE Console; 141 PCONSOLE_SCREEN_BUFFER Buff; 142 143 Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 144 SetDisplayModeRequest->OutputHandle, 145 &Buff, 146 GENERIC_WRITE, 147 TRUE); 148 if (!NT_SUCCESS(Status)) return Status; 149 150 Console = (PCONSRV_CONSOLE)Buff->Header.Console; 151 152 if (TermSetDisplayMode(Console, SetDisplayModeRequest->DisplayMode)) 153 { 154 SetDisplayModeRequest->NewSBDim = Buff->ScreenBufferSize; 155 Status = STATUS_SUCCESS; 156 } 157 else 158 { 159 Status = STATUS_INVALID_PARAMETER; 160 } 161 162 ConSrvReleaseScreenBuffer(Buff, TRUE); 163 return Status; 164 } 165 166 /* API_NUMBER: ConsolepGetLargestWindowSize */ 167 CSR_API(SrvGetLargestConsoleWindowSize) 168 { 169 NTSTATUS Status; 170 PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetLargestWindowSizeRequest; 171 PCONSOLE /*PCONSRV_CONSOLE*/ Console; 172 PCONSOLE_SCREEN_BUFFER Buff; 173 174 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 175 GetLargestWindowSizeRequest->OutputHandle, 176 &Buff, 177 GENERIC_READ, 178 TRUE); 179 if (!NT_SUCCESS(Status)) return Status; 180 181 Console = Buff->Header.Console; 182 183 /* 184 * Retrieve the largest possible console window size, without 185 * taking into account the size of the console screen buffer 186 * (thus differs from ConDrvGetConsoleScreenBufferInfo). 187 */ 188 TermGetLargestConsoleWindowSize(Console, &GetLargestWindowSizeRequest->Size); 189 190 ConSrvReleaseScreenBuffer(Buff, TRUE); 191 return STATUS_SUCCESS; 192 } 193 194 /* API_NUMBER: ConsolepShowCursor */ 195 CSR_API(SrvShowConsoleCursor) 196 { 197 NTSTATUS Status; 198 PCONSOLE_SHOWCURSOR ShowCursorRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ShowCursorRequest; 199 PCONSOLE /*PCONSRV_CONSOLE*/ Console; 200 PCONSOLE_SCREEN_BUFFER Buff; 201 202 Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 203 ShowCursorRequest->OutputHandle, 204 &Buff, 205 GENERIC_WRITE, 206 TRUE); 207 if (!NT_SUCCESS(Status)) return Status; 208 209 Console = Buff->Header.Console; 210 211 ShowCursorRequest->RefCount = TermShowMouseCursor(Console, ShowCursorRequest->Show); 212 213 ConSrvReleaseScreenBuffer(Buff, TRUE); 214 return STATUS_SUCCESS; 215 } 216 217 /* API_NUMBER: ConsolepSetCursor */ 218 CSR_API(SrvSetConsoleCursor) 219 { 220 NTSTATUS Status; 221 BOOL Success; 222 PCONSOLE_SETCURSOR SetCursorRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetCursorRequest; 223 PCONSRV_CONSOLE Console; 224 PCONSOLE_SCREEN_BUFFER Buff; 225 226 // NOTE: Tests show that this function is used only for graphics screen buffers 227 // and otherwise it returns FALSE and sets last error to ERROR_INVALID_HANDLE. 228 // I find that behaviour is ridiculous but ok, let's accept it at the moment... 229 Status = ConSrvGetGraphicsBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 230 SetCursorRequest->OutputHandle, 231 &Buff, 232 GENERIC_WRITE, 233 TRUE); 234 if (!NT_SUCCESS(Status)) return Status; 235 236 Console = (PCONSRV_CONSOLE)Buff->Header.Console; 237 238 Success = TermSetMouseCursor(Console, SetCursorRequest->CursorHandle); 239 240 ConSrvReleaseScreenBuffer(Buff, TRUE); 241 return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); 242 } 243 244 /* API_NUMBER: ConsolepMenuControl */ 245 CSR_API(SrvConsoleMenuControl) 246 { 247 NTSTATUS Status; 248 PCONSOLE_MENUCONTROL MenuControlRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.MenuControlRequest; 249 PCONSRV_CONSOLE Console; 250 PCONSOLE_SCREEN_BUFFER Buff; 251 252 Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 253 MenuControlRequest->OutputHandle, 254 &Buff, 255 GENERIC_WRITE, 256 TRUE); 257 if (!NT_SUCCESS(Status)) return Status; 258 259 Console = (PCONSRV_CONSOLE)Buff->Header.Console; 260 261 MenuControlRequest->MenuHandle = TermMenuControl(Console, 262 MenuControlRequest->CmdIdLow, 263 MenuControlRequest->CmdIdHigh); 264 265 ConSrvReleaseScreenBuffer(Buff, TRUE); 266 return STATUS_SUCCESS; 267 } 268 269 /* API_NUMBER: ConsolepSetMenuClose */ 270 CSR_API(SrvSetConsoleMenuClose) 271 { 272 NTSTATUS Status; 273 BOOL Success; 274 PCONSOLE_SETMENUCLOSE SetMenuCloseRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetMenuCloseRequest; 275 PCONSRV_CONSOLE Console; 276 277 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 278 &Console, TRUE); 279 if (!NT_SUCCESS(Status)) return Status; 280 281 Success = TermSetMenuClose(Console, SetMenuCloseRequest->Enable); 282 283 ConSrvReleaseConsole(Console, TRUE); 284 return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); 285 } 286 287 /* Used by USERSRV!SrvGetThreadConsoleDesktop() */ 288 NTSTATUS 289 NTAPI 290 GetThreadConsoleDesktop( 291 IN ULONG_PTR ThreadId, 292 OUT HDESK* ConsoleDesktop) 293 { 294 NTSTATUS Status; 295 PCSR_THREAD CsrThread; 296 PCONSRV_CONSOLE Console; 297 298 /* No console desktop handle by default */ 299 *ConsoleDesktop = NULL; 300 301 /* Retrieve and lock the thread */ 302 Status = CsrLockThreadByClientId(ULongToHandle(ThreadId), &CsrThread); 303 if (!NT_SUCCESS(Status)) 304 return Status; 305 306 ASSERT(CsrThread->Process); 307 308 /* Retrieve the console to which the process is attached, and unlock the thread */ 309 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrThread->Process), 310 &Console, TRUE); 311 CsrUnlockThread(CsrThread); 312 313 if (!NT_SUCCESS(Status)) 314 return Status; 315 316 /* Retrieve the console desktop handle, and release the console */ 317 *ConsoleDesktop = TermGetThreadConsoleDesktop(Console); 318 ConSrvReleaseConsole(Console, TRUE); 319 320 return STATUS_SUCCESS; 321 } 322 323 /* API_NUMBER: ConsolepGetConsoleWindow */ 324 CSR_API(SrvGetConsoleWindow) 325 { 326 NTSTATUS Status; 327 PCONSOLE_GETWINDOW GetWindowRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetWindowRequest; 328 PCONSRV_CONSOLE Console; 329 330 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 331 &Console, TRUE); 332 if (!NT_SUCCESS(Status)) return Status; 333 334 GetWindowRequest->WindowHandle = TermGetConsoleWindowHandle(Console); 335 336 ConSrvReleaseConsole(Console, TRUE); 337 return STATUS_SUCCESS; 338 } 339 340 /* API_NUMBER: ConsolepSetIcon */ 341 CSR_API(SrvSetConsoleIcon) 342 { 343 NTSTATUS Status; 344 PCONSOLE_SETICON SetIconRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetIconRequest; 345 PCONSRV_CONSOLE Console; 346 347 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 348 &Console, TRUE); 349 if (!NT_SUCCESS(Status)) return Status; 350 351 Status = (TermChangeIcon(Console, SetIconRequest->IconHandle) 352 ? STATUS_SUCCESS 353 : STATUS_UNSUCCESSFUL); 354 355 ConSrvReleaseConsole(Console, TRUE); 356 return Status; 357 } 358 359 /* API_NUMBER: ConsolepGetSelectionInfo */ 360 CSR_API(SrvGetConsoleSelectionInfo) 361 { 362 NTSTATUS Status; 363 PCONSOLE_GETSELECTIONINFO GetSelectionInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetSelectionInfoRequest; 364 PCONSRV_CONSOLE Console; 365 366 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 367 &Console, TRUE); 368 if (!NT_SUCCESS(Status)) return Status; 369 370 Status = (TermGetSelectionInfo(Console, &GetSelectionInfoRequest->Info) 371 ? STATUS_SUCCESS 372 : STATUS_UNSUCCESSFUL); 373 374 ConSrvReleaseConsole(Console, TRUE); 375 return Status; 376 } 377 378 /* API_NUMBER: ConsolepGetNumberOfFonts */ 379 CSR_API(SrvGetConsoleNumberOfFonts) 380 { 381 NTSTATUS Status; 382 PCONSOLE_GETNUMFONTS GetNumFontsRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetNumFontsRequest; 383 PCONSOLE /*PCONSRV_CONSOLE*/ Console; 384 385 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 386 &Console, TRUE); 387 if (!NT_SUCCESS(Status)) return Status; 388 389 // FIXME! 390 // TermGetNumberOfFonts(Console, ...); 391 DPRINT1("%s not yet implemented\n", __FUNCTION__); 392 GetNumFontsRequest->NumFonts = 0; 393 394 ConSrvReleaseConsole(Console, TRUE); 395 return STATUS_SUCCESS; 396 } 397 398 /* API_NUMBER: ConsolepGetFontInfo */ 399 CSR_API(SrvGetConsoleFontInfo) 400 { 401 NTSTATUS Status; 402 PCONSOLE_GETFONTINFO GetFontInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetFontInfoRequest; 403 // PCONSOLE /*PCONSRV_CONSOLE*/ Console; 404 PCONSOLE_SCREEN_BUFFER Buff; 405 406 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 407 GetFontInfoRequest->OutputHandle, 408 &Buff, 409 GENERIC_READ, 410 TRUE); 411 if (!NT_SUCCESS(Status)) return Status; 412 413 // FIXME! 414 // Console = Buff->Header.Console; 415 // TermGetFontInfo(Console, ...); 416 DPRINT1("%s not yet implemented\n", __FUNCTION__); 417 GetFontInfoRequest->NumFonts = 0; 418 419 ConSrvReleaseScreenBuffer(Buff, TRUE); 420 return STATUS_SUCCESS; 421 } 422 423 /* API_NUMBER: ConsolepGetFontSize */ 424 CSR_API(SrvGetConsoleFontSize) 425 { 426 NTSTATUS Status; 427 PCONSOLE_GETFONTSIZE GetFontSizeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetFontSizeRequest; 428 // PCONSOLE /*PCONSRV_CONSOLE*/ Console; 429 PCONSOLE_SCREEN_BUFFER Buff; 430 431 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 432 GetFontSizeRequest->OutputHandle, 433 &Buff, 434 GENERIC_READ, 435 TRUE); 436 if (!NT_SUCCESS(Status)) return Status; 437 438 // FIXME! 439 // Console = Buff->Header.Console; 440 // TermGetFontSize(Console, ...); 441 DPRINT1("%s not yet implemented\n", __FUNCTION__); 442 443 ConSrvReleaseScreenBuffer(Buff, TRUE); 444 return STATUS_SUCCESS; 445 } 446 447 /* API_NUMBER: ConsolepGetCurrentFont */ 448 CSR_API(SrvGetConsoleCurrentFont) 449 { 450 NTSTATUS Status; 451 PCONSOLE_GETCURRENTFONT GetCurrentFontRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCurrentFontRequest; 452 // PCONSOLE /*PCONSRV_CONSOLE*/ Console; 453 PCONSOLE_SCREEN_BUFFER Buff; 454 455 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 456 GetCurrentFontRequest->OutputHandle, 457 &Buff, 458 GENERIC_READ, 459 TRUE); 460 if (!NT_SUCCESS(Status)) return Status; 461 462 // FIXME! 463 // Console = Buff->Header.Console; 464 // TermGetCurrentFont(Console, ...); 465 DPRINT1("%s not yet implemented\n", __FUNCTION__); 466 GetCurrentFontRequest->FontIndex = 0; 467 468 ConSrvReleaseScreenBuffer(Buff, TRUE); 469 return STATUS_SUCCESS; 470 } 471 472 /* API_NUMBER: ConsolepSetFont */ 473 CSR_API(SrvSetConsoleFont) 474 { 475 NTSTATUS Status; 476 PCONSOLE_SETFONT SetFontRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetFontRequest; 477 // PCONSOLE /*PCONSRV_CONSOLE*/ Console; 478 PCONSOLE_SCREEN_BUFFER Buff; 479 480 Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), 481 SetFontRequest->OutputHandle, 482 &Buff, 483 GENERIC_WRITE, 484 TRUE); 485 if (!NT_SUCCESS(Status)) return Status; 486 487 // FIXME! 488 // Console = Buff->Header.Console; 489 // TermSetFont(Console, ...); 490 DPRINT1("%s not yet implemented\n", __FUNCTION__); 491 492 ConSrvReleaseScreenBuffer(Buff, TRUE); 493 return STATUS_SUCCESS; 494 } 495 496 /* EOF */ 497