dbus/dbus-sysdeps-*win.c: remove DBusFile abstraction (cherry picked from commit...
[platform/upstream/dbus.git] / dbus / dbus-sysdeps-win.c
index 98bf4c9..b8adeba 100644 (file)
@@ -31,7 +31,9 @@
 #define STRSAFE_NO_DEPRECATE
 
 #ifndef DBUS_WINCE
-#define _WIN32_WINNT 0x0500
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501
+#endif
 #endif
 
 #include "dbus-internals.h"
 #include "dbus-credentials.h"
 
 #include <windows.h>
+#include <ws2tcpip.h>
 #include <fcntl.h>
 
 #include <process.h>
+#include <stdio.h>
+#include <io.h>
+
+#include <string.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;
-    }
-}
-
-int
-_dbus_file_write (DBusFile         *file,
-                  const DBusString *buffer,
-                  int               start,
-                  int               len)
-{
-  const int fd = file->FDATA;
-  const char *data;
-  int bytes_written;
-
-  data = _dbus_string_get_const_data_len (buffer, start, len);
-
-  _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;
-}
-
-dbus_bool_t _dbus_fstat (DBusFile    *file,
-                         struct stat *sb)
-{
-  return fstat(file->FDATA, sb) >= 0;
-}
+typedef int socklen_t;
 
 /**
  * write data to a pipe.
@@ -231,14 +95,14 @@ _dbus_pipe_write (DBusPipe         *pipe,
                   DBusError        *error)
 {
   int written;
-  DBusFile file;
-  file.FDATA = pipe->fd_or_handle;
-  written = _dbus_file_write (&file, buffer, start, len);
+  const char *buffer_c = _dbus_string_get_const_data (buffer);
+
+  written = _write (pipe->fd_or_handle, buffer_c + start, len);
   if (written < 0)
     {
       dbus_set_error (error, DBUS_ERROR_FAILED,
                       "Writing to pipe: %s\n",
-                      _dbus_strerror (errno));
+                      strerror (errno));
     }
   return written;
 }
@@ -254,9 +118,9 @@ int
 _dbus_pipe_close  (DBusPipe         *pipe,
                    DBusError        *error)
 {
-  DBusFile file;
-  file.FDATA = pipe->fd_or_handle;
-  if (_dbus_file_close (&file, error) < 0)
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+  if (_close (pipe->fd_or_handle) < 0)
     {
       return -1;
     }
@@ -267,8 +131,6 @@ _dbus_pipe_close  (DBusPipe         *pipe,
     }
 }
 
-#undef FDATA
-
 /**
  * Socket interface
  *
@@ -523,7 +385,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);
@@ -654,23 +515,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;
 }
 
@@ -849,15 +711,6 @@ _dbus_getuid (void)
        return DBUS_UID_UNSET;
 }
 
-/** Gets our effective UID
- * @returns process effective UID
- */
-dbus_uid_t
-_dbus_geteuid (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.
@@ -1210,7 +1063,7 @@ _dbus_poll (DBusPollFD *fds,
     {
       DBUS_SOCKET_SET_ERRNO ();
       if (errno != EWOULDBLOCK)
-        _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", _dbus_strerror (errno));
+        _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", strerror (errno));
       ret = -1;
     }
   else if (ready == WSA_WAIT_TIMEOUT)
@@ -1438,17 +1291,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
@@ -1464,21 +1306,21 @@ _dbus_exit (int code)
  * and port. The connection fd is returned, and is set up as
  * nonblocking.
  *
- * @param host the host name to connect to, NULL for loopback
- * @param port the prot to connect to
+ * @param host the host name to connect to
+ * @param port the port to connect to
+ * @param family the address family to listen on, NULL for all
  * @param error return location for error code
  * @returns connection file descriptor or -1 on error
  */
 int
 _dbus_connect_tcp_socket (const char     *host,
-                          dbus_uint32_t   port,
+                          const char     *port,
+                          const char     *family,
                           DBusError      *error)
 {
-  int fd;
-  struct sockaddr_in addr;
-  struct hostent *he;
-  struct in_addr *haddr;
-  struct in_addr ina;
+  int fd = -1, res;
+  struct addrinfo hints;
+  struct addrinfo *ai, *tmp;
 
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
@@ -1497,50 +1339,80 @@ _dbus_connect_tcp_socket (const char     *host,
       return -1;
     }
 
-  if (host == NULL)
+  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
+
+  _DBUS_ZERO (hints);
+
+  if (!family)
+    hints.ai_family = AF_UNSPEC;
+  else if (!strcmp(family, "ipv4"))
+    hints.ai_family = AF_INET;
+  else if (!strcmp(family, "ipv6"))
+    hints.ai_family = AF_INET6;
+  else
     {
-      host = "localhost";
-      ina.s_addr = htonl (INADDR_LOOPBACK);
-      haddr = &ina;
+      dbus_set_error (error,
+                      _dbus_error_from_errno (errno),
+                      "Unknown address family %s", family);
+      return -1;
     }
+  hints.ai_protocol = IPPROTO_TCP;
+  hints.ai_socktype = SOCK_STREAM;
+#ifdef AI_ADDRCONFIG
+  hints.ai_flags = AI_ADDRCONFIG;
+#else
+  hints.ai_flags = 0;
+#endif
 
-  he = gethostbyname (host);
-  if (he == NULL)
+  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
     {
-      DBUS_SOCKET_SET_ERRNO ();
       dbus_set_error (error,
                       _dbus_error_from_errno (errno),
-                      "Failed to lookup hostname: %s",
-                      host);
-      DBUS_CLOSE_SOCKET (fd);
+                      "Failed to lookup host/port: \"%s:%s\": %s (%d)",
+                      host, port, gai_strerror(res), res);
+      closesocket (fd);
       return -1;
     }
 
-  haddr = ((struct in_addr *) (he->h_addr_list)[0]);
-
-  _DBUS_ZERO (addr);
-  memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr));
-  addr.sin_family = AF_INET;
-  addr.sin_port = htons (port);
-
-  if (DBUS_SOCKET_API_RETURNS_ERROR
-      (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0))
+  tmp = ai;
+  while (tmp)
     {
-      DBUS_SOCKET_SET_ERRNO ();
+      if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) < 0)
+        {
+          freeaddrinfo(ai);
       dbus_set_error (error,
                       _dbus_error_from_errno (errno),
-                      "Failed to connect to socket %s:%d %s",
-                      host, port, _dbus_strerror (errno));
+                         "Failed to open socket: %s",
+                         _dbus_strerror (errno));
+          return -1;
+        }
+      _DBUS_ASSERT_ERROR_IS_CLEAR(error);
 
