diff --git a/babl/babl-cache.c b/babl/babl-cache.c
index 4a26db0..6237cf3 100644
--- a/babl/babl-cache.c
+++ b/babl/babl-cache.c
@@ -18,44 +18,101 @@
 
 #include <time.h>
 #include <sys/stat.h>
+#include <errno.h>
 #include "config.h"
 #include "babl-internal.h"
 #include "git-version.h"
 
+#define BABL_DISCARD_RATE 100
+
+#ifdef _WIN32
+
+#define FALLBACK_CACHE_PATH  "C:/babl-fishes.txt"
+/* fixme  mkdir takes one arg on native msys2/mingw-w64, but what
+ *        about other build environments (MSVC, cross-compile, etc)? */
+#define MKDIR(path, mode)    mkdir (path)
+
+#else
+
+#define FALLBACK_CACHE_PATH  "/tmp/babl.db"
+#define MKDIR(path, mode)    mkdir (path, mode)
+
+#endif
+
+
+/* Adapted from http://stackoverflow.com/a/9210960
+ * mkpath a/b/c  ==>  mkdir a a/b
+ * mkpath a/b/c/ ==>  mkdir a a/b a/b/c
+ * spaces in path work correctly
+ * On Windows, '\\' is also allowed as a path delimiter
+ *
+ * fixme  Maybe move mkpath somewhere more global,
+ *        or use an already existing function?
+ */
+static int mkpath (const char *_path)
+{
+  char *path = strdup (_path);
+  char *delim = path;
+
+#ifdef _WIN32
+  for (char *ch = path; *ch; ch++)
+    if (*ch == '\\')
+      *ch = '/';
+#endif
+
+  while (( delim = strchr (delim+1, '/') ))
+  {
+    *delim = '\0';
+    if (MKDIR (path, mode) == -1)
+    {
+      struct stat stat_buf;
+
+      if (errno != EEXIST ||
+          (stat (path, &stat_buf)==0 && !S_ISDIR(stat_buf.st_mode)) )
+      {
+        free (path);
+        return -1;
+      }
+    }
+    *delim = '/';
+  }
+
+  free (path);
+  return 0;
+}
+
 static const char *fish_cache_path (void)
 {
-#ifdef _WIN32  // XXX: fixme - make this work - and be a reasonable location
-               // on windows
-  return "C:\\babl.txt"; 
-#else
-  // FIXME: need a location for this temporary file on win32
   struct stat stat_buf;
-  static char resolved[4096];
-  char *ret = NULL;
+  static char cache_path[4096];
+
+#ifndef _WIN32
   if (getenv ("HOME"))
   {
-    sprintf (resolved, "%s/.cache/babl/fishes", getenv("HOME"));
+    sprintf (cache_path, "%s/%s", getenv ("HOME"), ".cache/babl/fishes");
   }
   else
+#endif
+  if (getenv ("TEMP"))
   {
-    return "/tmp/babl.db";
+    sprintf (cache_path, "%s/%s", getenv ("TEMP"), "babl.db");
   }
-
-  if (stat (resolved, &stat_buf)==0 && S_ISREG(stat_buf.st_mode))
-    return resolved;
-  ret = strdup (resolved);
-
-  while (strrchr (resolved, '/'))
+  else
   {
-    *strrchr (resolved, '/') = '\0';
-    mkdir (resolved, S_IRWXU);
+    return FALLBACK_CACHE_PATH;
   }
 
-  strcpy (resolved, ret);
-  free (ret);
+  if (stat (cache_path, &stat_buf)==0 && S_ISREG(stat_buf.st_mode))
+    return cache_path;
 
-  return resolved;
-#endif
+  if (mkpath (cache_path) == -1)
+    {
+    fprintf (stderr, "%s:%i: in %s(): path not created for babl cache \"%s\"\n",
+                     __FILE__, __LINE__, __FUNCTION__, cache_path);
+    return FALLBACK_CACHE_PATH;
+    }
+
+  return cache_path;
 }
 
 static char *
@@ -64,7 +121,7 @@ babl_fish_serialize (Babl *fish, char *dest, int n)
   char *d = dest;
   if (fish->class_type != BABL_FISH_PATH)
     return NULL;
-                              
+
   snprintf (d, n, "%s\n%s\n",
   babl_get_name (fish->fish.source),
   babl_get_name (fish->fish.destination));
