1 /* Copyright 2005 Ulrich Czekalla 2 * 3 * This library is free software; you can redistribute it and/or 4 * modify it under the terms of the GNU Lesser General Public 5 * License as published by the Free Software Foundation; either 6 * version 2.1 of the License, or (at your option) any later version. 7 * 8 * This library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * Lesser General Public License for more details. 12 * 13 * You should have received a copy of the GNU Lesser General Public 14 * License along with this library; if not, write to the Free Software 15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 16 */ 17 18 #include "config.h" 19 #include <stdarg.h> 20 #include <stdlib.h> 21 #include "ntstatus.h" 22 #define WIN32_NO_STATUS 23 #include "windef.h" 24 #include "winbase.h" 25 #include "wine/winternl.h" 26 #include "wtsapi32.h" 27 #include "wine/debug.h" 28 #include "wine/heap.h" 29 30 WINE_DEFAULT_DEBUG_CHANNEL(wtsapi); 31 32 #ifdef __REACTOS__ /* FIXME: Inspect */ 33 #define GetCurrentProcessToken() ((HANDLE)~(ULONG_PTR)3) 34 #endif 35 36 /************************************************************ 37 * WTSCloseServer (WTSAPI32.@) 38 */ 39 void WINAPI WTSCloseServer(HANDLE hServer) 40 { 41 FIXME("Stub %p\n", hServer); 42 } 43 44 /************************************************************ 45 * WTSConnectSessionA (WTSAPI32.@) 46 */ 47 BOOL WINAPI WTSConnectSessionA(ULONG LogonId, ULONG TargetLogonId, PSTR pPassword, BOOL bWait) 48 { 49 FIXME("Stub %d %d (%s) %d\n", LogonId, TargetLogonId, debugstr_a(pPassword), bWait); 50 return TRUE; 51 } 52 53 /************************************************************ 54 * WTSConnectSessionW (WTSAPI32.@) 55 */ 56 BOOL WINAPI WTSConnectSessionW(ULONG LogonId, ULONG TargetLogonId, PWSTR pPassword, BOOL bWait) 57 { 58 FIXME("Stub %d %d (%s) %d\n", LogonId, TargetLogonId, debugstr_w(pPassword), bWait); 59 return TRUE; 60 } 61 62 /************************************************************ 63 * WTSDisconnectSession (WTSAPI32.@) 64 */ 65 BOOL WINAPI WTSDisconnectSession(HANDLE hServer, DWORD SessionId, BOOL bWait) 66 { 67 FIXME("Stub %p 0x%08x %d\n", hServer, SessionId, bWait); 68 return TRUE; 69 } 70 71 /************************************************************ 72 * WTSEnableChildSessions (WTSAPI32.@) 73 */ 74 BOOL WINAPI WTSEnableChildSessions(BOOL enable) 75 { 76 FIXME("Stub %d\n", enable); 77 return TRUE; 78 } 79 80 /************************************************************ 81 * WTSEnumerateProcessesA (WTSAPI32.@) 82 */ 83 BOOL WINAPI WTSEnumerateProcessesA(HANDLE hServer, DWORD Reserved, DWORD Version, 84 PWTS_PROCESS_INFOA* ppProcessInfo, DWORD* pCount) 85 { 86 FIXME("Stub %p 0x%08x 0x%08x %p %p\n", hServer, Reserved, Version, 87 ppProcessInfo, pCount); 88 89 if (!ppProcessInfo || !pCount) return FALSE; 90 91 *pCount = 0; 92 *ppProcessInfo = NULL; 93 94 return TRUE; 95 } 96 97 /************************************************************ 98 * WTSEnumerateProcessesW (WTSAPI32.@) 99 */ 100 BOOL WINAPI WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version, 101 PWTS_PROCESS_INFOW* ppProcessInfo, DWORD* pCount) 102 { 103 WTS_PROCESS_INFOW *processInfo; 104 SYSTEM_PROCESS_INFORMATION *spi; 105 ULONG size = 0x4000; 106 void *buf = NULL; 107 NTSTATUS status; 108 DWORD count; 109 WCHAR *name; 110 111 if (!ppProcessInfo || !pCount || Reserved != 0 || Version != 1) 112 { 113 SetLastError(ERROR_INVALID_PARAMETER); 114 return FALSE; 115 } 116 117 if (hServer != WTS_CURRENT_SERVER_HANDLE) 118 { 119 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 120 return FALSE; 121 } 122 123 do 124 { 125 size *= 2; 126 HeapFree(GetProcessHeap(), 0, buf); 127 buf = HeapAlloc(GetProcessHeap(), 0, size); 128 if (!buf) 129 { 130 SetLastError(ERROR_OUTOFMEMORY); 131 return FALSE; 132 } 133 status = NtQuerySystemInformation(SystemProcessInformation, buf, size, NULL); 134 } 135 while (status == STATUS_INFO_LENGTH_MISMATCH); 136 137 if (status != STATUS_SUCCESS) 138 { 139 HeapFree(GetProcessHeap(), 0, buf); 140 SetLastError(RtlNtStatusToDosError(status)); 141 return FALSE; 142 } 143 144 spi = buf; 145 count = size = 0; 146 for (;;) 147 { 148 size += sizeof(WTS_PROCESS_INFOW) + spi->ProcessName.Length + sizeof(WCHAR); 149 count++; 150 if (spi->NextEntryOffset == 0) break; 151 spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset); 152 } 153 154 processInfo = HeapAlloc(GetProcessHeap(), 0, size); 155 if (!processInfo) 156 { 157 HeapFree(GetProcessHeap(), 0, buf); 158 SetLastError(ERROR_OUTOFMEMORY); 159 return FALSE; 160 } 161 name = (WCHAR *)&processInfo[count]; 162 163 *ppProcessInfo = processInfo; 164 *pCount = count; 165 166 spi = buf; 167 while (count--) 168 { 169 processInfo->SessionId = 0; 170 processInfo->ProcessId = HandleToUlong(spi->UniqueProcessId); 171 processInfo->pProcessName = name; 172 processInfo->pUserSid = NULL; 173 memcpy( name, spi->ProcessName.Buffer, spi->ProcessName.Length ); 174 name[ spi->ProcessName.Length/sizeof(WCHAR) ] = 0; 175 176 processInfo++; 177 name += (spi->ProcessName.Length + sizeof(WCHAR))/sizeof(WCHAR); 178 spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset); 179 } 180 181 HeapFree(GetProcessHeap(), 0, buf); 182 return TRUE; 183 } 184 185 /************************************************************ 186 * WTSEnumerateServersA (WTSAPI32.@) 187 */ 188 BOOL WINAPI WTSEnumerateServersA(LPSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOA *ppServerInfo, DWORD *pCount) 189 { 190 FIXME("Stub %s 0x%08x 0x%08x %p %p\n", debugstr_a(pDomainName), Reserved, Version, ppServerInfo, pCount); 191 return FALSE; 192 } 193 194 /************************************************************ 195 * WTSEnumerateServersW (WTSAPI32.@) 196 */ 197 BOOL WINAPI WTSEnumerateServersW(LPWSTR pDomainName, DWORD Reserved, DWORD Version, PWTS_SERVER_INFOW *ppServerInfo, DWORD *pCount) 198 { 199 FIXME("Stub %s 0x%08x 0x%08x %p %p\n", debugstr_w(pDomainName), Reserved, Version, ppServerInfo, pCount); 200 return FALSE; 201 } 202 203 204 /************************************************************ 205 * WTSEnumerateEnumerateSessionsA (WTSAPI32.@) 206 */ 207 BOOL WINAPI WTSEnumerateSessionsA(HANDLE hServer, DWORD Reserved, DWORD Version, 208 PWTS_SESSION_INFOA* ppSessionInfo, DWORD* pCount) 209 { 210 static int once; 211 212 if (!once++) FIXME("Stub %p 0x%08x 0x%08x %p %p\n", hServer, Reserved, Version, 213 ppSessionInfo, pCount); 214 215 if (!ppSessionInfo || !pCount) return FALSE; 216 217 *pCount = 0; 218 *ppSessionInfo = NULL; 219 220 return TRUE; 221 } 222 223 /************************************************************ 224 * WTSEnumerateEnumerateSessionsW (WTSAPI32.@) 225 */ 226 BOOL WINAPI WTSEnumerateSessionsW(HANDLE hServer, DWORD Reserved, DWORD Version, 227 PWTS_SESSION_INFOW* ppSessionInfo, DWORD* pCount) 228 { 229 FIXME("Stub %p 0x%08x 0x%08x %p %p\n", hServer, Reserved, Version, 230 ppSessionInfo, pCount); 231 232 if (!ppSessionInfo || !pCount) return FALSE; 233 234 *pCount = 0; 235 *ppSessionInfo = NULL; 236 237 return TRUE; 238 } 239 240 /************************************************************ 241 * WTSFreeMemory (WTSAPI32.@) 242 */ 243 void WINAPI WTSFreeMemory(PVOID pMemory) 244 { 245 heap_free(pMemory); 246 } 247 248 /************************************************************ 249 * WTSLogoffSession (WTSAPI32.@) 250 */ 251 BOOL WINAPI WTSLogoffSession(HANDLE hserver, DWORD session_id, BOOL bwait) 252 { 253 FIXME("(%p, 0x%x, %d): stub\n", hserver, session_id, bwait); 254 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 255 return FALSE; 256 } 257 258 /************************************************************ 259 * WTSOpenServerA (WTSAPI32.@) 260 */ 261 HANDLE WINAPI WTSOpenServerA(LPSTR pServerName) 262 { 263 FIXME("(%s) stub\n", debugstr_a(pServerName)); 264 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 265 return NULL; 266 } 267 268 /************************************************************ 269 * WTSOpenServerW (WTSAPI32.@) 270 */ 271 HANDLE WINAPI WTSOpenServerW(LPWSTR pServerName) 272 { 273 FIXME("(%s) stub\n", debugstr_w(pServerName)); 274 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 275 return NULL; 276 } 277 278 /************************************************************ 279 * WTSQuerySessionInformationA (WTSAPI32.@) 280 */ 281 BOOL WINAPI WTSQuerySessionInformationA( 282 HANDLE hServer, 283 DWORD SessionId, 284 WTS_INFO_CLASS WTSInfoClass, 285 LPSTR* Buffer, 286 DWORD* BytesReturned) 287 { 288 #ifdef __REACTOS__ 289 const size_t wcsErrorCode = -1; 290 LPWSTR buffer = NULL; 291 LPSTR ansiBuffer = NULL; 292 DWORD bytesReturned = 0; 293 BOOL result = FALSE; 294 size_t len; 295 296 if (!BytesReturned || !Buffer) 297 { 298 SetLastError(ERROR_INVALID_USER_BUFFER); 299 return FALSE; 300 } 301 302 if (!WTSQuerySessionInformationW(hServer, SessionId, WTSInfoClass, &buffer, &bytesReturned)) 303 { 304 ansiBuffer = (LPSTR)buffer; 305 *Buffer = ansiBuffer; 306 *BytesReturned = bytesReturned; 307 return FALSE; 308 } 309 310 switch (WTSInfoClass) 311 { 312 case WTSInitialProgram: 313 case WTSApplicationName: 314 case WTSWorkingDirectory: 315 case WTSOEMId: 316 case WTSUserName: 317 case WTSWinStationName: 318 case WTSDomainName: 319 case WTSClientName: 320 case WTSClientDirectory: 321 { 322 len = wcstombs(NULL, buffer, 0); 323 if (len != wcsErrorCode) 324 { 325 len++; 326 ansiBuffer = heap_alloc_zero(len); 327 if (ansiBuffer && (wcstombs(ansiBuffer, buffer, len) != wcsErrorCode)) 328 { 329 result = TRUE; 330 bytesReturned = len; 331 } 332 } 333 WTSFreeMemory(buffer); 334 break; 335 } 336 337 default: 338 { 339 result = TRUE; 340 ansiBuffer = (LPSTR)buffer; 341 break; 342 } 343 } 344 345 *Buffer = ansiBuffer; 346 *BytesReturned = bytesReturned; 347 348 return result; 349 #else 350 /* FIXME: Forward request to winsta.dll::WinStationQueryInformationA */ 351 FIXME("Stub %p 0x%08x %d %p %p\n", hServer, SessionId, WTSInfoClass, 352 Buffer, BytesReturned); 353 354 return FALSE; 355 #endif 356 } 357 358 /************************************************************ 359 * WTSQuerySessionInformationW (WTSAPI32.@) 360 */ 361 BOOL WINAPI WTSQuerySessionInformationW( 362 HANDLE hServer, 363 DWORD SessionId, 364 WTS_INFO_CLASS WTSInfoClass, 365 LPWSTR* Buffer, 366 DWORD* BytesReturned) 367 { 368 #ifdef __REACTOS__ 369 if (!BytesReturned || !Buffer) 370 { 371 SetLastError(ERROR_INVALID_USER_BUFFER); 372 return FALSE; 373 } 374 375 #if (NTDDI_VERSION >= NTDDI_WS08) 376 if (WTSInfoClass > WTSIsRemoteSession) 377 #else 378 if (WTSInfoClass > WTSClientProtocolType) 379 #endif 380 { 381 SetLastError(ERROR_INVALID_PARAMETER); 382 return FALSE; 383 } 384 385 switch (WTSInfoClass) 386 { 387 case WTSSessionId: 388 { 389 const DWORD size = sizeof(ULONG); 390 ULONG* output = heap_alloc_zero(size); 391 if (!output) 392 { 393 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 394 return FALSE; 395 } 396 397 *output = NtCurrentTeb()->Peb->SessionId; 398 *Buffer = (LPWSTR)output; 399 *BytesReturned = size; 400 return TRUE; 401 } 402 403 case WTSUserName: 404 { 405 WCHAR* username; 406 DWORD count = 0; 407 408 GetUserNameW(NULL, &count); 409 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 410 return FALSE; 411 username = heap_alloc(count * sizeof(WCHAR)); 412 if (!username) 413 { 414 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 415 return FALSE; 416 } 417 418 GetUserNameW(username, &count); 419 *Buffer = username; 420 *BytesReturned = count * sizeof(WCHAR); 421 return TRUE; 422 } 423 424 case WTSConnectState: 425 { 426 const DWORD size = sizeof(DWORD); 427 WCHAR* output = heap_alloc_zero(size); 428 if (!output) 429 { 430 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 431 return FALSE; 432 } 433 434 *Buffer = output; 435 *BytesReturned = size; 436 return TRUE; 437 } 438 439 case WTSClientProtocolType: 440 { 441 const DWORD size = sizeof(WORD); 442 WCHAR* output = heap_alloc_zero(size); 443 if (!output) 444 { 445 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 446 return FALSE; 447 } 448 449 *Buffer = output; 450 *BytesReturned = size; 451 return TRUE; 452 } 453 454 #if (NTDDI_VERSION >= NTDDI_WS08) 455 case WTSIdleTime: 456 case WTSLogonTime: 457 case WTSIncomingBytes: 458 case WTSOutgoingBytes: 459 case WTSIncomingFrames: 460 case WTSOutgoingFrames: 461 { 462 SetLastError(ERROR_NOT_SUPPORTED); 463 return FALSE; 464 } 465 #endif /* (NTDDI_VERSION >= NTDDI_WS08) */ 466 467 default: 468 { 469 if (BytesReturned) 470 *BytesReturned = 0; 471 472 break; 473 } 474 } 475 476 /* FIXME: Forward request to winsta.dll::WinStationQueryInformationW */ 477 FIXME("Stub %p 0x%08x %d %p %p\n", hServer, SessionId, WTSInfoClass, 478 Buffer, BytesReturned); 479 480 return FALSE; 481 #else 482 /* FIXME: Forward request to winsta.dll::WinStationQueryInformationW */ 483 FIXME("Stub %p 0x%08x %d %p %p\n", hServer, SessionId, WTSInfoClass, 484 Buffer, BytesReturned); 485 486 if (WTSInfoClass == WTSUserName) 487 { 488 WCHAR *username; 489 DWORD count = 0; 490 491 GetUserNameW(NULL, &count); 492 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FALSE; 493 if (!(username = heap_alloc(count * sizeof(WCHAR)))) return FALSE; 494 GetUserNameW(username, &count); 495 *Buffer = username; 496 *BytesReturned = count * sizeof(WCHAR); 497 return TRUE; 498 } 499 return FALSE; 500 #endif 501 } 502 503 /************************************************************ 504 * WTSQueryUserToken (WTSAPI32.@) 505 */ 506 BOOL WINAPI WTSQueryUserToken(ULONG session_id, PHANDLE token) 507 { 508 FIXME("%u %p\n", session_id, token); 509 510 if (!token) 511 { 512 SetLastError(ERROR_INVALID_PARAMETER); 513 return FALSE; 514 } 515 516 return DuplicateHandle(GetCurrentProcess(), GetCurrentProcessToken(), 517 GetCurrentProcess(), token, 518 0, FALSE, DUPLICATE_SAME_ACCESS); 519 } 520 521 /************************************************************ 522 * WTSQueryUserConfigA (WTSAPI32.@) 523 */ 524 BOOL WINAPI WTSQueryUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPSTR *ppBuffer, DWORD *pBytesReturned) 525 { 526 FIXME("Stub (%s) (%s) 0x%08x %p %p\n", debugstr_a(pServerName), debugstr_a(pUserName), WTSConfigClass, 527 ppBuffer, pBytesReturned); 528 return FALSE; 529 } 530 531 /************************************************************ 532 * WTSQueryUserConfigW (WTSAPI32.@) 533 */ 534 BOOL WINAPI WTSQueryUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPWSTR *ppBuffer, DWORD *pBytesReturned) 535 { 536 FIXME("Stub (%s) (%s) 0x%08x %p %p\n", debugstr_w(pServerName), debugstr_w(pUserName), WTSConfigClass, 537 ppBuffer, pBytesReturned); 538 return FALSE; 539 } 540 541 542 /************************************************************ 543 * WTSRegisterSessionNotification (WTSAPI32.@) 544 */ 545 BOOL WINAPI WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags) 546 { 547 FIXME("Stub %p 0x%08x\n", hWnd, dwFlags); 548 return TRUE; 549 } 550 551 /************************************************************ 552 * WTSRegisterSessionNotificationEx (WTSAPI32.@) 553 */ 554 BOOL WINAPI WTSRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd, DWORD dwFlags) 555 { 556 FIXME("Stub %p %p 0x%08x\n", hServer, hWnd, dwFlags); 557 return FALSE; 558 } 559 560 561 /************************************************************ 562 * WTSSendMessageA (WTSAPI32.@) 563 */ 564 BOOL WINAPI WTSSendMessageA(HANDLE hServer, DWORD SessionId, LPSTR pTitle, DWORD TitleLength, LPSTR pMessage, 565 DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD *pResponse, BOOL bWait) 566 { 567 FIXME("Stub %p 0x%08x (%s) %d (%s) %d 0x%08x %d %p %d\n", hServer, SessionId, debugstr_a(pTitle), TitleLength, debugstr_a(pMessage), MessageLength, Style, Timeout, pResponse, bWait); 568 return FALSE; 569 } 570 571 /************************************************************ 572 * WTSSendMessageW (WTSAPI32.@) 573 */ 574 BOOL WINAPI WTSSendMessageW(HANDLE hServer, DWORD SessionId, LPWSTR pTitle, DWORD TitleLength, LPWSTR pMessage, 575 DWORD MessageLength, DWORD Style, DWORD Timeout, DWORD *pResponse, BOOL bWait) 576 { 577 FIXME("Stub %p 0x%08x (%s) %d (%s) %d 0x%08x %d %p %d\n", hServer, SessionId, debugstr_w(pTitle), TitleLength, debugstr_w(pMessage), MessageLength, Style, Timeout, pResponse, bWait); 578 return FALSE; 579 } 580 581 /************************************************************ 582 * WTSSetUserConfigA (WTSAPI32.@) 583 */ 584 BOOL WINAPI WTSSetUserConfigA(LPSTR pServerName, LPSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPSTR pBuffer, DWORD DataLength) 585 { 586 FIXME("Stub (%s) (%s) 0x%08x %p %d\n", debugstr_a(pServerName), debugstr_a(pUserName), WTSConfigClass,pBuffer, DataLength); 587 return FALSE; 588 } 589 590 /************************************************************ 591 * WTSSetUserConfigW (WTSAPI32.@) 592 */ 593 BOOL WINAPI WTSSetUserConfigW(LPWSTR pServerName, LPWSTR pUserName, WTS_CONFIG_CLASS WTSConfigClass, LPWSTR pBuffer, DWORD DataLength) 594 { 595 FIXME("Stub (%s) (%s) 0x%08x %p %d\n", debugstr_w(pServerName), debugstr_w(pUserName), WTSConfigClass,pBuffer, DataLength); 596 return FALSE; 597 } 598 599 /************************************************************ 600 * WTSShutdownSystem (WTSAPI32.@) 601 */ 602 BOOL WINAPI WTSShutdownSystem(HANDLE hServer, DWORD ShutdownFlag) 603 { 604 FIXME("Stub %p 0x%08x\n", hServer,ShutdownFlag); 605 return FALSE; 606 } 607 608 /************************************************************ 609 * WTSStartRemoteControlSessionA (WTSAPI32.@) 610 */ 611 BOOL WINAPI WTSStartRemoteControlSessionA(LPSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers) 612 { 613 FIXME("Stub (%s) %d %d %d\n", debugstr_a(pTargetServerName), TargetLogonId, HotkeyVk, HotkeyModifiers); 614 return FALSE; 615 } 616 617 /************************************************************ 618 * WTSStartRemoteControlSessionW (WTSAPI32.@) 619 */ 620 BOOL WINAPI WTSStartRemoteControlSessionW(LPWSTR pTargetServerName, ULONG TargetLogonId, BYTE HotkeyVk, USHORT HotkeyModifiers) 621 { 622 FIXME("Stub (%s) %d %d %d\n", debugstr_w(pTargetServerName), TargetLogonId, HotkeyVk, HotkeyModifiers); 623 return FALSE; 624 } 625 626 /************************************************************ 627 * WTSStopRemoteControlSession (WTSAPI32.@) 628 */ 629 BOOL WINAPI WTSStopRemoteControlSession(ULONG LogonId) 630 { 631 FIXME("Stub %d\n", LogonId); 632 return FALSE; 633 } 634 635 /************************************************************ 636 * WTSTerminateProcess (WTSAPI32.@) 637 */ 638 BOOL WINAPI WTSTerminateProcess(HANDLE hServer, DWORD ProcessId, DWORD ExitCode) 639 { 640 FIXME("Stub %p %d %d\n", hServer, ProcessId, ExitCode); 641 return FALSE; 642 } 643 644 /************************************************************ 645 * WTSUnRegisterSessionNotification (WTSAPI32.@) 646 */ 647 BOOL WINAPI WTSUnRegisterSessionNotification(HWND hWnd) 648 { 649 FIXME("Stub %p\n", hWnd); 650 return FALSE; 651 } 652 653 /************************************************************ 654 * WTSUnRegisterSessionNotification (WTSAPI32.@) 655 */ 656 BOOL WINAPI WTSUnRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd) 657 { 658 FIXME("Stub %p %p\n", hServer, hWnd); 659 return FALSE; 660 } 661 662 663 /************************************************************ 664 * WTSVirtualChannelClose (WTSAPI32.@) 665 */ 666 BOOL WINAPI WTSVirtualChannelClose(HANDLE hChannelHandle) 667 { 668 FIXME("Stub %p\n", hChannelHandle); 669 return FALSE; 670 } 671 672 /************************************************************ 673 * WTSVirtualChannelOpen (WTSAPI32.@) 674 */ 675 HANDLE WINAPI WTSVirtualChannelOpen(HANDLE hServer, DWORD SessionId, LPSTR pVirtualName) 676 { 677 FIXME("Stub %p %d (%s)\n", hServer, SessionId, debugstr_a(pVirtualName)); 678 return NULL; 679 } 680 681 /************************************************************ 682 * WTSVirtualChannelOpen (WTSAPI32.@) 683 */ 684 HANDLE WINAPI WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualName, DWORD flags) 685 { 686 FIXME("Stub %d (%s) %d\n", SessionId, debugstr_a(pVirtualName), flags); 687 return NULL; 688 } 689 690 /************************************************************ 691 * WTSVirtualChannelPurgeInput (WTSAPI32.@) 692 */ 693 BOOL WINAPI WTSVirtualChannelPurgeInput(HANDLE hChannelHandle) 694 { 695 FIXME("Stub %p\n", hChannelHandle); 696 return FALSE; 697 } 698 699 /************************************************************ 700 * WTSVirtualChannelPurgeOutput (WTSAPI32.@) 701 */ 702 BOOL WINAPI WTSVirtualChannelPurgeOutput(HANDLE hChannelHandle) 703 { 704 FIXME("Stub %p\n", hChannelHandle); 705 return FALSE; 706 } 707 708 709 /************************************************************ 710 * WTSVirtualChannelQuery (WTSAPI32.@) 711 */ 712 BOOL WINAPI WTSVirtualChannelQuery(HANDLE hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, PVOID *ppBuffer, DWORD *pBytesReturned) 713 { 714 FIXME("Stub %p %d %p %p\n", hChannelHandle, WtsVirtualClass, ppBuffer, pBytesReturned); 715 return FALSE; 716 } 717 718 /************************************************************ 719 * WTSVirtualChannelRead (WTSAPI32.@) 720 */ 721 BOOL WINAPI WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut, PCHAR Buffer, ULONG BufferSize, PULONG pBytesRead) 722 { 723 FIXME("Stub %p %d %p %d %p\n", hChannelHandle, TimeOut, Buffer, BufferSize, pBytesRead); 724 return FALSE; 725 } 726 727 /************************************************************ 728 * WTSVirtualChannelWrite (WTSAPI32.@) 729 */ 730 BOOL WINAPI WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, ULONG Length, PULONG pBytesWritten) 731 { 732 FIXME("Stub %p %p %d %p\n", hChannelHandle, Buffer, Length, pBytesWritten); 733 return FALSE; 734 } 735 736 /************************************************************ 737 * WTSWaitSystemEvent (WTSAPI32.@) 738 */ 739 BOOL WINAPI WTSWaitSystemEvent(HANDLE hServer, DWORD Mask, DWORD* Flags) 740 { 741 /* FIXME: Forward request to winsta.dll::WinStationWaitSystemEvent */ 742 FIXME("Stub %p 0x%08x %p\n", hServer, Mask, Flags); 743 return FALSE; 744 } 745