First version of DLL preloader.
[wincetools.git] / loader / kernel32_module.c
1 /* From wine1.2-1.1.42/dlls/kernel32/module.c  */\r
2 \r
3 /*\r
4  * Modules\r
5  *\r
6  * Copyright 1995 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 \r
25 #include "wine.h"\r
26 #include "kernel32_kernel_private.h"\r
27 \r
28 \r
29 void MODULE_get_binary_info (HANDLE hfile, struct binary_info *info)\r
30 {\r
31   union\r
32   {\r
33     IMAGE_DOS_HEADER mz;\r
34   } header;\r
35   \r
36   DWORD len;\r
37 \r
38   memset( info, 0, sizeof(*info) );\r
39   /* Seek to the start of the file and read the header information. */\r
40   if (SetFilePointer( hfile, 0, NULL, SEEK_SET ) == -1) return;\r
41   if (!ReadFile( hfile, &header, sizeof(header), &len, NULL ) || len != sizeof(header)) return;\r
42   \r
43   if (header.mz.e_magic == IMAGE_DOS_SIGNATURE)\r
44     {\r
45       union\r
46       {\r
47         IMAGE_OS2_HEADER os2;\r
48         IMAGE_NT_HEADERS32 nt;\r
49       } ext_header;\r
50       \r
51       /* We do have a DOS image so we will now try to seek into\r
52        * the file by the amount indicated by the field\r
53        * "Offset to extended header" and read in the\r
54        * "magic" field information at that location.\r
55        * This will tell us if there is more header information\r
56        * to read or not.\r
57        */\r
58       info->type = BINARY_DOS;\r
59       if (SetFilePointer( hfile, header.mz.e_lfanew, NULL, SEEK_SET ) == -1) return;\r
60       if (!ReadFile( hfile, &ext_header, sizeof(ext_header), &len, NULL ) || len < 4) return;\r
61       \r
62       /* Reading the magic field succeeded so\r
63        * we will try to determine what type it is.\r
64        */\r
65       if (!memcmp( &ext_header.nt.Signature, "PE\0\0", 4 ))\r
66         {\r
67           if (len >= sizeof(ext_header.nt.FileHeader))\r
68             {\r
69               info->type = BINARY_PE;\r
70               if (ext_header.nt.FileHeader.Characteristics & IMAGE_FILE_DLL)\r
71                 info->flags |= BINARY_FLAG_DLL;\r
72               if (len < sizeof(ext_header.nt))  /* clear remaining part of header if missing */\r
73                 memset( (char *)&ext_header.nt + len, 0, sizeof(ext_header.nt) - len );\r
74               switch (ext_header.nt.OptionalHeader.Magic)\r
75                 {\r
76                 case IMAGE_NT_OPTIONAL_HDR32_MAGIC:\r
77                   info->res_start = (void *)(ULONG_PTR)ext_header.nt.OptionalHeader.ImageBase;\r
78                   info->res_end = (void *)((ULONG_PTR)ext_header.nt.OptionalHeader.ImageBase +\r
79                                            ext_header.nt.OptionalHeader.SizeOfImage);\r
80                   break;\r
81                 case IMAGE_NT_OPTIONAL_HDR64_MAGIC:\r
82                   info->flags |= BINARY_FLAG_64BIT;\r
83                   break;\r
84                 } \r
85 \r
86               info->machine = ext_header.nt.FileHeader.Machine;\r
87            }\r
88         }\r
89     }\r
90 }\r
91 \r
92 \f\r
93 static HMODULE load_library( LPCWSTR libname, DWORD flags )\r
94 {\r
95   NTSTATUS nts;\r
96   HMODULE hModule;\r
97 \r
98   /* We don't use any special DLL load path.  */\r
99 \r
100   if (flags & LOAD_LIBRARY_AS_DATAFILE)\r
101     {\r
102       SetLastError(ERROR_INVALID_PARAMETER);\r
103       return NULL;\r
104     }\r
105 \r
106   nts = MyLdrLoadDll( NULL, flags, libname, &hModule );\r
107   if (nts != STATUS_SUCCESS)\r
108     {\r
109       hModule = 0;\r
110       SetLastError( MyRtlNtStatusToDosError( nts ) );\r
111     }\r
112   return hModule;\r
113 }\r
114 \r
115 \r
116 HMODULE MyLoadLibraryExW(LPCWSTR libnameW, HANDLE hfile, DWORD flags)\r
117 {\r
118 /* We would like to use the native LoadLibraryEx, but on Windows CE\r
119    that is only implemented for DLLs.  Also, base addresses are\r
120    restricted to the process slot, but we want to load at high\r
121    addresses.  */\r
122   TRACE ("MyLoadLibraryExW (\"%S\", 0x%p, 0x%x)\n", libnameW, hfile, flags);\r
123   if (!libnameW)\r
124     {\r
125       SetLastError(ERROR_INVALID_PARAMETER);\r
126       return 0;\r
127     }\r
128   return load_library( libnameW, flags );\r
129 }\r