@@ -87,7 +144,7 @@ babl_fish_serialize (Babl *fish, char *dest, int n)
 
   for (int i = 0; i < fish->fish_path.conversion_list->count; i++)
   {
-    snprintf (d, n, "\t%s\n", 
+    snprintf (d, n, "\t%s\n",
       babl_get_name(fish->fish_path.conversion_list->items[i]  ));
     n -= strlen (d);d += strlen (d);
   }
@@ -181,17 +238,13 @@ void babl_init_db (void)
 {
   const char *path = fish_cache_path ();
   long  length = -1;
-  char  seps[] = "\n";
+  char  seps[] = "\r\n"; /* ... because Windows */
   Babl *babl   = NULL;
   char *contents = NULL;
   char *token;
   char *tokp;
   const Babl  *from_format = NULL;
   const Babl  *to_format   = NULL;
-  time_t tim = time (NULL);
-#ifdef _WIN32  // XXX: fixme - make this work on windows
-  return;
-#endif
 
   if (getenv ("BABL_DEBUG_CONVERSIONS"))
     return;
@@ -208,8 +261,8 @@ void babl_init_db (void)
         case '-': /* finalize */
           if (babl)
           {
-            if ( ((babl->fish.pixels+1 + babl->fish.processings) % 
-                (tim % 100)) == 0)
+            if (( (babl->fish.pixels+1 + babl->fish.processings + time (NULL)) %
+                  BABL_DISCARD_RATE ) == 0)
             {
               /* 1% chance of individual cached conversions being dropped -
                * making sure mis-measured conversions do not
@@ -248,8 +301,8 @@ void babl_init_db (void)
             babl = babl_db_exist_by_name (babl_fish_db (), name);
             if (babl)
             {
-              fprintf (stderr, "%s:%i: loading of cache failed\n",
-                              __FUNCTION__, __LINE__);
+              fprintf (stderr, "%s:%i: in %s(): loading babl cache failed\n",
+                               __FILE__, __LINE__, __FUNCTION__);
               return;
             }
 
diff --git a/babl/babl-fish-stats.c b/babl/babl-fish-stats.c
index 2b9cc7c..2a42012 100644
--- a/babl/babl-fish-stats.c
+++ b/babl/babl-fish-stats.c
@@ -19,6 +19,9 @@
 #include "config.h"
 #include "babl-internal.h"
 
+/* from babl-fish-path.c */
+double _babl_legal_error (void);
+
 static FILE *output_file = NULL;
 static int   qux         = 0;
 
@@ -241,24 +244,6 @@ table_source_each (Babl *babl,
   return 0;
 }
 
-/* copied from babl-fish-path.c */
-#define BABL_LEGAL_ERROR    0.000001
-static double legal_error (void)
-{
-  static double error = 0.0;
-  const char   *env;
-
-  if (error != 0.0)
-    return error;
-
-  env = getenv ("BABL_TOLERANCE");
-  if (env && env[0] != '\0')
-    error = babl_parse_double (env);
-  else
-    error = BABL_LEGAL_ERROR;
-  return error;
-}
-
 static int
 each_conv (Babl *babl,
            void *data)
@@ -271,7 +256,7 @@ each_conv (Babl *babl,
   error = babl_conversion_error (&babl->conversion);
   cost  = babl_conversion_cost (&babl->conversion);
 
-  if (error > legal_error ())
+  if (error > _babl_legal_error ())
     {
       fprintf (output_file, "<dt style='background-color: #fcc;'>%s</dt>", babl->instance.name);
       fprintf (output_file, "<dd style='background-color: #fcc;'>");
diff --git a/babl/babl.c b/babl/babl.c
index caec6a6..599cf49 100644
--- a/babl/babl.c
+++ b/babl/babl.c
@@ -160,10 +160,7 @@ babl_exit (void)
 {
   if (!-- ref_count)
     {
-#ifdef _WIN32  // XXX: fixme - make this work on windows
-#else
       babl_store_db ();
-#endif
 
       if (getenv ("BABL_STATS"))
         {
diff --git a/tools/babl-verify.c b/tools/babl-verify.c
index 15654e2..818d530 100644
--- a/tools/babl-verify.c
+++ b/tools/babl-verify.c
@@ -9,9 +9,13 @@ int main (int argc, char **argv)
     fprintf (stderr, "need two args, from and to babl-formats\n");
     return -1;
   }
+#ifdef _WIN32
+  putenv ("BABL_DEBUG_CONVERSIONS=1");
+#else
   setenv ("BABL_DEBUG_CONVERSIONS", "1", 0);
+#endif
   babl_init ();
-  babl_fish (babl_format(argv[1]), babl_format (argv[2]));
+  babl_fish (babl_format (argv[1]), babl_format (argv[2]));
   babl_exit ();
 
   return 0;
