60658fd29c3302cece1f3459c17f8ef302b897db
[reactos.git] / dll / win32 / wtsapi32 / wtsapi32.c
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 }