-      DBUS_CLOSE_SOCKET (fd);
+      if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
+        {
+          closesocket(fd);
       fd = -1;
+          tmp = tmp->ai_next;
+          continue;
+        }
+
+      break;
+    }
+  freeaddrinfo(ai);
 
+  if (fd == -1)
+    {
+      dbus_set_error (error,
+                      _dbus_error_from_errno (errno),
+                      "Failed to connect to socket \"%s:%s\" %s",
+                      host, port, _dbus_strerror(errno));
       return -1;
     }
 
+
   if (!_dbus_set_fd_nonblocking (fd, error))
     {
-      _dbus_close_socket (fd, NULL);
+      closesocket (fd);
       fd = -1;
 
       return -1;
@@ -1549,114 +1421,198 @@ _dbus_connect_tcp_socket (const char     *host,
   return fd;
 }
 
+
 void
 _dbus_daemon_init(const char *host, dbus_uint32_t port);
+
 /**
- * Creates a socket and binds it to the given port,
- * then listens on the socket. The socket is
- * set to be nonblocking. 
- * In case of port=0 a random free port is used and 
- * returned in the port parameter. 
+ * 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
+ * a random free port is used and returned in the port parameter.
+ * If inaddr_any is specified, the hostname is ignored.
  *
- * @param host the interface to listen on, NULL for loopback, empty for any
+ * @param host the host name to listen on
  * @param port the port to listen on, if zero a free port will be used 
+ * @param family the address family to listen on, NULL for all
+ * @param retport string to return the actual port listened on
+ * @param fds_p location to store returned file descriptors
  * @param error return location for errors
- * @returns the listening file descriptor or -1 on error
+ * @returns the number of listening file descriptors or -1 on error
  */
 
 int
 _dbus_listen_tcp_socket (const char     *host,
-                         dbus_uint32_t  *port,
-                         dbus_bool_t     inaddr_any,
+                         const char     *port,
+                         const char     *family,
+                         DBusString     *retport,
+                         int           **fds_p,
                          DBusError      *error)
 {
-  int fd;
-  struct sockaddr_in addr;
-  struct hostent *he;
-  struct in_addr *haddr;
-  socklen_t len = (socklen_t) sizeof (struct sockaddr);
-  struct in_addr ina;
-
+  int nlisten_fd = 0, *listen_fd = NULL, res, i, port_num = -1;
+  struct addrinfo hints;
+  struct addrinfo *ai, *tmp;
 
+  *fds_p = NULL;
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
   _dbus_win_startup_winsock ();
 
-  fd = socket (AF_INET, SOCK_STREAM, 0);
+  _DBUS_ZERO (hints);
 
-  if (DBUS_SOCKET_IS_INVALID (fd))
+  if (!family)
+    hints.ai_family = AF_UNSPEC;
+  else if (!strcmp(family, "ipv4"))
+    hints.ai_family = AF_INET;
+  else if (!strcmp(family, "ipv6"))
+    hints.ai_family = AF_INET6;
+  else
     {
-      DBUS_SOCKET_SET_ERRNO ();
-      dbus_set_error (error, _dbus_error_from_errno (errno),
-                      "Failed to create socket \"%s:%d\": %s",
-                      host, port, _dbus_strerror (errno));
+      dbus_set_error (error,
+                      _dbus_error_from_errno (errno),
+                      "Unknown address family %s", family);
       return -1;
     }
-  if (host == NULL)
-    {
-      host = "localhost";
-      ina.s_addr = htonl (INADDR_LOOPBACK);
-      haddr = &ina;
-    }
-  else if (!host[0])
+
+  hints.ai_protocol = IPPROTO_TCP;
+  hints.ai_socktype = SOCK_STREAM;
+#ifdef AI_ADDRCONFIG
+  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
+#else
+  hints.ai_flags = AI_PASSIVE;
+#endif
+
+ redo_lookup_with_port:
+  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
     {
-      ina.s_addr = htonl (INADDR_ANY);
-      haddr = &ina;
+      dbus_set_error (error,
+                      _dbus_error_from_errno (errno),
+                      "Failed to lookup host/port: \"%s:%s\": %s (%d)",
+                      host ? host : "*", port, gai_strerror(res), res);
+      return -1;
     }
-  else
+
+  tmp = ai;
+  while (tmp)
     {
-      he = gethostbyname (host);
-      if (he == NULL)
+      int fd = -1, *newlisten_fd;
+      if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) < 0)
         {
-          DBUS_SOCKET_SET_ERRNO ();
           dbus_set_error (error,
                           _dbus_error_from_errno (errno),
-                          "Failed to lookup hostname: %s",
-                          host);
-          DBUS_CLOSE_SOCKET (fd);
-          return -1;
+                         "Failed to open socket: %s",
+                         _dbus_strerror (errno));
+          goto failed;
         }
