First version of DLL preloader.
[wincetools.git] / loader / kernel32_process.c
1 /* From wine1.2-1.1.42/dlls/kernel32/process.c  */\r
2 \r
3 /*\r
4  * Win32 processes\r
5  *\r
6  * Copyright 1996, 1998 Alexandre Julliard\r
7  * Copyright 2010 g10 Code GmbH\r
8  *\r
9  * This library is free software; you can redistribute it and/or\r
10  * modify it under the terms of the GNU Lesser General Public\r
11  * License as published by the Free Software Foundation; either\r
12  * version 2.1 of the License, or (at your option) any later version.\r
13  *\r
14  * This library is distributed in the hope that it will be useful,\r
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
17  * Lesser General Public License for more details.\r
18  *\r
19  * You should have received a copy of the GNU Lesser General Public\r
20  * License along with this library; if not, write to the Free Software\r
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA\r
22  */\r
23 \r
24 #include <windef.h>\r
25 #include "wine.h"\r
26 #include "kernel32_kernel_private.h"\r
27 \r
28 \f\r
29 typedef int (APIENTRY *ENTRY_POINT) (HINSTANCE hInstance,\r
30                                      HINSTANCE hPrevInstance,\r
31                                      LPWSTR lpCmdLine, int nCmdShow);\r
32 \r
33 static BOOL start_process( PEB *peb )\r
34 {\r
35   IMAGE_NT_HEADERS *nt;\r
36   ENTRY_POINT entry;\r
37   \r
38   nt = MyRtlImageNtHeader( peb->ImageBaseAddress );\r
39   entry = (ENTRY_POINT)((char *)peb->ImageBaseAddress +\r
40                         nt->OptionalHeader.AddressOfEntryPoint);\r
41   \r
42   if (!nt->OptionalHeader.AddressOfEntryPoint)\r
43     {\r
44       ERR( "%S doesn't have an entry point, it cannot be executed\n",\r
45              peb->ImagePathName );\r
46       SetLastError (ERROR_BAD_EXE_FORMAT);\r
47       return FALSE;\r
48     }\r
49 \r
50   TRACE( "Starting process %S (entryproc=%p)\n",\r
51          peb->ImagePathName, entry );\r
52 \r
53   SetLastError( 0 );  /* clear error code */\r
54   peb->ExitStatus = entry (GetModuleHandle (NULL), NULL, peb->CommandLine, 0);\r
55 \r
56   return 0;\r
57 }\r
58 \r
59 \r
60 static BOOL __wine_kernel_init (HANDLE hFile, LPCWSTR main_exe_name,\r
61                                 LPWSTR cmd_line, int *exit_code)\r
62 {\r
63   PEB *peb = current_peb();\r
64 \r
65   peb->CommandLine = cmd_line;\r
66   peb->ImageBaseAddress = MyLoadLibraryExW( main_exe_name, 0,\r
67                                             DONT_RESOLVE_DLL_REFERENCES );\r
68 \r
69   if (! peb->ImageBaseAddress)\r
70     {\r
71       ERR ("can not load %S: %i\n", main_exe_name, GetLastError());\r
72       return FALSE;\r
73     }\r
74 \r
75   /* FIXME: Error checking?  */\r
76   MyLdrInitializeThunk( start_process, 0, 0, 0 );\r
77 \r
78   *exit_code = peb->ExitStatus;\r
79   return TRUE;\r
80 }\r
81 \r
82 \r
83 static HANDLE open_exe_file (LPCWSTR name, struct binary_info *binary_info)\r
84 {\r
85   HANDLE handle;\r
86   \r
87   handle = CreateFileForMappingW( name, GENERIC_READ, FILE_SHARE_READ,\r
88                                   NULL, OPEN_EXISTING, 0, 0 );\r
89   if (handle != INVALID_HANDLE_VALUE)\r
90     MODULE_get_binary_info( handle, binary_info );\r
91   \r
92   return handle;\r
93 }\r
94 \r
95 \r
96 BOOL MyCreateProcessW (LPCWSTR app_name, LPWSTR cmd_line,\r
97                        int *exit_code)\r
98 {\r
99   BOOL retv = FALSE;\r
100   HANDLE hFile = 0;\r
101   struct binary_info binary_info;\r
102   \r
103   hFile = open_exe_file (app_name, &binary_info);\r
104   if (hFile == INVALID_HANDLE_VALUE)\r
105     {\r
106       ERR ("could not open file %S: %i\n", app_name, GetLastError());\r
107       goto err;\r
108     }\r
109   \r
110   TRACE ("MyCreateProcessW: 0x%p type=0x%x flags=0x%x "\r
111          "res_start=0x%p res_end=0x%p\n",\r
112          hFile, binary_info.type, binary_info.flags,\r
113          binary_info.res_start, binary_info.res_end);\r
114 \r
115   /* Some sanity checks.  */\r
116   if (binary_info.flags & BINARY_FLAG_DLL)\r
117     {\r
118       ERR ("not starting %S since it is a DLL\n", app_name);\r
119       SetLastError( ERROR_BAD_EXE_FORMAT );\r
120       goto err;\r
121     }\r
122 \r
123   if (binary_info.flags & BINARY_FLAG_64BIT)\r
124     {\r
125       ERR( "starting 64-bit process %S not supported on this platform\n",\r
126            app_name);\r
127       SetLastError( ERROR_BAD_EXE_FORMAT );\r
128       return FALSE;\r
129     }\r
130 \r
131   if (binary_info.type != BINARY_PE)\r
132     {\r
133       ERR ("not starting %S of type %i (expected %i)\n", app_name,\r
134            binary_info.type, BINARY_PE);\r
135       SetLastError( ERROR_BAD_EXE_FORMAT );\r
136       return FALSE;\r
137     }\r
138 \r
139   retv = __wine_kernel_init (hFile, app_name, cmd_line, exit_code);\r
140 \r
141  err:\r
142   if (hFile)\r
143     CloseHandle( hFile );\r
144   \r
145   return retv;\r
146 }\r
147 \r