1 //
2 // CreateProcessA.cpp
3 //
4 //      Copyright (c) Microsoft Corporation. All rights reserved.
5 //
6 // Definition of __acrt_CreateProcessA.
7 //
8 
9 #include <corecrt_internal_win32_buffer.h>
10 
__acrt_CreateProcessA(LPCSTR const lpApplicationName,LPSTR const lpCommandLine,LPSECURITY_ATTRIBUTES const lpProcessAttributes,LPSECURITY_ATTRIBUTES const lpThreadAttributes,BOOL const bInheritHandles,DWORD const dwCreationFlags,LPVOID const lpEnvironment,LPCSTR const lpCurrentDirectory,LPSTARTUPINFOW const lpStartupInfo,LPPROCESS_INFORMATION const lpProcessInformation)11 BOOL __cdecl __acrt_CreateProcessA(
12     LPCSTR const                lpApplicationName,
13     LPSTR const                 lpCommandLine,
14     LPSECURITY_ATTRIBUTES const lpProcessAttributes,
15     LPSECURITY_ATTRIBUTES const lpThreadAttributes,
16     BOOL const                  bInheritHandles,
17     DWORD const                 dwCreationFlags,
18     LPVOID const                lpEnvironment,
19     LPCSTR const                lpCurrentDirectory,
20     LPSTARTUPINFOW const        lpStartupInfo,
21     LPPROCESS_INFORMATION const lpProcessInformation
22     )
23 {
24     __crt_internal_win32_buffer<wchar_t> wide_application_name;
25     __crt_internal_win32_buffer<wchar_t> wide_command_line;
26     __crt_internal_win32_buffer<wchar_t> wide_current_directory;
27 
28     errno_t const cvt1 = __acrt_mbs_to_wcs_cp(
29         lpApplicationName,
30         wide_application_name,
31         __acrt_get_utf8_acp_compatibility_codepage()
32         );
33 
34     if (cvt1 != 0) {
35         return FALSE;
36     }
37 
38     errno_t const cvt2 = __acrt_mbs_to_wcs_cp(
39         lpCommandLine,
40         wide_command_line,
41         __acrt_get_utf8_acp_compatibility_codepage()
42         );
43 
44     if (cvt2 != 0) {
45         return FALSE;
46     }
47 
48     LPWSTR wide_current_directory_ptr = nullptr;
49 
50     if (lpCurrentDirectory != nullptr) {
51         errno_t const cvt3 = __acrt_mbs_to_wcs_cp(
52             lpCurrentDirectory,
53             wide_current_directory,
54             __acrt_get_utf8_acp_compatibility_codepage()
55             );
56 
57         if (cvt3 != 0) {
58             return FALSE;
59         }
60 
61         wide_current_directory_ptr = wide_current_directory.data();
62     }
63 
64     // converted_command_line is an out parameter, but is not reconverted to utf8 string,
65     // since it is only written to in the Wide version. CreateProcessA does not expect it
66     // to have changed.
67     return ::CreateProcessW(
68         wide_application_name.data(),
69         wide_command_line.data(),
70         lpProcessAttributes,
71         lpThreadAttributes,
72         bInheritHandles,
73         dwCreationFlags,
74         lpEnvironment,
75         wide_current_directory_ptr,
76         lpStartupInfo,
77         lpProcessInformation
78         );
79 }
80