+      _DBUS_ASSERT_ERROR_IS_CLEAR(error);
 
-      haddr = ((struct in_addr *) (he->h_addr_list)[0]);
+      if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
+        {
+          closesocket (fd);
+          dbus_set_error (error, _dbus_error_from_errno (errno),
+                          "Failed to bind socket \"%s:%s\": %s",
+                          host ? host : "*", port, _dbus_strerror (errno));
+          goto failed;
     }
 
-  _DBUS_ZERO (addr);
-  memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
-  addr.sin_family = AF_INET;
-  addr.sin_port = htons (*port);
+      if (listen (fd, 30 /* backlog */) == SOCKET_ERROR)
+        {
+          closesocket (fd);
+          dbus_set_error (error, _dbus_error_from_errno (errno),
+                          "Failed to listen on socket \"%s:%s\": %s",
+                          host ? host : "*", port, _dbus_strerror (errno));
+          goto failed;
+        }
 
-  if (bind (fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
+      newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
+      if (!newlisten_fd)
     {
-      DBUS_SOCKET_SET_ERRNO ();
+          closesocket (fd);
       dbus_set_error (error, _dbus_error_from_errno (errno),
-                      "Failed to bind socket \"%s:%d\": %s",
-                      host, *port, _dbus_strerror (errno));
-      DBUS_CLOSE_SOCKET (fd);
-      return -1;
+                          "Failed to allocate file handle array: %s",
+                          _dbus_strerror (errno));
+          goto failed;
     }
+      listen_fd = newlisten_fd;
+      listen_fd[nlisten_fd] = fd;
+      nlisten_fd++;
 
-  if (DBUS_SOCKET_API_RETURNS_ERROR (listen (fd, 30 /* backlog */)))
+      if (!_dbus_string_get_length(retport))
+        {
+          /* If the user didn't specify a port, or used 0, then
+             the kernel chooses a port. After the first address
+             is bound to, we need to force all remaining addresses
+             to use the same port */
+          if (!port || !strcmp(port, "0"))
+            {
+              sockaddr_gen addr;
+              socklen_t addrlen = sizeof(addr);
+              char portbuf[10];
+
+              if ((res = getsockname(fd, &addr.Address, &addrlen)) != 0)
     {
-      DBUS_SOCKET_SET_ERRNO ();
       dbus_set_error (error, _dbus_error_from_errno (errno),
-                      "Failed to listen on socket \"%s:%d\": %s",
-                      host, *port, _dbus_strerror (errno));
-      DBUS_CLOSE_SOCKET (fd);
+                                  "Failed to resolve port \"%s:%s\": %s (%d)",
+                                  host ? host : "*", port, gai_strerror(res), res);
+                  goto failed;
+                }
+              snprintf( portbuf, sizeof( portbuf ) - 1, "%d", addr.AddressIn.sin_port );
+              if (!_dbus_string_append(retport, portbuf))
+                {
+                  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+                  goto failed;
+    }
+
+              /* Release current address list & redo lookup */
+              port = _dbus_string_get_const_data(retport);
+              freeaddrinfo(ai);
+              goto redo_lookup_with_port;
+            }
+          else
+            {
+              if (!_dbus_string_append(retport, port))
+                {
+                    dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+                    goto failed;
+                }
+            }
+        }
+  
+      tmp = tmp->ai_next;
+    }
+  freeaddrinfo(ai);
+  ai = NULL;
+
+  if (!nlisten_fd)
+    {
+      errno = WSAEADDRINUSE;
+      dbus_set_error (error, _dbus_error_from_errno (errno),
+                      "Failed to bind socket \"%s:%s\": %s",
+                      host ? host : "*", port, _dbus_strerror (errno));
       return -1;
     }
 
