--- src/define.h~0	2013-12-27 18:44:13 +0200
+++ src/define.h	2014-11-12 13:53:46 +0200
@@ -59,12 +59,14 @@
 
 #ifdef _WIN32
     #include <direct.h>
+    #include <malloc.h>
 
-    #define D_MKDIR(x) mkdir(x)
+    #define D_MKDIR(x) _mkdir(x)
     #define chdir      _chdir
     #define strcasecmp _stricmp
     #define vsnprintf  _vsnprintf
     #define snprintf   _snprintf
+    #define lstat      stat
     #ifdef _MSC_VER
         #define ftello     _ftelli64
         #define fseeko     _fseeki64


--- src/deltasearch.cpp~0	2013-12-27 18:44:13 +0200
+++ src/deltasearch.cpp	2014-11-11 13:54:15 +0200
@@ -46,7 +46,7 @@ int main(int argc, char* const* argv) {
         printf("usage: %s filename.pst integer-delta search-string\n", argv[0]);
 		return 0;
 	}
-	int  fd = open(argv[1], O_RDONLY);
+	int  fd = open(argv[1], O_RDONLY | O_BINARY);
 	int   d = atoi(argv[2]);
 	string search(argv[3]);
     printf("using file %s with delta %d looking for %s\n", argv[1], d, argv[3]);


--- src/readpst.c~0	2013-12-27 18:44:13 +0200
+++ src/readpst.c	2014-11-26 08:43:03 +0200
@@ -232,6 +232,33 @@ pid_t try_fork(char *folder)
     return 0;
 }
 
+int readpst_print_string(const char *fmt, const char *str, int is_utf8) {
+    int result;
+#if defined(WIN32) && !defined(__CYGWIN__)
+    HANDLE hstdout = GetStdHandle (STD_OUTPUT_HANDLE);
+    DWORD console_mode;
+    /* If writing to the console, write in UTF-16; but keep the
+       original UTF-8 encoding if stdout is redirected to a file,
+       because UTF-16 writes to a file need to reopen stdout in
+       Unicode mode, which is too much of a hassle.  */
+    if (is_utf8 && GetConsoleMode(hstdout, &console_mode)) {
+	size_t fmt_len = strlen(fmt) + 1;
+	size_t str_len = strlen(str) + 1;
+	wchar_t *str_w = alloca(str_len * sizeof (wchar_t));
+	wchar_t *wfmt = alloca(fmt_len * sizeof (wchar_t));
+	wchar_t *msg = alloca((fmt_len + str_len) * sizeof (wchar_t));
+	DWORD written;
+	MultiByteToWideChar(CP_UTF8, 0, str, -1, str_w, str_len);
+	MultiByteToWideChar(CP_ACP, 0, fmt, -1, wfmt, fmt_len);
+        result = swprintf(msg, wfmt, str_w);
+	WriteConsoleW (hstdout, msg, result, &written, NULL);
+	result = written;
+    }
+    else
+#endif
+    result = printf(fmt, str);
+    return result;
+}
 
 void process(pst_item *outeritem, pst_desc_tree *d_ptr)
 {
@@ -268,7 +295,9 @@ void process(pst_item *outeritem, pst_de
             DEBUG_INFO(("Processing Folder \"%s\"\n", item->file_as.str));
             if (output_mode != OUTPUT_QUIET) {
                 pst_debug_lock();
-                    printf("Processing Folder \"%s\"\n", item->file_as.str);
+                    readpst_print_string("Processing Folder \"%s\"\n",
+					 item->file_as.str,
+					 item->file_as.is_utf8);
                     fflush(stdout);
                 pst_debug_unlock();
             }
@@ -424,7 +453,17 @@ void process(pst_item *outeritem, pst_de
         } else {
             ff.skip_count++;
             DEBUG_INFO(("Unknown item type %i (%s) name (%s)\n",
-                        item->type, item->ascii_type, item->file_as.str));
+                        item->type, item->ascii_type,
+			item->file_as.str ? item->file_as.str : "<NONE>"));
+	    if (output_mode != OUTPUT_QUIET) {
+                printf("   Unknown item type %i (%s)",
+                       item->type, item->ascii_type);
+		if (item->file_as.str)
+		    readpst_print_string(" name (%s)\n", item->file_as.str,
+					 item->file_as.is_utf8);
+		else
+		    printf(" name (%s)\n", "<NONE>");
+	    }
         }
         pst_freeItem(item);
     }
