wtsapi/tests: Use a heap buffer for the user SID.
[wine.git] / dlls / wtsapi32 / tests / wtsapi.c
blob5be1764b6b3e10182e4e142110ecfd2028e622b1
1 /*
2 * Copyright 2014 Stefan Leichter
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <ntstatus.h>
20 #define WIN32_NO_STATUS
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include <windef.h>
24 #include <winbase.h>
25 #include <winternl.h>
26 #include <lmcons.h>
27 #include <wtsapi32.h>
28 #define PSAPI_VERSION 1
29 #include <psapi.h>
31 #include "wine/test.h"
33 static BOOL (WINAPI *pWTSEnumerateProcessesExW)(HANDLE server, DWORD *level, DWORD session, WCHAR **info, DWORD *count);
34 static BOOL (WINAPI *pWTSFreeMemoryExW)(WTS_TYPE_CLASS class, void *memory, ULONG count);
36 static const SYSTEM_PROCESS_INFORMATION *find_nt_process_info(const SYSTEM_PROCESS_INFORMATION *head, DWORD pid)
38 for (;;)
40 if ((DWORD)(DWORD_PTR)head->UniqueProcessId == pid)
41 return head;
42 if (!head->NextEntryOffset)
43 break;
44 head = (SYSTEM_PROCESS_INFORMATION *)((char *)head + head->NextEntryOffset);
46 return NULL;
49 static void check_wts_process_info(const WTS_PROCESS_INFOW *info, DWORD count)
51 ULONG nt_length = 1024;
52 SYSTEM_PROCESS_INFORMATION *nt_info = malloc(nt_length);
53 WCHAR process_name[MAX_PATH], *process_filepart;
54 BOOL ret, found = FALSE;
55 NTSTATUS status;
56 DWORD i;
58 GetModuleFileNameW(NULL, process_name, MAX_PATH);
59 process_filepart = wcsrchr(process_name, '\\') + 1;
61 while ((status = NtQuerySystemInformation(SystemProcessInformation, nt_info,
62 nt_length, NULL)) == STATUS_INFO_LENGTH_MISMATCH)
64 nt_length *= 2;
65 nt_info = realloc(nt_info, nt_length);
67 ok(!status, "got %#lx\n", status);
69 for (i = 0; i < count; i++)
71 SID_AND_ATTRIBUTES *sid;
72 const SYSTEM_PROCESS_INFORMATION *nt_process;
73 HANDLE process, token;
74 DWORD size;
76 nt_process = find_nt_process_info(nt_info, info[i].ProcessId);
77 ok(!!nt_process, "failed to find pid %#lx\n", info[i].ProcessId);
79 winetest_push_context("pid %#lx", info[i].ProcessId);
81 ok(info[i].SessionId == nt_process->SessionId, "expected session id %#lx, got %#lx\n",
82 nt_process->SessionId, info[i].SessionId);
84 ok(!memcmp(info[i].pProcessName, nt_process->ProcessName.Buffer, nt_process->ProcessName.Length),
85 "expected process name %s, got %s\n",
86 debugstr_w(nt_process->ProcessName.Buffer), debugstr_w(info[i].pProcessName));
88 if ((process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, info[i].ProcessId)))
90 sid = malloc(50);
91 ret = OpenProcessToken(process, TOKEN_QUERY, &token);
92 ok(ret, "failed to open token, error %lu\n", GetLastError());
93 ret = GetTokenInformation(token, TokenUser, sid, 50, &size);
94 ok(ret, "failed to get token user, error %lu\n", GetLastError());
95 ok(EqualSid(info[i].pUserSid, sid->Sid), "SID did not match\n");
96 free(sid);
97 CloseHandle(token);
98 CloseHandle(process);
101 winetest_pop_context();
103 found = found || !wcscmp(info[i].pProcessName, process_filepart);
106 ok(found, "did not find current process\n");
108 free(nt_info);
111 static void test_WTSEnumerateProcessesW(void)
113 PWTS_PROCESS_INFOW info;
114 DWORD count, level;
115 BOOL ret;
117 info = NULL;
118 SetLastError(0xdeadbeef);
119 ret = WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE, 1, 1, &info, &count);
120 ok(!ret, "expected WTSEnumerateProcessesW to fail\n");
121 ok(GetLastError()== ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got: %ld\n", GetLastError());
122 WTSFreeMemory(info);
124 info = NULL;
125 SetLastError(0xdeadbeef);
126 ret = WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE, 0, 0, &info, &count);
127 ok(!ret, "expected WTSEnumerateProcessesW to fail\n");
128 ok(GetLastError()== ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got: %ld\n", GetLastError());
129 WTSFreeMemory(info);
131 info = NULL;
132 SetLastError(0xdeadbeef);
133 ret = WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE, 0, 2, &info, &count);
134 ok(!ret, "expected WTSEnumerateProcessesW to fail\n");
135 ok(GetLastError()== ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got: %ld\n", GetLastError());
136 WTSFreeMemory(info);
138 SetLastError(0xdeadbeef);
139 ret = WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE, 0, 1, NULL, &count);
140 ok(!ret, "expected WTSEnumerateProcessesW to fail\n");
141 ok(GetLastError()== ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got: %ld\n", GetLastError());
143 info = NULL;
144 SetLastError(0xdeadbeef);
145 ret = WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &info, NULL);
146 ok(!ret, "expected WTSEnumerateProcessesW to fail\n");
147 ok(GetLastError()== ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got: %ld\n", GetLastError());
148 WTSFreeMemory(info);
150 count = 0;
151 info = NULL;
152 SetLastError(0xdeadbeef);
153 ret = WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &info, &count);
154 ok(ret, "expected success\n");
155 ok(!GetLastError(), "got error %lu\n", GetLastError());
156 check_wts_process_info(info, count);
157 WTSFreeMemory(info);
159 if (!pWTSEnumerateProcessesExW)
161 win_skip("WTSEnumerateProcessesEx is not available\n");
162 return;
165 level = 0;
167 SetLastError(0xdeadbeef);
168 count = 0xdeadbeef;
169 ret = pWTSEnumerateProcessesExW(WTS_CURRENT_SERVER_HANDLE, &level, WTS_ANY_SESSION, NULL, &count);
170 ok(!ret, "expected failure\n");
171 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
172 ok(count == 0xdeadbeef, "got count %lu\n", count);
174 info = (void *)0xdeadbeef;
175 SetLastError(0xdeadbeef);
176 ret = pWTSEnumerateProcessesExW(WTS_CURRENT_SERVER_HANDLE, &level, WTS_ANY_SESSION, (WCHAR **)&info, NULL);
177 ok(!ret, "expected failure\n");
178 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
179 ok(info == (void *)0xdeadbeef, "got info %p\n", info);
181 info = NULL;
182 count = 0;
183 SetLastError(0xdeadbeef);
184 ret = pWTSEnumerateProcessesExW(WTS_CURRENT_SERVER_HANDLE, &level, WTS_ANY_SESSION, (WCHAR **)&info, &count);
185 ok(ret, "expected success\n");
186 ok(!GetLastError(), "got error %lu\n", GetLastError());
187 check_wts_process_info(info, count);
188 pWTSFreeMemoryExW(WTSTypeProcessInfoLevel0, info, count);
191 static void test_WTSQuerySessionInformation(void)
193 WCHAR *buf1, usernameW[UNLEN + 1], computernameW[MAX_COMPUTERNAME_LENGTH + 1];
194 char *buf2, username[UNLEN + 1], computername[MAX_COMPUTERNAME_LENGTH + 1];
195 DWORD count, tempsize;
196 USHORT *protocol;
197 BOOL ret;
199 SetLastError(0xdeadbeef);
200 count = 0;
201 ret = WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSUserName, NULL, &count);
202 ok(!ret, "got %lu\n", GetLastError());
203 ok(count == 0, "got %lu\n", count);
204 ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "got %lu\n", GetLastError());
206 SetLastError(0xdeadbeef);
207 count = 1;
208 ret = WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSUserName, NULL, &count);
209 ok(!ret, "got %lu\n", GetLastError());
210 ok(count == 1, "got %lu\n", count);
211 ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "got %lu\n", GetLastError());
213 SetLastError(0xdeadbeef);
214 ret = WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSUserName, &buf1, NULL);
215 ok(!ret, "got %lu\n", GetLastError());
216 ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "got %lu\n", GetLastError());
218 count = 0;
219 buf1 = NULL;
220 ret = WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSUserName, &buf1, &count);
221 ok(ret, "got %lu\n", GetLastError());
222 ok(buf1 != NULL, "buf not set\n");
223 ok(count == (lstrlenW(buf1) + 1) * sizeof(WCHAR), "expected %Iu, got %lu\n", (lstrlenW(buf1) + 1) * sizeof(WCHAR), count);
224 tempsize = UNLEN + 1;
225 GetUserNameW(usernameW, &tempsize);
226 /* Windows Vista, 7 and 8 return uppercase username, while the rest return lowercase. */
227 ok(!wcsicmp(buf1, usernameW), "expected %s, got %s\n", wine_dbgstr_w(usernameW), wine_dbgstr_w(buf1));
228 ok(count == tempsize * sizeof(WCHAR), "got %lu\n", count);
229 WTSFreeMemory(buf1);
231 count = 0;
232 buf1 = NULL;
233 ret = WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSDomainName, &buf1, &count);
234 ok(ret, "got %lu\n", GetLastError());
235 ok(buf1 != NULL, "buf not set\n");
236 ok(count == (lstrlenW(buf1) + 1) * sizeof(WCHAR), "expected %Iu, got %lu\n", (lstrlenW(buf1) + 1) * sizeof(WCHAR), count);
237 tempsize = MAX_COMPUTERNAME_LENGTH + 1;
238 GetComputerNameW(computernameW, &tempsize);
239 /* Windows Vista, 7 and 8 return uppercase computername, while the rest return lowercase. */
240 ok(!wcsicmp(buf1, computernameW), "expected %s, got %s\n", wine_dbgstr_w(computernameW), wine_dbgstr_w(buf1));
241 ok(count == (tempsize + 1) * sizeof(WCHAR), "got %lu\n", count);
242 WTSFreeMemory(buf1);
244 SetLastError(0xdeadbeef);
245 count = 0;
246 ret = WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSUserName, NULL, &count);
247 ok(!ret, "got %lu\n", GetLastError());
248 ok(count == 0, "got %lu\n", count);
249 ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "got %lu\n", GetLastError());
251 SetLastError(0xdeadbeef);
252 count = 1;
253 ret = WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSUserName, NULL, &count);
254 ok(!ret, "got %lu\n", GetLastError());
255 ok(count == 1, "got %lu\n", count);
256 ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "got %lu\n", GetLastError());
258 SetLastError(0xdeadbeef);
259 ret = WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSUserName, &buf2, NULL);
260 ok(!ret, "got %lu\n", GetLastError());
261 ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "got %lu\n", GetLastError());
263 count = 0;
264 buf2 = NULL;
265 ret = WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSUserName, &buf2, &count);
266 ok(ret, "got %lu\n", GetLastError());
267 ok(buf2 != NULL, "buf not set\n");
268 ok(count == lstrlenA(buf2) + 1, "expected %u, got %lu\n", lstrlenA(buf2) + 1, count);
269 tempsize = UNLEN + 1;
270 GetUserNameA(username, &tempsize);
271 /* Windows Vista, 7 and 8 return uppercase username, while the rest return lowercase. */
272 ok(!stricmp(buf2, username), "expected %s, got %s\n", username, buf2);
273 ok(count == tempsize, "expected %lu, got %lu\n", tempsize, count);
274 WTSFreeMemory(buf2);
276 count = 0;
277 buf2 = NULL;
278 ret = WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSDomainName, &buf2, &count);
279 ok(ret, "got %lu\n", GetLastError());
280 ok(buf2 != NULL, "buf not set\n");
281 ok(count == lstrlenA(buf2) + 1, "expected %u, got %lu\n", lstrlenA(buf2) + 1, count);
282 tempsize = MAX_COMPUTERNAME_LENGTH + 1;
283 GetComputerNameA(computername, &tempsize);
284 /* Windows Vista, 7 and 8 return uppercase computername, while the rest return lowercase. */
285 ok(!stricmp(buf2, computername), "expected %s, got %s\n", computername, buf2);
286 ok(count == tempsize + 1, "expected %lu, got %lu\n", tempsize + 1, count);
287 WTSFreeMemory(buf2);
289 count = 0;
290 protocol = NULL;
291 ret = WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSClientProtocolType,
292 (char **)&protocol, &count);
293 ok(ret, "got %lu\n", GetLastError());
294 ok(protocol != NULL, "protocol not set\n");
295 ok(count == sizeof(*protocol), "got %lu\n", count);
296 WTSFreeMemory(protocol);
299 static void test_WTSQueryUserToken(void)
301 BOOL ret;
303 SetLastError(0xdeadbeef);
304 ret = WTSQueryUserToken(WTS_CURRENT_SESSION, NULL);
305 ok(!ret, "expected WTSQueryUserToken to fail\n");
306 ok(GetLastError()==ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got: %ld\n", GetLastError());
309 START_TEST (wtsapi)
311 pWTSEnumerateProcessesExW = (void *)GetProcAddress(GetModuleHandleA("wtsapi32"), "WTSEnumerateProcessesExW");
312 pWTSFreeMemoryExW = (void *)GetProcAddress(GetModuleHandleA("wtsapi32"), "WTSFreeMemoryExW");
314 test_WTSEnumerateProcessesW();
315 test_WTSQuerySessionInformation();
316 test_WTSQueryUserToken();