sync with latest
[sdk/emulator/qemu.git] / 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.h"
31 #include "main-loop.h"
32 #include "trace.h"
33 #include "qemu_socket.h"
34
35 #ifdef CONFIG_MARU
36 #include "../tizen/src/skin/maruskin_client.h"
37
38 #ifdef CONFIG_WIN32
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 the function
48     //and GetProcAddress to get a pointer to the function if available.
49
50     fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
51         GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
52
53     if(NULL != fnIsWow64Process)
54     {
55         if (!fnIsWow64Process(GetCurrentProcess(),&result))
56         {
57             //handle error
58                         //INFO("Can not find 'IsWow64Process'\n");
59         }
60     }
61     return result;
62 }
63
64 int get_java_path_temp(char** java_path)
65 {
66         HKEY hKeyNew;
67         HKEY hKey;
68         //char strJavaRuntimePath[JAVA_MAX_COMMAND_LENGTH] = {0};
69         char strChoosenName[JAVA_MAX_COMMAND_LENGTH] = {0};
70         char strSubKeyName[JAVA_MAX_COMMAND_LENGTH] = {0};
71         char strJavaHome[JAVA_MAX_COMMAND_LENGTH] = {0};
72         int index;
73         DWORD dwSubKeyNameMax = JAVA_MAX_COMMAND_LENGTH;
74         DWORD dwBufLen = JAVA_MAX_COMMAND_LENGTH;
75
76     RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\JavaSoft\\Java Runtime Environment", 0,
77                                      KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | MY_KEY_WOW64_64KEY, &hKey);
78     RegEnumKeyEx(hKey, 0, (LPSTR)strSubKeyName, &dwSubKeyNameMax, NULL, NULL, NULL, NULL);
79     strcpy(strChoosenName, strSubKeyName);
80
81         index = 1;
82         while (ERROR_SUCCESS == RegEnumKeyEx(hKey, index, (LPSTR)strSubKeyName, &dwSubKeyNameMax,
83                         NULL, NULL, NULL, NULL)) {
84         if (strcmp(strChoosenName, strSubKeyName) < 0) {
85             strcpy(strChoosenName, strSubKeyName);
86         }
87         index++;
88         }
89
90         RegOpenKeyEx(hKey, strChoosenName, 0, KEY_QUERY_VALUE | MY_KEY_WOW64_64KEY, &hKeyNew);
91         RegQueryValueEx(hKeyNew, "JavaHome", NULL, NULL, (LPBYTE)strJavaHome, &dwBufLen);
92         RegCloseKey(hKey);
93         if (strJavaHome[0] != '\0') {
94         sprintf(*java_path, "\"%s\\bin\\java\"", strJavaHome);
95                 //strcpy(*java_path, strJavaHome);
96                 //strcat(*java_path, "\\bin\\java");
97     } else {
98                 return 0;
99         }
100     return 1;
101 }
102 #endif
103 #endif // CONFIG_MARU
104
105 void *qemu_oom_check(void *ptr)
106 {
107     if (ptr == NULL) {
108         fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
109
110 #ifdef CONFIG_MARU
111         char _msg[] = "Failed to allocate memory in qemu.";
112         char cmd[JAVA_MAX_COMMAND_LENGTH] = { 0, };
113
114 #ifdef CONFIG_WIN32
115         char* JAVA_EXEFILE_PATH = malloc(JAVA_MAX_COMMAND_LENGTH);
116         memset(JAVA_EXEFILE_PATH, 0, JAVA_MAX_COMMAND_LENGTH);
117         if (is_wow64_temp()) {            
118             if (!get_java_path_temp(&JAVA_EXEFILE_PATH)) {
119                                 strcpy(JAVA_EXEFILE_PATH, "java");
120                     }
121         } else {
122             strcpy(JAVA_EXEFILE_PATH, "java");
123         }
124 #endif
125         int len = strlen(JAVA_EXEFILE_PATH) + strlen(JAVA_EXEOPTION) + strlen(JAR_SKINFILE) +
126            strlen(JAVA_SIMPLEMODE_OPTION) + strlen(_msg) + 7;
127         if (len > JAVA_MAX_COMMAND_LENGTH) {
128             len = JAVA_MAX_COMMAND_LENGTH;
129         }
130
131         snprintf(cmd, len, "%s %s %s %s=\"%s\"",
132             JAVA_EXEFILE_PATH, JAVA_EXEOPTION, JAR_SKINFILE, JAVA_SIMPLEMODE_OPTION, _msg);
133         int ret = WinExec(cmd, SW_SHOW);
134 #ifdef CONFIG_WIN32
135             // for 64bit windows
136             free(JAVA_EXEFILE_PATH);
137             JAVA_EXEFILE_PATH=0;
138 #endif
139 #endif
140
141         abort();
142     }
143     return ptr;
144 }
145
146 void *qemu_memalign(size_t alignment, size_t size)
147 {
148     void *ptr;
149
150     if (!size) {
151         abort();
152     }
153     ptr = qemu_oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
154     trace_qemu_memalign(alignment, size, ptr);
155     return ptr;
156 }
157
158 void *qemu_vmalloc(size_t size)
159 {
160     void *ptr;
161
162     /* FIXME: this is not exactly optimal solution since VirtualAlloc
163        has 64Kb granularity, but at least it guarantees us that the
164        memory is page aligned. */
165     if (!size) {
166         abort();
167     }
168     ptr = qemu_oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
169     trace_qemu_vmalloc(size, ptr);
170     return ptr;
171 }
172
173 void qemu_vfree(void *ptr)
174 {
175     trace_qemu_vfree(ptr);
176     VirtualFree(ptr, 0, MEM_RELEASE);
177 }
178
179 void socket_set_block(int fd)
180 {
181     unsigned long opt = 0;
182     WSAEventSelect(fd, NULL, 0);
183     ioctlsocket(fd, FIONBIO, &opt);
184 }
185
186 void socket_set_nonblock(int fd)
187 {
188     unsigned long opt = 1;
189     ioctlsocket(fd, FIONBIO, &opt);
190     qemu_fd_register(fd);
191 }
192
193 int inet_aton(const char *cp, struct in_addr *ia)
194 {
195     uint32_t addr = inet_addr(cp);
196     if (addr == 0xffffffff) {
197         return 0;
198     }
199     ia->s_addr = addr;
200     return 1;
201 }
202
203 void qemu_set_cloexec(int fd)
204 {
205 }
206
207 /* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
208 #define _W32_FT_OFFSET (116444736000000000ULL)
209
210 int qemu_gettimeofday(qemu_timeval *tp)
211 {
212   union {
213     unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
214     FILETIME ft;
215   }  _now;
216
217   if(tp) {
218       GetSystemTimeAsFileTime (&_now.ft);
219       tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
220       tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
221   }
222   /* Always return 0 as per Open Group Base Specifications Issue 6.
223      Do not set errno on error.  */
224   return 0;
225 }
226
227 int qemu_get_thread_id(void)
228 {
229     return GetCurrentThreadId();
230 }