| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/host/win/launch_process_with_token.h" | 5 #include "remoting/host/win/launch_process_with_token.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <winternl.h> | 8 #include <winternl.h> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 | 25 |
| 26 // Undocumented WINSTATIONINFOCLASS value causing | 26 // Undocumented WINSTATIONINFOCLASS value causing |
| 27 // winsta!WinStationQueryInformationW() to return the name of the pipe for | 27 // winsta!WinStationQueryInformationW() to return the name of the pipe for |
| 28 // requesting cross-session process creation. | 28 // requesting cross-session process creation. |
| 29 const WINSTATIONINFOCLASS kCreateProcessPipeNameClass = | 29 const WINSTATIONINFOCLASS kCreateProcessPipeNameClass = |
| 30 static_cast<WINSTATIONINFOCLASS>(0x21); | 30 static_cast<WINSTATIONINFOCLASS>(0x21); |
| 31 | 31 |
| 32 const int kPipeBusyWaitTimeoutMs = 2000; | 32 const int kPipeBusyWaitTimeoutMs = 2000; |
| 33 const int kPipeConnectMaxAttempts = 3; | 33 const int kPipeConnectMaxAttempts = 3; |
| 34 | 34 |
| 35 // The minimum and maximum delays between attempts to inject host process into | |
| 36 // a session. | |
| 37 const int kMaxLaunchDelaySeconds = 60; | |
| 38 const int kMinLaunchDelaySeconds = 1; | |
| 39 | |
| 40 // Name of the default session desktop. | 35 // Name of the default session desktop. |
| 41 const char kDefaultDesktopName[] = "winsta0\\default"; | 36 const char kDefaultDesktopName[] = "winsta0\\default"; |
| 42 | 37 |
| 43 // Copies the process token making it a primary impersonation token. | 38 // Copies the process token making it a primary impersonation token. |
| 44 // The returned handle will have |desired_access| rights. | 39 // The returned handle will have |desired_access| rights. |
| 45 bool CopyProcessToken(DWORD desired_access, ScopedHandle* token_out) { | 40 bool CopyProcessToken(DWORD desired_access, ScopedHandle* token_out) { |
| 46 ScopedHandle process_token; | 41 ScopedHandle process_token; |
| 47 if (!OpenProcessToken(GetCurrentProcess(), | 42 if (!OpenProcessToken(GetCurrentProcess(), |
| 48 TOKEN_DUPLICATE | desired_access, | 43 TOKEN_DUPLICATE | desired_access, |
| 49 process_token.Receive())) { | 44 process_token.Receive())) { |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 PROCESS_SUSPEND_RESUME; | 280 PROCESS_SUSPEND_RESUME; |
| 286 response.process_information.hProcess = | 281 response.process_information.hProcess = |
| 287 OpenProcess(desired_access, | 282 OpenProcess(desired_access, |
| 288 FALSE, | 283 FALSE, |
| 289 response.process_information.dwProcessId); | 284 response.process_information.dwProcessId); |
| 290 if (!response.process_information.hProcess) { | 285 if (!response.process_information.hProcess) { |
| 291 LOG_GETLASTERROR(ERROR) << "Failed to open process " | 286 LOG_GETLASTERROR(ERROR) << "Failed to open process " |
| 292 << response.process_information.dwProcessId; | 287 << response.process_information.dwProcessId; |
| 293 return false; | 288 return false; |
| 294 } | 289 } |
| 290 |
| 291 // N.B. THREAD_ALL_ACCESS is different in XP and Vista+ versions of |
| 292 // the SDK. |desired_access| below is effectively THREAD_ALL_ACCESS from |
| 293 // the XP version of the SDK. |
| 294 desired_access = |
| 295 STANDARD_RIGHTS_REQUIRED | |
| 296 SYNCHRONIZE | |
| 297 THREAD_TERMINATE | |
| 298 THREAD_SUSPEND_RESUME | |
| 299 THREAD_GET_CONTEXT | |
| 300 THREAD_SET_CONTEXT | |
| 301 THREAD_QUERY_INFORMATION | |
| 302 THREAD_SET_INFORMATION | |
| 303 THREAD_SET_THREAD_TOKEN | |
| 304 THREAD_IMPERSONATE | |
| 305 THREAD_DIRECT_IMPERSONATION; |
| 306 response.process_information.hThread = |
| 307 OpenThread(desired_access, |
| 308 FALSE, |
| 309 response.process_information.dwThreadId); |
| 310 if (!response.process_information.hThread) { |
| 311 LOG_GETLASTERROR(ERROR) << "Failed to open thread " |
| 312 << response.process_information.dwThreadId; |
| 313 CloseHandle(response.process_information.hProcess); |
| 314 return false; |
| 315 } |
| 295 } | 316 } |
| 296 | 317 |
| 297 *process_information_out = response.process_information; | 318 *process_information_out = response.process_information; |
| 298 return true; | 319 return true; |
| 299 } | 320 } |
| 300 | 321 |
| 301 } // namespace | 322 } // namespace |
| 302 | 323 |
| 303 namespace remoting { | 324 namespace remoting { |
| 304 | 325 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 return false; | 429 return false; |
| 409 } | 430 } |
| 410 | 431 |
| 411 CHECK(process_info.IsValid()); | 432 CHECK(process_info.IsValid()); |
| 412 process_out->Set(process_info.TakeProcessHandle()); | 433 process_out->Set(process_info.TakeProcessHandle()); |
| 413 thread_out->Set(process_info.TakeThreadHandle()); | 434 thread_out->Set(process_info.TakeThreadHandle()); |
| 414 return true; | 435 return true; |
| 415 } | 436 } |
| 416 | 437 |
| 417 } // namespace remoting | 438 } // namespace remoting |
| OLD | NEW |