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
++)
72 SID_AND_ATTRIBUTES
*sid
= (SID_AND_ATTRIBUTES
*)sid_buffer
;
73 const SYSTEM_PROCESS_INFORMATION
*nt_process
;
74 HANDLE process
, token
;
77 nt_process
= find_nt_process_info(nt_info
, info
[i
].ProcessId
);
78 ok(!!nt_process
, "failed to find pid %#lx\n", info
[i
].ProcessId
);
80 winetest_push_context("pid %#lx", info
[i
].ProcessId
);
82 ok(info
[i
].SessionId
== nt_process
->SessionId
, "expected session id %#lx, got %#lx\n",
83 nt_process
->SessionId
, info
[i
].SessionId
);
85 ok(!memcmp(info
[i
].pProcessName
, nt_process
->ProcessName
.Buffer
, nt_process
->ProcessName
.Length
),
86 "expected process name %s, got %s\n",
87 debugstr_w(nt_process
->ProcessName
.Buffer
), debugstr_w(info
[i
].pProcessName
));
89 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_buffer
, sizeof(sid_buffer
), &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");
100 winetest_pop_context();
102 found
= found
|| !wcscmp(info
[i
].pProcessName
, process_filepart
);
105 ok(found
, "did not find current process\n");
110 static void test_WTSEnumerateProcessesW(void)
112 PWTS_PROCESS_INFOW info
;
117 SetLastError(0xdeadbeef);
118 ret
= WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE
, 1, 1, &info
, &count
);
119 ok(!ret
, "expected WTSEnumerateProcessesW to fail\n");
120 ok(GetLastError()== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER got: %ld\n", GetLastError());
124 SetLastError(0xdeadbeef);
125 ret
= WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE
, 0, 0, &info
, &count
);
126 ok(!ret
, "expected WTSEnumerateProcessesW to fail\n");
127 ok(GetLastError()== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER got: %ld\n", GetLastError());
131 SetLastError(0xdeadbeef);
132 ret
= WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE
, 0, 2, &info
, &count
);
133 ok(!ret
, "expected WTSEnumerateProcessesW to fail\n");
134 ok(GetLastError()== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER got: %ld\n", GetLastError());
137 SetLastError(0xdeadbeef);
138 ret
= WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE
, 0, 1, NULL
, &count
);
139 ok(!ret
, "expected WTSEnumerateProcessesW to fail\n");
140 ok(GetLastError()== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER got: %ld\n", GetLastError());
143 SetLastError(0xdeadbeef);
144 ret
= WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE
, 0, 1, &info
, NULL
);
145 ok(!ret
, "expected WTSEnumerateProcessesW to fail\n");
146 ok(GetLastError()== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER got: %ld\n", GetLastError());
151 SetLastError(0xdeadbeef);
152 ret
= WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE
, 0, 1, &info
, &count
);
153 ok(ret
, "expected success\n");
154 ok(!GetLastError(), "got error %lu\n", GetLastError());
155 check_wts_process_info(info
, count
);
158 if (!pWTSEnumerateProcessesExW
)
160 win_skip("WTSEnumerateProcessesEx is not available\n");
166 SetLastError(0xdeadbeef);
168 ret
= pWTSEnumerateProcessesExW(WTS_CURRENT_SERVER_HANDLE
, &level
, WTS_ANY_SESSION
, NULL
, &count
);
169 ok(!ret
, "expected failure\n");
170 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got error %lu\n", GetLastError());
171 ok(count
== 0xdeadbeef, "got count %lu\n", count
);
173 info
= (void *)0xdeadbeef;
174 SetLastError(0xdeadbeef);
175 ret
= pWTSEnumerateProcessesExW(WTS_CURRENT_SERVER_HANDLE
, &level
, WTS_ANY_SESSION
, (WCHAR
**)&info
, NULL
);
176 ok(!ret
, "expected failure\n");
177 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got error %lu\n", GetLastError());
178 ok(info
== (void *)0xdeadbeef, "got info %p\n", info
);
182 SetLastError(0xdeadbeef);
183 ret
= pWTSEnumerateProcessesExW(WTS_CURRENT_SERVER_HANDLE
, &level
, WTS_ANY_SESSION
, (WCHAR
**)&info
, &count
);
184 ok(ret
, "expected success\n");
185 ok(!GetLastError(), "got error %lu\n", GetLastError());
186 check_wts_process_info(info
, count
);
187 pWTSFreeMemoryExW(WTSTypeProcessInfoLevel0
, info
, count
);
190 static void test_WTSQuerySessionInformation(void)
192 WCHAR
*buf1
, usernameW
[UNLEN
+ 1], computernameW
[MAX_COMPUTERNAME_LENGTH
+ 1];
193 char *buf2
, username
[UNLEN
+ 1], computername
[MAX_COMPUTERNAME_LENGTH
+ 1];
194 DWORD count
, tempsize
;
198 SetLastError(0xdeadbeef);
200 ret
= WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE
, WTS_CURRENT_SESSION
, WTSUserName
, NULL
, &count
);
201 ok(!ret
, "got %lu\n", GetLastError());
202 ok(count
== 0, "got %lu\n", count
);
203 ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "got %lu\n", GetLastError());
205 SetLastError(0xdeadbeef);
207 ret
= WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE
, WTS_CURRENT_SESSION
, WTSUserName
, NULL
, &count
);
208 ok(!ret
, "got %lu\n", GetLastError());
209 ok(count
== 1, "got %lu\n", count
);
210 ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "got %lu\n", GetLastError());
212 SetLastError(0xdeadbeef);
213 ret
= WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE
, WTS_CURRENT_SESSION
, WTSUserName
, &buf1
, NULL
);
214 ok(!ret
, "got %lu\n", GetLastError());
215 ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "got %lu\n", GetLastError());
219 ret
= WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE
, WTS_CURRENT_SESSION
, WTSUserName
, &buf1
, &count
);
220 ok(ret
, "got %lu\n", GetLastError());
221 ok(buf1
!= NULL
, "buf not set\n");
222 ok(count
== (lstrlenW(buf1
) + 1) * sizeof(WCHAR
), "expected %Iu, got %lu\n", (lstrlenW(buf1
) + 1) * sizeof(WCHAR
), count
);
223 tempsize
= UNLEN
+ 1;
224 GetUserNameW(usernameW
, &tempsize
);
225 /* Windows Vista, 7 and 8 return uppercase username, while the rest return lowercase. */
226 ok(!wcsicmp(buf1
, usernameW
), "expected %s, got %s\n", wine_dbgstr_w(usernameW
), wine_dbgstr_w(buf1
));
227 ok(count
== tempsize
* sizeof(WCHAR
), "got %lu\n", count
);
232 ret
= WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE
, WTS_CURRENT_SESSION
, WTSDomainName
, &buf1
, &count
);
233 ok(ret
, "got %lu\n", GetLastError());
234 ok(buf1
!= NULL
, "buf not set\n");
235 ok(count
== (lstrlenW(buf1
) + 1) * sizeof(WCHAR
), "expected %Iu, got %lu\n", (lstrlenW(buf1
) + 1) * sizeof(WCHAR
), count
);
236 tempsize
= MAX_COMPUTERNAME_LENGTH
+ 1;
237 GetComputerNameW(computernameW
, &tempsize
);
238 /* Windows Vista, 7 and 8 return uppercase computername, while the rest return lowercase. */
239 ok(!wcsicmp(buf1
, computernameW
), "expected %s, got %s\n", wine_dbgstr_w(computernameW
), wine_dbgstr_w(buf1
));
240 ok(count
== (tempsize
+ 1) * sizeof(WCHAR
), "got %lu\n", count
);
243 SetLastError(0xdeadbeef);
245 ret
= WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE
, WTS_CURRENT_SESSION
, WTSUserName
, NULL
, &count
);
246 ok(!ret
, "got %lu\n", GetLastError());
247 ok(count
== 0, "got %lu\n", count
);
248 ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "got %lu\n", GetLastError());
250 SetLastError(0xdeadbeef);
252 ret
= WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE
, WTS_CURRENT_SESSION
, WTSUserName
, NULL
, &count
);
253 ok(!ret
, "got %lu\n", GetLastError());
254 ok(count
== 1, "got %lu\n", count
);
255 ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "got %lu\n", GetLastError());
257 SetLastError(0xdeadbeef);
258 ret
= WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE
, WTS_CURRENT_SESSION
, WTSUserName
, &buf2
, NULL
);
259 ok(!ret
, "got %lu\n", GetLastError());
260 ok(GetLastError() == ERROR_INVALID_USER_BUFFER
, "got %lu\n", GetLastError());
264 ret
= WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE
, WTS_CURRENT_SESSION
, WTSUserName
, &buf2
, &count
);
265 ok(ret
, "got %lu\n", GetLastError());
266 ok(buf2
!= NULL
, "buf not set\n");
267 ok(count
== lstrlenA(buf2
) + 1, "expected %u, got %lu\n", lstrlenA(buf2
) + 1, count
);
268 tempsize
= UNLEN
+ 1;
269 GetUserNameA(username
, &tempsize
);
270 /* Windows Vista, 7 and 8 return uppercase username, while the rest return lowercase. */
271 ok(!stricmp(buf2
, username
), "expected %s, got %s\n", username
, buf2
);
272 ok(count
== tempsize
, "expected %lu, got %lu\n", tempsize
, count
);
277 ret
= WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE
, WTS_CURRENT_SESSION
, WTSDomainName
, &buf2
, &count
);
278 ok(ret
, "got %lu\n", GetLastError());
279 ok(buf2
!= NULL
, "buf not set\n");
280 ok(count
== lstrlenA(buf2
) + 1, "expected %u, got %lu\n", lstrlenA(buf2
) + 1, count
);
281 tempsize
= MAX_COMPUTERNAME_LENGTH
+ 1;
282 GetComputerNameA(computername
, &tempsize
);
283 /* Windows Vista, 7 and 8 return uppercase computername, while the rest return lowercase. */
284 ok(!stricmp(buf2
, computername
), "expected %s, got %s\n", computername
, buf2
);
285 ok(count
== tempsize
+ 1, "expected %lu, got %lu\n", tempsize
+ 1, count
);
290 ret
= WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE
, WTS_CURRENT_SESSION
, WTSClientProtocolType
,
291 (char **)&protocol
, &count
);
292 ok(ret
, "got %lu\n", GetLastError());
293 ok(protocol
!= NULL
, "protocol not set\n");
294 ok(count
== sizeof(*protocol
), "got %lu\n", count
);
295 WTSFreeMemory(protocol
);
298 static void test_WTSQueryUserToken(void)
302 SetLastError(0xdeadbeef);
303 ret
= WTSQueryUserToken(WTS_CURRENT_SESSION
, NULL
);
304 ok(!ret
, "expected WTSQueryUserToken to fail\n");
305 ok(GetLastError()==ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER got: %ld\n", GetLastError());
310 pWTSEnumerateProcessesExW
= (void *)GetProcAddress(GetModuleHandleA("wtsapi32"), "WTSEnumerateProcessesExW");
311 pWTSFreeMemoryExW
= (void *)GetProcAddress(GetModuleHandleA("wtsapi32"), "WTSFreeMemoryExW");
313 test_WTSEnumerateProcessesW();
314 test_WTSQuerySessionInformation();
315 test_WTSQueryUserToken();