Consistently include <config.h> in all C source files and never in header files.
[platform/upstream/dbus.git] / dbus / dbus-sysdeps-win.c
index 2163da7..bba8915 100644 (file)
  *
  */
 
-#undef open
+#include <config.h>
 
 #define STRSAFE_NO_DEPRECATE
 
 #ifndef DBUS_WINCE
+#ifndef _WIN32_WINNT
 #define _WIN32_WINNT 0x0501
 #endif
+#endif
 
 #include "dbus-internals.h"
 #include "dbus-sysdeps.h"
 #include "dbus-hash.h"
 #include "dbus-sockets-win.h"
 #include "dbus-list.h"
+#include "dbus-nonce.h"
 #include "dbus-credentials.h"
 
 #include <windows.h>
 #include <ws2tcpip.h>
+#include <wincrypt.h>
+
+/* Declarations missing in mingw's headers */
+extern BOOL WINAPI ConvertStringSidToSidA (LPCSTR  StringSid, PSID *Sid);
+extern BOOL WINAPI ConvertSidToStringSidA (PSID Sid, LPSTR *StringSid);
+
 #include <fcntl.h>
 
 #include <process.h>
+#include <stdio.h>
+#include <io.h>
+
+#include <string.h>
+#include <mbstring.h>
+#include <errno.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
 #define O_BINARY 0
 #endif
 
-#ifndef HAVE_SOCKLEN_T
-#define socklen_t int
-#endif
-
-/**
- * File interface
- *
- */
-dbus_bool_t
-_dbus_file_open (DBusFile   *file,
-                 const char *filename,
-                 int         oflag,
-                 int         pmode)
-{
-  if (pmode!=-1)
-    file->FDATA = _open (filename, oflag, pmode);
-  else
-    file->FDATA = _open (filename, oflag);
-  if (file->FDATA >= 0)
-    return TRUE;
-  else
-    {
-      file->FDATA = -1;
-      return FALSE;
-    }
-}
-
-dbus_bool_t
-_dbus_file_close (DBusFile  *file,
-                  DBusError *error)
-{
-  const int fd = file->FDATA;
-
-  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
-  _dbus_assert (fd >= 0);
-
-  if (_close (fd) == -1)
-    {
-      dbus_set_error (error, _dbus_error_from_errno (errno),
-                      "Could not close fd %d: %s", fd,
-                      _dbus_strerror (errno));
-      return FALSE;
-    }
-
-  file->FDATA = -1;
-  _dbus_verbose ("closed C file descriptor %d:\n",fd);
-
-  return TRUE;
-}
-
-int
-_dbus_file_read(DBusFile   *file,
-                DBusString *buffer,
-                int         count)
-{
-  const int fd = file->FDATA;
-  int bytes_read;
-  int start;
-  char *data;
-  _dbus_assert (count >= 0);
-
-  start = _dbus_string_get_length (buffer);
-
-  if (!_dbus_string_lengthen (buffer, count))
-    {
-      errno = ENOMEM;
-      return -1;
-    }
-
-  data = _dbus_string_get_data_len (buffer, start, count);
-
-  _dbus_assert (fd >= 0);
-
-  _dbus_verbose ("read: count=%d fd=%d\n", count, fd);
-  bytes_read = read (fd, data, count);
-
-  if (bytes_read == -1)
-    _dbus_verbose ("read: failed: %s\n", _dbus_strerror (errno));
-  else
-    _dbus_verbose ("read: = %d\n", bytes_read);
-
-  if (bytes_read < 0)
-    {
-      /* put length back (note that this doesn't actually realloc anything) */
-      _dbus_string_set_length (buffer, start);
-      return -1;
-    }
-  else
-    {
-      /* put length back (doesn't actually realloc) */
-      _dbus_string_set_length (buffer, start + bytes_read);
-
-#if 0
-
-      if (bytes_read > 0)
-        _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
-#endif
-
-      return bytes_read;
-    }
-}
+typedef int socklen_t;
 
-int
-_dbus_file_write (DBusFile         *file,
-                  const DBusString *buffer,
-                  int               start,
-                  int               len)
+char*
+_dbus_win_error_string (int error_number)
 {
-  const int fd = file->FDATA;
-  const char *data;
-  int bytes_written;
-
-  data = _dbus_string_get_const_data_len (buffer, start, len);
+  char *msg;
 
-  _dbus_assert (fd >= 0);
-
-  _dbus_verbose ("write: len=%d fd=%d\n", len, fd);
-  bytes_written = write (fd, data, len);
-
-  if (bytes_written == -1)
-    _dbus_verbose ("write: failed: %s\n", _dbus_strerror (errno));
-  else
-    _dbus_verbose ("write: = %d\n", bytes_written);
-
-#if 0
-
-  if (bytes_written > 0)
-    _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
-#endif
-
-  return bytes_written;
-}
-
-dbus_bool_t
-_dbus_is_valid_file (DBusFile* file)
-{
-  return file->FDATA >= 0;
-}
+  FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                 FORMAT_MESSAGE_IGNORE_INSERTS |
+                 FORMAT_MESSAGE_FROM_SYSTEM,
+                 NULL, error_number, 0,
+                 (LPSTR) &msg, 0, NULL);
 
-dbus_bool_t _dbus_fstat (DBusFile    *file,
-                         struct stat *sb)
-{
-  return fstat(file->FDATA, sb) >= 0;
-}
+  if (msg[strlen (msg) - 1] == '\n')
+    msg[strlen (msg) - 1] = '\0';
+  if (msg[strlen (msg) - 1] == '\r')
+    msg[strlen (msg) - 1] = '\0';
 
-/**
- * write data to a pipe.
- *
- * @param pipe the pipe instance
- * @param buffer the buffer to write data from
- * @param start the first byte in the buffer to write
- * @param len the number of bytes to try to write
- * @param error error return
- * @returns the number of bytes written or -1 on error
- */
-int
-_dbus_pipe_write (DBusPipe         *pipe,
-                  const DBusString *buffer,
-                  int               start,
-                  int               len,
-                  DBusError        *error)
-{
-  int written;
-  DBusFile file;
-  file.FDATA = pipe->fd_or_handle;
-  written = _dbus_file_write (&file, buffer, start, len);
-  if (written < 0)
-    {
-      dbus_set_error (error, DBUS_ERROR_FAILED,
-                      "Writing to pipe: %s\n",
-                      _dbus_strerror (errno));
-    }
-  return written;
+  return msg;
 }
 
