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 23void g_atomic_int_inc(int volatile* atomic) { 24 assert(sizeof(LONG) == sizeof(int)); 25 InterlockedIncrement((LONG volatile*)atomic); 26} 27 28gboolean 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 35static char* 36utf16_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 57char * 58g_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