D-Bus  1.4.10
dbus-sysdeps-win.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-sysdeps.c Wrappers around system/libc features (internal to D-BUS implementation)
3  *
4  * Copyright (C) 2002, 2003 Red Hat, Inc.
5  * Copyright (C) 2003 CodeFactory AB
6  * Copyright (C) 2005 Novell, Inc.
7  * Copyright (C) 2006 Peter Kümmel <syntheticpp@gmx.net>
8  * Copyright (C) 2006 Christian Ehrlicher <ch.ehrlicher@gmx.de>
9  * Copyright (C) 2006-2010 Ralf Habacker <ralf.habacker@freenet.de>
10  *
11  * Licensed under the Academic Free License version 2.1
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26  *
27  */
28 
29 #include <config.h>
30 
31 #define STRSAFE_NO_DEPRECATE
32 
33 #ifndef DBUS_WINCE
34 #ifndef _WIN32_WINNT
35 #define _WIN32_WINNT 0x0501
36 #endif
37 #endif
38 
39 #include "dbus-internals.h"
40 #include "dbus-sha.h"
41 #include "dbus-sysdeps.h"
42 #include "dbus-threads.h"
43 #include "dbus-protocol.h"
44 #include "dbus-string.h"
45 #include "dbus-sysdeps.h"
46 #include "dbus-sysdeps-win.h"
47 #include "dbus-protocol.h"
48 #include "dbus-hash.h"
49 #include "dbus-sockets-win.h"
50 #include "dbus-list.h"
51 #include "dbus-nonce.h"
52 #include "dbus-credentials.h"
53 
54 #include <windows.h>
55 #include <ws2tcpip.h>
56 #include <wincrypt.h>
57 
58 /* Declarations missing in mingw's headers */
59 extern BOOL WINAPI ConvertStringSidToSidA (LPCSTR StringSid, PSID *Sid);
60 extern BOOL WINAPI ConvertSidToStringSidA (PSID Sid, LPSTR *StringSid);
61 
62 #include <stdio.h>
63 
64 #include <string.h>
65 #if HAVE_ERRNO_H
66 #include <errno.h>
67 #endif
68 #ifndef DBUS_WINCE
69 #include <mbstring.h>
70 #include <sys/stat.h>
71 #include <sys/types.h>
72 #endif
73 
74 #ifdef HAVE_WS2TCPIP_H
75 /* getaddrinfo for Windows CE (and Windows). */
76 #include <ws2tcpip.h>
77 #endif
78 
79 #ifdef HAVE_WSPIAPI_H
80 // needed for w2k compatibility (getaddrinfo/freeaddrinfo/getnameinfo)
81 #ifdef __GNUC__
82 #define _inline
83 #include "wspiapi.h"
84 #else
85 #include <wspiapi.h>
86 #endif
87 #endif // HAVE_WSPIAPI_H
88 
89 #ifndef O_BINARY
90 #define O_BINARY 0
91 #endif
92 
93 typedef int socklen_t;
94 
95 
96 void
97 _dbus_win_set_errno (int err)
98 {
99 #ifdef DBUS_WINCE
100  SetLastError (err);
101 #else
102  errno = err;
103 #endif
104 }
105 
106 
107 /* Convert GetLastError() to a dbus error. */
108 const char*
109 _dbus_win_error_from_last_error (void)
110 {
111  switch (GetLastError())
112  {
113  case 0:
114  return DBUS_ERROR_FAILED;
115 
116  case ERROR_NO_MORE_FILES:
117  case ERROR_TOO_MANY_OPEN_FILES:
118  return DBUS_ERROR_LIMITS_EXCEEDED; /* kernel out of memory */
119 
120  case ERROR_ACCESS_DENIED:
121  case ERROR_CANNOT_MAKE:
123 
124  case ERROR_NOT_ENOUGH_MEMORY:
125  return DBUS_ERROR_NO_MEMORY;
126 
127  case ERROR_FILE_EXISTS:
128  return DBUS_ERROR_FILE_EXISTS;
129 
130  case ERROR_FILE_NOT_FOUND:
131  case ERROR_PATH_NOT_FOUND:
133  }
134 
135  return DBUS_ERROR_FAILED;
136 }
137 
138 
139 char*
140 _dbus_win_error_string (int error_number)
141 {
142  char *msg;
143 
144  FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
145  FORMAT_MESSAGE_IGNORE_INSERTS |
146  FORMAT_MESSAGE_FROM_SYSTEM,
147  NULL, error_number, 0,
148  (LPSTR) &msg, 0, NULL);
149 
150  if (msg[strlen (msg) - 1] == '\n')
151  msg[strlen (msg) - 1] = '\0';
152  if (msg[strlen (msg) - 1] == '\r')
153  msg[strlen (msg) - 1] = '\0';
154 
155  return msg;
156 }
157 
158 void
159 _dbus_win_free_error_string (char *string)
160 {
161  LocalFree (string);
162 }
163 
184 int
186  DBusString *buffer,
187  int count)
188 {
189  int bytes_read;
190  int start;
191  char *data;
192 
193  _dbus_assert (count >= 0);
194 
195  start = _dbus_string_get_length (buffer);
196 
197  if (!_dbus_string_lengthen (buffer, count))
198  {
199  _dbus_win_set_errno (ENOMEM);
200  return -1;
201  }
202 
203  data = _dbus_string_get_data_len (buffer, start, count);
204 
205  again:
206 
207  _dbus_verbose ("recv: count=%d fd=%d\n", count, fd);
208  bytes_read = recv (fd, data, count, 0);
209 
210  if (bytes_read == SOCKET_ERROR)
211  {
212  DBUS_SOCKET_SET_ERRNO();
213  _dbus_verbose ("recv: failed: %s (%d)\n", _dbus_strerror (errno), errno);
214  bytes_read = -1;
215  }
216  else
217  _dbus_verbose ("recv: = %d\n", bytes_read);
218 
219  if (bytes_read < 0)
220  {
221  if (errno == EINTR)
222  goto again;
223  else
224  {
225  /* put length back (note that this doesn't actually realloc anything) */
226  _dbus_string_set_length (buffer, start);
227  return -1;
228  }
229  }
230  else
231  {
232  /* put length back (doesn't actually realloc) */
233  _dbus_string_set_length (buffer, start + bytes_read);
234 
235 #if 0
236  if (bytes_read > 0)
237  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
238 #endif
239 
240  return bytes_read;
241  }
242 }
243 
254 int
256  const DBusString *buffer,
257  int start,
258  int len)
259 {
260  const char *data;
261  int bytes_written;
262 
263  data = _dbus_string_get_const_data_len (buffer, start, len);
264 
265  again:
266 
267  _dbus_verbose ("send: len=%d fd=%d\n", len, fd);
268  bytes_written = send (fd, data, len, 0);
269 
270  if (bytes_written == SOCKET_ERROR)
271  {
272  DBUS_SOCKET_SET_ERRNO();
273  _dbus_verbose ("send: failed: %s\n", _dbus_strerror_from_errno ());
274  bytes_written = -1;
275  }
276  else
277  _dbus_verbose ("send: = %d\n", bytes_written);
278 
279  if (bytes_written < 0 && errno == EINTR)
280  goto again;
281 
282 #if 0
283  if (bytes_written > 0)
284  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
285 #endif
286 
287  return bytes_written;
288 }
289 
290 
300  DBusError *error)
301 {
302  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
303 
304  again:
305  if (closesocket (fd) == SOCKET_ERROR)
306  {
307  DBUS_SOCKET_SET_ERRNO ();
308 
309  if (errno == EINTR)
310  goto again;
311 
312  dbus_set_error (error, _dbus_error_from_errno (errno),
313  "Could not close socket: socket=%d, , %s",
315  return FALSE;
316  }
317  _dbus_verbose ("_dbus_close_socket: socket=%d, \n", fd);
318 
319  return TRUE;
320 }
321 
329 void
330 _dbus_fd_set_close_on_exec (intptr_t handle)
331 {
332  if ( !SetHandleInformation( (HANDLE) handle,
333  HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE,
334  0 /*disable both flags*/ ) )
335  {
336  _dbus_win_warn_win_error ("Disabling socket handle inheritance failed:", GetLastError());
337  }
338 }
339 
348 _dbus_set_fd_nonblocking (int handle,
349  DBusError *error)
350 {
351  u_long one = 1;
352 
353  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
354 
355  if (ioctlsocket (handle, FIONBIO, &one) == SOCKET_ERROR)
356  {
357  DBUS_SOCKET_SET_ERRNO ();
358  dbus_set_error (error, _dbus_error_from_errno (errno),
359  "Failed to set socket %d:%d to nonblocking: %s", handle,
361  return FALSE;
362  }
363 
364  return TRUE;
365 }
366 
367 
388 int
390  const DBusString *buffer1,
391  int start1,
392  int len1,
393  const DBusString *buffer2,
394  int start2,
395  int len2)
396 {
397  WSABUF vectors[2];
398  const char *data1;
399  const char *data2;
400  int rc;
401  DWORD bytes_written;
402 
403  _dbus_assert (buffer1 != NULL);
404  _dbus_assert (start1 >= 0);
405  _dbus_assert (start2 >= 0);
406  _dbus_assert (len1 >= 0);
407  _dbus_assert (len2 >= 0);
408 
409 
410  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
411 
412  if (buffer2 != NULL)
413  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
414  else
415  {
416  data2 = NULL;
417  start2 = 0;
418  len2 = 0;
419  }
420 
421  vectors[0].buf = (char*) data1;
422  vectors[0].len = len1;
423  vectors[1].buf = (char*) data2;
424  vectors[1].len = len2;
425 
426  again:
427 
428  _dbus_verbose ("WSASend: len1+2=%d+%d fd=%d\n", len1, len2, fd);
429  rc = WSASend (fd,
430  vectors,
431  data2 ? 2 : 1,
432  &bytes_written,
433  0,
434  NULL,
435  NULL);
436 
437  if (rc == SOCKET_ERROR)
438  {
439  DBUS_SOCKET_SET_ERRNO ();
440  _dbus_verbose ("WSASend: failed: %s\n", _dbus_strerror_from_errno ());
441  bytes_written = -1;
442  }
443  else
444  _dbus_verbose ("WSASend: = %ld\n", bytes_written);
445 
446  if (bytes_written < 0 && errno == EINTR)
447  goto again;
448 
449  return bytes_written;
450 }
451 
453 _dbus_socket_is_invalid (int fd)
454 {
455  return fd == INVALID_SOCKET ? TRUE : FALSE;
456 }
457 
458 #if 0
459 
468 int
469 _dbus_connect_named_pipe (const char *path,
470  DBusError *error)
471 {
472  _dbus_assert_not_reached ("not implemented");
473 }
474 
475 #endif
476 
477 
478 
479 void
480 _dbus_win_startup_winsock (void)
481 {
482  /* Straight from MSDN, deuglified */
483 
484  static dbus_bool_t beenhere = FALSE;
485 
486  WORD wVersionRequested;
487  WSADATA wsaData;
488  int err;
489 
490  if (beenhere)
491  return;
492 
493  wVersionRequested = MAKEWORD (2, 0);
494 
495  err = WSAStartup (wVersionRequested, &wsaData);
496  if (err != 0)
497  {
498  _dbus_assert_not_reached ("Could not initialize WinSock");
499  _dbus_abort ();
500  }
501 
502  /* Confirm that the WinSock DLL supports 2.0. Note that if the DLL
503  * supports versions greater than 2.0 in addition to 2.0, it will
504  * still return 2.0 in wVersion since that is the version we
505  * requested.
506  */
507  if (LOBYTE (wsaData.wVersion) != 2 ||
508  HIBYTE (wsaData.wVersion) != 0)
509  {
510  _dbus_assert_not_reached ("No usable WinSock found");
511  _dbus_abort ();
512  }
513 
514  beenhere = TRUE;
515 }
516 
517 
518 
519 
520 
521 
522 
523 
524 
525 /************************************************************************
526 
527  UTF / string code
528 
529  ************************************************************************/
530 
534 int _dbus_printf_string_upper_bound (const char *format,
535  va_list args)
536 {
537  /* MSVCRT's vsnprintf semantics are a bit different */
538  char buf[1024];
539  int bufsize;
540  int len;
541 
542  bufsize = sizeof (buf);
543  len = _vsnprintf (buf, bufsize - 1, format, args);
544 
545  while (len == -1) /* try again */
546  {
547  char *p;
548 
549  bufsize *= 2;
550 
551  p = malloc (bufsize);
552  len = _vsnprintf (p, bufsize - 1, format, args);
553  free (p);
554  }
555 
556  return len;
557 }
558 
559 
567 wchar_t *
568 _dbus_win_utf8_to_utf16 (const char *str,
569  DBusError *error)
570 {
571  DBusString s;
572  int n;
573  wchar_t *retval;
574 
575  _dbus_string_init_const (&s, str);
576 
578  {
579  dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid UTF-8");
580  return NULL;
581  }
582 
583  n = MultiByteToWideChar (CP_UTF8, 0, str, -1, NULL, 0);
584 
585  if (n == 0)
586  {
587  _dbus_win_set_error_from_win_error (error, GetLastError ());
588  return NULL;
589  }
590 
591  retval = dbus_new (wchar_t, n);
592 
593  if (!retval)
594  {
595  _DBUS_SET_OOM (error);
596  return NULL;
597  }
598 
599  if (MultiByteToWideChar (CP_UTF8, 0, str, -1, retval, n) != n)
600  {
601  dbus_free (retval);
602  dbus_set_error_const (error, DBUS_ERROR_FAILED, "MultiByteToWideChar inconsistency");
603  return NULL;
604  }
605 
606  return retval;
607 }
608 
616 char *
617 _dbus_win_utf16_to_utf8 (const wchar_t *str,
618  DBusError *error)
619 {
620  int n;
621  char *retval;
622 
623  n = WideCharToMultiByte (CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
624 
625  if (n == 0)
626  {
627  _dbus_win_set_error_from_win_error (error, GetLastError ());
628  return NULL;
629  }
630 
631  retval = dbus_malloc (n);
632 
633  if (!retval)
634  {
635  _DBUS_SET_OOM (error);
636  return NULL;
637  }
638 
639  if (WideCharToMultiByte (CP_UTF8, 0, str, -1, retval, n, NULL, NULL) != n)
640  {
641  dbus_free (retval);
642  dbus_set_error_const (error, DBUS_ERROR_FAILED, "WideCharToMultiByte inconsistency");
643  return NULL;
644  }
645 
646  return retval;
647 }
648 
649 
650 
651 
652 
653 
654 /************************************************************************
655 
656 
657  ************************************************************************/
658 
660 _dbus_win_account_to_sid (const wchar_t *waccount,
661  void **ppsid,
662  DBusError *error)
663 {
664  dbus_bool_t retval = FALSE;
665  DWORD sid_length, wdomain_length;
666  SID_NAME_USE use;
667  wchar_t *wdomain;
668 
669  *ppsid = NULL;
670 
671  sid_length = 0;
672  wdomain_length = 0;
673  if (!LookupAccountNameW (NULL, waccount, NULL, &sid_length,
674  NULL, &wdomain_length, &use) &&
675  GetLastError () != ERROR_INSUFFICIENT_BUFFER)
676  {
677  _dbus_win_set_error_from_win_error (error, GetLastError ());
678  return FALSE;
679  }
680 
681  *ppsid = dbus_malloc (sid_length);
682  if (!*ppsid)
683  {
684  _DBUS_SET_OOM (error);
685  return FALSE;
686  }
687 
688  wdomain = dbus_new (wchar_t, wdomain_length);
689  if (!wdomain)
690  {
691  _DBUS_SET_OOM (error);
692  goto out1;
693  }
694 
695  if (!LookupAccountNameW (NULL, waccount, (PSID) *ppsid, &sid_length,
696  wdomain, &wdomain_length, &use))
697  {
698  _dbus_win_set_error_from_win_error (error, GetLastError ());
699  goto out2;
700  }
701 
702  if (!IsValidSid ((PSID) *ppsid))
703  {
704  dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID");
705  goto out2;
706  }
707 
708  retval = TRUE;
709 
710 out2:
711  dbus_free (wdomain);
712 out1:
713  if (!retval)
714  {
715  dbus_free (*ppsid);
716  *ppsid = NULL;
717  }
718 
719  return retval;
720 }
721 
731 unsigned long
733 {
734  return _dbus_getpid ();
735 }
736 
737 
738 #ifndef DBUS_WINCE
739 
743 static dbus_bool_t
744 _dbus_getsid(char **sid)
745 {
746  HANDLE process_token = INVALID_HANDLE_VALUE;
747  TOKEN_USER *token_user = NULL;
748  DWORD n;
749  PSID psid;
750  int retval = FALSE;
751 
752  if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &process_token))
753  {
754  _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ());
755  goto failed;
756  }
757  if ((!GetTokenInformation (process_token, TokenUser, NULL, 0, &n)
758  && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
759  || (token_user = alloca (n)) == NULL
760  || !GetTokenInformation (process_token, TokenUser, token_user, n, &n))
761  {
762  _dbus_win_warn_win_error ("GetTokenInformation failed", GetLastError ());
763  goto failed;
764  }
765  psid = token_user->User.Sid;
766  if (!IsValidSid (psid))
767  {
768  _dbus_verbose("%s invalid sid\n",__FUNCTION__);
769  goto failed;
770  }
771  if (!ConvertSidToStringSidA (psid, sid))
772  {
773  _dbus_verbose("%s invalid sid\n",__FUNCTION__);
774  goto failed;
775  }
776 //okay:
777  retval = TRUE;
778 
779 failed:
780  if (process_token != INVALID_HANDLE_VALUE)
781  CloseHandle (process_token);
782 
783  _dbus_verbose("_dbus_getsid() returns %d\n",retval);
784  return retval;
785 }
786 #endif
787 
788 /************************************************************************
789 
790  pipes
791 
792  ************************************************************************/
793 
811  int *fd2,
812  dbus_bool_t blocking,
813  DBusError *error)
814 {
815  SOCKET temp, socket1 = -1, socket2 = -1;
816  struct sockaddr_in saddr;
817  int len;
818  u_long arg;
819  fd_set read_set, write_set;
820  struct timeval tv;
821  int res;
822 
823  _dbus_win_startup_winsock ();
824 
825  temp = socket (AF_INET, SOCK_STREAM, 0);
826  if (temp == INVALID_SOCKET)
827  {
828  DBUS_SOCKET_SET_ERRNO ();
829  goto out0;
830  }
831 
832  _DBUS_ZERO (saddr);
833  saddr.sin_family = AF_INET;
834  saddr.sin_port = 0;
835  saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
836 
837  if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr)) == SOCKET_ERROR)
838  {
839  DBUS_SOCKET_SET_ERRNO ();
840  goto out0;
841  }
842 
843  if (listen (temp, 1) == SOCKET_ERROR)
844  {
845  DBUS_SOCKET_SET_ERRNO ();
846  goto out0;
847  }
848 
849  len = sizeof (saddr);
850  if (getsockname (temp, (struct sockaddr *)&saddr, &len) == SOCKET_ERROR)
851  {
852  DBUS_SOCKET_SET_ERRNO ();
853  goto out0;
854  }
855 
856  socket1 = socket (AF_INET, SOCK_STREAM, 0);
857  if (socket1 == INVALID_SOCKET)
858  {
859  DBUS_SOCKET_SET_ERRNO ();
860  goto out0;
861  }
862 
863  if (connect (socket1, (struct sockaddr *)&saddr, len) == SOCKET_ERROR)
864  {
865  DBUS_SOCKET_SET_ERRNO ();
866  goto out1;
867  }
868 
869  socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
870  if (socket2 == INVALID_SOCKET)
871  {
872  DBUS_SOCKET_SET_ERRNO ();
873  goto out1;
874  }
875 
876  if (!blocking)
877  {
878  arg = 1;
879  if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
880  {
881  DBUS_SOCKET_SET_ERRNO ();
882  goto out2;
883  }
884 
885  arg = 1;
886  if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
887  {
888  DBUS_SOCKET_SET_ERRNO ();
889  goto out2;
890  }
891  }
892 
893  *fd1 = socket1;
894  *fd2 = socket2;
895 
896  _dbus_verbose ("full-duplex pipe %d:%d <-> %d:%d\n",
897  *fd1, socket1, *fd2, socket2);
898 
899  closesocket (temp);
900 
901  return TRUE;
902 
903 out2:
904  closesocket (socket2);
905 out1:
906  closesocket (socket1);
907 out0:
908  closesocket (temp);
909 
910  dbus_set_error (error, _dbus_error_from_errno (errno),
911  "Could not setup socket pair: %s",
913 
914  return FALSE;
915 }
916 
925 int
927  int n_fds,
928  int timeout_milliseconds)
929 {
930 #define USE_CHRIS_IMPL 0
931 
932 #if USE_CHRIS_IMPL
933 
934 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
935  char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
936  char *msgp;
937 
938  int ret = 0;
939  int i;
940  struct timeval tv;
941  int ready;
942 
943 #define DBUS_STACK_WSAEVENTS 256
944  WSAEVENT eventsOnStack[DBUS_STACK_WSAEVENTS];
945  WSAEVENT *pEvents = NULL;
946  if (n_fds > DBUS_STACK_WSAEVENTS)
947  pEvents = calloc(sizeof(WSAEVENT), n_fds);
948  else
949  pEvents = eventsOnStack;
950 
951 
952 #ifdef DBUS_ENABLE_VERBOSE_MODE
953  msgp = msg;
954  msgp += sprintf (msgp, "WSAEventSelect: to=%d\n\t", timeout_milliseconds);
955  for (i = 0; i < n_fds; i++)
956  {
957  static dbus_bool_t warned = FALSE;
958  DBusPollFD *fdp = &fds[i];
959 
960 
961  if (fdp->events & _DBUS_POLLIN)
962  msgp += sprintf (msgp, "R:%d ", fdp->fd);
963 
964  if (fdp->events & _DBUS_POLLOUT)
965  msgp += sprintf (msgp, "W:%d ", fdp->fd);
966 
967  msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
968 
969  // FIXME: more robust code for long msg
970  // create on heap when msg[] becomes too small
971  if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
972  {
973  _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
974  }
975  }
976 
977  msgp += sprintf (msgp, "\n");
978  _dbus_verbose ("%s",msg);
979 #endif
980  for (i = 0; i < n_fds; i++)
981  {
982  DBusPollFD *fdp = &fds[i];
983  WSAEVENT ev;
984  long lNetworkEvents = FD_OOB;
985 
986  ev = WSACreateEvent();
987 
988  if (fdp->events & _DBUS_POLLIN)
989  lNetworkEvents |= FD_READ | FD_ACCEPT | FD_CLOSE;
990 
991  if (fdp->events & _DBUS_POLLOUT)
992  lNetworkEvents |= FD_WRITE | FD_CONNECT;
993 
994  WSAEventSelect(fdp->fd, ev, lNetworkEvents);
995 
996  pEvents[i] = ev;
997  }
998 
999 
1000  ready = WSAWaitForMultipleEvents (n_fds, pEvents, FALSE, timeout_milliseconds, FALSE);
1001 
1002  if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
1003  {
1004  DBUS_SOCKET_SET_ERRNO ();
1005  if (errno != WSAEWOULDBLOCK)
1006  _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", _dbus_strerror_from_errno ());
1007  ret = -1;
1008  }
1009  else if (ready == WSA_WAIT_TIMEOUT)
1010  {
1011  _dbus_verbose ("WSAWaitForMultipleEvents: WSA_WAIT_TIMEOUT\n");
1012  ret = 0;
1013  }
1014  else if (ready >= WSA_WAIT_EVENT_0 && ready < (int)(WSA_WAIT_EVENT_0 + n_fds))
1015  {
1016  msgp = msg;
1017  msgp += sprintf (msgp, "WSAWaitForMultipleEvents: =%d\n\t", ready);
1018 
1019  for (i = 0; i < n_fds; i++)
1020  {
1021  DBusPollFD *fdp = &fds[i];
1022  WSANETWORKEVENTS ne;
1023 
1024  fdp->revents = 0;
1025 
1026  WSAEnumNetworkEvents(fdp->fd, pEvents[i], &ne);
1027 
1028  if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
1029  fdp->revents |= _DBUS_POLLIN;
1030 
1031  if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
1032  fdp->revents |= _DBUS_POLLOUT;
1033 
1034  if (ne.lNetworkEvents & (FD_OOB))
1035  fdp->revents |= _DBUS_POLLERR;
1036 
1037  if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
1038  msgp += sprintf (msgp, "R:%d ", fdp->fd);
1039 
1040  if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
1041  msgp += sprintf (msgp, "W:%d ", fdp->fd);
1042 
1043  if (ne.lNetworkEvents & (FD_OOB))
1044  msgp += sprintf (msgp, "E:%d ", fdp->fd);
1045 
1046  msgp += sprintf (msgp, "lNetworkEvents:%d ", ne.lNetworkEvents);
1047 
1048  if(ne.lNetworkEvents)
1049  ret++;
1050 
1051  WSAEventSelect(fdp->fd, pEvents[i], 0);
1052  }
1053 
1054  msgp += sprintf (msgp, "\n");
1055  _dbus_verbose ("%s",msg);
1056  }
1057  else
1058  {
1059  _dbus_verbose ("WSAWaitForMultipleEvents: failed for unknown reason!");
1060  ret = -1;
1061  }
1062 
1063  for(i = 0; i < n_fds; i++)
1064  {
1065  WSACloseEvent(pEvents[i]);
1066  }
1067 
1068  if (n_fds > DBUS_STACK_WSAEVENTS)
1069  free(pEvents);
1070 
1071  return ret;
1072 
1073 #else /* USE_CHRIS_IMPL */
1074 
1075 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
1076  char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
1077  char *msgp;
1078 
1079  fd_set read_set, write_set, err_set;
1080  int max_fd = 0;
1081  int i;
1082  struct timeval tv;
1083  int ready;
1084 
1085  FD_ZERO (&read_set);
1086  FD_ZERO (&write_set);
1087  FD_ZERO (&err_set);
1088 
1089 
1090 #ifdef DBUS_ENABLE_VERBOSE_MODE
1091  msgp = msg;
1092  msgp += sprintf (msgp, "select: to=%d\n\t", timeout_milliseconds);
1093  for (i = 0; i < n_fds; i++)
1094  {
1095  static dbus_bool_t warned = FALSE;
1096  DBusPollFD *fdp = &fds[i];
1097 
1098 
1099  if (fdp->events & _DBUS_POLLIN)
1100  msgp += sprintf (msgp, "R:%d ", fdp->fd);
1101 
1102  if (fdp->events & _DBUS_POLLOUT)
1103  msgp += sprintf (msgp, "W:%d ", fdp->fd);
1104 
1105  msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
1106 
1107  // FIXME: more robust code for long msg
1108  // create on heap when msg[] becomes too small
1109  if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
1110  {
1111  _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
1112  }
1113  }
1114 
1115  msgp += sprintf (msgp, "\n");
1116  _dbus_verbose ("%s",msg);
1117 #endif
1118  for (i = 0; i < n_fds; i++)
1119  {
1120  DBusPollFD *fdp = &fds[i];
1121 
1122  if (fdp->events & _DBUS_POLLIN)
1123  FD_SET (fdp->fd, &read_set);
1124 
1125  if (fdp->events & _DBUS_POLLOUT)
1126  FD_SET (fdp->fd, &write_set);
1127 
1128  FD_SET (fdp->fd, &err_set);
1129 
1130  max_fd = MAX (max_fd, fdp->fd);
1131  }
1132 
1133  // Avoid random lockups with send(), for lack of a better solution so far
1134  tv.tv_sec = timeout_milliseconds < 0 ? 1 : timeout_milliseconds / 1000;
1135  tv.tv_usec = timeout_milliseconds < 0 ? 0 : (timeout_milliseconds % 1000) * 1000;
1136 
1137  ready = select (max_fd + 1, &read_set, &write_set, &err_set, &tv);
1138 
1139  if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
1140  {
1141  DBUS_SOCKET_SET_ERRNO ();
1142  if (errno != WSAEWOULDBLOCK)
1143  _dbus_verbose ("select: failed: %s\n", _dbus_strerror_from_errno ());
1144  }
1145  else if (ready == 0)
1146  _dbus_verbose ("select: = 0\n");
1147  else
1148  if (ready > 0)
1149  {
1150 #ifdef DBUS_ENABLE_VERBOSE_MODE
1151  msgp = msg;
1152  msgp += sprintf (msgp, "select: = %d:\n\t", ready);
1153 
1154  for (i = 0; i < n_fds; i++)
1155  {
1156  DBusPollFD *fdp = &fds[i];
1157 
1158  if (FD_ISSET (fdp->fd, &read_set))
1159  msgp += sprintf (msgp, "R:%d ", fdp->fd);
1160 
1161  if (FD_ISSET (fdp->fd, &write_set))
1162  msgp += sprintf (msgp, "W:%d ", fdp->fd);
1163 
1164  if (FD_ISSET (fdp->fd, &err_set))
1165  msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
1166  }
1167  msgp += sprintf (msgp, "\n");
1168  _dbus_verbose ("%s",msg);
1169 #endif
1170 
1171  for (i = 0; i < n_fds; i++)
1172  {
1173  DBusPollFD *fdp = &fds[i];
1174 
1175  fdp->revents = 0;
1176 
1177  if (FD_ISSET (fdp->fd, &read_set))
1178  fdp->revents |= _DBUS_POLLIN;
1179 
1180  if (FD_ISSET (fdp->fd, &write_set))
1181  fdp->revents |= _DBUS_POLLOUT;
1182 
1183  if (FD_ISSET (fdp->fd, &err_set))
1184  fdp->revents |= _DBUS_POLLERR;
1185  }
1186  }
1187  return ready;
1188 #endif /* USE_CHRIS_IMPL */
1189 }
1190 
1191 
1192 
1193 
1194 /******************************************************************************
1195 
1196 Original CVS version of dbus-sysdeps.c
1197 
1198 ******************************************************************************/
1199 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
1200 /* dbus-sysdeps.c Wrappers around system/libc features (internal to D-Bus implementation)
1201  *
1202  * Copyright (C) 2002, 2003 Red Hat, Inc.
1203  * Copyright (C) 2003 CodeFactory AB
1204  * Copyright (C) 2005 Novell, Inc.
1205  *
1206  * Licensed under the Academic Free License version 2.1
1207  *
1208  * This program is free software; you can redistribute it and/or modify
1209  * it under the terms of the GNU General Public License as published by
1210  * the Free Software Foundation; either version 2 of the License, or
1211  * (at your option) any later version.
1212  *
1213  * This program is distributed in the hope that it will be useful,
1214  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1215  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1216  * GNU General Public License for more details.
1217  *
1218  * You should have received a copy of the GNU General Public License
1219  * along with this program; if not, write to the Free Software
1220  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1221  *
1222  */
1223 
1224 
1230 void
1231 _dbus_exit (int code)
1232 {
1233  _exit (code);
1234 }
1235 
1247 int
1248 _dbus_connect_tcp_socket (const char *host,
1249  const char *port,
1250  const char *family,
1251  DBusError *error)
1252 {
1253  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1254 }
1255 
1256 int
1257 _dbus_connect_tcp_socket_with_nonce (const char *host,
1258  const char *port,
1259  const char *family,
1260  const char *noncefile,
1261  DBusError *error)
1262 {
1263  int fd = -1, res;
1264  struct addrinfo hints;
1265  struct addrinfo *ai, *tmp;
1266 
1267  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1268 
1269  _dbus_win_startup_winsock ();
1270 
1271  _DBUS_ZERO (hints);
1272 
1273  if (!family)
1274  hints.ai_family = AF_UNSPEC;
1275  else if (!strcmp(family, "ipv4"))
1276  hints.ai_family = AF_INET;
1277  else if (!strcmp(family, "ipv6"))
1278  hints.ai_family = AF_INET6;
1279  else
1280  {
1281  dbus_set_error (error,
1283  "Unknown address family %s", family);
1284  return -1;
1285  }
1286  hints.ai_protocol = IPPROTO_TCP;
1287  hints.ai_socktype = SOCK_STREAM;
1288 #ifdef AI_ADDRCONFIG
1289  hints.ai_flags = AI_ADDRCONFIG;
1290 #else
1291  hints.ai_flags = 0;
1292 #endif
1293 
1294  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1295  {
1296  dbus_set_error (error,
1297  _dbus_error_from_errno (res),
1298  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1299  host, port, _dbus_strerror(res), res);
1300  return -1;
1301  }
1302 
1303  tmp = ai;
1304  while (tmp)
1305  {
1306  if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
1307  {
1308  DBUS_SOCKET_SET_ERRNO ();
1309  dbus_set_error (error,
1310  _dbus_error_from_errno (errno),
1311  "Failed to open socket: %s",
1313  freeaddrinfo(ai);
1314  return -1;
1315  }
1316  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1317 
1318  if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
1319  {
1320  DBUS_SOCKET_SET_ERRNO ();
1321  closesocket(fd);
1322  fd = -1;
1323  tmp = tmp->ai_next;
1324  continue;
1325  }
1326 
1327  break;
1328  }
1329  freeaddrinfo(ai);
1330 
1331  if (fd == -1)
1332  {
1333  dbus_set_error (error,
1334  _dbus_error_from_errno (errno),
1335  "Failed to connect to socket \"%s:%s\" %s",
1336  host, port, _dbus_strerror_from_errno ());
1337  return -1;
1338  }
1339 
1340  if (noncefile != NULL)
1341  {
1342  DBusString noncefileStr;
1343  dbus_bool_t ret;
1344  if (!_dbus_string_init (&noncefileStr) ||
1345  !_dbus_string_append(&noncefileStr, noncefile))
1346  {
1347  closesocket (fd);
1349  return -1;
1350  }
1351 
1352  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1353 
1354  _dbus_string_free (&noncefileStr);
1355 
1356  if (!ret)
1357  {
1358  closesocket (fd);
1359  return -1;
1360  }
1361  }
1362 
1364 
1365  if (!_dbus_set_fd_nonblocking (fd, error))
1366  {
1367  closesocket (fd);
1368  return -1;
1369  }
1370 
1371  return fd;
1372 }
1373 
1389 int
1390 _dbus_listen_tcp_socket (const char *host,
1391  const char *port,
1392  const char *family,
1393  DBusString *retport,
1394  int **fds_p,
1395  DBusError *error)
1396 {
1397  int nlisten_fd = 0, *listen_fd = NULL, res, i, port_num = -1;
1398  struct addrinfo hints;
1399  struct addrinfo *ai, *tmp;
1400 
1401  // On Vista, sockaddr_gen must be a sockaddr_in6, and not a sockaddr_in6_old
1402  //That's required for family == IPv6(which is the default on Vista if family is not given)
1403  //So we use our own union instead of sockaddr_gen:
1404 
1405  typedef union {
1406  struct sockaddr Address;
1407  struct sockaddr_in AddressIn;
1408  struct sockaddr_in6 AddressIn6;
1409  } mysockaddr_gen;
1410 
1411  *fds_p = NULL;
1412  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1413 
1414  _dbus_win_startup_winsock ();
1415 
1416  _DBUS_ZERO (hints);
1417 
1418  if (!family)
1419  hints.ai_family = AF_UNSPEC;
1420  else if (!strcmp(family, "ipv4"))
1421  hints.ai_family = AF_INET;
1422  else if (!strcmp(family, "ipv6"))
1423  hints.ai_family = AF_INET6;
1424  else
1425  {
1426  dbus_set_error (error,
1428  "Unknown address family %s", family);
1429  return -1;
1430  }
1431 
1432  hints.ai_protocol = IPPROTO_TCP;
1433  hints.ai_socktype = SOCK_STREAM;
1434 #ifdef AI_ADDRCONFIG
1435  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1436 #else
1437  hints.ai_flags = AI_PASSIVE;
1438 #endif
1439 
1440  redo_lookup_with_port:
1441  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1442  {
1443  dbus_set_error (error,
1444  _dbus_error_from_errno (res),
1445  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1446  host ? host : "*", port, _dbus_strerror(res), res);
1447  return -1;
1448  }
1449 
1450  tmp = ai;
1451  while (tmp)
1452  {
1453  int fd = -1, *newlisten_fd;
1454  if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
1455  {
1456  DBUS_SOCKET_SET_ERRNO ();
1457  dbus_set_error (error,
1458  _dbus_error_from_errno (errno),
1459  "Failed to open socket: %s",
1461  goto failed;
1462  }
1463  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1464 
1465  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
1466  {
1467  DBUS_SOCKET_SET_ERRNO ();
1468  dbus_set_error (error, _dbus_error_from_errno (errno),
1469  "Failed to bind socket \"%s:%s\": %s",
1470  host ? host : "*", port, _dbus_strerror_from_errno ());
1471  closesocket (fd);
1472  goto failed;
1473  }
1474 
1475  if (listen (fd, 30 /* backlog */) == SOCKET_ERROR)
1476  {
1477  DBUS_SOCKET_SET_ERRNO ();
1478  dbus_set_error (error, _dbus_error_from_errno (errno),
1479  "Failed to listen on socket \"%s:%s\": %s",
1480  host ? host : "*", port, _dbus_strerror_from_errno ());
1481  closesocket (fd);
1482  goto failed;
1483  }
1484 
1485  newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1486  if (!newlisten_fd)
1487  {
1488  closesocket (fd);
1490  "Failed to allocate file handle array");
1491  goto failed;
1492  }
1493  listen_fd = newlisten_fd;
1494  listen_fd[nlisten_fd] = fd;
1495  nlisten_fd++;
1496 
1497  if (!_dbus_string_get_length(retport))
1498  {
1499  /* If the user didn't specify a port, or used 0, then
1500  the kernel chooses a port. After the first address
1501  is bound to, we need to force all remaining addresses
1502  to use the same port */
1503  if (!port || !strcmp(port, "0"))
1504  {
1505  mysockaddr_gen addr;
1506  socklen_t addrlen = sizeof(addr);
1507  char portbuf[10];
1508 
1509  if (getsockname(fd, &addr.Address, &addrlen) == SOCKET_ERROR)
1510  {
1511  DBUS_SOCKET_SET_ERRNO ();
1512  dbus_set_error (error, _dbus_error_from_errno (errno),
1513  "Failed to resolve port \"%s:%s\": %s",
1514  host ? host : "*", port, _dbus_strerror_from_errno());
1515  goto failed;
1516  }
1517  snprintf( portbuf, sizeof( portbuf ) - 1, "%d", addr.AddressIn.sin_port );
1518  if (!_dbus_string_append(retport, portbuf))
1519  {
1521  goto failed;
1522  }
1523 
1524  /* Release current address list & redo lookup */
1525  port = _dbus_string_get_const_data(retport);
1526  freeaddrinfo(ai);
1527  goto redo_lookup_with_port;
1528  }
1529  else
1530  {
1531  if (!_dbus_string_append(retport, port))
1532  {
1534  goto failed;
1535  }
1536  }
1537  }
1538 
1539  tmp = tmp->ai_next;
1540  }
1541  freeaddrinfo(ai);
1542  ai = NULL;
1543 
1544  if (!nlisten_fd)
1545  {
1546  _dbus_win_set_errno (WSAEADDRINUSE);
1547  dbus_set_error (error, _dbus_error_from_errno (errno),
1548  "Failed to bind socket \"%s:%s\": %s",
1549  host ? host : "*", port, _dbus_strerror_from_errno ());
1550  return -1;
1551  }
1552 
1553  sscanf(_dbus_string_get_const_data(retport), "%d", &port_num);
1554 
1555  for (i = 0 ; i < nlisten_fd ; i++)
1556  {
1557  _dbus_fd_set_close_on_exec (listen_fd[i]);
1558  if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1559  {
1560  goto failed;
1561  }
1562  }
1563 
1564  *fds_p = listen_fd;
1565 
1566  return nlisten_fd;
1567 
1568  failed:
1569  if (ai)
1570  freeaddrinfo(ai);
1571  for (i = 0 ; i < nlisten_fd ; i++)
1572  closesocket (listen_fd[i]);
1573  dbus_free(listen_fd);
1574  return -1;
1575 }
1576 
1577 
1585 int
1586 _dbus_accept (int listen_fd)
1587 {
1588  int client_fd;
1589 
1590  retry:
1591  client_fd = accept (listen_fd, NULL, NULL);
1592 
1593  if (DBUS_SOCKET_IS_INVALID (client_fd))
1594  {
1595  DBUS_SOCKET_SET_ERRNO ();
1596  if (errno == EINTR)
1597  goto retry;
1598  }
1599 
1600  _dbus_verbose ("client fd %d accepted\n", client_fd);
1601 
1602  return client_fd;
1603 }
1604 
1605 
1606 
1607 
1610  DBusError *error)
1611 {
1612 /* FIXME: for the session bus credentials shouldn't matter (?), but
1613  * for the system bus they are presumably essential. A rough outline
1614  * of a way to implement the credential transfer would be this:
1615  *
1616  * client waits to *read* a byte.
1617  *
1618  * server creates a named pipe with a random name, sends a byte
1619  * contining its length, and its name.
1620  *
1621  * client reads the name, connects to it (using Win32 API).
1622  *
1623  * server waits for connection to the named pipe, then calls
1624  * ImpersonateNamedPipeClient(), notes its now-current credentials,
1625  * calls RevertToSelf(), closes its handles to the named pipe, and
1626  * is done. (Maybe there is some other way to get the SID of a named
1627  * pipe client without having to use impersonation?)
1628  *
1629  * client closes its handles and is done.
1630  *
1631  * Ralf: Why not sending credentials over the given this connection ?
1632  * Using named pipes makes it impossible to be connected from a unix client.
1633  *
1634  */
1635  int bytes_written;
1636  DBusString buf;
1637 
1638  _dbus_string_init_const_len (&buf, "\0", 1);
1639 again:
1640  bytes_written = _dbus_write_socket (handle, &buf, 0, 1 );
1641 
1642  if (bytes_written < 0 && errno == EINTR)
1643  goto again;
1644 
1645  if (bytes_written < 0)
1646  {
1647  dbus_set_error (error, _dbus_error_from_errno (errno),
1648  "Failed to write credentials byte: %s",
1650  return FALSE;
1651  }
1652  else if (bytes_written == 0)
1653  {
1655  "wrote zero bytes writing credentials byte");
1656  return FALSE;
1657  }
1658  else
1659  {
1660  _dbus_assert (bytes_written == 1);
1661  _dbus_verbose ("wrote 1 zero byte, credential sending isn't implemented yet\n");
1662  return TRUE;
1663  }
1664  return TRUE;
1665 }
1666 
1687  DBusCredentials *credentials,
1688  DBusError *error)
1689 {
1690  int bytes_read = 0;
1691  DBusString buf;
1692 
1693  // could fail due too OOM
1694  if (_dbus_string_init(&buf))
1695  {
1696  bytes_read = _dbus_read_socket(handle, &buf, 1 );
1697 
1698  if (bytes_read > 0)
1699  _dbus_verbose("got one zero byte from server");
1700 
1701  _dbus_string_free(&buf);
1702  }
1703 
1705  _dbus_verbose("FIXME: get faked credentials from current process");
1706 
1707  return TRUE;
1708 }
1709 
1720 {
1721  /* TODO */
1722  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1723  return TRUE;
1724 }
1725 
1726 
1739  const DBusString *next_component)
1740 {
1741  dbus_bool_t dir_ends_in_slash;
1742  dbus_bool_t file_starts_with_slash;
1743 
1744  if (_dbus_string_get_length (dir) == 0 ||
1745  _dbus_string_get_length (next_component) == 0)
1746  return TRUE;
1747 
1748  dir_ends_in_slash =
1749  ('/' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1) ||
1750  '\\' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1));
1751 
1752  file_starts_with_slash =
1753  ('/' == _dbus_string_get_byte (next_component, 0) ||
1754  '\\' == _dbus_string_get_byte (next_component, 0));
1755 
1756  if (dir_ends_in_slash && file_starts_with_slash)
1757  {
1758  _dbus_string_shorten (dir, 1);
1759  }
1760  else if (!(dir_ends_in_slash || file_starts_with_slash))
1761  {
1762  if (!_dbus_string_append_byte (dir, '\\'))
1763  return FALSE;
1764  }
1765 
1766  return _dbus_string_copy (next_component, 0, dir,
1767  _dbus_string_get_length (dir));
1768 }
1769 
1770 /*---------------- DBusCredentials ----------------------------------*/
1771 
1781  const DBusString *username)
1782 {
1783  return _dbus_credentials_add_windows_sid (credentials,
1784  _dbus_string_get_const_data(username));
1785 }
1786 
1797 {
1798  dbus_bool_t retval = FALSE;
1799  char *sid = NULL;
1800 
1801  if (!_dbus_getsid(&sid))
1802  goto failed;
1803 
1804  if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
1805  goto failed;
1806 
1807  if (!_dbus_credentials_add_windows_sid (credentials,sid))
1808  goto failed;
1809 
1810  retval = TRUE;
1811  goto end;
1812 failed:
1813  retval = FALSE;
1814 end:
1815  if (sid)
1816  LocalFree(sid);
1817 
1818  return retval;
1819 }
1820 
1835 {
1836  dbus_bool_t retval = FALSE;
1837  char *sid = NULL;
1838 
1839  if (!_dbus_getsid(&sid))
1840  return FALSE;
1841 
1842  retval = _dbus_string_append (str,sid);
1843 
1844  LocalFree(sid);
1845  return retval;
1846 }
1847 
1852 dbus_pid_t
1854 {
1855  return GetCurrentProcessId ();
1856 }
1857 
1859 #define NANOSECONDS_PER_SECOND 1000000000
1860 
1861 #define MICROSECONDS_PER_SECOND 1000000
1862 
1863 #define MILLISECONDS_PER_SECOND 1000
1864 
1865 #define NANOSECONDS_PER_MILLISECOND 1000000
1866 
1867 #define MICROSECONDS_PER_MILLISECOND 1000
1868 
1873 void
1874 _dbus_sleep_milliseconds (int milliseconds)
1875 {
1876  Sleep (milliseconds);
1877 }
1878 
1879 
1886 void
1888  long *tv_usec)
1889 {
1890  FILETIME ft;
1891  dbus_uint64_t time64;
1892 
1893  GetSystemTimeAsFileTime (&ft);
1894 
1895  memcpy (&time64, &ft, sizeof (time64));
1896 
1897  /* Convert from 100s of nanoseconds since 1601-01-01
1898  * to Unix epoch. Yes, this is Y2038 unsafe.
1899  */
1900  time64 -= DBUS_INT64_CONSTANT (116444736000000000);
1901  time64 /= 10;
1902 
1903  if (tv_sec)
1904  *tv_sec = time64 / 1000000;
1905 
1906  if (tv_usec)
1907  *tv_usec = time64 % 1000000;
1908 }
1909 
1910 
1914 void
1916 {
1917 }
1918 
1929  DBusError *error)
1930 {
1931  const char *filename_c;
1932 
1933  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1934 
1935  filename_c = _dbus_string_get_const_data (filename);
1936 
1937  if (!CreateDirectoryA (filename_c, NULL))
1938  {
1939  if (GetLastError () == ERROR_ALREADY_EXISTS)
1940  return TRUE;
1941 
1943  "Failed to create directory %s: %s\n",
1944  filename_c, _dbus_strerror_from_errno ());
1945  return FALSE;
1946  }
1947  else
1948  return TRUE;
1949 }
1950 
1951 
1962  int n_bytes)
1963 {
1964  int old_len;
1965  char *p;
1966  HCRYPTPROV hprov;
1967 
1968  old_len = _dbus_string_get_length (str);
1969 
1970  if (!_dbus_string_lengthen (str, n_bytes))
1971  return FALSE;
1972 
1973  p = _dbus_string_get_data_len (str, old_len, n_bytes);
1974 
1975  if (!CryptAcquireContext (&hprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
1976  return FALSE;
1977 
1978  if (!CryptGenRandom (hprov, n_bytes, p))
1979  {
1980  CryptReleaseContext (hprov, 0);
1981  return FALSE;
1982  }
1983 
1984  CryptReleaseContext (hprov, 0);
1985 
1986  return TRUE;
1987 }
1988 
1995 const char*
1997 {
1998  static const char* tmpdir = NULL;
1999  static char buf[1000];
2000 
2001  if (tmpdir == NULL)
2002  {
2003  char *last_slash;
2004 
2005  if (!GetTempPathA (sizeof (buf), buf))
2006  {
2007  _dbus_warn ("GetTempPath failed\n");
2008  _dbus_abort ();
2009  }
2010 
2011  /* Drop terminating backslash or slash */
2012  last_slash = _mbsrchr (buf, '\\');
2013  if (last_slash > buf && last_slash[1] == '\0')
2014  last_slash[0] = '\0';
2015  last_slash = _mbsrchr (buf, '/');
2016  if (last_slash > buf && last_slash[1] == '\0')
2017  last_slash[0] = '\0';
2018 
2019  tmpdir = buf;
2020  }
2021 
2022  _dbus_assert(tmpdir != NULL);
2023 
2024  return tmpdir;
2025 }
2026 
2027 
2038  DBusError *error)
2039 {
2040  const char *filename_c;
2041 
2042  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2043 
2044  filename_c = _dbus_string_get_const_data (filename);
2045 
2046  if (DeleteFileA (filename_c) == 0)
2047  {
2049  "Failed to delete file %s: %s\n",
2050  filename_c, _dbus_strerror_from_errno ());
2051  return FALSE;
2052  }
2053  else
2054  return TRUE;
2055 }
2056 
2057 /*
2058  * replaces the term DBUS_PREFIX in configure_time_path by the
2059  * current dbus installation directory. On unix this function is a noop
2060  *
2061  * @param configure_time_path
2062  * @return real path
2063  */
2064 const char *
2065 _dbus_replace_install_prefix (const char *configure_time_path)
2066 {
2067 #ifndef DBUS_PREFIX
2068  return configure_time_path;
2069 #else
2070  static char retval[1000];
2071  static char runtime_prefix[1000];
2072  int len = 1000;
2073  int i;
2074 
2075  if (!configure_time_path)
2076  return NULL;
2077 
2078  if ((!_dbus_get_install_root(runtime_prefix, len) ||
2079  strncmp (configure_time_path, DBUS_PREFIX "/",
2080  strlen (DBUS_PREFIX) + 1))) {
2081  strcat (retval, configure_time_path);
2082  return retval;
2083  }
2084 
2085  strcpy (retval, runtime_prefix);
2086  strcat (retval, configure_time_path + strlen (DBUS_PREFIX) + 1);
2087 
2088  /* Somehow, in some situations, backslashes get collapsed in the string.
2089  * Since windows C library accepts both forward and backslashes as
2090  * path separators, convert all backslashes to forward slashes.
2091  */
2092 
2093  for(i = 0; retval[i] != '\0'; i++) {
2094  if(retval[i] == '\\')
2095  retval[i] = '/';
2096  }
2097  return retval;
2098 #endif
2099 }
2100 
2101 #if !defined (DBUS_DISABLE_ASSERTS) || defined(DBUS_BUILD_TESTS)
2102 
2103 #if defined(_MSC_VER) || defined(DBUS_WINCE)
2104 # ifdef BACKTRACES
2105 # undef BACKTRACES
2106 # endif
2107 #else
2108 # define BACKTRACES
2109 #endif
2110 
2111 #ifdef BACKTRACES
2112 /*
2113  * Backtrace Generator
2114  *
2115  * Copyright 2004 Eric Poech
2116  * Copyright 2004 Robert Shearman
2117  *
2118  * This library is free software; you can redistribute it and/or
2119  * modify it under the terms of the GNU Lesser General Public
2120  * License as published by the Free Software Foundation; either
2121  * version 2.1 of the License, or (at your option) any later version.
2122  *
2123  * This library is distributed in the hope that it will be useful,
2124  * but WITHOUT ANY WARRANTY; without even the implied warranty of
2125  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2126  * Lesser General Public License for more details.
2127  *
2128  * You should have received a copy of the GNU Lesser General Public
2129  * License along with this library; if not, write to the Free Software
2130  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2131  */
2132 
2133 #include <winver.h>
2134 #include <imagehlp.h>
2135 #include <stdio.h>
2136 
2137 #define DPRINTF _dbus_warn
2138 
2139 #ifdef _MSC_VER
2140 #define BOOL int
2141 
2142 #define __i386__
2143 #endif
2144 
2145 //#define MAKE_FUNCPTR(f) static typeof(f) * p##f
2146 
2147 //MAKE_FUNCPTR(StackWalk);
2148 //MAKE_FUNCPTR(SymGetModuleBase);
2149 //MAKE_FUNCPTR(SymFunctionTableAccess);
2150 //MAKE_FUNCPTR(SymInitialize);
2151 //MAKE_FUNCPTR(SymGetSymFromAddr);
2152 //MAKE_FUNCPTR(SymGetModuleInfo);
2153 static BOOL (WINAPI *pStackWalk)(
2154  DWORD MachineType,
2155  HANDLE hProcess,
2156  HANDLE hThread,
2157  LPSTACKFRAME StackFrame,
2158  PVOID ContextRecord,
2159  PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
2160  PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
2161  PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
2162  PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
2163 );
2164 #ifdef _WIN64
2165 static DWORD64 (WINAPI *pSymGetModuleBase)(
2166  HANDLE hProcess,
2167  DWORD64 dwAddr
2168 );
2169 static PVOID (WINAPI *pSymFunctionTableAccess)(
2170  HANDLE hProcess,
2171  DWORD64 AddrBase
2172 );
2173 #else
2174 static DWORD (WINAPI *pSymGetModuleBase)(
2175  HANDLE hProcess,
2176  DWORD dwAddr
2177 );
2178 static PVOID (WINAPI *pSymFunctionTableAccess)(
2179  HANDLE hProcess,
2180  DWORD AddrBase
2181 );
2182 #endif
2183 static BOOL (WINAPI *pSymInitialize)(
2184  HANDLE hProcess,
2185  PSTR UserSearchPath,
2186  BOOL fInvadeProcess
2187 );
2188 static BOOL (WINAPI *pSymGetSymFromAddr)(
2189  HANDLE hProcess,
2190  DWORD Address,
2191  PDWORD Displacement,
2192  PIMAGEHLP_SYMBOL Symbol
2193 );
2194 static BOOL (WINAPI *pSymGetModuleInfo)(
2195  HANDLE hProcess,
2196  DWORD dwAddr,
2197  PIMAGEHLP_MODULE ModuleInfo
2198 );
2199 static DWORD (WINAPI *pSymSetOptions)(
2200  DWORD SymOptions
2201 );
2202 
2203 
2204 static BOOL init_backtrace()
2205 {
2206  HMODULE hmodDbgHelp = LoadLibraryA("dbghelp");
2207 /*
2208  #define GETFUNC(x) \
2209  p##x = (typeof(x)*)GetProcAddress(hmodDbgHelp, #x); \
2210  if (!p##x) \
2211  { \
2212  return FALSE; \
2213  }
2214  */
2215 
2216 
2217 // GETFUNC(StackWalk);
2218 // GETFUNC(SymGetModuleBase);
2219 // GETFUNC(SymFunctionTableAccess);
2220 // GETFUNC(SymInitialize);
2221 // GETFUNC(SymGetSymFromAddr);
2222 // GETFUNC(SymGetModuleInfo);
2223 
2224 #define FUNC(x) #x
2225 
2226  pStackWalk = (BOOL (WINAPI *)(
2227 DWORD MachineType,
2228 HANDLE hProcess,
2229 HANDLE hThread,
2230 LPSTACKFRAME StackFrame,
2231 PVOID ContextRecord,
2232 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
2233 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
2234 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
2235 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
2236 ))GetProcAddress (hmodDbgHelp, FUNC(StackWalk));
2237 #ifdef _WIN64
2238  pSymGetModuleBase=(DWORD64 (WINAPI *)(
2239  HANDLE hProcess,
2240  DWORD64 dwAddr
2241 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
2242  pSymFunctionTableAccess=(PVOID (WINAPI *)(
2243  HANDLE hProcess,
2244  DWORD64 AddrBase
2245 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
2246 #else
2247  pSymGetModuleBase=(DWORD (WINAPI *)(
2248  HANDLE hProcess,
2249  DWORD dwAddr
2250 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
2251  pSymFunctionTableAccess=(PVOID (WINAPI *)(
2252  HANDLE hProcess,
2253  DWORD AddrBase
2254 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
2255 #endif
2256  pSymInitialize = (BOOL (WINAPI *)(
2257  HANDLE hProcess,
2258  PSTR UserSearchPath,
2259  BOOL fInvadeProcess
2260 ))GetProcAddress (hmodDbgHelp, FUNC(SymInitialize));
2261  pSymGetSymFromAddr = (BOOL (WINAPI *)(
2262  HANDLE hProcess,
2263  DWORD Address,
2264  PDWORD Displacement,
2265  PIMAGEHLP_SYMBOL Symbol
2266 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetSymFromAddr));
2267  pSymGetModuleInfo = (BOOL (WINAPI *)(
2268  HANDLE hProcess,
2269  DWORD dwAddr,
2270  PIMAGEHLP_MODULE ModuleInfo
2271 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleInfo));
2272 pSymSetOptions = (DWORD (WINAPI *)(
2273 DWORD SymOptions
2274 ))GetProcAddress (hmodDbgHelp, FUNC(SymSetOptions));
2275 
2276 
2277  pSymSetOptions(SYMOPT_UNDNAME);
2278 
2279  pSymInitialize(GetCurrentProcess(), NULL, TRUE);
2280 
2281  return TRUE;
2282 }
2283 
2284 static void dump_backtrace_for_thread(HANDLE hThread)
2285 {
2286  STACKFRAME sf;
2287  CONTEXT context;
2288  DWORD dwImageType;
2289 
2290  if (!pStackWalk)
2291  if (!init_backtrace())
2292  return;
2293 
2294  /* can't use this function for current thread as GetThreadContext
2295  * doesn't support getting context from current thread */
2296  if (hThread == GetCurrentThread())
2297  return;
2298 
2299  DPRINTF("Backtrace:\n");
2300 
2301  _DBUS_ZERO(context);
2302  context.ContextFlags = CONTEXT_FULL;
2303 
2304  SuspendThread(hThread);
2305 
2306  if (!GetThreadContext(hThread, &context))
2307  {
2308  DPRINTF("Couldn't get thread context (error %ld)\n", GetLastError());
2309  ResumeThread(hThread);
2310  return;
2311  }
2312 
2313  _DBUS_ZERO(sf);
2314 
2315 #ifdef __i386__
2316  sf.AddrFrame.Offset = context.Ebp;
2317  sf.AddrFrame.Mode = AddrModeFlat;
2318  sf.AddrPC.Offset = context.Eip;
2319  sf.AddrPC.Mode = AddrModeFlat;
2320  dwImageType = IMAGE_FILE_MACHINE_I386;
2321 #elif _M_X64
2322  dwImageType = IMAGE_FILE_MACHINE_AMD64;
2323  sf.AddrPC.Offset = context.Rip;
2324  sf.AddrPC.Mode = AddrModeFlat;
2325  sf.AddrFrame.Offset = context.Rsp;
2326  sf.AddrFrame.Mode = AddrModeFlat;
2327  sf.AddrStack.Offset = context.Rsp;
2328  sf.AddrStack.Mode = AddrModeFlat;
2329 #elif _M_IA64
2330  dwImageType = IMAGE_FILE_MACHINE_IA64;
2331  sf.AddrPC.Offset = context.StIIP;
2332  sf.AddrPC.Mode = AddrModeFlat;
2333  sf.AddrFrame.Offset = context.IntSp;
2334  sf.AddrFrame.Mode = AddrModeFlat;
2335  sf.AddrBStore.Offset= context.RsBSP;
2336  sf.AddrBStore.Mode = AddrModeFlat;
2337  sf.AddrStack.Offset = context.IntSp;
2338  sf.AddrStack.Mode = AddrModeFlat;
2339 #else
2340 # error You need to fill in the STACKFRAME structure for your architecture
2341 #endif
2342 
2343  while (pStackWalk(dwImageType, GetCurrentProcess(),
2344  hThread, &sf, &context, NULL, pSymFunctionTableAccess,
2345  pSymGetModuleBase, NULL))
2346  {
2347  BYTE buffer[256];
2348  IMAGEHLP_SYMBOL * pSymbol = (IMAGEHLP_SYMBOL *)buffer;
2349  DWORD dwDisplacement;
2350 
2351  pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
2352  pSymbol->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1;
2353 
2354  if (!pSymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset,
2355  &dwDisplacement, pSymbol))
2356  {
2357  IMAGEHLP_MODULE ModuleInfo;
2358  ModuleInfo.SizeOfStruct = sizeof(ModuleInfo);
2359 
2360  if (!pSymGetModuleInfo(GetCurrentProcess(), sf.AddrPC.Offset,
2361  &ModuleInfo))
2362  DPRINTF("1\t%p\n", (void*)sf.AddrPC.Offset);
2363  else
2364  DPRINTF("2\t%s+0x%lx\n", ModuleInfo.ImageName,
2365  sf.AddrPC.Offset - ModuleInfo.BaseOfImage);
2366  }
2367  else if (dwDisplacement)
2368  DPRINTF("3\t%s+0x%lx\n", pSymbol->Name, dwDisplacement);
2369  else
2370  DPRINTF("4\t%s\n", pSymbol->Name);
2371  }
2372 
2373  ResumeThread(hThread);
2374 }
2375 
2376 static DWORD WINAPI dump_thread_proc(LPVOID lpParameter)
2377 {
2378  dump_backtrace_for_thread((HANDLE)lpParameter);
2379  return 0;
2380 }
2381 
2382 /* cannot get valid context from current thread, so we have to execute
2383  * backtrace from another thread */
2384 static void dump_backtrace()
2385 {
2386  HANDLE hCurrentThread;
2387  HANDLE hThread;
2388  DWORD dwThreadId;
2389  DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
2390  GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
2391  hThread = CreateThread(NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread,
2392  0, &dwThreadId);
2393  WaitForSingleObject(hThread, INFINITE);
2394  CloseHandle(hThread);
2395  CloseHandle(hCurrentThread);
2396 }
2397 #endif
2398 #endif /* asserts or tests enabled */
2399 
2400 #ifdef BACKTRACES
2402 {
2403  init_backtrace();
2404  dump_backtrace();
2405 }
2406 #else
2407 void _dbus_print_backtrace(void)
2408 {
2409  _dbus_verbose (" D-Bus not compiled with backtrace support\n");
2410 }
2411 #endif
2412 
2413 static dbus_uint32_t fromAscii(char ascii)
2414 {
2415  if(ascii >= '0' && ascii <= '9')
2416  return ascii - '0';
2417  if(ascii >= 'A' && ascii <= 'F')
2418  return ascii - 'A' + 10;
2419  if(ascii >= 'a' && ascii <= 'f')
2420  return ascii - 'a' + 10;
2421  return 0;
2422 }
2423 
2425  dbus_bool_t create_if_not_found,
2426  DBusError *error)
2427 {
2428 #ifdef DBUS_WINCE
2429  return TRUE;
2430  // TODO
2431 #else
2432  HW_PROFILE_INFOA info;
2433  char *lpc = &info.szHwProfileGuid[0];
2434  dbus_uint32_t u;
2435 
2436  // the hw-profile guid lives long enough
2437  if(!GetCurrentHwProfileA(&info))
2438  {
2439  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); // FIXME
2440  return FALSE;
2441  }
2442 
2443  // Form: {12340001-4980-1920-6788-123456789012}
2444  lpc++;
2445  // 12340001
2446  u = ((fromAscii(lpc[0]) << 0) |
2447  (fromAscii(lpc[1]) << 4) |
2448  (fromAscii(lpc[2]) << 8) |
2449  (fromAscii(lpc[3]) << 12) |
2450  (fromAscii(lpc[4]) << 16) |
2451  (fromAscii(lpc[5]) << 20) |
2452  (fromAscii(lpc[6]) << 24) |
2453  (fromAscii(lpc[7]) << 28));
2454  machine_id->as_uint32s[0] = u;
2455 
2456  lpc += 9;
2457  // 4980-1920
2458  u = ((fromAscii(lpc[0]) << 0) |
2459  (fromAscii(lpc[1]) << 4) |
2460  (fromAscii(lpc[2]) << 8) |
2461  (fromAscii(lpc[3]) << 12) |
2462  (fromAscii(lpc[5]) << 16) |
2463  (fromAscii(lpc[6]) << 20) |
2464  (fromAscii(lpc[7]) << 24) |
2465  (fromAscii(lpc[8]) << 28));
2466  machine_id->as_uint32s[1] = u;
2467 
2468  lpc += 10;
2469  // 6788-1234
2470  u = ((fromAscii(lpc[0]) << 0) |
2471  (fromAscii(lpc[1]) << 4) |
2472  (fromAscii(lpc[2]) << 8) |
2473  (fromAscii(lpc[3]) << 12) |
2474  (fromAscii(lpc[5]) << 16) |
2475  (fromAscii(lpc[6]) << 20) |
2476  (fromAscii(lpc[7]) << 24) |
2477  (fromAscii(lpc[8]) << 28));
2478  machine_id->as_uint32s[2] = u;
2479 
2480  lpc += 9;
2481  // 56789012
2482  u = ((fromAscii(lpc[0]) << 0) |
2483  (fromAscii(lpc[1]) << 4) |
2484  (fromAscii(lpc[2]) << 8) |
2485  (fromAscii(lpc[3]) << 12) |
2486  (fromAscii(lpc[4]) << 16) |
2487  (fromAscii(lpc[5]) << 20) |
2488  (fromAscii(lpc[6]) << 24) |
2489  (fromAscii(lpc[7]) << 28));
2490  machine_id->as_uint32s[3] = u;
2491 #endif
2492  return TRUE;
2493 }
2494 
2495 static
2496 HANDLE _dbus_global_lock (const char *mutexname)
2497 {
2498  HANDLE mutex;
2499  DWORD gotMutex;
2500 
2501  mutex = CreateMutexA( NULL, FALSE, mutexname );
2502  if( !mutex )
2503  {
2504  return FALSE;
2505  }
2506 
2507  gotMutex = WaitForSingleObject( mutex, INFINITE );
2508  switch( gotMutex )
2509  {
2510  case WAIT_ABANDONED:
2511  ReleaseMutex (mutex);
2512  CloseHandle (mutex);
2513  return 0;
2514  case WAIT_FAILED:
2515  case WAIT_TIMEOUT:
2516  return 0;
2517  }
2518 
2519  return mutex;
2520 }
2521 
2522 static
2523 void _dbus_global_unlock (HANDLE mutex)
2524 {
2525  ReleaseMutex (mutex);
2526  CloseHandle (mutex);
2527 }
2528 
2529 // for proper cleanup in dbus-daemon
2530 static HANDLE hDBusDaemonMutex = NULL;
2531 static HANDLE hDBusSharedMem = NULL;
2532 // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
2533 static const char *cUniqueDBusInitMutex = "UniqueDBusInitMutex";
2534 // sync _dbus_get_autolaunch_address
2535 static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex";
2536 // mutex to determine if dbus-daemon is already started (per user)
2537 static const char *cDBusDaemonMutex = "DBusDaemonMutex";
2538 // named shm for dbus adress info (per user)
2539 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
2540 
2541 static dbus_bool_t
2542 _dbus_get_install_root_as_hash(DBusString *out)
2543 {
2544  DBusString install_path;
2545 
2546  char path[MAX_PATH*2];
2547  int path_size = sizeof(path);
2548 
2549  if (!_dbus_get_install_root(path,path_size))
2550  return FALSE;
2551 
2552  _dbus_string_init(&install_path);
2553  _dbus_string_append(&install_path,path);
2554 
2555  _dbus_string_init(out);
2556  _dbus_string_tolower_ascii(&install_path,0,_dbus_string_get_length(&install_path));
2557 
2558  if (!_dbus_sha_compute (&install_path, out))
2559  return FALSE;
2560 
2561  return TRUE;
2562 }
2563 
2564 static dbus_bool_t
2565 _dbus_get_address_string (DBusString *out, const char *basestring, const char *scope)
2566 {
2567  _dbus_string_init(out);
2568  _dbus_string_append(out,basestring);
2569 
2570  if (!scope)
2571  {
2572  return TRUE;
2573  }
2574  else if (strcmp(scope,"*install-path") == 0
2575  // for 1.3 compatibility
2576  || strcmp(scope,"install-path") == 0)
2577  {
2578  DBusString temp;
2579  if (!_dbus_get_install_root_as_hash(&temp))
2580  {
2581  _dbus_string_free(out);
2582  return FALSE;
2583  }
2584  _dbus_string_append(out,"-");
2586  _dbus_string_free(&temp);
2587  }
2588  else if (strcmp(scope,"*user") == 0)
2589  {
2590  _dbus_string_append(out,"-");
2592  {
2593  _dbus_string_free(out);
2594  return FALSE;
2595  }
2596  }
2597  else if (strlen(scope) > 0)
2598  {
2599  _dbus_string_append(out,"-");
2600  _dbus_string_append(out,scope);
2601  return TRUE;
2602  }
2603  return TRUE;
2604 }
2605 
2606 static dbus_bool_t
2607 _dbus_get_shm_name (DBusString *out,const char *scope)
2608 {
2609  return _dbus_get_address_string (out,cDBusDaemonAddressInfo,scope);
2610 }
2611 
2612 static dbus_bool_t
2613 _dbus_get_mutex_name (DBusString *out,const char *scope)
2614 {
2615  return _dbus_get_address_string (out,cDBusDaemonMutex,scope);
2616 }
2617 
2619 _dbus_daemon_is_session_bus_address_published (const char *scope)
2620 {
2621  HANDLE lock;
2622  HANDLE mutex;
2623  DBusString mutex_name;
2624  DWORD ret;
2625 
2626  if (!_dbus_get_mutex_name(&mutex_name,scope))
2627  {
2628  _dbus_string_free( &mutex_name );
2629  return FALSE;
2630  }
2631 
2632  if (hDBusDaemonMutex)
2633  return TRUE;
2634 
2635  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
2636  lock = _dbus_global_lock( cUniqueDBusInitMutex );
2637 
2638  // we use CreateMutex instead of OpenMutex because of possible race conditions,
2639  // see http://msdn.microsoft.com/en-us/library/ms684315%28VS.85%29.aspx
2640  hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
2641 
2642  _dbus_global_unlock( lock );
2643 
2644  _dbus_string_free( &mutex_name );
2645 
2646  if (hDBusDaemonMutex == NULL)
2647  return FALSE;
2648  if (GetLastError() == ERROR_ALREADY_EXISTS)
2649  {
2650  CloseHandle(hDBusDaemonMutex);
2651  hDBusDaemonMutex = NULL;
2652  return TRUE;
2653  }
2654  // mutex wasn't created before, so return false.
2655  // We leave the mutex name allocated for later reusage
2656  // in _dbus_daemon_publish_session_bus_address.
2657  return FALSE;
2658 }
2659 
2661 _dbus_daemon_publish_session_bus_address (const char* address, const char *scope)
2662 {
2663  HANDLE lock;
2664  char *shared_addr = NULL;
2665  DWORD ret;
2666  char addressInfo[1024];
2667  DBusString shm_name;
2668  DBusString mutex_name;
2669 
2670  _dbus_assert (address);
2671 
2672  if (!_dbus_get_mutex_name(&mutex_name,scope))
2673  {
2674  _dbus_string_free( &mutex_name );
2675  return FALSE;
2676  }
2677 
2678  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
2679  lock = _dbus_global_lock( cUniqueDBusInitMutex );
2680 
2681  if (!hDBusDaemonMutex)
2682  {
2683  hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
2684  }
2685  _dbus_string_free( &mutex_name );
2686 
2687  if (!_dbus_get_shm_name(&shm_name,scope))
2688  {
2689  _dbus_string_free( &shm_name );
2690  _dbus_global_unlock( lock );
2691  return FALSE;
2692  }
2693 
2694  // create shm
2695  hDBusSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
2696  0, strlen( address ) + 1, _dbus_string_get_const_data(&shm_name) );
2697  _dbus_assert( hDBusSharedMem );
2698 
2699  shared_addr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
2700 
2701  _dbus_assert (shared_addr);
2702 
2703  strcpy( shared_addr, address);
2704 
2705  // cleanup
2706  UnmapViewOfFile( shared_addr );
2707 
2708  _dbus_global_unlock( lock );
2709  _dbus_verbose( "published session bus address at %s\n",_dbus_string_get_const_data (&shm_name) );
2710 
2711  _dbus_string_free( &shm_name );
2712  return TRUE;
2713 }
2714 
2715 void
2716 _dbus_daemon_unpublish_session_bus_address (void)
2717 {
2718  HANDLE lock;
2719 
2720  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
2721  lock = _dbus_global_lock( cUniqueDBusInitMutex );
2722 
2723  CloseHandle( hDBusSharedMem );
2724 
2725  hDBusSharedMem = NULL;
2726 
2727  ReleaseMutex( hDBusDaemonMutex );
2728 
2729  CloseHandle( hDBusDaemonMutex );
2730 
2731  hDBusDaemonMutex = NULL;
2732 
2733  _dbus_global_unlock( lock );
2734 }
2735 
2736 static dbus_bool_t
2737 _dbus_get_autolaunch_shm (DBusString *address, DBusString *shm_name)
2738 {
2739  HANDLE sharedMem;
2740  char *shared_addr;
2741  int i;
2742 
2743  // read shm
2744  for(i=0;i<20;++i) {
2745  // we know that dbus-daemon is available, so we wait until shm is available
2746  sharedMem = OpenFileMappingA( FILE_MAP_READ, FALSE, _dbus_string_get_const_data(shm_name));
2747  if( sharedMem == 0 )
2748  Sleep( 100 );
2749  if ( sharedMem != 0)
2750  break;
2751  }
2752 
2753  if( sharedMem == 0 )
2754  return FALSE;
2755 
2756  shared_addr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
2757 
2758  if( !shared_addr )
2759  return FALSE;
2760 
2761  _dbus_string_init( address );
2762 
2763  _dbus_string_append( address, shared_addr );
2764 
2765  // cleanup
2766  UnmapViewOfFile( shared_addr );
2767 
2768  CloseHandle( sharedMem );
2769 
2770  return TRUE;
2771 }
2772 
2773 static dbus_bool_t
2774 _dbus_daemon_already_runs (DBusString *address, DBusString *shm_name, const char *scope)
2775 {
2776  HANDLE lock;
2777  HANDLE daemon;
2778  DBusString mutex_name;
2779  dbus_bool_t bRet = TRUE;
2780 
2781  if (!_dbus_get_mutex_name(&mutex_name,scope))
2782  {
2783  _dbus_string_free( &mutex_name );
2784  return FALSE;
2785  }
2786 
2787  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
2788  lock = _dbus_global_lock( cUniqueDBusInitMutex );
2789 
2790  // do checks
2791  daemon = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
2792  if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT)
2793  {
2794  ReleaseMutex (daemon);
2795  CloseHandle (daemon);
2796 
2797  _dbus_global_unlock( lock );
2798  _dbus_string_free( &mutex_name );
2799  return FALSE;
2800  }
2801 
2802  // read shm
2803  bRet = _dbus_get_autolaunch_shm( address, shm_name );
2804 
2805  // cleanup
2806  CloseHandle ( daemon );
2807 
2808  _dbus_global_unlock( lock );
2809  _dbus_string_free( &mutex_name );
2810 
2811  return bRet;
2812 }
2813 
2815 _dbus_get_autolaunch_address (const char *scope, DBusString *address,
2816  DBusError *error)
2817 {
2818  HANDLE mutex;
2819  STARTUPINFOA si;
2820  PROCESS_INFORMATION pi;
2821  dbus_bool_t retval = FALSE;
2822  LPSTR lpFile;
2823  char dbus_exe_path[MAX_PATH];
2824  char dbus_args[MAX_PATH * 2];
2825  const char * daemon_name = DBUS_DAEMON_NAME ".exe";
2826  DBusString shm_name;
2827 
2828  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2829 
2830  if (!_dbus_get_shm_name(&shm_name,scope))
2831  {
2832  dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not determine shm name");
2833  return FALSE;
2834  }
2835 
2836  mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
2837 
2838  if (_dbus_daemon_already_runs(address,&shm_name,scope))
2839  {
2840  _dbus_verbose( "found running dbus daemon at %s\n",
2841  _dbus_string_get_const_data (&shm_name) );
2842  retval = TRUE;
2843  goto out;
2844  }
2845 
2846  if (!SearchPathA(NULL, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
2847  {
2848  printf ("please add the path to %s to your PATH environment variable\n", daemon_name);
2849  printf ("or start the daemon manually\n\n");
2850  goto out;
2851  }
2852 
2853  // Create process
2854  ZeroMemory( &si, sizeof(si) );
2855  si.cb = sizeof(si);
2856  ZeroMemory( &pi, sizeof(pi) );
2857 
2858  _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path, " --session");
2859 
2860 // argv[i] = "--config-file=bus\\session.conf";
2861 // printf("create process \"%s\" %s\n", dbus_exe_path, dbus_args);
2862  if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
2863  {
2864  CloseHandle (pi.hThread);
2865  CloseHandle (pi.hProcess);
2866  retval = _dbus_get_autolaunch_shm( address, &shm_name );
2867  if (retval == FALSE)
2868  dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to get autolaunch address from launched dbus-daemon");
2869  }
2870  else
2871  {
2872  dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to launch dbus-daemon");
2873  retval = FALSE;
2874  }
2875 
2876 out:
2877  if (retval)
2878  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2879  else
2880  _DBUS_ASSERT_ERROR_IS_SET (error);
2881 
2882  _dbus_global_unlock (mutex);
2883 
2884  return retval;
2885  }
2886 
2887 
2896  DBusError *error)
2897 {
2898  // TODO
2899  return TRUE;
2900 }
2901 
2908 static const char *
2909 _dbus_windows_get_datadir (void)
2910 {
2911  return _dbus_replace_install_prefix(DBUS_DATADIR);
2912 }
2913 
2914 #undef DBUS_DATADIR
2915 #define DBUS_DATADIR _dbus_windows_get_datadir ()
2916 
2917 
2918 #define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
2919 #define DBUS_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
2920 
2937 dbus_bool_t
2939 {
2940  const char *common_progs;
2941  DBusString servicedir_path;
2942 
2943  if (!_dbus_string_init (&servicedir_path))
2944  return FALSE;
2945 
2946 #ifdef DBUS_WINCE
2947  {
2948  /* On Windows CE, we adjust datadir dynamically to installation location. */
2949  const char *data_dir = _dbus_getenv ("DBUS_DATADIR");
2950 
2951  if (data_dir != NULL)
2952  {
2953  if (!_dbus_string_append (&servicedir_path, data_dir))
2954  goto oom;
2955 
2956  if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
2957  goto oom;
2958  }
2959  }
2960 #else
2961 /*
2962  the code for accessing services requires absolute base pathes
2963  in case DBUS_DATADIR is relative make it absolute
2964 */
2965 #ifdef DBUS_WIN
2966  {
2967  DBusString p;
2968 
2969  _dbus_string_init_const (&p, DBUS_DATADIR);
2970 
2971  if (!_dbus_path_is_absolute (&p))
2972  {
2973  char install_root[1000];
2974  if (_dbus_get_install_root (install_root, sizeof(install_root)))
2975  if (!_dbus_string_append (&servicedir_path, install_root))
2976  goto oom;
2977  }
2978  }
2979 #endif
2980  if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
2981  goto oom;
2982 
2983  if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
2984  goto oom;
2985 #endif
2986 
2987  common_progs = _dbus_getenv ("CommonProgramFiles");
2988 
2989  if (common_progs != NULL)
2990  {
2991  if (!_dbus_string_append (&servicedir_path, common_progs))
2992  goto oom;
2993 
2994  if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
2995  goto oom;
2996  }
2997 
2998  if (!_dbus_split_paths_and_append (&servicedir_path,
2999  DBUS_STANDARD_SESSION_SERVICEDIR,
3000  dirs))
3001  goto oom;
3002 
3003  _dbus_string_free (&servicedir_path);
3004  return TRUE;
3005 
3006  oom:
3007  _dbus_string_free (&servicedir_path);
3008  return FALSE;
3009 }
3010 
3031 {
3032  *dirs = NULL;
3033  return TRUE;
3034 }
3035 
3036 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
3037 
3047 {
3048  // +/- 1 is needed here!
3049  // no volatile argument with mingw
3050  return InterlockedIncrement (&atomic->value) - 1;
3051 }
3052 
3062 {
3063  // +/- 1 is needed here!
3064  // no volatile argument with mingw
3065  return InterlockedDecrement (&atomic->value) + 1;
3066 }
3067 
3075 void
3077 {
3078 }
3079 
3088 {
3089  return errno == WSAEWOULDBLOCK;
3090 }
3091 
3100 _dbus_get_install_root(char *prefix, int len)
3101 {
3102  //To find the prefix, we cut the filename and also \bin\ if present
3103  char* p = 0;
3104  int i;
3105  DWORD pathLength;
3106  char *lastSlash;
3107  SetLastError( 0 );
3108  pathLength = GetModuleFileNameA(_dbus_win_get_dll_hmodule(), prefix, len);
3109  if ( pathLength == 0 || GetLastError() != 0 ) {
3110  *prefix = '\0';
3111  return FALSE;
3112  }
3113  lastSlash = _mbsrchr(prefix, '\\');
3114  if (lastSlash == NULL) {
3115  *prefix = '\0';
3116  return FALSE;
3117  }
3118  //cut off binary name
3119  lastSlash[1] = 0;
3120 
3121  //cut possible "\\bin"
3122 
3123  //this fails if we are in a double-byte system codepage and the
3124  //folder's name happens to end with the *bytes*
3125  //"\\bin"... (I.e. the second byte of some Han character and then
3126  //the Latin "bin", but that is not likely I think...
3127  if (lastSlash - prefix >= 4 && strnicmp(lastSlash - 4, "\\bin", 4) == 0)
3128  lastSlash[-3] = 0;
3129  else if (lastSlash - prefix >= 10 && strnicmp(lastSlash - 10, "\\bin\\debug", 10) == 0)
3130  lastSlash[-9] = 0;
3131  else if (lastSlash - prefix >= 12 && strnicmp(lastSlash - 12, "\\bin\\release", 12) == 0)
3132  lastSlash[-11] = 0;
3133 
3134  return TRUE;
3135 }
3136 
3150 dbus_bool_t
3151 _dbus_get_config_file_name(DBusString *config_file, char *s)
3152 {
3153  char path[MAX_PATH*2];
3154  int path_size = sizeof(path);
3155 
3156  if (!_dbus_get_install_root(path,path_size))
3157  return FALSE;
3158 
3159  if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
3160  return FALSE;
3161  strcat(path,"etc\\");
3162  strcat(path,s);
3163  if (_dbus_file_exists(path))
3164  {
3165  // find path from executable
3166  if (!_dbus_string_append (config_file, path))
3167  return FALSE;
3168  }
3169  else
3170  {
3171  if (!_dbus_get_install_root(path,path_size))
3172  return FALSE;
3173  if(strlen(s) + 11 + strlen(path) > sizeof(path)-2)
3174  return FALSE;
3175  strcat(path,"etc\\dbus-1\\");
3176  strcat(path,s);
3177 
3178  if (_dbus_file_exists(path))
3179  {
3180  if (!_dbus_string_append (config_file, path))
3181  return FALSE;
3182  }
3183  else
3184  {
3185  if (!_dbus_get_install_root(path,path_size))
3186  return FALSE;
3187  if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
3188  return FALSE;
3189  strcat(path,"bus\\");
3190  strcat(path,s);
3191 
3192  if (_dbus_file_exists(path))
3193  {
3194  if (!_dbus_string_append (config_file, path))
3195  return FALSE;
3196  }
3197  }
3198  }
3199  return TRUE;
3200 }
3201 
3212 {
3213  return _dbus_get_config_file_name(str, "system.conf");
3214 }
3215 
3224 {
3225  return _dbus_get_config_file_name(str, "session.conf");
3226 }
3227 
3228 /* See comment in dbus-sysdeps-unix.c */
3231  DBusString *address,
3232  DBusError *error)
3233 {
3234  /* Probably fill this in with something based on COM? */
3235  *supported = FALSE;
3236  return TRUE;
3237 }
3238 
3254  DBusCredentials *credentials)
3255 {
3256  DBusString homedir;
3257  DBusString dotdir;
3258  dbus_uid_t uid;
3259  const char *homepath;
3260  const char *homedrive;
3261 
3262  _dbus_assert (credentials != NULL);
3264 
3265  if (!_dbus_string_init (&homedir))
3266  return FALSE;
3267 
3268  homedrive = _dbus_getenv("HOMEDRIVE");
3269  if (homedrive != NULL && *homedrive != '\0')
3270  {
3271  _dbus_string_append(&homedir,homedrive);
3272  }
3273 
3274  homepath = _dbus_getenv("HOMEPATH");
3275  if (homepath != NULL && *homepath != '\0')
3276  {
3277  _dbus_string_append(&homedir,homepath);
3278  }
3279 
3280 #ifdef DBUS_BUILD_TESTS
3281  {
3282  const char *override;
3283 
3284  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3285  if (override != NULL && *override != '\0')
3286  {
3287  _dbus_string_set_length (&homedir, 0);
3288  if (!_dbus_string_append (&homedir, override))
3289  goto failed;
3290 
3291  _dbus_verbose ("Using fake homedir for testing: %s\n",
3292  _dbus_string_get_const_data (&homedir));
3293  }
3294  else
3295  {
3296  static dbus_bool_t already_warned = FALSE;
3297  if (!already_warned)
3298  {
3299  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3300  already_warned = TRUE;
3301  }
3302  }
3303  }
3304 #endif
3305 
3306 #ifdef DBUS_WINCE
3307  /* It's not possible to create a .something directory in Windows CE
3308  using the file explorer. */
3309 #define KEYRING_DIR "dbus-keyrings"
3310 #else
3311 #define KEYRING_DIR ".dbus-keyrings"
3312 #endif
3313 
3314  _dbus_string_init_const (&dotdir, KEYRING_DIR);
3315  if (!_dbus_concat_dir_and_file (&homedir,
3316  &dotdir))
3317  goto failed;
3318 
3319  if (!_dbus_string_copy (&homedir, 0,
3320  directory, _dbus_string_get_length (directory))) {
3321  goto failed;
3322  }
3323 
3324  _dbus_string_free (&homedir);
3325  return TRUE;
3326 
3327  failed:
3328  _dbus_string_free (&homedir);
3329  return FALSE;
3330 }
3331 
3337 dbus_bool_t
3338 _dbus_file_exists (const char *file)
3339 {
3340  DWORD attributes = GetFileAttributesA (file);
3341 
3342  if (attributes != INVALID_FILE_ATTRIBUTES && GetLastError() != ERROR_PATH_NOT_FOUND)
3343  return TRUE;
3344  else
3345  return FALSE;
3346 }
3347 
3355 const char*
3356 _dbus_strerror (int error_number)
3357 {
3358 #ifdef DBUS_WINCE
3359  // TODO
3360  return "unknown";
3361 #else
3362  const char *msg;
3363 
3364  switch (error_number)
3365  {
3366  case WSAEINTR:
3367  return "Interrupted function call";
3368  case WSAEACCES:
3369  return "Permission denied";
3370  case WSAEFAULT:
3371  return "Bad address";
3372  case WSAEINVAL:
3373  return "Invalid argument";
3374  case WSAEMFILE:
3375  return "Too many open files";
3376  case WSAEWOULDBLOCK:
3377  return "Resource temporarily unavailable";
3378  case WSAEINPROGRESS:
3379  return "Operation now in progress";
3380  case WSAEALREADY:
3381  return "Operation already in progress";
3382  case WSAENOTSOCK:
3383  return "Socket operation on nonsocket";
3384  case WSAEDESTADDRREQ:
3385  return "Destination address required";
3386  case WSAEMSGSIZE:
3387  return "Message too long";
3388  case WSAEPROTOTYPE:
3389  return "Protocol wrong type for socket";
3390  case WSAENOPROTOOPT:
3391  return "Bad protocol option";
3392  case WSAEPROTONOSUPPORT:
3393  return "Protocol not supported";
3394  case WSAESOCKTNOSUPPORT:
3395  return "Socket type not supported";
3396  case WSAEOPNOTSUPP:
3397  return "Operation not supported";
3398  case WSAEPFNOSUPPORT:
3399  return "Protocol family not supported";
3400  case WSAEAFNOSUPPORT:
3401  return "Address family not supported by protocol family";
3402  case WSAEADDRINUSE:
3403  return "Address already in use";
3404  case WSAEADDRNOTAVAIL:
3405  return "Cannot assign requested address";
3406  case WSAENETDOWN:
3407  return "Network is down";
3408  case WSAENETUNREACH:
3409  return "Network is unreachable";
3410  case WSAENETRESET:
3411  return "Network dropped connection on reset";
3412  case WSAECONNABORTED:
3413  return "Software caused connection abort";
3414  case WSAECONNRESET:
3415  return "Connection reset by peer";
3416  case WSAENOBUFS:
3417  return "No buffer space available";
3418  case WSAEISCONN:
3419  return "Socket is already connected";
3420  case WSAENOTCONN:
3421  return "Socket is not connected";
3422  case WSAESHUTDOWN:
3423  return "Cannot send after socket shutdown";
3424  case WSAETIMEDOUT:
3425  return "Connection timed out";
3426  case WSAECONNREFUSED:
3427  return "Connection refused";
3428  case WSAEHOSTDOWN:
3429  return "Host is down";
3430  case WSAEHOSTUNREACH:
3431  return "No route to host";
3432  case WSAEPROCLIM:
3433  return "Too many processes";
3434  case WSAEDISCON:
3435  return "Graceful shutdown in progress";
3436  case WSATYPE_NOT_FOUND:
3437  return "Class type not found";
3438  case WSAHOST_NOT_FOUND:
3439  return "Host not found";
3440  case WSATRY_AGAIN:
3441  return "Nonauthoritative host not found";
3442  case WSANO_RECOVERY:
3443  return "This is a nonrecoverable error";
3444  case WSANO_DATA:
3445  return "Valid name, no data record of requested type";
3446  case WSA_INVALID_HANDLE:
3447  return "Specified event object handle is invalid";
3448  case WSA_INVALID_PARAMETER:
3449  return "One or more parameters are invalid";
3450  case WSA_IO_INCOMPLETE:
3451  return "Overlapped I/O event object not in signaled state";
3452  case WSA_IO_PENDING:
3453  return "Overlapped operations will complete later";
3454  case WSA_NOT_ENOUGH_MEMORY:
3455  return "Insufficient memory available";
3456  case WSA_OPERATION_ABORTED:
3457  return "Overlapped operation aborted";
3458 #ifdef WSAINVALIDPROCTABLE
3459 
3460  case WSAINVALIDPROCTABLE:
3461  return "Invalid procedure table from service provider";
3462 #endif
3463 #ifdef WSAINVALIDPROVIDER
3464 
3465  case WSAINVALIDPROVIDER:
3466  return "Invalid service provider version number";
3467 #endif
3468 #ifdef WSAPROVIDERFAILEDINIT
3469 
3470  case WSAPROVIDERFAILEDINIT:
3471  return "Unable to initialize a service provider";
3472 #endif
3473 
3474  case WSASYSCALLFAILURE:
3475  return "System call failure";
3476  }
3477  msg = strerror (error_number);
3478  if (msg == NULL)
3479  msg = "unknown";
3480 
3481  return msg;
3482 #endif //DBUS_WINCE
3483 }
3484 
3492 void
3493 _dbus_win_set_error_from_win_error (DBusError *error,
3494  int code)
3495 {
3496  char *msg;
3497 
3498  /* As we want the English message, use the A API */
3499  FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
3500  FORMAT_MESSAGE_IGNORE_INSERTS |
3501  FORMAT_MESSAGE_FROM_SYSTEM,
3502  NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
3503  (LPSTR) &msg, 0, NULL);
3504  if (msg)
3505  {
3506  char *msg_copy;
3507 
3508  msg_copy = dbus_malloc (strlen (msg));
3509  strcpy (msg_copy, msg);
3510  LocalFree (msg);
3511 
3512  dbus_set_error (error, "win32.error", "%s", msg_copy);
3513  }
3514  else
3515  dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code);
3516 }
3517 
3518 void
3519 _dbus_win_warn_win_error (const char *message,
3520  int code)
3521 {
3522  DBusError error;
3523 
3524  dbus_error_init (&error);
3525  _dbus_win_set_error_from_win_error (&error, code);
3526  _dbus_warn ("%s: %s\n", message, error.message);
3527  dbus_error_free (&error);
3528 }
3529 
3539  DBusError *error)
3540 {
3541  const char *filename_c;
3542 
3543  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3544 
3545  filename_c = _dbus_string_get_const_data (filename);
3546 
3547  if (RemoveDirectoryA (filename_c) == 0)
3548  {
3549  char *emsg = _dbus_win_error_string (GetLastError ());
3550  dbus_set_error (error, _dbus_win_error_from_last_error (),
3551  "Failed to remove directory %s: %s",
3552  filename_c, emsg);
3553  _dbus_win_free_error_string (emsg);
3554  return FALSE;
3555  }
3556 
3557  return TRUE;
3558 }
3559 
3568 {
3569  if (_dbus_string_get_length (filename) > 0)
3570  return _dbus_string_get_byte (filename, 1) == ':'
3571  || _dbus_string_get_byte (filename, 0) == '\\'
3572  || _dbus_string_get_byte (filename, 0) == '/';
3573  else
3574  return FALSE;
3575 }
3576 
3579 {
3580  return FALSE;
3581 }
3582 
3584 /* tests in dbus-sysdeps-util.c */
3585