Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Side by Side Diff: remoting/host/win/launch_process_with_token.cc

Issue 10824166: Cleaned up usage of std::wstring in src/remoting. Added presubmit warning supressions for the reman… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: string16 is not in std. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/scoped_native_library.h" 12 #include "base/scoped_native_library.h"
13 #include "base/stringprintf.h" 13 #include "base/stringprintf.h"
14 #include "base/utf_string_conversions.h" 14 #include "base/utf_string_conversions.h"
15 #include "base/win/scoped_handle.h" 15 #include "base/win/scoped_handle.h"
16 #include "base/win/scoped_process_information.h" 16 #include "base/win/scoped_process_information.h"
17 #include "base/win/windows_version.h" 17 #include "base/win/windows_version.h"
18 18
19 using base::win::ScopedHandle; 19 using base::win::ScopedHandle;
20 20
21 namespace { 21 namespace {
22 22
23 const wchar_t kCreateProcessDefaultPipeNameFormat[] = 23 const char kCreateProcessDefaultPipeNameFormat[] =
24 L"\\\\.\\Pipe\\TerminalServer\\SystemExecSrvr\\%d"; 24 "\\\\.\\Pipe\\TerminalServer\\SystemExecSrvr\\%d";
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 35 // The minimum and maximum delays between attempts to inject host process into
36 // a session. 36 // a session.
37 const int kMaxLaunchDelaySeconds = 60; 37 const int kMaxLaunchDelaySeconds = 60;
38 const int kMinLaunchDelaySeconds = 1; 38 const int kMinLaunchDelaySeconds = 1;
39 39
40 // Name of the default session desktop. 40 // Name of the default session desktop.
41 wchar_t kDefaultDesktopName[] = L"winsta0\\default"; 41 wchar_t kDefaultDesktopName[] = L"winsta0\\default";
42 42
43 // Requests the execution server to create a process in the specified session 43 // Requests the execution server to create a process in the specified session
44 // using the default (i.e. Winlogon) token. This routine relies on undocumented 44 // using the default (i.e. Winlogon) token. This routine relies on undocumented
45 // OS functionality and will likely not work on anything but XP or W2K3. 45 // OS functionality and will likely not work on anything but XP or W2K3.
46 bool CreateRemoteSessionProcess( 46 bool CreateRemoteSessionProcess(
47 uint32 session_id, 47 uint32 session_id,
48 const std::wstring& application_name, 48 const FilePath::StringType& application_name,
49 const std::wstring& command_line, 49 const CommandLine::StringType& command_line,
50 PROCESS_INFORMATION* process_information_out) 50 PROCESS_INFORMATION* process_information_out)
51 { 51 {
52 DCHECK(base::win::GetVersion() == base::win::VERSION_XP); 52 DCHECK(base::win::GetVersion() == base::win::VERSION_XP);
53 53
54 std::wstring pipe_name; 54 string16 pipe_name;
55 55
56 // Use winsta!WinStationQueryInformationW() to determine the process creation 56 // Use winsta!WinStationQueryInformationW() to determine the process creation
57 // pipe name for the session. 57 // pipe name for the session.
58 FilePath winsta_path(base::GetNativeLibraryName(UTF8ToUTF16("winsta"))); 58 FilePath winsta_path(base::GetNativeLibraryName(UTF8ToUTF16("winsta")));
59 base::ScopedNativeLibrary winsta(winsta_path); 59 base::ScopedNativeLibrary winsta(winsta_path);
60 if (winsta.is_valid()) { 60 if (winsta.is_valid()) {
61 PWINSTATIONQUERYINFORMATIONW win_station_query_information = 61 PWINSTATIONQUERYINFORMATIONW win_station_query_information =
62 static_cast<PWINSTATIONQUERYINFORMATIONW>( 62 static_cast<PWINSTATIONQUERYINFORMATIONW>(
63 winsta.GetFunctionPointer("WinStationQueryInformationW")); 63 winsta.GetFunctionPointer("WinStationQueryInformationW"));
64 if (win_station_query_information) { 64 if (win_station_query_information) {
65 wchar_t name[MAX_PATH]; 65 wchar_t name[MAX_PATH];
66 ULONG name_length; 66 ULONG name_length;
67 if (win_station_query_information(0, 67 if (win_station_query_information(0,
68 session_id, 68 session_id,
69 kCreateProcessPipeNameClass, 69 kCreateProcessPipeNameClass,
70 name, 70 name,
71 sizeof(name), 71 sizeof(name),
72 &name_length)) { 72 &name_length)) {
73 pipe_name.assign(name); 73 pipe_name.assign(name);
74 } 74 }
75 } 75 }
76 } 76 }
77 77
78 // Use the default pipe name if we couldn't query its name. 78 // Use the default pipe name if we couldn't query its name.
79 if (pipe_name.empty()) { 79 if (pipe_name.empty()) {
80 pipe_name = StringPrintf(kCreateProcessDefaultPipeNameFormat, session_id); 80 pipe_name = UTF8ToUTF16(
Wez 2012/08/03 21:26:15 nit: Why not have pipe_name be std::string and UTF
alexeypa (please no reviews) 2012/08/03 22:00:18 To avoid UTF8 <-> UTF16 conversion in three places
Wez 2012/08/06 17:29:38 Makes sense; I'd recommend working with std::strin
alexeypa (please no reviews) 2012/08/06 17:56:18 This will reduce number of conversions to two, not
Wez 2012/08/06 18:41:21 Of course; good point.
81 StringPrintf(kCreateProcessDefaultPipeNameFormat, session_id));
81 } 82 }
82 83
83 // Try to connect to the named pipe. 84 // Try to connect to the named pipe.
84 base::win::ScopedHandle pipe; 85 base::win::ScopedHandle pipe;
85 for (int i = 0; i < kPipeConnectMaxAttempts; ++i) { 86 for (int i = 0; i < kPipeConnectMaxAttempts; ++i) {
86 pipe.Set(CreateFile(pipe_name.c_str(), 87 pipe.Set(CreateFile(pipe_name.c_str(),
87 GENERIC_READ | GENERIC_WRITE, 88 GENERIC_READ | GENERIC_WRITE,
88 0, 89 0,
89 NULL, 90 NULL,
90 OPEN_EXISTING, 91 OPEN_EXISTING,
(...skipping 13 matching lines...) Expand all
104 if (!WaitNamedPipe(pipe_name.c_str(), kPipeBusyWaitTimeoutMs)) { 105 if (!WaitNamedPipe(pipe_name.c_str(), kPipeBusyWaitTimeoutMs)) {
105 break; 106 break;
106 } 107 }
107 } 108 }
108 109
109 if (!pipe.IsValid()) { 110 if (!pipe.IsValid()) {
110 LOG_GETLASTERROR(ERROR) << "Failed to connect to '" << pipe_name << "'"; 111 LOG_GETLASTERROR(ERROR) << "Failed to connect to '" << pipe_name << "'";
111 return false; 112 return false;
112 } 113 }
113 114
114 std::wstring desktop_name(kDefaultDesktopName); 115 string16 desktop_name(WideToUTF16(kDefaultDesktopName));
Wez 2012/08/03 21:26:15 nit: Why does kDefaultDesktopName need to be wide?
alexeypa (please no reviews) 2012/08/03 22:00:18 Done.
115 116
116 // |CreateProcessRequest| structure passes the same parameters to 117 // |CreateProcessRequest| structure passes the same parameters to
117 // the execution server as CreateProcessAsUser() function does. Strings are 118 // the execution server as CreateProcessAsUser() function does. Strings are
118 // stored as wide strings immediately after the structure. String pointers are 119 // stored as wide strings immediately after the structure. String pointers are
119 // represented as byte offsets to string data from the beginning of 120 // represented as byte offsets to string data from the beginning of
120 // the structure. 121 // the structure.
121 struct CreateProcessRequest { 122 struct CreateProcessRequest {
122 DWORD size; 123 DWORD size;
123 DWORD process_id; 124 DWORD process_id;
124 BOOL use_default_token; 125 BOOL use_default_token;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 238
238 *process_information_out = response.process_information; 239 *process_information_out = response.process_information;
239 return true; 240 return true;
240 } 241 }
241 242
242 } // namespace 243 } // namespace
243 244
244 namespace remoting { 245 namespace remoting {
245 246
246 bool LaunchProcessWithToken(const FilePath& binary, 247 bool LaunchProcessWithToken(const FilePath& binary,
247 const std::wstring& command_line, 248 const CommandLine::StringType& command_line,
248 HANDLE user_token, 249 HANDLE user_token,
249 base::Process* process_out) { 250 base::Process* process_out) {
250 std::wstring application_name = binary.value(); 251 FilePath::StringType application_name = binary.value();
251 252
252 base::win::ScopedProcessInformation process_info; 253 base::win::ScopedProcessInformation process_info;
253 STARTUPINFOW startup_info; 254 STARTUPINFOW startup_info;
254 255
255 memset(&startup_info, 0, sizeof(startup_info)); 256 memset(&startup_info, 0, sizeof(startup_info));
256 startup_info.cb = sizeof(startup_info); 257 startup_info.cb = sizeof(startup_info);
257 startup_info.lpDesktop = kDefaultDesktopName; 258 startup_info.lpDesktop = kDefaultDesktopName;
258 259
259 BOOL result = CreateProcessAsUser(user_token, 260 BOOL result = CreateProcessAsUser(user_token,
260 application_name.c_str(), 261 application_name.c_str(),
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 "Failed to launch a process with a user token"; 302 "Failed to launch a process with a user token";
302 return false; 303 return false;
303 } 304 }
304 305
305 CHECK(process_info.IsValid()); 306 CHECK(process_info.IsValid());
306 process_out->set_handle(process_info.TakeProcessHandle()); 307 process_out->set_handle(process_info.TakeProcessHandle());
307 return true; 308 return true;
308 } 309 }
309 310
310 } // namespace remoting 311 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698