merge some files, and delete some duplicated files
[sdk/emulator/qemu.git] / util / oslib-win32.c
1 /*
2  * os-win32.c
3  *
4  * Copyright (c) 2003-2008 Fabrice Bellard
5  * Copyright (c) 2010 Red Hat, Inc.
6  *
7  * QEMU library functions for win32 which are shared between QEMU and
8  * the QEMU tools.
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a copy
11  * of this software and associated documentation files (the "Software"), to deal
12  * in the Software without restriction, including without limitation the rights
13  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14  * copies of the Software, and to permit persons to whom the Software is
15  * furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included in
18  * all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26  * THE SOFTWARE.
27  */
28 #include <windows.h>
29 #include "config-host.h"
30 #include "sysemu/sysemu.h"
31 #include "qemu/main-loop.h"
32 #include "trace.h"
33 #include "qemu/sockets.h"
34
35 #ifdef CONFIG_MARU
36 #include "../../tizen/src/skin/maruskin_client.h"
37 #endif
38
39 typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
40 LPFN_ISWOW64PROCESS fnIsWow64Process;
41
42 int is_wow64_temp(void)
43 {
44     int result = 0;
45
46     /* IsWow64Process is not available on all supported versions of Windows.
47        Use GetModuleHandle to get a handle to the DLL that contains
48        the function and GetProcAddress to get a pointer to the function
49        if available. */
50
51     fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
52         GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
53
54     if (NULL != fnIsWow64Process) {
55         if (!fnIsWow64Process(GetCurrentProcess(),&result)) {
56             /* handle error */
57             /* INFO("Can not find 'IsWow64Process'\n"); */
58         }
59     }
60     return result;
61 }
62
63 int get_java_path_temp(char** java_path)
64 {
65     HKEY hKeyNew;
66     HKEY hKey;
67     //char strJavaRuntimePath[JAVA_MAX_COMMAND_LENGTH] = {0};
68     char strChoosenName[JAVA_MAX_COMMAND_LENGTH] = {0};
69     char strSubKeyName[JAVA_MAX_COMMAND_LENGTH] = {0};
70     char strJavaHome[JAVA_MAX_COMMAND_LENGTH] = {0};
71     int index;
72     DWORD dwSubKeyNameMax = JAVA_MAX_COMMAND_LENGTH;
73     DWORD dwBufLen = JAVA_MAX_COMMAND_LENGTH;
74
75     RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\JavaSoft\\Java Runtime Environment", 0,
76                  KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | MY_KEY_WOW64_64KEY, &hKey);
77     RegEnumKeyEx(hKey, 0, (LPSTR)strSubKeyName, &dwSubKeyNameMax,
78                  NULL, NULL, NULL, NULL);
79     strcpy(strChoosenName, strSubKeyName);
80
81     index = 1;
82     while (ERROR_SUCCESS == RegEnumKeyEx(hKey, index,
83                                          (LPSTR)strSubKeyName, &dwSubKeyNameMax,
84                                          NULL, NULL, NULL, NULL)) {
85         if (strcmp(strChoosenName, strSubKeyName) < 0) {
86             strcpy(strChoosenName, strSubKeyName);
87         }
88         index++;
89     }
90
91     RegOpenKeyEx(hKey, strChoosenName, 0, KEY_QUERY_VALUE | MY_KEY_WOW64_64KEY,
92                  &hKeyNew);
93     RegQueryValueEx(hKeyNew, "JavaHome", NULL, NULL, (LPBYTE)strJavaHome, &dwBufLen);
94     RegCloseKey(hKey);
95
96     if (strJavaHome[0] != '\0') {
97         sprintf(*java_path, "\"%s\\bin\\java\"", strJavaHome);
98         //strcpy(*java_path, strJavaHome);
99         //strcat(*java_path, "\\bin\\java");
100     } else {
101         return 0;
102     }
103     return 1;
104 }
105 #endif
106
107 void *qemu_oom_check(void *ptr)
108 {
109     if (ptr == NULL) {
110         fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
111 #ifdef CONFIG_MARU
112         char _msg[] = "Failed to allocate memory in qemu.";
113         char cmd[JAVA_MAX_COMMAND_LENGTH] = { 0, };
114         char *JAVA_EXEFILE_PATH = malloc(JAVA_MAX_COMMAND_LENGTH);
115         memset(JAVA_EXEFILE_PATH, 0, JAVA_MAX_COMMAND_LENGTH);
116         if (is_wow64_temp()) {
117             if (!get_java_path_temp(&JAVA_EXEFILE_PATH)) {
118                 strcpy(JAVA_EXEFILE_PATH, "java");
119             }
120         } else {
121             strcpy(JAVA_EXEFILE_PATH, "java");
122         }
123         int len = strlen(JAVA_EXEFILE_PATH) + strlen(JAVA_EXEOPTION) +
124                   strlen(JAR_SKINFILE) + strlen(JAVA_SIMPLEMODE_OPTION) +
125                   strlen(_msg) + 7;
126         if (len > JAVA_MAX_COMMAND_LENGTH) {
127             len = JAVA_MAX_COMMAND_LENGTH;
128         }
129
130         snprintf(cmd, len, "%s %s %s %s=\"%s\"",
131             JAVA_EXEFILE_PATH, JAVA_EXEOPTION, JAR_SKINFILE,
132             JAVA_SIMPLEMODE_OPTION, _msg);
133         int ret = WinExec(cmd, SW_SHOW);
134
135         /* for 64bit windows */
136         free(JAVA_EXEFILE_PATH);
137         JAVA_EXEFILE_PATH=0;
138 #endif
139         abort();
140     }
141     return ptr;
142 }
143
144 void *qemu_memalign(size_t alignment, size_t size)
145 {
146     void *ptr;
147
148     if (!size) {
149         abort();
150     }
151     ptr = qemu_oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
152     trace_qemu_memalign(alignment, size, ptr);
153     return ptr;
154 }
155
156 void *qemu_anon_ram_alloc(size_t size)
157 {
158     void *ptr;
159
160     /* FIXME: this is not exactly optimal solution since VirtualAlloc
161        has 64Kb granularity, but at least it guarantees us that the
162        memory is page aligned. */
163     if (!size) {
164         abort();
165     }
166     ptr = qemu_oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
167     trace_qemu_anon_ram_alloc(size, ptr);
168     return ptr;
169 }
170
171 void qemu_vfree(void *ptr)
172 {
173     trace_qemu_vfree(ptr);
174     if (ptr) {
175         VirtualFree(ptr, 0, MEM_RELEASE);
176     }
177 }
178
179 void qemu_anon_ram_free(void *ptr, size_t size)
180 {
181     trace_qemu_anon_ram_free(ptr, size);
182     if (ptr) {
183         VirtualFree(ptr, 0, MEM_RELEASE);
184     }
185 }
186
187 /* FIXME: add proper locking */
188 struct tm *gmtime_r(const time_t *timep, struct tm *result)
189 {
190     struct tm *p = gmtime(timep);
191     memset(result, 0, sizeof(*result));
192     if (p) {
193         *result = *p;
194         p = result;
195     }
196     return p;
197 }
198
199 /* FIXME: add proper locking */
200 struct tm *localtime_r(const time_t *timep, struct tm *result)
201 {
202     struct tm *p = localtime(timep);
203     memset(result, 0, sizeof(*result));
204     if (p) {
205         *result = *p;
206         p = result;
207     }
208     return p;
209 }
210
211 void qemu_set_block(int fd)
212 {
213     unsigned long opt = 0;
214     WSAEventSelect(fd, NULL, 0);
215     ioctlsocket(fd, FIONBIO, &opt);
216 }
217
218 void qemu_set_nonblock(int fd)
219 {
220     unsigned long opt = 1;
221     ioctlsocket(fd, FIONBIO, &opt);
222     qemu_fd_register(fd);
223 }
224
225 int inet_aton(const char *cp, struct in_addr *ia)
226 {
227     uint32_t addr = inet_addr(cp);
228     if (addr == 0xffffffff) {
229         return 0;
230     }
231     ia->s_addr = addr;
232     return 1;
233 }
234
235 void qemu_set_cloexec(int fd)
236 {
237 }
238
239 /* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
240 #define _W32_FT_OFFSET (116444736000000000ULL)
241
242 int qemu_gettimeofday(qemu_timeval *tp)
243 {
244   union {
245     unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
246     FILETIME ft;
247   }  _now;
248
249   if(tp) {
250       GetSystemTimeAsFileTime (&_now.ft);
251       tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
252       tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
253   }
254   /* Always return 0 as per Open Group Base Specifications Issue 6.
255      Do not set errno on error.  */
256   return 0;
257 }
258
259 int qemu_get_thread_id(void)
260 {
261     return GetCurrentThreadId();
262 }