+int
+win32_fputs(const char *string, FILE *stream)
+{
+ /* we use WriteConsoleA / WriteConsoleA
+ so we can be sure that unicode support works on win32.
+ with fallback if something fails
+ */
+
+ HANDLE hOut = GetStdHandle (STD_OUTPUT_HANDLE);
+ if (hOut && (hOut != INVALID_HANDLE_VALUE) && p_WideCharToMultiByte &&
+ p_MultiByteToWideChar && (stream == stdout)) {
+
+ POOLMEM* pwszBuf = get_pool_memory(PM_MESSAGE);
+
+ DWORD dwCharsWritten;
+ DWORD dwChars;
+
+ dwChars = UTF8_2_wchar(&pwszBuf, string);
+
+ /* try WriteConsoleW */
+ if (WriteConsoleW (hOut, pwszBuf, dwChars-1, &dwCharsWritten, NULL)) {
+ free_pool_memory(pwszBuf);
+ return dwCharsWritten;
+ }
+
+ /* convert to local codepage and try WriteConsoleA */
+ POOLMEM* pszBuf = get_pool_memory(PM_MESSAGE);
+ pszBuf = check_pool_memory_size(pszBuf, dwChars+1);
+
+ dwChars = p_WideCharToMultiByte(GetConsoleOutputCP(),0,(LPCWSTR) pwszBuf,-1,pszBuf,dwChars,NULL,NULL);
+ free_pool_memory(pwszBuf);
+
+ if (WriteConsoleA (hOut, pszBuf, dwChars-1, &dwCharsWritten, NULL)) {
+ free_pool_memory(pszBuf);
+ return dwCharsWritten;
+ }
+ }
+
+ return fputs(string, stream);
+}
+
+char*
+win32_cgets (char* buffer, int len)
+{
+ /* we use console ReadConsoleA / ReadConsoleW to be able to read unicode
+ from the win32 console and fallback if seomething fails */
+
+ HANDLE hIn = GetStdHandle (STD_INPUT_HANDLE);
+ if (hIn && (hIn != INVALID_HANDLE_VALUE) && p_WideCharToMultiByte && p_MultiByteToWideChar) {
+ DWORD dwRead;
+ wchar_t wszBuf[1024];
+ char szBuf[1024];
+
+ /* nt and unicode conversion */
+ if (ReadConsoleW (hIn, wszBuf, 1024, &dwRead, NULL)) {
+
+ /* null terminate at end */
+ if (wszBuf[dwRead-1] == L'\n') {
+ wszBuf[dwRead-1] = L'\0';
+ dwRead --;
+ }
+
+ if (wszBuf[dwRead-1] == L'\r') {
+ wszBuf[dwRead-1] = L'\0';
+ dwRead --;
+ }
+
+ wchar_2_UTF8(buffer, wszBuf, len);
+ return buffer;
+ }
+
+ /* win 9x and unicode conversion */
+ if (ReadConsoleA (hIn, szBuf, 1024, &dwRead, NULL)) {
+
+ /* null terminate at end */
+ if (szBuf[dwRead-1] == L'\n') {
+ szBuf[dwRead-1] = L'\0';
+ dwRead --;
+ }
+
+ if (szBuf[dwRead-1] == L'\r') {
+ szBuf[dwRead-1] = L'\0';
+ dwRead --;
+ }
+
+ /* convert from ansii to wchar_t */
+ p_MultiByteToWideChar(GetConsoleCP(), 0, szBuf, -1, wszBuf,1024);
+ /* convert from wchar_t to UTF-8 */
+ if (wchar_2_UTF8(buffer, wszBuf, len))
+ return buffer;
+ }
+ }
+
+ /* fallback */
+ if (fgets(buffer, len, stdin))
+ return buffer;
+ else
+ return NULL;
+}
+
+int
+win32_unlink(const char *filename)
+{
+ int nRetCode;
+ if (p_wunlink) {
+ POOLMEM* pwszBuf = get_pool_memory(PM_FNAME);
+ make_win32_path_UTF8_2_wchar(&pwszBuf, filename);
+
+ nRetCode = _wunlink((LPCWSTR) pwszBuf);
+
+ /* special case if file is readonly,
+ we retry but unset attribute before */
+ if (nRetCode == -1 && errno == EACCES && p_SetFileAttributesW && p_GetFileAttributesW) {
+ DWORD dwAttr = p_GetFileAttributesW((LPCWSTR)pwszBuf);
+ if (dwAttr != INVALID_FILE_ATTRIBUTES) {
+ if (p_SetFileAttributesW((LPCWSTR)pwszBuf, dwAttr & ~FILE_ATTRIBUTE_READONLY)) {
+ nRetCode = _wunlink((LPCWSTR) pwszBuf);
+ /* reset to original if it didn't help */
+ if (nRetCode == -1)
+ p_SetFileAttributesW((LPCWSTR)pwszBuf, dwAttr);
+ }
+ }
+ }
+ free_pool_memory(pwszBuf);
+ } else {
+ nRetCode = _unlink(filename);
+
+ /* special case if file is readonly,
+ we retry but unset attribute before */
+ if (nRetCode == -1 && errno == EACCES && p_SetFileAttributesA && p_GetFileAttributesA) {
+ DWORD dwAttr = p_GetFileAttributesA(filename);
+ if (dwAttr != INVALID_FILE_ATTRIBUTES) {
+ if (p_SetFileAttributesA(filename, dwAttr & ~FILE_ATTRIBUTE_READONLY)) {
+ nRetCode = _unlink(filename);
+ /* reset to original if it didn't help */
+ if (nRetCode == -1)
+ p_SetFileAttributesA(filename, dwAttr);
+ }
+ }
+ }
+ }
+ return nRetCode;
+}
+
+