-/**
- * close a pipe.
- *
- * @param pipe the pipe instance
- * @param error return location for an error
- * @returns #FALSE if error is set
- */
-int
-_dbus_pipe_close  (DBusPipe         *pipe,
-                   DBusError        *error)
+void
+_dbus_win_free_error_string (char *string)
 {
-  DBusFile file;
-  file.FDATA = pipe->fd_or_handle;
-  if (_dbus_file_close (&file, error) < 0)
-    {
-      return -1;
-    }
-  else
-    {
-      _dbus_pipe_invalidate (pipe);
-      return 0;
-    }
+  LocalFree (string);
 }
 
-#undef FDATA
-
 /**
  * Socket interface
  *
@@ -280,14 +120,16 @@ _dbus_pipe_close  (DBusPipe         *pipe,
  * the data it reads to the DBusString buffer. It appends
  * up to the given count, and returns the same value
  * and same errno as read(). The only exception is that
- * _dbus_read() handles EINTR for you. _dbus_read() can
- * return ENOMEM, even though regular UNIX read doesn't.
+ * _dbus_read_socket() handles EINTR for you. 
+ * _dbus_read_socket() can return ENOMEM, even though 
+ * regular UNIX read doesn't.
  *
  * @param fd the file descriptor to read from
  * @param buffer the buffer to append data to
  * @param count the amount of data to read
  * @returns the number of bytes read or -1
  */
