1 // Copyright 2014 The Android Open Source Project 2 // 3 // This software is licensed under the terms of the GNU General Public 4 // License version 2, as published by the Free Software Foundation, and 5 // may be copied, distributed, and modified under those terms. 6 // 7 // This program is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 // GNU General Public License for more details. 11 12 #ifdef _WIN32 13 14 #include <glib.h> 15 16 #include <assert.h> 17 #include <wchar.h> 18 #define WIN32_LEAN_AND_MEAN 19 #include <windows.h> 20 21 // Atomic operations 22 23 void g_atomic_int_inc(int volatile* atomic) { 24 assert(sizeof(LONG) == sizeof(int)); 25 InterlockedIncrement((LONG volatile*)atomic); 26 } 27 28 gboolean g_atomic_int_dec_and_test(int volatile* atomic) { 29 assert(sizeof(LONG) == sizeof(int)); 30 return !InterlockedIncrement((LONG volatile*)atomic); 31 } 32 33 // Win32 error messages. 34 35 static char* 36 utf16_to_utf8(const wchar_t* wstring, int wstring_len) 37 { 38 int utf8_len = WideCharToMultiByte(CP_UTF8, // CodePage 39 0, // dwFlags 40 (LPWSTR) wstring, // lpWideCharStr 41 wstring_len, // cchWideChar 42 NULL, // lpMultiByteStr 43 0, // cbMultiByte 44 NULL, // lpDefaultChar 45 NULL); // lpUsedDefaultChar 46 if (utf8_len == 0) 47 return g_strdup(""); 48 49 char* result = g_malloc(utf8_len + 1); 50 51 WideCharToMultiByte(CP_UTF8, 0, (LPWSTR) wstring, wstring_len, 52 result, utf8_len, NULL, NULL); 53 result[utf8_len] = '\0'; 54 return result; 55 } 56 57 char * 58 g_win32_error_message (int error) 59 { 60 LPWSTR msg = NULL; 61 int nchars; 62 char* result; 63 64 // Work around for compiler warning, due to brain-dead API. 65 union { 66 LPWSTR* address; 67 LPWSTR value; 68 } msg_param; 69 msg_param.address = &msg; 70 71 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER 72 |FORMAT_MESSAGE_IGNORE_INSERTS 73 |FORMAT_MESSAGE_FROM_SYSTEM, 74 NULL, error, 0, 75 msg_param.value, 76 0, NULL); 77 if (!msg) 78 return g_strdup(""); 79 80 // Get rid of trailing \r\n if any. 81 nchars = wcslen (msg); 82 if (nchars > 2 && msg[nchars-1] == '\n' && msg[nchars-2] == '\r') 83 msg[nchars-2] = '\0'; 84 85 result = utf16_to_utf8 (msg, nchars); 86 87 LocalFree (msg); 88 89 return result; 90 } 91 92 #endif // _WIN32 93