@@ -777,6 +816,47 @@ void version() {
     DEBUG_RET();
 }
 
+int readpst_mkdir(char *dir_name) {
+    int result;
+#if defined(WIN32) && !defined(__CYGWIN__)
+    wchar_t wdir[MAX_PATH];
+    if (MultiByteToWideChar(CP_UTF8, 0, dir_name, -1, wdir, MAX_PATH))
+        result = _wmkdir(wdir);
+    else
+        result = _mkdir(dir_name);
+#else
+    result = D_MKDIR(dir_name);
+#endif
+    return result;
+}
+
+int readpst_chdir(char *dir_name) {
+    int result;
+#if defined(WIN32) && !defined(__CYGWIN__)
+    wchar_t wdir[MAX_PATH];
+    if (MultiByteToWideChar(CP_UTF8, 0, dir_name, -1, wdir, MAX_PATH))
+        result = _wchdir(wdir);
+    else
+        result = _chdir(dir_name);
+#else
+    result = chdir(dir_name);
+#endif
+    return result;
+}
+
+FILE *readpst_fopen(const char *fname, const char *mode) {
+    FILE *result;
+#if defined(WIN32) && !defined(__CYGWIN__)
+    wchar_t wfile[MAX_PATH];
+    if (MultiByteToWideChar(CP_UTF8, 0, fname, -1, wfile, MAX_PATH)) {
+	wchar_t *wmode = alloca((strlen(mode) + 1) * sizeof(wchar_t));
+	MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, strlen(mode) + 1);
+        result = _wfopen(wfile, wmode);
+    } else
+#endif
+        result = fopen(fname, mode);
+    return result;
+}
 
 char *mk_kmail_dir(char *fname) {
     //change to that directory
@@ -786,14 +866,14 @@ char *mk_kmail_dir(char *fname) {
     char *dir, *out_name, *index;
     int x;
     DEBUG_ENT("mk_kmail_dir");
-    if (kmail_chdir && chdir(kmail_chdir)) {
+    if (kmail_chdir && readpst_chdir(kmail_chdir)) {
         x = errno;
         DIE(("mk_kmail_dir: Cannot change to directory %s: %s\n", kmail_chdir, strerror(x)));
     }
     dir = pst_malloc(strlen(fname)+strlen(OUTPUT_KMAIL_DIR_TEMPLATE)+1);
     sprintf(dir, OUTPUT_KMAIL_DIR_TEMPLATE, fname);
     check_filename(dir);
-    if (D_MKDIR(dir)) {
+    if (readpst_mkdir(dir)) {
         if (errno != EEXIST) {  // not an error because it exists
             x = errno;
             DIE(("mk_kmail_dir: Cannot create directory %s: %s\n", dir, strerror(x)));
@@ -841,13 +921,13 @@ char *mk_recurse_dir(char *dir, int32_t
     char *out_name;
     DEBUG_ENT("mk_recurse_dir");
     check_filename(dir);
-    if (D_MKDIR (dir)) {
+    if (readpst_mkdir(dir)) {
         if (errno != EEXIST) {  // not an error because it exists
             x = errno;
             DIE(("mk_recurse_dir: Cannot create directory %s: %s\n", dir, strerror(x)));
         }
     }
-    if (chdir (dir)) {
+    if (readpst_chdir(dir)) {
         x = errno;
         DIE(("mk_recurse_dir: Cannot change to directory %s: %s\n", dir, strerror(x)));
     }
@@ -901,7 +981,7 @@ char *mk_separate_dir(char *dir) {
 
         check_filename(dir_name);
         DEBUG_INFO(("about to try creating %s\n", dir_name));
-        if (D_MKDIR(dir_name)) {
+	if (readpst_mkdir(dir_name)) {
             if (errno != EEXIST) { // if there is an error, and it doesn't already exist
                 x = errno;
                 DIE(("mk_separate_dir: Cannot create directory %s: %s\n", dir, strerror(x)));
@@ -912,14 +992,13 @@ char *mk_separate_dir(char *dir) {
         y++;
     } while (overwrite == 0);
 
-    if (chdir(dir_name)) {
+    if (readpst_chdir(dir_name)) {
         x = errno;
         DIE(("mk_separate_dir: Cannot change to directory %s: %s\n", dir, strerror(x)));
     }
 
     if (overwrite) {
         // we should probably delete all files from this directory
-#if !defined(WIN32) && !defined(__CYGWIN__)
         DIR * sdir = NULL;
         struct dirent *dirent = NULL;
         struct stat filestat;
@@ -936,7 +1015,6 @@ char *mk_separate_dir(char *dir) {
                     }
             }
         }
-#endif
     }
 
     // we don't return a filename here cause it isn't necessary.
@@ -966,7 +1044,7 @@ void mk_separate_file(struct file_ll *f,
     sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->item_count, extension);
     check_filename(f->name);
     if (openit) {
-        if (!(f->output = fopen(f->name, "w"))) {
+        if (!(f->output = fopen(f->name, "wb"))) {
             DIE(("mk_separate_file: Cannot open file to save email \"%s\"\n", f->name));
         }
     }
@@ -1098,13 +1176,13 @@ void write_separate_attachment(char f_na
                 sprintf(temp, "%s-%s", f_name, attach_filename);
             else
                 sprintf(temp, "%s-%s-%i", f_name, attach_filename, x);
-        } while ((fp = fopen(temp, "r")) && ++x < 99999999);
+        } while ((fp = readpst_fopen(temp, "r")) && ++x < 99999999);
         if (x > 99999999) {
             DIE(("error finding attachment name. exhausted possibilities to %s\n", temp));
         }
     }
     DEBUG_INFO(("Saving attachment to %s\n", temp));
-    if (!(fp = fopen(temp, "w"))) {
+    if (!(fp = readpst_fopen(temp, "wb"))) {
         DEBUG_WARN(("write_separate_attachment: Cannot open attachment save file \"%s\"\n", temp));
     } else {
         (void)pst_attach_to_file(pst, attach, fp);
@@ -2163,7 +2241,7 @@ void create_enter_dir(struct file_ll* f,
     else if (mode == MODE_RECURSE) {
         f->name = mk_recurse_dir(item->file_as.str, f->type);
         if (mode_thunder) {
-            FILE *type_file = fopen(".type", "w");
+            FILE *type_file = fopen(".type", "wb");
             fprintf(type_file, "%d\n", item->type);
             fclose(type_file);
         }
@@ -2186,7 +2264,7 @@ void create_enter_dir(struct file_ll* f,
 
         sprintf(temp, "%s", f->name);
         check_filename(temp);
-        while ((f->output = fopen(temp, "r"))) {
+        while ((f->output = readpst_fopen(temp, "r"))) {
             DEBUG_INFO(("need to increase filename because one already exists with that name\n"));
             DEBUG_INFO(("- increasing it to %s%d\n", f->name, x));
             x++;
@@ -2208,7 +2286,7 @@ void create_enter_dir(struct file_ll* f,
     DEBUG_INFO(("f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as.str));
     if (mode != MODE_SEPARATE) {
         check_filename(f->name);
-        if (!(f->output = fopen(f->name, "w"))) {
+        if (!(f->output = readpst_fopen(f->name, "wb"))) {
             DIE(("create_enter_dir: Could not open file \"%s\" for write\n", f->name));
         }
     }
@@ -2222,7 +2300,8 @@ void close_enter_dir(struct file_ll *f)
                 f->dname, f->item_count, f->skip_count, f->stored_count));
     if (output_mode != OUTPUT_QUIET) {
         pst_debug_lock();
-            printf("\t\"%s\" - %i items done, %i items skipped.\n", f->dname, f->item_count, f->skip_count);
+	readpst_print_string("\t\"%s\"", f->dname, 1);
+        printf(" - %i items done, %i items skipped.\n", f->item_count, f->skip_count);
             fflush(stdout);
         pst_debug_unlock();
     }
@@ -2244,7 +2323,7 @@ void close_enter_dir(struct file_ll *f)
         close_kmail_dir();
     else if (mode == MODE_RECURSE) {
         if (mode_thunder) {
-            FILE *type_file = fopen(".size", "w");
+            FILE *type_file = fopen(".size", "wb");
             fprintf(type_file, "%i %i\n", f->item_count, f->stored_count);
             fclose(type_file);
         }