+
 int
 _dbus_read_socket (int               fd,
                    DBusString       *buffer,
@@ -317,7 +159,7 @@ _dbus_read_socket (int               fd,
   if (bytes_read == SOCKET_ERROR)
        {
          DBUS_SOCKET_SET_ERRNO();
-         _dbus_verbose ("recv: failed: %s\n", _dbus_strerror (errno));
+         _dbus_verbose ("recv: failed: %s (%d)\n", _dbus_strerror (errno), errno);
          bytes_read = -1;
        }
        else
@@ -436,31 +278,12 @@ _dbus_close_socket (int        fd,
 void
 _dbus_fd_set_close_on_exec (int handle)
 {
-#ifdef ENABLE_DBUSSOCKET
-  DBusSocket *s;
-  if (handle < 0)
-    return;
-
-  _dbus_lock_sockets();
-
-  _dbus_handle_to_socket_unlocked (handle, &s);
-  s->close_on_exec = TRUE;
-
-  _dbus_unlock_sockets();
-#else
-  /* TODO unic code.
-  int val;
-  
-  val = fcntl (fd, F_GETFD, 0);
-  
-  if (val < 0)
-    return;
-
-  val |= FD_CLOEXEC;
-  
-  fcntl (fd, F_SETFD, val);
-  */
-#endif
+  if ( !SetHandleInformation( (HANDLE) handle,
+                        HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE,
+                        0 /*disable both flags*/ ) )
+    {
+      _dbus_win_warn_win_error ("Disabling socket handle inheritance failed:", GetLastError());
+    }
 }
 
 /**
@@ -524,7 +347,6 @@ _dbus_write_socket_two (int               fd,
   const char *data2;
   int rc;
   DWORD bytes_written;
-  int ret1;
 
   _dbus_assert (buffer1 != NULL);
   _dbus_assert (start1 >= 0);
@@ -575,6 +397,12 @@ _dbus_write_socket_two (int               fd,
   return bytes_written;
 }
 
+dbus_bool_t
+_dbus_socket_is_invalid (int fd)
+{
+    return fd == INVALID_SOCKET ? TRUE : FALSE;
+}
+
 #if 0
 
 /**
@@ -655,23 +483,24 @@ int _dbus_printf_string_upper_bound (const char *format,
                                      va_list args)
 {
   /* MSVCRT's vsnprintf semantics are a bit different */
-  /* The C library source in the Platform SDK indicates that this
-   * would work, but alas, it doesn't. At least not on Windows
-   * 2000. Presumably those sources correspond to the C library on
-   * some newer or even future Windows version.
-   *
-    len = _vsnprintf (NULL, _DBUS_INT_MAX, format, args);
-   */
-  char p[1024];
+  char buf[1024];
+  int bufsize;
   int len;
-  len = _vsnprintf (p, sizeof(p)-1, format, args);
-  if (len == -1) // try again
+
+  bufsize = sizeof (buf);
+  len = _vsnprintf (buf, bufsize - 1, format, args);
+
+  while (len == -1) /* try again */
     {
       char *p;
-      p = malloc (strlen(format)*3);
-      len = _vsnprintf (p, sizeof(p)-1, format, args);
-      free(p);
+
+      bufsize *= 2;
+
+      p = malloc (bufsize);
+      len = _vsnprintf (p, bufsize - 1, format, args);
+      free (p);
     }
+
   return len;
 }
 
@@ -841,15 +670,6 @@ out1:
 /** @} end of sysdeps-win */
 
 
-/** Gets our UID
- * @returns process UID
- */
-dbus_uid_t
-_dbus_getuid (void)
-{
-       return DBUS_UID_UNSET;
-}
-
 /**
  * The only reason this is separate from _dbus_getpid() is to allow it
  * on Windows for logging but not for other purposes.
@@ -866,10 +686,10 @@ _dbus_pid_for_log (void)
  * @param points to sid buffer, need to be freed with LocalFree()
  * @returns process sid
  */
-dbus_bool_t
+static dbus_bool_t
 _dbus_getsid(char **sid)
 {
-  HANDLE process_token = NULL;
+  HANDLE process_token = INVALID_HANDLE_VALUE;
   TOKEN_USER *token_user = NULL;
   DWORD n;
   PSID psid;
@@ -903,38 +723,13 @@ _dbus_getsid(char **sid)
   retval = TRUE;
 
 failed:
-  if (process_token != NULL)
+  if (process_token != INVALID_HANDLE_VALUE)
     CloseHandle (process_token);
 
   _dbus_verbose("_dbus_getsid() returns %d\n",retval);
   return retval;
 }
 
-
-#ifdef DBUS_BUILD_TESTS
-/** Gets our GID
- * @returns process GID
- */
-dbus_gid_t
-_dbus_getgid (void)
-{
-       return DBUS_GID_UNSET;
-}
-
-#if 0
-dbus_bool_t
-_dbus_domain_test (const char *test_data_dir)
-{
-  if (!_dbus_test_oom_handling ("spawn_nonexistent",
-                                check_spawn_nonexistent,
-                                NULL))
-    return FALSE;
-}
-
-#endif
-
-#endif //DBUS_BUILD_TESTS
-
 /************************************************************************
  
  pipes
@@ -1123,13 +918,15 @@ out0:
  * @param timeout_milliseconds timeout or -1 for infinite
  * @returns numbers of fds with revents, or <0 on error
  */
-#define USE_CHRIS_IMPL 0
-#if USE_CHRIS_IMPL
 int
 _dbus_poll (DBusPollFD *fds,
             int         n_fds,
             int         timeout_milliseconds)
 {
+#define USE_CHRIS_IMPL 0
+
+#if USE_CHRIS_IMPL
+
 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
   char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
   char *msgp;
@@ -1201,8 +998,8 @@ _dbus_poll (DBusPollFD *fds,
   if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
     {
       DBUS_SOCKET_SET_ERRNO ();
-      if (errno != EWOULDBLOCK)
-        _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", _dbus_strerror (errno));
+      if (errno != WSAEWOULDBLOCK)
+        _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", strerror (errno));
       ret = -1;
     }
   else if (ready == WSA_WAIT_TIMEOUT)
@@ -1268,15 +1065,9 @@ _dbus_poll (DBusPollFD *fds,
     free(pEvents);
 
   return ret;
-}
 
-#else   // USE_CHRIS_IMPL
+#else   /* USE_CHRIS_IMPL */
 
-int
-_dbus_poll (DBusPollFD *fds,
-            int         n_fds,
-            int         timeout_milliseconds)
-{
 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
   char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
   char *msgp;
@@ -1345,7 +1136,7 @@ _dbus_poll (DBusPollFD *fds,
   if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
     {
       DBUS_SOCKET_SET_ERRNO ();
-      if (errno != EWOULDBLOCK)
+      if (errno != WSAEWOULDBLOCK)
         _dbus_verbose ("select: failed: %s\n", _dbus_strerror (errno));
     }
   else if (ready == 0)
@@ -1391,10 +1182,9 @@ _dbus_poll (DBusPollFD *fds,
           }
       }
   return ready;
+#endif  /* USE_CHRIS_IMPL */
 }
 
-#endif  // USE_CHRIS_IMPL
-
 
 
 
@@ -1430,17 +1220,6 @@ Original CVS version of dbus-sysdeps.c
 
 
 /**
- * @addtogroup DBusInternalsUtils
- * @{
- */
-
-int _dbus_mkdir (const char *path,
-                 mode_t mode)
-{
-  return _mkdir(path);
-}
-
-/**
  * Exit the process, returning the given value.
  *
  * @param code the exit code
@@ -1468,6 +1247,16 @@ _dbus_connect_tcp_socket (const char     *host,
                           const char     *family,
                           DBusError      *error)
 {
+  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
+}
+
+int
+_dbus_connect_tcp_socket_with_nonce (const char     *host,
+                                     const char     *port,
+                                     const char     *family,
+                                     const char     *noncefile,
+                                     DBusError      *error)
+{
   int fd = -1, res;
   struct addrinfo hints;
   struct addrinfo *ai, *tmp;
@@ -1538,7 +1327,7 @@ _dbus_connect_tcp_socket (const char     *host,
         }
       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
 
-      if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
+      if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) != 0)
         {
           closesocket(fd);
       fd = -1;
@@ -1559,22 +1348,38 @@ _dbus_connect_tcp_socket (const char     *host,
       return -1;
     }
 
+  if ( noncefile != NULL )
+    {
+      DBusString noncefileStr;
+      dbus_bool_t ret;
+      if (!_dbus_string_init (&noncefileStr) ||
+          !_dbus_string_append(&noncefileStr, noncefile))
+        {
+          closesocket (fd);
+          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+          return -1;
+       }
+
+      ret = _dbus_send_nonce (fd, &noncefileStr, error);
 
-  if (!_dbus_set_fd_nonblocking (fd, error))
+      _dbus_string_free (&noncefileStr);
+
+      if (!ret)
     {
       closesocket (fd);
-      fd = -1;
+          return -1;
+        }
+    }
 
+  if (!_dbus_set_fd_nonblocking (fd, error) )
+    {
+      closesocket (fd);
       return -1;
     }
 
   return fd;
 }
 
-
-void
-_dbus_daemon_init(const char *host, dbus_uint32_t port);
-
 /**
  * Creates a socket and binds it to the given path, then listens on
  * the socket. The socket is set to be nonblocking.  In case of port=0
@@ -1602,6 +1407,16 @@ _dbus_listen_tcp_socket (const char     *host,
   struct addrinfo hints;
   struct addrinfo *ai, *tmp;
 
+  // On Vista, sockaddr_gen must be a sockaddr_in6, and not a sockaddr_in6_old
+  //That's required for family == IPv6(which is the default on Vista if family is not given)
+  //So we use our own union instead of sockaddr_gen:
+
+  typedef union {
+       struct sockaddr Address;
+       struct sockaddr_in AddressIn;
+       struct sockaddr_in6 AddressIn6;
+  } mysockaddr_gen;
+
   *fds_p = NULL;
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
@@ -1694,7 +1509,7 @@ _dbus_listen_tcp_socket (const char     *host,
              to use the same port */
           if (!port || !strcmp(port, "0"))
             {
-              sockaddr_gen addr;
+              mysockaddr_gen addr;
               socklen_t addrlen = sizeof(addr);
               char portbuf[10];
 
@@ -1742,7 +1557,6 @@ _dbus_listen_tcp_socket (const char     *host,
     }
 
   sscanf(_dbus_string_get_const_data(retport), "%d", &port_num);
-  _dbus_daemon_init(host, port_num);
 
   for (i = 0 ; i < nlisten_fd ; i++)
     {
@@ -1961,7 +1775,7 @@ _dbus_concat_dir_and_file (DBusString       *dir,
                             _dbus_string_get_length (dir));
 }
 
-/*---------------- DBusCredentials ----------------------------------
+/*---------------- DBusCredentials ----------------------------------*/
 
 /**
  * Adds the credentials corresponding to the given username.
@@ -2043,7 +1857,7 @@ _dbus_append_user_from_current_process (DBusString *str)
  * Gets our process ID
  * @returns process ID
  */
-unsigned long
+dbus_pid_t
 _dbus_getpid (void)
 {
   return GetCurrentProcessId ();
@@ -2082,21 +1896,23 @@ _dbus_get_current_time (long *tv_sec,
                         long *tv_usec)
 {
   FILETIME ft;
-  dbus_uint64_t *time64 = (dbus_uint64_t *) &ft;
+  dbus_uint64_t time64;
 
   GetSystemTimeAsFileTime (&ft);
 
+  memcpy (&time64, &ft, sizeof (time64));
+
   /* Convert from 100s of nanoseconds since 1601-01-01
   * to Unix epoch. Yes, this is Y2038 unsafe.
   */
-  *time64 -= DBUS_INT64_CONSTANT (116444736000000000);
-  *time64 /= 10;
+  time64 -= DBUS_INT64_CONSTANT (116444736000000000);
+  time64 /= 10;
 
   if (tv_sec)
-    *tv_sec = *time64 / 1000000;
+    *tv_sec = time64 / 1000000;
 
   if (tv_usec)
-    *tv_usec = *time64 % 1000000;
+    *tv_usec = time64 % 1000000;
 }
 
 
@@ -2106,373 +1922,74 @@ _dbus_get_current_time (long *tv_sec,
 void
 _dbus_disable_sigpipe (void)
 {
-    _dbus_verbose("FIXME: implement _dbus_disable_sigpipe (void)\n");
 }
 
-
 /**
- * Appends the contents of the given file to the string,
- * returning error code. At the moment, won't open a file
- * more than a megabyte in size.
+ * Creates a directory; succeeds if the directory
+ * is created or already existed.
  *
- * @param str the string to append to
- * @param filename filename to load
- * @param error place to set an error
- * @returns #FALSE if error was set
+ * @param filename directory filename
+ * @param error initialized error object
+ * @returns #TRUE on success
  */
 dbus_bool_t
-_dbus_file_get_contents (DBusString       *str,
-                         const DBusString *filename,
-                         DBusError        *error)
+_dbus_create_directory (const DBusString *filename,
+                        DBusError        *error)
 {
-  DBusFile file;
-  struct stat sb;
-  int orig_len;
-  int total;
   const char *filename_c;
 
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
   filename_c = _dbus_string_get_const_data (filename);
 
-  /* O_BINARY useful on Cygwin and Win32 */
-  if (!_dbus_file_open (&file, filename_c, O_RDONLY | O_BINARY, -1))
+  if (!CreateDirectory (filename_c, NULL))
     {
-      dbus_set_error (error, _dbus_error_from_errno (errno),
-                      "Failed to open \"%s\": %s",
-                      filename_c,
-                      _dbus_strerror (errno));
+      if (GetLastError () == ERROR_ALREADY_EXISTS)
+        return TRUE;
+
+      dbus_set_error (error, DBUS_ERROR_FAILED,
+                      "Failed to create directory %s: %s\n",
+                      filename_c, strerror (errno));
       return FALSE;
     }
+  else
+    return TRUE;
+}
 
-  if (!_dbus_fstat (&file, &sb))
-    {
-      dbus_set_error (error, _dbus_error_from_errno (errno),
-                      "Failed to stat \"%s\": %s",
-                      filename_c,
-                      _dbus_strerror (errno));
 
-      _dbus_verbose ("fstat() failed: %s",
-                     _dbus_strerror (errno));
+/**
+ * Generates the given number of random bytes,
+ * using the best mechanism we can come up with.
+ *
+ * @param str the string
+ * @param n_bytes the number of random bytes to append to string
+ * @returns #TRUE on success, #FALSE if no memory
+ */
+dbus_bool_t
+_dbus_generate_random_bytes (DBusString *str,
+                             int         n_bytes)
+{
+  int old_len;
+  char *p;
+  HCRYPTPROV hprov;
 
-      _dbus_file_close (&file, NULL);
+  old_len = _dbus_string_get_length (str);
 
-      return FALSE;
-    }
+  if (!_dbus_string_lengthen (str, n_bytes))
+    return FALSE;
 
-  if (sb.st_size > _DBUS_ONE_MEGABYTE)
-    {
-      dbus_set_error (error, DBUS_ERROR_FAILED,
-                      "File size %lu of \"%s\" is too large.",
-                      (unsigned long) sb.st_size, filename_c);
-      _dbus_file_close (&file, NULL);
-      return FALSE;
-    }
-
-  total = 0;
-  orig_len = _dbus_string_get_length (str);
-  if (sb.st_size > 0 && S_ISREG (sb.st_mode))
-    {
-      int bytes_read;
-
-      while (total < (int) sb.st_size)
-        {
-          bytes_read = _dbus_file_read (&file, str,
-                                        sb.st_size - total);
-          if (bytes_read <= 0)
-            {
-              dbus_set_error (error, _dbus_error_from_errno (errno),
-                              "Error reading \"%s\": %s",
-                              filename_c,
-                              _dbus_strerror (errno));
-
-              _dbus_verbose ("read() failed: %s",
-                             _dbus_strerror (errno));
-
-              _dbus_file_close (&file, NULL);
-              _dbus_string_set_length (str, orig_len);
-              return FALSE;
-            }
-          else
-            total += bytes_read;
-        }
-
-      _dbus_file_close (&file, NULL);
-      return TRUE;
-    }
-  else if (sb.st_size != 0)
-    {
-      _dbus_verbose ("Can only open regular files at the moment.\n");
-      dbus_set_error (error, DBUS_ERROR_FAILED,
-                      "\"%s\" is not a regular file",
-                      filename_c);
-      _dbus_file_close (&file, NULL);
-      return FALSE;
-    }
-  else
-    {
-      _dbus_file_close (&file, NULL);
-      return TRUE;
-    }
-}
-
-/**
- * Writes a string out to a file. If the file exists,
- * it will be atomically overwritten by the new data.
- *
- * @param str the string to write out
- * @param filename the file to save string to
- * @param error error to be filled in on failure
- * @returns #FALSE on failure
- */
-dbus_bool_t
-_dbus_string_save_to_file (const DBusString *str,
-                           const DBusString *filename,
-                           DBusError        *error)
-{
-  DBusFile file;
-  int bytes_to_write;
-  const char *filename_c;
-  DBusString tmp_filename;
-  const char *tmp_filename_c;
-  int total;
-  dbus_bool_t need_unlink;
-  dbus_bool_t retval;
-
-  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
-  retval = FALSE;
-  need_unlink = FALSE;
-
-  if (!_dbus_string_init (&tmp_filename))
-    {
-      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
-      return FALSE;
-    }
-
-  if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
-    {
-      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
-      _dbus_string_free (&tmp_filename);
-      return FALSE;
-    }
-
-  if (!_dbus_string_append (&tmp_filename, "."))
-    {
-      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
-      _dbus_string_free (&tmp_filename);
-      return FALSE;
-    }
-
-#define N_TMP_FILENAME_RANDOM_BYTES 8
-  if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
-    {
-      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
-      _dbus_string_free (&tmp_filename);
-      return FALSE;
-    }
-
-  filename_c = _dbus_string_get_const_data (filename);
-  tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
-
-  if (!_dbus_file_open (&file, tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
-                        0600))
-    {
-      dbus_set_error (error, _dbus_error_from_errno (errno),
-                      "Could not create %s: %s", tmp_filename_c,
-                      _dbus_strerror (errno));
-      goto out;
-    }
-
-  need_unlink = TRUE;
-
-  total = 0;
-  bytes_to_write = _dbus_string_get_length (str);
-
-  while (total < bytes_to_write)
-    {
-      int bytes_written;
-
-      bytes_written = _dbus_file_write (&file, str, total,
-                                        bytes_to_write - total);
-
-      if (bytes_written <= 0)
-        {
-          dbus_set_error (error, _dbus_error_from_errno (errno),
-                          "Could not write to %s: %s", tmp_filename_c,
-                          _dbus_strerror (errno));
-
-          goto out;
-        }
-
-      total += bytes_written;
-    }
-
-  if (!_dbus_file_close (&file, NULL))
-    {
-      dbus_set_error (error, _dbus_error_from_errno (errno),
-                      "Could not close file %s: %s",
-                      tmp_filename_c, _dbus_strerror (errno));
-
-      goto out;
-    }
-
-
-  if ((unlink (filename_c) == -1 && errno != ENOENT) ||
-       rename (tmp_filename_c, filename_c) < 0)
-    {
-      dbus_set_error (error, _dbus_error_from_errno (errno),
-                      "Could not rename %s to %s: %s",
-                      tmp_filename_c, filename_c,
-                      _dbus_strerror (errno));
-
-      goto out;
-    }
-
-  need_unlink = FALSE;
-
-  retval = TRUE;
-
-out:
-  /* close first, then unlink, to prevent ".nfs34234235" garbage
-   * files
-   */
-
-  if (_dbus_is_valid_file(&file))
-    _dbus_file_close (&file, NULL);
-
-  if (need_unlink && unlink (tmp_filename_c) < 0)
-    _dbus_verbose ("Failed to unlink temp file %s: %s\n",
-                   tmp_filename_c, _dbus_strerror (errno));
-
-  _dbus_string_free (&tmp_filename);
-
-  if (!retval)
-    _DBUS_ASSERT_ERROR_IS_SET (error);
-
-  return retval;
-}
-
-
-/** Creates the given file, failing if the file already exists.
- *
- * @param filename the filename
- * @param error error location
- * @returns #TRUE if we created the file and it didn't exist
- */
-dbus_bool_t
-_dbus_create_file_exclusively (const DBusString *filename,
-                               DBusError        *error)
-{
-  DBusFile file;
-  const char *filename_c;
-
-  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+  p = _dbus_string_get_data_len (str, old_len, n_bytes);
 
-  filename_c = _dbus_string_get_const_data (filename);
+  if (!CryptAcquireContext (&hprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
+    return FALSE;
 
-  if (!_dbus_file_open (&file, filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
-                        0600))
+  if (!CryptGenRandom (hprov, n_bytes, p))
     {
-      dbus_set_error (error,
-                      DBUS_ERROR_FAILED,
-                      "Could not create file %s: %s\n",
-                      filename_c,
-                      _dbus_strerror (errno));
+      CryptReleaseContext (hprov, 0);
       return FALSE;
     }
 
-  if (!_dbus_file_close (&file, NULL))
-    {
-      dbus_set_error (error,
-                      DBUS_ERROR_FAILED,
-                      "Could not close file %s: %s\n",
-                      filename_c,
-                      _dbus_strerror (errno));
-      return FALSE;
-    }
-
-  return TRUE;
-}
-
-
-/**
- * Creates a directory; succeeds if the directory
- * is created or already existed.
- *
- * @param filename directory filename
- * @param error initialized error object
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_create_directory (const DBusString *filename,
-                        DBusError        *error)
-{
-  const char *filename_c;
-
-  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
-  filename_c = _dbus_string_get_const_data (filename);
-
-  if (_dbus_mkdir (filename_c, 0700) < 0)
-    {
-      if (errno == EEXIST)
-        return TRUE;
-
-      dbus_set_error (error, DBUS_ERROR_FAILED,
-                      "Failed to create directory %s: %s\n",
-                      filename_c, _dbus_strerror (errno));
-      return FALSE;
-    }
-  else
-    return TRUE;
-}
-
-
-static void
-pseudorandom_generate_random_bytes_buffer (char *buffer,
-    int   n_bytes)
-{
-  long tv_usec;
-  int i;
-
-  /* fall back to pseudorandom */
-  _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
-                 n_bytes);
-
-  _dbus_get_current_time (NULL, &tv_usec);
-  srand (tv_usec);
-
-  i = 0;
-  while (i < n_bytes)
-    {
-      double r;
-      unsigned int b;
-
-      r = rand ();
-      b = (r / (double) RAND_MAX) * 255.0;
-
-      buffer[i] = b;
-
-      ++i;
-    }
-}
-
-static dbus_bool_t
-pseudorandom_generate_random_bytes (DBusString *str,
-                                    int         n_bytes)
-{
-  int old_len;
-  char *p;
-
-  old_len = _dbus_string_get_length (str);
-
-  if (!_dbus_string_lengthen (str, n_bytes))
-    return FALSE;
-
-  p = _dbus_string_get_data_len (str, old_len, n_bytes);
-
-  pseudorandom_generate_random_bytes_buffer (p, n_bytes);
+  CryptReleaseContext (hprov, 0);
 
   return TRUE;
 }
@@ -2487,17 +2004,27 @@ const char*
 _dbus_get_tmpdir(void)
 {
   static const char* tmpdir = NULL;
+  static char buf[1000];
 
   if (tmpdir == NULL)
     {
-      if (tmpdir == NULL)
-        tmpdir = getenv("TMP");
-      if (tmpdir == NULL)
-        tmpdir = getenv("TEMP");
-      if (tmpdir == NULL)
-        tmpdir = getenv("TMPDIR");
-      if (tmpdir == NULL)
-          tmpdir = "C:\\Temp";
+      char *last_slash;
+
+      if (!GetTempPath (sizeof (buf), buf))
+        {
+          _dbus_warn ("GetTempPath failed\n");
+          _dbus_abort ();
+        }
+
+      /* Drop terminating backslash or slash */
+      last_slash = _mbsrchr (buf, '\\');
+      if (last_slash > buf && last_slash[1] == '\0')
+        last_slash[0] = '\0';
+      last_slash = _mbsrchr (buf, '/');
+      if (last_slash > buf && last_slash[1] == '\0')
+        last_slash[0] = '\0';
+
+      tmpdir = buf;
     }
 
   _dbus_assert(tmpdir != NULL);
@@ -2524,32 +2051,17 @@ _dbus_delete_file (const DBusString *filename,
 
   filename_c = _dbus_string_get_const_data (filename);
 
-  if (unlink (filename_c) < 0)
+  if (_unlink (filename_c) < 0)
     {
       dbus_set_error (error, DBUS_ERROR_FAILED,
                       "Failed to delete file %s: %s\n",
-                      filename_c, _dbus_strerror (errno));
+                      filename_c, strerror (errno));
       return FALSE;
     }
   else
     return TRUE;
 }
 
-/**
- * Generates the given number of random bytes,
- * using the best mechanism we can come up with.
- *
- * @param str the string
- * @param n_bytes the number of random bytes to append to string
- * @returns #TRUE on success, #FALSE if no memory
- */
-dbus_bool_t
-_dbus_generate_random_bytes (DBusString *str,
-                             int         n_bytes)
-{
-  return pseudorandom_generate_random_bytes (str, n_bytes);
-}
-
 #if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_BUILD_TESTS)
 
 #ifdef _MSC_VER
@@ -2938,7 +2450,7 @@ void _dbus_global_unlock (HANDLE mutex)
 // for proper cleanup in dbus-daemon
 static HANDLE hDBusDaemonMutex = NULL;
 static HANDLE hDBusSharedMem = NULL;
-// sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs
+// sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
 static const char *cUniqueDBusInitMutex = "UniqueDBusInitMutex";
 // sync _dbus_get_autolaunch_address
 static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex";
@@ -2951,60 +2463,49 @@ static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfoDebug";
 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
 #endif
 
+
 void
-_dbus_daemon_init(const char *host, dbus_uint32_t port)
+_dbus_daemon_publish_session_bus_address (const char* address)
 {
   HANDLE lock;
-  char *adr = NULL;
-  char szUserName[64];
-  DWORD dwUserNameSize = sizeof(szUserName);
-  char szDBusDaemonMutex[128];
-  char szDBusDaemonAddressInfo[128];
-  char szAddress[128];
+  char *shared_addr = NULL;
   DWORD ret;
 
-  _dbus_assert(host);
-  _dbus_assert(port);
-
-  _snprintf(szAddress, sizeof(szAddress) - 1, "tcp:host=%s,port=%d", host, port);
-  ret = GetUserName(szUserName, &dwUserNameSize);
-  _dbus_assert(ret != 0);
-  _snprintf(szDBusDaemonMutex, sizeof(szDBusDaemonMutex) - 1, "%s:%s",
-            cDBusDaemonMutex, szUserName);
-  _snprintf(szDBusDaemonAddressInfo, sizeof(szDBusDaemonAddressInfo) - 1, "%s:%s",
-            cDBusDaemonAddressInfo, szUserName);
-
+  _dbus_assert (address);
   // before _dbus_global_lock to keep correct lock/release order
-  hDBusDaemonMutex = CreateMutex( NULL, FALSE, szDBusDaemonMutex );
+  hDBusDaemonMutex = CreateMutex( NULL, FALSE, cDBusDaemonMutex );
   ret = WaitForSingleObject( hDBusDaemonMutex, 1000 );
-  _dbus_assert(ret == WAIT_OBJECT_0);
+  if ( ret != WAIT_OBJECT_0 ) {
+    _dbus_warn("Could not lock mutex %s (return code %d). daemon already running? Bus address not published.\n", cDBusDaemonMutex, ret );
+    return;
+  }
 
-  // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs
+  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
   lock = _dbus_global_lock( cUniqueDBusInitMutex );
 
   // create shm
   hDBusSharedMem = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
-                                      0, strlen( szAddress ) + 1, szDBusDaemonAddressInfo );
+                                      0, strlen( address ) + 1, cDBusDaemonAddressInfo );
   _dbus_assert( hDBusSharedMem );
 
-  adr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
+  shared_addr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
 
-  _dbus_assert( adr );
+  _dbus_assert (shared_addr);
 
-  strcpy( adr, szAddress);
+  strcpy( shared_addr, address);
 
   // cleanup
-  UnmapViewOfFile( adr );
+  UnmapViewOfFile( shared_addr );
 
   _dbus_global_unlock( lock );
 }
 
 void
-_dbus_daemon_release()
+_dbus_daemon_unpublish_session_bus_address (void)
 {
   HANDLE lock;
 
-  // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs
+  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
   lock = _dbus_global_lock( cUniqueDBusInitMutex );
 
   CloseHandle( hDBusSharedMem );
@@ -3021,24 +2522,16 @@ _dbus_daemon_release()
 }
 
 static dbus_bool_t
-_dbus_get_autolaunch_shm(DBusString *adress)
+_dbus_get_autolaunch_shm (DBusString *address)
 {
   HANDLE sharedMem;
-  char *adr;
-  char szUserName[64];
-  DWORD dwUserNameSize = sizeof(szUserName);
-  char szDBusDaemonAddressInfo[128];
+  char *shared_addr;
   int i;
 
-  if( !GetUserName(szUserName, &dwUserNameSize) )
-      return FALSE;
-  _snprintf(szDBusDaemonAddressInfo, sizeof(szDBusDaemonAddressInfo) - 1, "%s:%s",
-            cDBusDaemonAddressInfo, szUserName);
-
   // read shm
   for(i=0;i<20;++i) {
       // we know that dbus-daemon is available, so we wait until shm is available
-      sharedMem = OpenFileMapping( FILE_MAP_READ, FALSE, szDBusDaemonAddressInfo );
+      sharedMem = OpenFileMapping( FILE_MAP_READ, FALSE, cDBusDaemonAddressInfo );
       if( sharedMem == 0 )
           Sleep( 100 );
       if ( sharedMem != 0)
@@ -3048,17 +2541,17 @@ _dbus_get_autolaunch_shm(DBusString *adress)
   if( sharedMem == 0 )
       return FALSE;
 
-  adr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
+  shared_addr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
 
-  if( adr == 0 )
+  if( !shared_addr )
       return FALSE;
 
-  _dbus_string_init( adress );
+  _dbus_string_init( address );
 
-  _dbus_string_append( adress, adr ); 
+  _dbus_string_append( address, shared_addr );
 
   // cleanup
-  UnmapViewOfFile( adr );
+  UnmapViewOfFile( shared_addr );
 
   CloseHandle( sharedMem );
 
@@ -3066,25 +2559,17 @@ _dbus_get_autolaunch_shm(DBusString *adress)
 }
 
 static dbus_bool_t
-_dbus_daemon_already_runs (DBusString *adress)
+_dbus_daemon_already_runs (DBusString *address)
 {
   HANDLE lock;
   HANDLE daemon;
   dbus_bool_t bRet = TRUE;
-  char szUserName[64];
-  DWORD dwUserNameSize = sizeof(szUserName);
-  char szDBusDaemonMutex[128];
 
-  // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs
+  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
   lock = _dbus_global_lock( cUniqueDBusInitMutex );
 
-  if( !GetUserName(szUserName, &dwUserNameSize) )
-      return FALSE;
-  _snprintf(szDBusDaemonMutex, sizeof(szDBusDaemonMutex) - 1, "%s:%s",
-            cDBusDaemonMutex, szUserName);
-
   // do checks
-  daemon = CreateMutex( NULL, FALSE, szDBusDaemonMutex );
+  daemon = CreateMutex( NULL, FALSE, cDBusDaemonMutex );
   if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT)
     {
       ReleaseMutex (daemon);
@@ -3095,7 +2580,7 @@ _dbus_daemon_already_runs (DBusString *adress)
     }
 
   // read shm
-  bRet = _dbus_get_autolaunch_shm( adress );
+  bRet = _dbus_get_autolaunch_shm( address );
 
   // cleanup
   CloseHandle ( daemon );
@@ -3116,11 +2601,7 @@ _dbus_get_autolaunch_address (DBusString *address,
   LPSTR lpFile;
   char dbus_exe_path[MAX_PATH];
   char dbus_args[MAX_PATH * 2];
-#ifdef _DEBUG
-  const char * daemon_name = "dbus-daemond.exe";
-#else
-  const char * daemon_name = "dbus-daemon.exe";
-#endif
+  const char * daemon_name = DBUS_DAEMON_NAME ".exe";
 
   mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
 
@@ -3152,7 +2633,8 @@ _dbus_get_autolaunch_address (DBusString *address,
 //  printf("create process \"%s\" %s\n", dbus_exe_path, dbus_args);
   if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
     {
-
+      CloseHandle (pi.hThread);
+      CloseHandle (pi.hProcess);
       retval = _dbus_get_autolaunch_shm( address );
     }
   
@@ -3310,12 +2792,6 @@ _dbus_atomic_dec (DBusAtomic *atomic)
 void
 _dbus_flush_caches (void)
 {
-
-}
-
-dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid)
-{
-    return TRUE;
 }
 
 /**
@@ -3327,7 +2803,7 @@ dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid)
 dbus_bool_t
 _dbus_get_is_errno_eagain_or_ewouldblock (void)
 {
-  return errno == EAGAIN || errno == EWOULDBLOCK;
+  return errno == WSAEWOULDBLOCK;
 }
 
 /**
@@ -3337,27 +2813,42 @@ _dbus_get_is_errno_eagain_or_ewouldblock (void)
  * @param len length of buffer
  * @returns #FALSE on failure
  */
-dbus_bool_t 
-_dbus_get_install_root(char *s, int len)
-{
-  char *p = NULL;
-  int ret = GetModuleFileName(NULL,s,len);
-  if ( ret == 0 
-    || ret == len && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
-    {
-      *s = '\0';
-      return FALSE;
-    }
-  else if ((p = strstr(s,"\\bin\\")))
-    {
-      *(p+1)= '\0';
-      return TRUE;
+static dbus_bool_t
+_dbus_get_install_root(char *prefix, int len)
+{
+    //To find the prefix, we cut the filename and also \bin\ if present
+    char* p = 0;
+    int i;
+    DWORD pathLength;
+    char *lastSlash;
+    SetLastError( 0 );
+    pathLength = GetModuleFileName(_dbus_win_get_dll_hmodule(), prefix, len);
+    if ( pathLength == 0 || GetLastError() != 0 ) {
+        *prefix = '\0';
+        return FALSE;
     }
-  else
-    {
-      *s = '\0';
-      return FALSE;
+    lastSlash = _mbsrchr(prefix, '\\');
+    if (lastSlash == NULL) {
+        *prefix = '\0';
+        return FALSE;
     }
+    //cut off binary name
+    lastSlash[1] = 0;
+
+    //cut possible "\\bin"
+
+    //this fails if we are in a double-byte system codepage and the
+    //folder's name happens to end with the *bytes*
+    //"\\bin"... (I.e. the second byte of some Han character and then
+    //the Latin "bin", but that is not likely I think...
+    if (lastSlash - prefix >= 4 && strnicmp(lastSlash - 4, "\\bin", 4) == 0)
+        lastSlash[-3] = 0;
+    else if (lastSlash - prefix >= 10 && strnicmp(lastSlash - 10, "\\bin\\debug", 10) == 0)
+        lastSlash[-9] = 0;
+    else if (lastSlash - prefix >= 12 && strnicmp(lastSlash - 12, "\\bin\\release", 12) == 0)
+        lastSlash[-11] = 0;
+
+    return TRUE;
 }
 
 /** 
@@ -3365,7 +2856,9 @@ _dbus_get_install_root(char *s, int len)
   the following path layout 
     install-root/
       bin/dbus-daemon[d].exe
-      etc/<config-file>.conf 
+      etc/<config-file>.conf *or* etc/dbus-1/<config-file>.conf
+      (the former above is what dbus4win uses, the latter above is
+      what a "normal" Unix-style "make install" uses)
 
     build-root/
       bin/dbus-daemon[d].exe
@@ -3376,12 +2869,11 @@ _dbus_get_config_file_name(DBusString *config_file, char *s)
 {
   char path[MAX_PATH*2];
   int path_size = sizeof(path);
-  int len = 4 + strlen(s);
 
   if (!_dbus_get_install_root(path,path_size))
     return FALSE;
 
-  if(len > sizeof(path)-2)
+  if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
     return FALSE;
   strcat(path,"etc\\");
   strcat(path,s);
@@ -3395,9 +2887,9 @@ _dbus_get_config_file_name(DBusString *config_file, char *s)
     {
       if (!_dbus_get_install_root(path,path_size))
         return FALSE;
-      if(len + strlen(path) > sizeof(path)-2)
+      if(strlen(s) + 11 + strlen(path) > sizeof(path)-2)
         return FALSE;
-      strcat(path,"bus\\");
+      strcat(path,"etc\\dbus-1\\");
       strcat(path,s);
   
       if (_dbus_file_exists(path)) 
@@ -3405,6 +2897,21 @@ _dbus_get_config_file_name(DBusString *config_file, char *s)
           if (!_dbus_string_append (config_file, path))
             return FALSE;
         }
+      else
+        {
+          if (!_dbus_get_install_root(path,path_size))
+            return FALSE;
+          if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
+            return FALSE;
+          strcat(path,"bus\\");
+          strcat(path,s);
+          
+          if (_dbus_file_exists(path)) 
+            {
+              if (!_dbus_string_append (config_file, path))
+                return FALSE;
+            }
+        }
     }
   return TRUE;
 }    
@@ -3467,6 +2974,7 @@ _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
   DBusString dotdir;
   dbus_uid_t uid;
   const char *homepath;
+  const char *homedrive;
 
   _dbus_assert (credentials != NULL);
   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
@@ -3474,6 +2982,12 @@ _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
   if (!_dbus_string_init (&homedir))
     return FALSE;
 
+  homedrive = _dbus_getenv("HOMEDRIVE");
+  if (homedrive != NULL && *homedrive != '\0')
+    {
+      _dbus_string_append(&homedir,homedrive);
+    }
+
   homepath = _dbus_getenv("HOMEPATH");
   if (homepath != NULL && *homepath != '\0')
     {
@@ -3524,6 +3038,232 @@ _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
   return FALSE;
 }
 
+/** Checks if a file exists
+*
+* @param file full path to the file
+* @returns #TRUE if file exists
+*/
+dbus_bool_t 
+_dbus_file_exists (const char *file)
+{
+  DWORD attributes = GetFileAttributes (file);
+
+  if (attributes != INVALID_FILE_ATTRIBUTES && GetLastError() != ERROR_PATH_NOT_FOUND)
+    return TRUE;
+  else
+    return FALSE;  
+}
+
+/**
+ * A wrapper around strerror() because some platforms
+ * may be lame and not have strerror().
+ *
+ * @param error_number errno.
+ * @returns error description.
+ */
+const char*
+_dbus_strerror (int error_number)
+{
+#ifdef DBUS_WINCE
+  // TODO
+  return "unknown";
+#else
+  const char *msg;
+
+  switch (error_number)
+    {
+    case WSAEINTR:
+      return "Interrupted function call";
+    case WSAEACCES:
+      return "Permission denied";
+    case WSAEFAULT:
+      return "Bad address";
+    case WSAEINVAL:
+      return "Invalid argument";
+    case WSAEMFILE:
+      return "Too many open files";
+    case WSAEWOULDBLOCK:
+      return "Resource temporarily unavailable";
+    case WSAEINPROGRESS:
+      return "Operation now in progress";
+    case WSAEALREADY:
+      return "Operation already in progress";
+    case WSAENOTSOCK:
+      return "Socket operation on nonsocket";
+    case WSAEDESTADDRREQ:
+      return "Destination address required";
+    case WSAEMSGSIZE:
+      return "Message too long";
+    case WSAEPROTOTYPE:
+      return "Protocol wrong type for socket";
+    case WSAENOPROTOOPT:
+      return "Bad protocol option";
+    case WSAEPROTONOSUPPORT:
+      return "Protocol not supported";
+    case WSAESOCKTNOSUPPORT:
+      return "Socket type not supported";
+    case WSAEOPNOTSUPP:
+      return "Operation not supported";
+    case WSAEPFNOSUPPORT:
+      return "Protocol family not supported";
+    case WSAEAFNOSUPPORT:
+      return "Address family not supported by protocol family";
+    case WSAEADDRINUSE:
+      return "Address already in use";
+    case WSAEADDRNOTAVAIL:
+      return "Cannot assign requested address";
+    case WSAENETDOWN:
+      return "Network is down";
+    case WSAENETUNREACH:
+      return "Network is unreachable";
+    case WSAENETRESET:
+      return "Network dropped connection on reset";
+    case WSAECONNABORTED:
+      return "Software caused connection abort";
+    case WSAECONNRESET:
+      return "Connection reset by peer";
+    case WSAENOBUFS:
+      return "No buffer space available";
+    case WSAEISCONN:
+      return "Socket is already connected";
+    case WSAENOTCONN:
+      return "Socket is not connected";
+    case WSAESHUTDOWN:
+      return "Cannot send after socket shutdown";
+    case WSAETIMEDOUT:
+      return "Connection timed out";
+    case WSAECONNREFUSED:
+      return "Connection refused";
+    case WSAEHOSTDOWN:
+      return "Host is down";
+    case WSAEHOSTUNREACH:
+      return "No route to host";
+    case WSAEPROCLIM:
+      return "Too many processes";
+    case WSAEDISCON:
+      return "Graceful shutdown in progress";
+    case WSATYPE_NOT_FOUND:
+      return "Class type not found";
+    case WSAHOST_NOT_FOUND:
+      return "Host not found";
+    case WSATRY_AGAIN:
+      return "Nonauthoritative host not found";
+    case WSANO_RECOVERY:
+      return "This is a nonrecoverable error";
+    case WSANO_DATA:
+      return "Valid name, no data record of requested type";
+    case WSA_INVALID_HANDLE:
+      return "Specified event object handle is invalid";
+    case WSA_INVALID_PARAMETER:
+      return "One or more parameters are invalid";
+    case WSA_IO_INCOMPLETE:
+      return "Overlapped I/O event object not in signaled state";
+    case WSA_IO_PENDING:
+      return "Overlapped operations will complete later";
+    case WSA_NOT_ENOUGH_MEMORY:
+      return "Insufficient memory available";
+    case WSA_OPERATION_ABORTED:
+      return "Overlapped operation aborted";
+#ifdef WSAINVALIDPROCTABLE
+
+    case WSAINVALIDPROCTABLE:
+      return "Invalid procedure table from service provider";
+#endif
+#ifdef WSAINVALIDPROVIDER
+
+    case WSAINVALIDPROVIDER:
+      return "Invalid service provider version number";
+#endif
+#ifdef WSAPROVIDERFAILEDINIT
+
+    case WSAPROVIDERFAILEDINIT:
+      return "Unable to initialize a service provider";
+#endif
+
+    case WSASYSCALLFAILURE:
+      return "System call failure";
+    }
+  msg = strerror (error_number);
+  if (msg == NULL)
+    msg = "unknown";
+
+  return msg;
+#endif //DBUS_WINCE
+}
+
+/**
+ * Assigns an error name and message corresponding to a Win32 error
+ * code to a DBusError. Does nothing if error is #NULL.
+ *
+ * @param error the error.
+ * @param code the Win32 error code
+ */
+void
+_dbus_win_set_error_from_win_error (DBusError *error,
+                                    int        code)
+{
+  char *msg;
+
+  /* As we want the English message, use the A API */
+  FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                  FORMAT_MESSAGE_IGNORE_INSERTS |
+                  FORMAT_MESSAGE_FROM_SYSTEM,
+                  NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
+                  (LPTSTR) &msg, 0, NULL);
+  if (msg)
+    {
+      char *msg_copy;
+
+      msg_copy = dbus_malloc (strlen (msg));
+      strcpy (msg_copy, msg);
+      LocalFree (msg);
+
+      dbus_set_error (error, "win32.error", "%s", msg_copy);
+    }
+  else
+    dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code);
+}
+
+void
+_dbus_win_warn_win_error (const char *message,
+                          int         code)
+{
+  DBusError error;
+
+  dbus_error_init (&error);
+  _dbus_win_set_error_from_win_error (&error, code);
+  _dbus_warn ("%s: %s\n", message, error.message);
+  dbus_error_free (&error);
+}
+
+/**
+ * Removes a directory; Directory must be empty
+ *
+ * @param filename directory filename
+ * @param error initialized error object
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+_dbus_delete_directory (const DBusString *filename,
+                        DBusError        *error)
+{
+  const char *filename_c;
+
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+  filename_c = _dbus_string_get_const_data (filename);
+
+  if (_rmdir (filename_c) != 0)
+    {
+      dbus_set_error (error, DBUS_ERROR_FAILED,
+                      "Failed to remove directory %s: %s\n",
+                      filename_c, strerror (errno));
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
 /** @} end of sysdeps-win */
 /* tests in dbus-sysdeps-util.c */