• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
g_atomic_int_inc(int volatile * atomic)23 void g_atomic_int_inc(int volatile* atomic) {
24   assert(sizeof(LONG) == sizeof(int));
25   InterlockedIncrement((LONG volatile*)atomic);
26 }
27 
g_atomic_int_dec_and_test(int volatile * atomic)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*
utf16_to_utf8(const wchar_t * wstring,int wstring_len)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 *
g_win32_error_message(int error)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