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
20 #define WIN32_NO_STATUS
28 #define PSAPI_VERSION 1
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
)
40 if ((DWORD
)(DWORD_PTR
)head
->UniqueProcessId
== pid
)
42 if (!head
->NextEntryOffset
)
44 head
= (SYSTEM_PROCESS_INFORMATION
*)((char *)head
+ head
->NextEntryOffset
);
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
;
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
)
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
;
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
)))
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");
101 winetest_pop_context();
103 found
= found
|| !wcscmp(info
[i
].pProcessName
, process_filepart
);
106 ok(found
, "did not find current process\n");
111 static void test_WTSEnumerateProcessesW(void)
113 PWTS_PROCESS_INFOW info
;
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());
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());
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());
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());
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());
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
);
159 if (!pWTSEnumerateProcessesExW
)
161 win_skip("WTSEnumerateProcessesEx is not available\n");
167 SetLastError(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
);
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
;
199 SetLastError(0xdeadbeef);
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);
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());
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
);
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
);
244 SetLastError(0xdeadbeef);
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);
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());
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
);
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
);
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)
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());
311 pWTSEnumerateProcessesExW
= (void *)GetProcAddress(GetModuleHandleA("wtsapi32"), "WTSEnumerateProcessesExW");
312 pWTSFreeMemoryExW
= (void *)GetProcAddress(GetModuleHandleA("wtsapi32"), "WTSFreeMemoryExW");
314 test_WTSEnumerateProcessesW();
315 test_WTSQuerySessionInformation();
316 test_WTSQueryUserToken();