Home | History | Annotate | Download | only in src
      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