1 // Copyright (c) 2011 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.
5 #include "content/common/handle_enumerator_win.h"
10 #include "base/command_line.h"
11 #include "base/logging.h"
12 #include "base/process/process.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/win/windows_version.h"
15 #include "content/public/common/content_switches.h"
16 #include "content/public/common/result_codes.h"
17 #include "sandbox/win/src/handle_table.h"
19 using base::ASCIIToUTF16
;
24 typedef std::map
<const base::string16
, HandleType
> HandleTypeMap
;
26 HandleTypeMap
& MakeHandleTypeMap() {
27 HandleTypeMap
& handle_types
= *(new HandleTypeMap());
28 handle_types
[sandbox::HandleTable::kTypeProcess
] = ProcessHandle
;
29 handle_types
[sandbox::HandleTable::kTypeThread
] = ThreadHandle
;
30 handle_types
[sandbox::HandleTable::kTypeFile
] = FileHandle
;
31 handle_types
[sandbox::HandleTable::kTypeDirectory
] = DirectoryHandle
;
32 handle_types
[sandbox::HandleTable::kTypeKey
] = KeyHandle
;
33 handle_types
[sandbox::HandleTable::kTypeWindowStation
] = WindowStationHandle
;
34 handle_types
[sandbox::HandleTable::kTypeDesktop
] = DesktopHandle
;
35 handle_types
[sandbox::HandleTable::kTypeService
] = ServiceHandle
;
36 handle_types
[sandbox::HandleTable::kTypeMutex
] = MutexHandle
;
37 handle_types
[sandbox::HandleTable::kTypeSemaphore
] = SemaphoreHandle
;
38 handle_types
[sandbox::HandleTable::kTypeEvent
] = EventHandle
;
39 handle_types
[sandbox::HandleTable::kTypeTimer
] = TimerHandle
;
40 handle_types
[sandbox::HandleTable::kTypeNamedPipe
] = NamedPipeHandle
;
41 handle_types
[sandbox::HandleTable::kTypeJobObject
] = JobHandle
;
42 handle_types
[sandbox::HandleTable::kTypeFileMap
] = FileMapHandle
;
43 handle_types
[sandbox::HandleTable::kTypeAlpcPort
] = AlpcPortHandle
;
50 const size_t kMaxHandleNameLength
= 1024;
52 void HandleEnumerator::EnumerateHandles() {
53 sandbox::HandleTable handles
;
54 std::string process_type
=
55 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
56 switches::kProcessType
);
57 base::string16 output
= ASCIIToUTF16(process_type
);
58 output
.append(ASCIIToUTF16(" process - Handles at shutdown:\n"));
59 for (sandbox::HandleTable::Iterator sys_handle
60 = handles
.HandlesForProcess(::GetCurrentProcessId());
61 sys_handle
!= handles
.end(); ++sys_handle
) {
62 HandleType current_type
= StringToHandleType(sys_handle
->Type());
63 if (!all_handles_
&& (current_type
!= ProcessHandle
&&
64 current_type
!= FileHandle
&&
65 current_type
!= DirectoryHandle
&&
66 current_type
!= KeyHandle
&&
67 current_type
!= WindowStationHandle
&&
68 current_type
!= DesktopHandle
&&
69 current_type
!= ServiceHandle
))
72 output
+= ASCIIToUTF16("[");
73 output
+= sys_handle
->Type();
74 output
+= ASCIIToUTF16("] (");
75 output
+= sys_handle
->Name();
76 output
+= ASCIIToUTF16(")\n");
77 output
+= GetAccessString(current_type
,
78 sys_handle
->handle_entry()->GrantedAccess
);
83 HandleType
StringToHandleType(const base::string16
& type
) {
84 static HandleTypeMap handle_types
= MakeHandleTypeMap();
85 HandleTypeMap::iterator result
= handle_types
.find(type
);
86 return result
!= handle_types
.end() ? result
->second
: OtherHandle
;
89 base::string16
GetAccessString(HandleType handle_type
,
91 base::string16 output
;
92 if (access
& GENERIC_READ
)
93 output
.append(ASCIIToUTF16("\tGENERIC_READ\n"));
94 if (access
& GENERIC_WRITE
)
95 output
.append(ASCIIToUTF16("\tGENERIC_WRITE\n"));
96 if (access
& GENERIC_EXECUTE
)
97 output
.append(ASCIIToUTF16("\tGENERIC_EXECUTE\n"));
98 if (access
& GENERIC_ALL
)
99 output
.append(ASCIIToUTF16("\tGENERIC_ALL\n"));
101 output
.append(ASCIIToUTF16("\tDELETE\n"));
102 if (access
& READ_CONTROL
)
103 output
.append(ASCIIToUTF16("\tREAD_CONTROL\n"));
104 if (access
& WRITE_DAC
)
105 output
.append(ASCIIToUTF16("\tWRITE_DAC\n"));
106 if (access
& WRITE_OWNER
)
107 output
.append(ASCIIToUTF16("\tWRITE_OWNER\n"));
108 if (access
& SYNCHRONIZE
)
109 output
.append(ASCIIToUTF16("\tSYNCHRONIZE\n"));
111 switch (handle_type
) {
113 if (access
& PROCESS_CREATE_PROCESS
)
114 output
.append(ASCIIToUTF16("\tPROCESS_CREATE_PROCESS\n"));
115 if (access
& PROCESS_CREATE_THREAD
)
116 output
.append(ASCIIToUTF16("\tPROCESS_CREATE_THREAD\n"));
117 if (access
& PROCESS_DUP_HANDLE
)
118 output
.append(ASCIIToUTF16("\tPROCESS_DUP_HANDLE\n"));
119 if (access
& PROCESS_QUERY_INFORMATION
)
120 output
.append(ASCIIToUTF16("\tPROCESS_QUERY_INFORMATION\n"));
121 if (access
& PROCESS_QUERY_LIMITED_INFORMATION
)
122 output
.append(ASCIIToUTF16("\tPROCESS_QUERY_LIMITED_INFORMATION\n"));
123 if (access
& PROCESS_SET_INFORMATION
)
124 output
.append(ASCIIToUTF16("\tPROCESS_SET_INFORMATION\n"));
125 if (access
& PROCESS_SET_QUOTA
)
126 output
.append(ASCIIToUTF16("\tPROCESS_SET_QUOTA\n"));
127 if (access
& PROCESS_SUSPEND_RESUME
)
128 output
.append(ASCIIToUTF16("\tPROCESS_SUSPEND_RESUME\n"));
129 if (access
& PROCESS_TERMINATE
)
130 output
.append(ASCIIToUTF16("\tPROCESS_TERMINATE\n"));
131 if (access
& PROCESS_VM_OPERATION
)
132 output
.append(ASCIIToUTF16("\tPROCESS_VM_OPERATION\n"));
133 if (access
& PROCESS_VM_READ
)
134 output
.append(ASCIIToUTF16("\tPROCESS_VM_READ\n"));
135 if (access
& PROCESS_VM_WRITE
)
136 output
.append(ASCIIToUTF16("\tPROCESS_VM_WRITE\n"));
139 if (access
& THREAD_DIRECT_IMPERSONATION
)
140 output
.append(ASCIIToUTF16("\tTHREAD_DIRECT_IMPERSONATION\n"));
141 if (access
& THREAD_GET_CONTEXT
)
142 output
.append(ASCIIToUTF16("\tTHREAD_GET_CONTEXT\n"));
143 if (access
& THREAD_IMPERSONATE
)
144 output
.append(ASCIIToUTF16("\tTHREAD_IMPERSONATE\n"));
145 if (access
& THREAD_QUERY_INFORMATION
)
146 output
.append(ASCIIToUTF16("\tTHREAD_QUERY_INFORMATION\n"));
147 if (access
& THREAD_QUERY_LIMITED_INFORMATION
)
148 output
.append(ASCIIToUTF16("\tTHREAD_QUERY_LIMITED_INFORMATION\n"));
149 if (access
& THREAD_SET_CONTEXT
)
150 output
.append(ASCIIToUTF16("\tTHREAD_SET_CONTEXT\n"));
151 if (access
& THREAD_SET_INFORMATION
)
152 output
.append(ASCIIToUTF16("\tTHREAD_SET_INFORMATION\n"));
153 if (access
& THREAD_SET_LIMITED_INFORMATION
)
154 output
.append(ASCIIToUTF16("\tTHREAD_SET_LIMITED_INFORMATION\n"));
155 if (access
& THREAD_SET_THREAD_TOKEN
)
156 output
.append(ASCIIToUTF16("\tTHREAD_SET_THREAD_TOKEN\n"));
157 if (access
& THREAD_SUSPEND_RESUME
)
158 output
.append(ASCIIToUTF16("\tTHREAD_SUSPEND_RESUME\n"));
159 if (access
& THREAD_TERMINATE
)
160 output
.append(ASCIIToUTF16("\tTHREAD_TERMINATE\n"));
163 if (access
& FILE_APPEND_DATA
)
164 output
.append(ASCIIToUTF16("\tFILE_APPEND_DATA\n"));
165 if (access
& FILE_EXECUTE
)
166 output
.append(ASCIIToUTF16("\tFILE_EXECUTE\n"));
167 if (access
& FILE_READ_ATTRIBUTES
)
168 output
.append(ASCIIToUTF16("\tFILE_READ_ATTRIBUTES\n"));
169 if (access
& FILE_READ_DATA
)
170 output
.append(ASCIIToUTF16("\tFILE_READ_DATA\n"));
171 if (access
& FILE_READ_EA
)
172 output
.append(ASCIIToUTF16("\tFILE_READ_EA\n"));
173 if (access
& FILE_WRITE_ATTRIBUTES
)
174 output
.append(ASCIIToUTF16("\tFILE_WRITE_ATTRIBUTES\n"));
175 if (access
& FILE_WRITE_DATA
)
176 output
.append(ASCIIToUTF16("\tFILE_WRITE_DATA\n"));
177 if (access
& FILE_WRITE_EA
)
178 output
.append(ASCIIToUTF16("\tFILE_WRITE_EA\n"));
180 case DirectoryHandle
:
181 if (access
& FILE_ADD_FILE
)
182 output
.append(ASCIIToUTF16("\tFILE_ADD_FILE\n"));
183 if (access
& FILE_ADD_SUBDIRECTORY
)
184 output
.append(ASCIIToUTF16("\tFILE_ADD_SUBDIRECTORY\n"));
185 if (access
& FILE_APPEND_DATA
)
186 output
.append(ASCIIToUTF16("\tFILE_APPEND_DATA\n"));
187 if (access
& FILE_DELETE_CHILD
)
188 output
.append(ASCIIToUTF16("\tFILE_DELETE_CHILD\n"));
189 if (access
& FILE_LIST_DIRECTORY
)
190 output
.append(ASCIIToUTF16("\tFILE_LIST_DIRECTORY\n"));
191 if (access
& FILE_READ_DATA
)
192 output
.append(ASCIIToUTF16("\tFILE_READ_DATA\n"));
193 if (access
& FILE_TRAVERSE
)
194 output
.append(ASCIIToUTF16("\tFILE_TRAVERSE\n"));
195 if (access
& FILE_WRITE_DATA
)
196 output
.append(ASCIIToUTF16("\tFILE_WRITE_DATA\n"));
199 if (access
& KEY_CREATE_LINK
)
200 output
.append(ASCIIToUTF16("\tKEY_CREATE_LINK\n"));
201 if (access
& KEY_CREATE_SUB_KEY
)
202 output
.append(ASCIIToUTF16("\tKEY_CREATE_SUB_KEY\n"));
203 if (access
& KEY_ENUMERATE_SUB_KEYS
)
204 output
.append(ASCIIToUTF16("\tKEY_ENUMERATE_SUB_KEYS\n"));
205 if (access
& KEY_EXECUTE
)
206 output
.append(ASCIIToUTF16("\tKEY_EXECUTE\n"));
207 if (access
& KEY_NOTIFY
)
208 output
.append(ASCIIToUTF16("\tKEY_NOTIFY\n"));
209 if (access
& KEY_QUERY_VALUE
)
210 output
.append(ASCIIToUTF16("\tKEY_QUERY_VALUE\n"));
211 if (access
& KEY_READ
)
212 output
.append(ASCIIToUTF16("\tKEY_READ\n"));
213 if (access
& KEY_SET_VALUE
)
214 output
.append(ASCIIToUTF16("\tKEY_SET_VALUE\n"));
215 if (access
& KEY_WOW64_32KEY
)
216 output
.append(ASCIIToUTF16("\tKEY_WOW64_32KEY\n"));
217 if (access
& KEY_WOW64_64KEY
)
218 output
.append(ASCIIToUTF16("\tKEY_WOW64_64KEY\n"));
220 case WindowStationHandle
:
221 if (access
& WINSTA_ACCESSCLIPBOARD
)
222 output
.append(ASCIIToUTF16("\tWINSTA_ACCESSCLIPBOARD\n"));
223 if (access
& WINSTA_ACCESSGLOBALATOMS
)
224 output
.append(ASCIIToUTF16("\tWINSTA_ACCESSGLOBALATOMS\n"));
225 if (access
& WINSTA_CREATEDESKTOP
)
226 output
.append(ASCIIToUTF16("\tWINSTA_CREATEDESKTOP\n"));
227 if (access
& WINSTA_ENUMDESKTOPS
)
228 output
.append(ASCIIToUTF16("\tWINSTA_ENUMDESKTOPS\n"));
229 if (access
& WINSTA_ENUMERATE
)
230 output
.append(ASCIIToUTF16("\tWINSTA_ENUMERATE\n"));
231 if (access
& WINSTA_EXITWINDOWS
)
232 output
.append(ASCIIToUTF16("\tWINSTA_EXITWINDOWS\n"));
233 if (access
& WINSTA_READATTRIBUTES
)
234 output
.append(ASCIIToUTF16("\tWINSTA_READATTRIBUTES\n"));
235 if (access
& WINSTA_READSCREEN
)
236 output
.append(ASCIIToUTF16("\tWINSTA_READSCREEN\n"));
237 if (access
& WINSTA_WRITEATTRIBUTES
)
238 output
.append(ASCIIToUTF16("\tWINSTA_WRITEATTRIBUTES\n"));
241 if (access
& DESKTOP_CREATEMENU
)
242 output
.append(ASCIIToUTF16("\tDESKTOP_CREATEMENU\n"));
243 if (access
& DESKTOP_CREATEWINDOW
)
244 output
.append(ASCIIToUTF16("\tDESKTOP_CREATEWINDOW\n"));
245 if (access
& DESKTOP_ENUMERATE
)
246 output
.append(ASCIIToUTF16("\tDESKTOP_ENUMERATE\n"));
247 if (access
& DESKTOP_HOOKCONTROL
)
248 output
.append(ASCIIToUTF16("\tDESKTOP_HOOKCONTROL\n"));
249 if (access
& DESKTOP_JOURNALPLAYBACK
)
250 output
.append(ASCIIToUTF16("\tDESKTOP_JOURNALPLAYBACK\n"));
251 if (access
& DESKTOP_JOURNALRECORD
)
252 output
.append(ASCIIToUTF16("\tDESKTOP_JOURNALRECORD\n"));
253 if (access
& DESKTOP_READOBJECTS
)
254 output
.append(ASCIIToUTF16("\tDESKTOP_READOBJECTS\n"));
255 if (access
& DESKTOP_SWITCHDESKTOP
)
256 output
.append(ASCIIToUTF16("\tDESKTOP_SWITCHDESKTOP\n"));
257 if (access
& DESKTOP_WRITEOBJECTS
)
258 output
.append(ASCIIToUTF16("\tDESKTOP_WRITEOBJECTS\n"));
261 if (access
& SC_MANAGER_CREATE_SERVICE
)
262 output
.append(ASCIIToUTF16("\tSC_MANAGER_CREATE_SERVICE\n"));
263 if (access
& SC_MANAGER_CONNECT
)
264 output
.append(ASCIIToUTF16("\tSC_MANAGER_CONNECT\n"));
265 if (access
& SC_MANAGER_ENUMERATE_SERVICE
)
266 output
.append(ASCIIToUTF16("\tSC_MANAGER_ENUMERATE_SERVICE\n"));
267 if (access
& SC_MANAGER_LOCK
)
268 output
.append(ASCIIToUTF16("\tSC_MANAGER_LOCK\n"));
269 if (access
& SC_MANAGER_MODIFY_BOOT_CONFIG
)
270 output
.append(ASCIIToUTF16("\tSC_MANAGER_MODIFY_BOOT_CONFIG\n"));
271 if (access
& SC_MANAGER_QUERY_LOCK_STATUS
)
272 output
.append(ASCIIToUTF16("\tSC_MANAGER_QUERY_LOCK_STATUS\n"));
275 if (access
& EVENT_MODIFY_STATE
)
276 output
.append(ASCIIToUTF16("\tEVENT_MODIFY_STATE\n"));
279 if (access
& MUTEX_MODIFY_STATE
)
280 output
.append(ASCIIToUTF16("\tMUTEX_MODIFY_STATE\n"));
282 case SemaphoreHandle
:
283 if (access
& SEMAPHORE_MODIFY_STATE
)
284 output
.append(ASCIIToUTF16("\tSEMAPHORE_MODIFY_STATE\n"));
287 if (access
& TIMER_MODIFY_STATE
)
288 output
.append(ASCIIToUTF16("\tTIMER_MODIFY_STATE\n"));
289 if (access
& TIMER_QUERY_STATE
)
290 output
.append(ASCIIToUTF16("\tTIMER_QUERY_STATE\n"));
292 case NamedPipeHandle
:
293 if (access
& PIPE_ACCESS_INBOUND
)
294 output
.append(ASCIIToUTF16("\tPIPE_ACCESS_INBOUND\n"));
295 if (access
& PIPE_ACCESS_OUTBOUND
)
296 output
.append(ASCIIToUTF16("\tPIPE_ACCESS_OUTBOUND\n"));
299 if (access
& JOB_OBJECT_ASSIGN_PROCESS
)
300 output
.append(ASCIIToUTF16("\tJOB_OBJECT_ASSIGN_PROCESS\n"));
301 if (access
& JOB_OBJECT_QUERY
)
302 output
.append(ASCIIToUTF16("\tJOB_OBJECT_QUERY\n"));
303 if (access
& JOB_OBJECT_SET_ATTRIBUTES
)
304 output
.append(ASCIIToUTF16("\tJOB_OBJECT_SET_ATTRIBUTES\n"));
305 if (access
& JOB_OBJECT_SET_SECURITY_ATTRIBUTES
)
306 output
.append(ASCIIToUTF16("\tJOB_OBJECT_SET_SECURITY_ATTRIBUTES\n"));
307 if (access
& JOB_OBJECT_TERMINATE
)
308 output
.append(ASCIIToUTF16("\tJOB_OBJECT_TERMINATE\n"));
311 if (access
& FILE_MAP_EXECUTE
)
312 output
.append(ASCIIToUTF16("\tFILE_MAP_EXECUTE\n"));
313 if (access
& FILE_MAP_READ
)
314 output
.append(ASCIIToUTF16("\tFILE_MAP_READ\n"));
315 if (access
& FILE_MAP_WRITE
)
316 output
.append(ASCIIToUTF16("\tFILE_MAP_WRITE\n"));
322 } // namespace content