1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "sandbox/win/tests/validation_tests/commands.h"
10 #include "sandbox/win/tests/common/controller.h"
14 // Returns the HKEY corresponding to name. If there is no HKEY corresponding
15 // to the name it returns NULL.
16 HKEY
GetHKEYFromString(const std::wstring
&name
) {
18 return HKEY_LOCAL_MACHINE
;
19 else if (L
"HKCR" == name
)
20 return HKEY_CLASSES_ROOT
;
21 else if (L
"HKCC" == name
)
22 return HKEY_CURRENT_CONFIG
;
23 else if (L
"HKCU" == name
)
24 return HKEY_CURRENT_USER
;
25 else if (L
"HKU" == name
)
31 // Modifies string to remove the leading and trailing quotes.
32 void trim_quote(std::wstring
* string
) {
33 std::wstring::size_type pos1
= string
->find_first_not_of(L
'"');
34 std::wstring::size_type pos2
= string
->find_last_not_of(L
'"');
36 if (std::wstring::npos
== pos1
|| std::wstring::npos
== pos2
)
39 (*string
) = string
->substr(pos1
, pos2
+ 1);
42 int TestOpenFile(std::wstring path
, bool for_write
) {
43 wchar_t path_expanded
[MAX_PATH
+ 1] = {0};
44 DWORD size
= ::ExpandEnvironmentStrings(path
.c_str(), path_expanded
,
47 return sandbox::SBOX_TEST_FAILED_TO_EXECUTE_COMMAND
;
50 file
= ::CreateFile(path_expanded
,
51 for_write
? GENERIC_READ
| GENERIC_WRITE
: GENERIC_READ
,
52 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
53 NULL
, // No security attributes.
55 FILE_FLAG_BACKUP_SEMANTICS
,
56 NULL
); // No template.
58 if (INVALID_HANDLE_VALUE
!= file
) {
60 return sandbox::SBOX_TEST_SUCCEEDED
;
62 if (ERROR_ACCESS_DENIED
== ::GetLastError()) {
63 return sandbox::SBOX_TEST_DENIED
;
65 return sandbox::SBOX_TEST_FAILED_TO_EXECUTE_COMMAND
;
74 SBOX_TESTS_COMMAND
int ValidWindow(int argc
, wchar_t **argv
) {
76 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND
;
78 HWND window
= reinterpret_cast<HWND
>(static_cast<ULONG_PTR
>(_wtoi(argv
[0])));
80 return TestValidWindow(window
);
83 int TestValidWindow(HWND window
) {
84 if (::IsWindow(window
))
85 return SBOX_TEST_SUCCEEDED
;
87 return SBOX_TEST_DENIED
;
90 SBOX_TESTS_COMMAND
int OpenProcessCmd(int argc
, wchar_t **argv
) {
92 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND
;
94 DWORD process_id
= _wtol(argv
[0]);
95 DWORD access_mask
= _wtol(argv
[1]);
96 return TestOpenProcess(process_id
, access_mask
);
99 int TestOpenProcess(DWORD process_id
, DWORD access_mask
) {
100 HANDLE process
= ::OpenProcess(access_mask
,
101 FALSE
, // Do not inherit handle.
103 if (NULL
== process
) {
104 if (ERROR_ACCESS_DENIED
== ::GetLastError()) {
105 return SBOX_TEST_DENIED
;
107 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND
;
110 ::CloseHandle(process
);
111 return SBOX_TEST_SUCCEEDED
;
115 SBOX_TESTS_COMMAND
int OpenThreadCmd(int argc
, wchar_t **argv
) {
117 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND
;
119 DWORD thread_id
= _wtoi(argv
[0]);
120 return TestOpenThread(thread_id
);
123 int TestOpenThread(DWORD thread_id
) {
125 HANDLE thread
= ::OpenThread(THREAD_QUERY_INFORMATION
,
126 FALSE
, // Do not inherit handles.
129 if (NULL
== thread
) {
130 if (ERROR_ACCESS_DENIED
== ::GetLastError()) {
131 return SBOX_TEST_DENIED
;
133 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND
;
136 ::CloseHandle(thread
);
137 return SBOX_TEST_SUCCEEDED
;
141 SBOX_TESTS_COMMAND
int OpenFile(int argc
, wchar_t **argv
) {
143 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND
;
145 std::wstring path
= argv
[0];
148 return TestOpenReadFile(path
);
151 int TestOpenReadFile(const std::wstring
& path
) {
152 return TestOpenFile(path
, false);
155 int TestOpenWriteFile(int argc
, wchar_t **argv
) {
157 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND
;
159 std::wstring path
= argv
[0];
162 return TestOpenWriteFile(path
);
165 int TestOpenWriteFile(const std::wstring
& path
) {
166 return TestOpenFile(path
, true);
169 SBOX_TESTS_COMMAND
int OpenKey(int argc
, wchar_t **argv
) {
170 if (0 == argc
|| argc
> 2)
171 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND
;
174 HKEY base_key
= GetHKEYFromString(argv
[0]);
183 return TestOpenKey(base_key
, subkey
);
186 int TestOpenKey(HKEY base_key
, std::wstring subkey
) {
188 LONG err_code
= ::RegOpenKeyEx(base_key
,
190 0, // Reserved, must be 0.
193 if (ERROR_SUCCESS
== err_code
) {
195 return SBOX_TEST_SUCCEEDED
;
196 } else if (ERROR_INVALID_HANDLE
== err_code
||
197 ERROR_ACCESS_DENIED
== err_code
) {
198 return SBOX_TEST_DENIED
;
200 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND
;
204 // Returns true if the current's thread desktop is the interactive desktop.
205 // In Vista there is a more direct test but for XP and w2k we need to check
207 bool IsInteractiveDesktop(bool* is_interactive
) {
208 HDESK current_desk
= ::GetThreadDesktop(::GetCurrentThreadId());
209 if (NULL
== current_desk
) {
212 wchar_t current_desk_name
[256] = {0};
213 if (!::GetUserObjectInformationW(current_desk
, UOI_NAME
, current_desk_name
,
214 sizeof(current_desk_name
), NULL
)) {
217 *is_interactive
= (0 == _wcsicmp(L
"default", current_desk_name
));
221 SBOX_TESTS_COMMAND
int OpenInteractiveDesktop(int, wchar_t **) {
222 return TestOpenInputDesktop();
225 int TestOpenInputDesktop() {
226 bool is_interactive
= false;
227 if (IsInteractiveDesktop(&is_interactive
) && is_interactive
) {
228 return SBOX_TEST_SUCCEEDED
;
230 HDESK desk
= ::OpenInputDesktop(0, FALSE
, DESKTOP_CREATEWINDOW
);
232 ::CloseDesktop(desk
);
233 return SBOX_TEST_SUCCEEDED
;
235 return SBOX_TEST_DENIED
;
238 SBOX_TESTS_COMMAND
int SwitchToSboxDesktop(int, wchar_t **) {
239 return TestSwitchDesktop();
242 int TestSwitchDesktop() {
243 HDESK sbox_desk
= ::GetThreadDesktop(::GetCurrentThreadId());
244 if (NULL
== sbox_desk
) {
245 return SBOX_TEST_FAILED
;
247 if (::SwitchDesktop(sbox_desk
)) {
248 return SBOX_TEST_SUCCEEDED
;
250 return SBOX_TEST_DENIED
;
253 SBOX_TESTS_COMMAND
int SleepCmd(int argc
, wchar_t **argv
) {
255 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND
;
257 ::Sleep(_wtoi(argv
[0]));
258 return SBOX_TEST_SUCCEEDED
;
262 } // namespace sandbox