-  getsockname(fd, (struct sockaddr*) &addr, &len);
-  *port = (dbus_uint32_t) ntohs(addr.sin_port);
-  
-  _dbus_daemon_init(host, ntohs(addr.sin_port));
+  sscanf(_dbus_string_get_const_data(retport), "%d", &port_num);
+  _dbus_daemon_init(host, port_num);
 
-  if (!_dbus_set_fd_nonblocking (fd, error))
+  for (i = 0 ; i < nlisten_fd ; i++)
     {
-      _dbus_close_socket (fd, NULL);
-      return -1;
+      if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
+        {
+          goto failed;
+        }
     }
 
-  return fd;
+  *fds_p = listen_fd;
+
+  return nlisten_fd;
+
+ failed:
+  if (ai)
+    freeaddrinfo(ai);
+  for (i = 0 ; i < nlisten_fd ; i++)
+    closesocket (listen_fd[i]);
+  dbus_free(listen_fd);
+  return -1;
 }
 
 
@@ -1671,13 +1627,9 @@ int
 _dbus_accept  (int listen_fd)
 {
   int client_fd;
-  struct sockaddr addr;
-  socklen_t addrlen;
-
-  addrlen = sizeof (addr);
 
  retry:
-  client_fd = accept (listen_fd, &addr, &addrlen);
+  client_fd = accept (listen_fd, NULL, NULL);
 
   if (DBUS_SOCKET_IS_INVALID (client_fd))
     {
@@ -2004,10 +1956,61 @@ _dbus_get_current_time (long *tv_sec,
 void
 _dbus_disable_sigpipe (void)
 {
-    _dbus_verbose("FIXME: implement _dbus_disable_sigpipe (void)\n");
 }
 
 
+/* _dbus_read() is static on Windows, only used below in this file.
+ */
+static int
+_dbus_read (int               fd,
+            DBusString       *buffer,
+            int               count)
+{
+  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);
+
+ again:
+
+  bytes_read = _read (fd, data, count);
+
+  if (bytes_read < 0)
+    {
+      if (errno == EINTR)
+        goto again;
+      else
+        {
+          /* 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;
+    }
+}
+
 /**
  * Appends the contents of the given file to the string,
  * returning error code. At the moment, won't open a file
@@ -2023,8 +2026,8 @@ _dbus_file_get_contents (DBusString       *str,
                          const DBusString *filename,
                          DBusError        *error)
 {
-  DBusFile file;
-  struct stat sb;
+  int fd;
+  struct _stati64 sb;
   int orig_len;
   int total;
   const char *filename_c;
@@ -2033,27 +2036,29 @@ _dbus_file_get_contents (DBusString       *str,
 
   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))
+  fd = _open (filename_c, O_RDONLY | O_BINARY);
+  if (fd < 0)
     {
       dbus_set_error (error, _dbus_error_from_errno (errno),
                       "Failed to open \"%s\": %s",
                       filename_c,
-                      _dbus_strerror (errno));
+                      strerror (errno));
       return FALSE;
     }
 
-  if (!_dbus_fstat (&file, &sb))
+  _dbus_verbose ("file %s fd %d opened\n", filename_c, fd);
+
+  if (_fstati64 (fd, &sb) < 0)
     {
       dbus_set_error (error, _dbus_error_from_errno (errno),
                       "Failed to stat \"%s\": %s",
                       filename_c,
-                      _dbus_strerror (errno));
+                      strerror (errno));
 
       _dbus_verbose ("fstat() failed: %s",
-                     _dbus_strerror (errno));
+                     strerror (errno));
 
-      _dbus_file_close (&file, NULL);
+      _close (fd);
 
       return FALSE;
     }
@@ -2063,7 +2068,7 @@ _dbus_file_get_contents (DBusString       *str,
       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);
+      _close (fd);
       return FALSE;
     }
 
@@ -2075,19 +2080,18 @@ _dbus_file_get_contents (DBusString       *str,
 
       while (total < (int) sb.st_size)
         {
-          bytes_read = _dbus_file_read (&file, str,
-                                        sb.st_size - total);
+          bytes_read = _dbus_read (fd, 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));
+                              strerror (errno));
 
               _dbus_verbose ("read() failed: %s",
-                             _dbus_strerror (errno));
+                             strerror (errno));
 
-              _dbus_file_close (&file, NULL);
+              _close (fd);
               _dbus_string_set_length (str, orig_len);
               return FALSE;
             }
@@ -2095,7 +2099,7 @@ _dbus_file_get_contents (DBusString       *str,
             total += bytes_read;
         }
 
-      _dbus_file_close (&file, NULL);
+      _close (fd);
       return TRUE;
     }
   else if (sb.st_size != 0)
@@ -2104,12 +2108,12 @@ _dbus_file_get_contents (DBusString       *str,
       dbus_set_error (error, DBUS_ERROR_FAILED,
                       "\"%s\" is not a regular file",
                       filename_c);
-      _dbus_file_close (&file, NULL);
+      _close (fd);
       return FALSE;
     }
   else
     {
-      _dbus_file_close (&file, NULL);
+      _close (fd);
       return TRUE;
     }
 }
@@ -2128,17 +2132,19 @@ _dbus_string_save_to_file (const DBusString *str,
                            const DBusString *filename,
                            DBusError        *error)
 {
-  DBusFile file;
+  int fd;
   int bytes_to_write;
   const char *filename_c;
   DBusString tmp_filename;
   const char *tmp_filename_c;
   int total;
+  const char *str_c;
   dbus_bool_t need_unlink;
   dbus_bool_t retval;
 
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
+  fd = -1;
   retval = FALSE;
   need_unlink = FALSE;
 
@@ -2173,48 +2179,51 @@ _dbus_string_save_to_file (const DBusString *str,
   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))
+  fd = _open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
+              0600);
+  if (fd < 0)
     {
       dbus_set_error (error, _dbus_error_from_errno (errno),
                       "Could not create %s: %s", tmp_filename_c,
-                      _dbus_strerror (errno));
+                      strerror (errno));
       goto out;
     }
 
+  _dbus_verbose ("tmp file %s fd %d opened\n", tmp_filename_c, fd);
+
   need_unlink = TRUE;
 
   total = 0;
   bytes_to_write = _dbus_string_get_length (str);
+  str_c = _dbus_string_get_const_data (str);
 
   while (total < bytes_to_write)
     {
       int bytes_written;
 
-      bytes_written = _dbus_file_write (&file, str, total,
-                                        bytes_to_write - total);
+      bytes_written = _write (fd, str_c + 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));
-
+                          strerror (errno));
           goto out;
         }
 
       total += bytes_written;
     }
 
-  if (!_dbus_file_close (&file, NULL))
+  if (_close (fd) < 0)
     {
       dbus_set_error (error, _dbus_error_from_errno (errno),
                       "Could not close file %s: %s",
-                      tmp_filename_c, _dbus_strerror (errno));
+                      tmp_filename_c, strerror (errno));
 
       goto out;
     }
 
+  fd = -1;
 
   if ((unlink (filename_c) == -1 && errno != ENOENT) ||
        rename (tmp_filename_c, filename_c) < 0)
@@ -2231,17 +2240,15 @@ _dbus_string_save_to_file (const DBusString *str,
 
   retval = TRUE;
 
-out:
-  /* close first, then unlink, to prevent ".nfs34234235" garbage
-   * files
-   */
+ out:
+  /* close first, then unlink */
 
-  if (_dbus_is_valid_file(&file))
-    _dbus_file_close (&file, NULL);
+  if (fd >= 0)
+    _close (fd);
 
-  if (need_unlink && unlink (tmp_filename_c) < 0)
-    _dbus_verbose ("Failed to unlink temp file %s: %s\n",
-                   tmp_filename_c, _dbus_strerror (errno));
+  if (need_unlink && _unlink (tmp_filename_c) < 0)
+    _dbus_verbose ("failed to unlink temp file %s: %s\n",
+                   tmp_filename_c, strerror (errno));
 
   _dbus_string_free (&tmp_filename);
 
@@ -2262,31 +2269,34 @@ dbus_bool_t
 _dbus_create_file_exclusively (const DBusString *filename,
                                DBusError        *error)
 {
-  DBusFile file;
+  int fd;
   const char *filename_c;
 
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
   filename_c = _dbus_string_get_const_data (filename);
 
-  if (!_dbus_file_open (&file, filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
-                        0600))
+  fd = _open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
+              0600);
+  if (fd < 0)
     {
       dbus_set_error (error,
                       DBUS_ERROR_FAILED,
                       "Could not create file %s: %s\n",
                       filename_c,
-                      _dbus_strerror (errno));
+                      strerror (errno));
       return FALSE;
     }
 
-  if (!_dbus_file_close (&file, NULL))
+  _dbus_verbose ("exclusive file %s fd %d opened\n", filename_c, fd);
+
+  if (_close (fd) < 0)
     {
       dbus_set_error (error,
                       DBUS_ERROR_FAILED,
                       "Could not close file %s: %s\n",
                       filename_c,
-                      _dbus_strerror (errno));
+                      strerror (errno));
       return FALSE;
     }
 
@@ -2312,14 +2322,14 @@ _dbus_create_directory (const DBusString *filename,
 
   filename_c = _dbus_string_get_const_data (filename);
 
-  if (_dbus_mkdir (filename_c, 0700) < 0)
+  if (!CreateDirectory (filename_c, NULL))
     {
-      if (errno == EEXIST)
+      if (GetLastError () == ERROR_ALREADY_EXISTS)
         return TRUE;
 
       dbus_set_error (error, DBUS_ERROR_FAILED,
                       "Failed to create directory %s: %s\n",
-                      filename_c, _dbus_strerror (errno));
+                      filename_c, strerror (errno));
       return FALSE;
     }
   else
@@ -2422,11 +2432,11 @@ _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
@@ -2843,25 +2853,30 @@ static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex";
 // mutex to determine if dbus-daemon is already started (per user)
 static const char *cDBusDaemonMutex = "DBusDaemonMutex";
 // named shm for dbus adress info (per user)
+#ifdef _DEBUG
+static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfoDebug";
+#else
 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
+#endif
 
 void
 _dbus_daemon_init(const char *host, dbus_uint32_t port)
 {
   HANDLE lock;
-  const char *adr = NULL;
+  char *adr = NULL;
   char szUserName[64];
   DWORD dwUserNameSize = sizeof(szUserName);
   char szDBusDaemonMutex[128];
   char szDBusDaemonAddressInfo[128];
   char szAddress[128];
+  DWORD ret;
 
   _dbus_assert(host);
   _dbus_assert(port);
 
   _snprintf(szAddress, sizeof(szAddress) - 1, "tcp:host=%s,port=%d", host, port);
-
-  _dbus_assert( GetUserName(szUserName, &dwUserNameSize) != 0);
+  ret = GetUserName(szUserName, &dwUserNameSize);
+  _dbus_assert(ret != 0);
   _snprintf(szDBusDaemonMutex, sizeof(szDBusDaemonMutex) - 1, "%s:%s",
             cDBusDaemonMutex, szUserName);
   _snprintf(szDBusDaemonAddressInfo, sizeof(szDBusDaemonAddressInfo) - 1, "%s:%s",
@@ -2869,8 +2884,11 @@ _dbus_daemon_init(const char *host, dbus_uint32_t port)
 
   // before _dbus_global_lock to keep correct lock/release order
   hDBusDaemonMutex = CreateMutex( NULL, FALSE, szDBusDaemonMutex );
-
-  _dbus_assert(WaitForSingleObject( hDBusDaemonMutex, 1000 ) == WAIT_OBJECT_0);
+  ret = WaitForSingleObject( hDBusDaemonMutex, 1000 );
+  if ( ret != WAIT_OBJECT_0 ) {
+    _dbus_warn("Could not lock mutex %s (return code %d). daemon already running?\n", szDBusDaemonMutex, ret );
+    _dbus_assert( !"Could not lock mutex, daemon already running?" );
+  }
 
   // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs
   lock = _dbus_global_lock( cUniqueDBusInitMutex );
@@ -2884,10 +2902,10 @@ _dbus_daemon_init(const char *host, dbus_uint32_t port)
 
   _dbus_assert( adr );
 
-  strcpy( (char*) adr, szAddress);
+  strcpy( adr, szAddress);
 
   // cleanup
-  UnmapViewOfFile( (char*) adr );
+  UnmapViewOfFile( adr );
 
   _dbus_global_unlock( lock );
 }
@@ -2917,10 +2935,11 @@ static dbus_bool_t
 _dbus_get_autolaunch_shm(DBusString *adress)
 {
   HANDLE sharedMem;
-  const char *adr;
+  char *adr;
   char szUserName[64];
   DWORD dwUserNameSize = sizeof(szUserName);
   char szDBusDaemonAddressInfo[128];
+  int i;
 
   if( !GetUserName(szUserName, &dwUserNameSize) )
       return FALSE;
@@ -2928,12 +2947,14 @@ _dbus_get_autolaunch_shm(DBusString *adress)
             cDBusDaemonAddressInfo, szUserName);
 
   // read shm
-  do {
+  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 );
       if( sharedMem == 0 )
           Sleep( 100 );
-  } while( sharedMem == 0 );
+      if ( sharedMem != 0)
+          break;
+  }
 
   if( sharedMem == 0 )
       return FALSE;
@@ -2948,7 +2969,7 @@ _dbus_get_autolaunch_shm(DBusString *adress)
   _dbus_string_append( adress, adr ); 
 
   // cleanup
-  UnmapViewOfFile( (char*) adr );
+  UnmapViewOfFile( adr );
 
   CloseHandle( sharedMem );
 
@@ -3006,6 +3027,11 @@ _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
 
   mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
 
@@ -3013,14 +3039,16 @@ _dbus_get_autolaunch_address (DBusString *address,
 
   if (_dbus_daemon_already_runs(address))
     {
-        printf("dbus daemon already exists\n");
+        _dbus_verbose("found already running dbus daemon\n");
         retval = TRUE;
         goto out;
     }
 
-  if (!SearchPathA(NULL, "dbus-daemon.exe", NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
+  if (!SearchPathA(NULL, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
     {
-      printf ("could not find dbus-daemon executable\n");
+      printf ("please add the path to %s to your PATH environment variable\n", daemon_name);
+      printf ("or start the daemon manually\n\n");
+      printf ("");
       goto out;
     }
 
@@ -3032,19 +3060,16 @@ _dbus_get_autolaunch_address (DBusString *address,
   _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path,  " --session");
 
 //  argv[i] = "--config-file=bus\\session.conf";
-  printf("create process \"%s\" %s\n", dbus_exe_path, dbus_args);
-  if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
+//  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))
     {
-      retval = TRUE;
-
-      // Wait until started (see _dbus_get_autolaunch_shm())
-      WaitForInputIdle(pi.hProcess, INFINITE);
 
       retval = _dbus_get_autolaunch_shm( address );
-    } else {
-      retval = FALSE;
     }
   
+  if (retval == FALSE)
+    dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to launch dbus-daemon");
+
 out:
   if (retval)
     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -3127,6 +3152,31 @@ _dbus_get_standard_session_servicedirs (DBusList **dirs)
   return FALSE;
 }
 
+/**
+ * Returns the standard directories for a system bus to look for service
+ * activation files
+ *
+ * On UNIX this should be the standard xdg freedesktop.org data directories:
+ *
+ * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
+ *
+ * and
+ *
+ * DBUS_DATADIR
+ *
+ * On Windows there is no system bus and this function can return nothing.
+ *
+ * @param dirs the directory list we are returning
+ * @returns #FALSE on OOM
+ */
+
+dbus_bool_t
+_dbus_get_standard_system_servicedirs (DBusList **dirs)
+{
+  *dirs = NULL;
+  return TRUE;
+}
+
 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
 
 /**
@@ -3237,12 +3287,15 @@ _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;
 
-  strcat_s(path,path_size,"etc\\");
-  strcat_s(path,path_size,s);
+  if(len > sizeof(path)-2)
+    return FALSE;
+  strcat(path,"etc\\");
+  strcat(path,s);
   if (_dbus_file_exists(path)) 
     {
       // find path from executable 
@@ -3253,8 +3306,10 @@ _dbus_get_config_file_name(DBusString *config_file, char *s)
     {
       if (!_dbus_get_install_root(path,path_size))
         return FALSE;
-      strcat_s(path,path_size,"bus\\");
-      strcat_s(path,path_size,s);
+      if(len + strlen(path) > sizeof(path)-2)
+        return FALSE;
+      strcat(path,"bus\\");
+      strcat(path,s);
   
       if (_dbus_file_exists(path)) 
         {