comparison src/file/SDL_rwops.c @ 4284:261ad7b40a31 SDL-1.2

Allow Unicode filenames in RWOPS on Windows. Fixes Bugzilla #733.
author Ryan C. Gordon <icculus@icculus.org>
date Thu, 08 Oct 2009 07:48:37 +0000
parents a1b03ba2fcd0
children
comparison
equal deleted inserted replaced
4283:cd511a8560b7 4284:261ad7b40a31
100 h = CreateFile(filenameW, (w_right|r_right), (w_right)? 0 : FILE_SHARE_READ, 100 h = CreateFile(filenameW, (w_right|r_right), (w_right)? 0 : FILE_SHARE_READ,
101 NULL, (must_exist|truncate|a_mode), FILE_ATTRIBUTE_NORMAL,NULL); 101 NULL, (must_exist|truncate|a_mode), FILE_ATTRIBUTE_NORMAL,NULL);
102 SDL_stack_free(filenameW); 102 SDL_stack_free(filenameW);
103 } 103 }
104 #else 104 #else
105 /* Do not open a dialog box if failure */ 105 {
106 old_error_mode = SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS); 106
107 107 /* handle Unicode filenames. We do some tapdancing here to make sure this
108 h = CreateFile(filename, (w_right|r_right), (w_right)? 0 : FILE_SHARE_READ, 108 works on Win9x, which doesn't support anything but 1-byte codepages. */
109 NULL, (must_exist|truncate|a_mode), FILE_ATTRIBUTE_NORMAL,NULL); 109 const size_t size = SDL_strlen(filename)+1;
110 110 static int unicode_support = -1;
111 /* restore old behaviour */ 111
112 SetErrorMode(old_error_mode); 112 if (unicode_support == -1) {
113 OSVERSIONINFO osVerInfo; /* Information about the OS */
114 osVerInfo.dwOSVersionInfoSize = sizeof(osVerInfo);
115 if (!GetVersionEx(&osVerInfo)) {
116 unicode_support = 0;
117 } else if (osVerInfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) {
118 unicode_support = 1; /* Not Win95/98/ME. */
119 } else {
120 unicode_support = 0;
121 }
122 }
123
124 if (unicode_support) { /* everything but Win95/98/ME. */
125 wchar_t *filenameW = SDL_stack_alloc(wchar_t, size);
126 if ( MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, size) == 0 ) {
127 SDL_stack_free(filenameW);
128 SDL_free(context->hidden.win32io.buffer.data);
129 context->hidden.win32io.buffer.data = NULL;
130 SDL_SetError("Unable to convert filename to Unicode");
131 return -1;
132 }
133
134 /* Do not open a dialog box if failure */
135 old_error_mode = SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);
136 h = CreateFileW(filenameW, (w_right|r_right), (w_right)? 0 : FILE_SHARE_READ,
137 NULL, (must_exist|truncate|a_mode), FILE_ATTRIBUTE_NORMAL,NULL);
138 /* restore old behaviour */
139 SetErrorMode(old_error_mode);
140
141 SDL_stack_free(filenameW);
142 } else {
143 /* CP_UTF8 might not be supported (Win95), so use SDL_iconv to get wchars. */
144 /* Use UCS2: no UTF-16 support here. Try again in SDL 1.3. :) */
145 char *utf16 = SDL_iconv_string("UCS2", "UTF8", filename, SDL_strlen(filename) + 1);
146 char *filenameA = SDL_stack_alloc(char, size * 6); /* 6, just in case. */
147 BOOL bDefCharUsed = FALSE;
148
149 /* Dither down to a codepage and hope for the best. */
150 if (!utf16 ||
151 !WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)utf16, -1, filenameA, size*6, 0, &bDefCharUsed) ||
152 bDefCharUsed) {
153 SDL_stack_free(filenameA);
154 SDL_free(utf16);
155 SDL_free(context->hidden.win32io.buffer.data);
156 context->hidden.win32io.buffer.data = NULL;
157 SDL_SetError("Unable to convert filename to Unicode");
158 return -1;
159 }
160
161 /* Do not open a dialog box if failure */
162 old_error_mode = SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);
163 h = CreateFile(filenameA, (w_right|r_right), (w_right)? 0 : FILE_SHARE_READ,
164 NULL, (must_exist|truncate|a_mode), FILE_ATTRIBUTE_NORMAL,NULL);
165 /* restore old behaviour */
166 SetErrorMode(old_error_mode);
167
168 SDL_stack_free(filenameA);
169 SDL_free(utf16);
170 }
171
172 }
113 #endif /* _WIN32_WCE */ 173 #endif /* _WIN32_WCE */
114 174
115 if (h==INVALID_HANDLE_VALUE) { 175 if (h==INVALID_HANDLE_VALUE) {
116 SDL_free(context->hidden.win32io.buffer.data); 176 SDL_free(context->hidden.win32io.buffer.data);
117 context->hidden.win32io.buffer.data = NULL; 177 context->hidden.win32io.buffer.data = NULL;