D-Bus  1.7.4
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-2013 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 #include <iphlpapi.h>
58 
59 /* Declarations missing in mingw's and windows sdk 7.0 headers */
60 extern BOOL WINAPI ConvertStringSidToSidA (LPCSTR StringSid, PSID *Sid);
61 extern BOOL WINAPI ConvertSidToStringSidA (PSID Sid, LPSTR *StringSid);
62 
63 #include <stdio.h>
64 
65 #include <string.h>
66 #if HAVE_ERRNO_H
67 #include <errno.h>
68 #endif
69 #ifndef DBUS_WINCE
70 #include <mbstring.h>
71 #include <sys/stat.h>
72 #include <sys/types.h>
73 #endif
74 
75 #ifdef HAVE_WS2TCPIP_H
76 /* getaddrinfo for Windows CE (and Windows). */
77 #include <ws2tcpip.h>
78 #endif
79 
80 #ifdef HAVE_WSPIAPI_H
81 // needed for w2k compatibility (getaddrinfo/freeaddrinfo/getnameinfo)
82 #ifdef __GNUC__
83 #define _inline
84 #include "wspiapi.h"
85 #else
86 #include <wspiapi.h>
87 #endif
88 #endif // HAVE_WSPIAPI_H
89 
90 #ifndef O_BINARY
91 #define O_BINARY 0
92 #endif
93 
94 typedef int socklen_t;
95 
96 
97 void
98 _dbus_win_set_errno (int err)
99 {
100 #ifdef DBUS_WINCE
101  SetLastError (err);
102 #else
103  errno = err;
104 #endif
105 }
106 
112 static dbus_pid_t
113 _dbus_get_peer_pid_from_tcp_handle (int handle)
114 {
115  struct sockaddr_storage addr;
116  socklen_t len = sizeof (addr);
117  int peer_port;
118 
119  dbus_pid_t result;
120  DWORD size;
121  MIB_TCPTABLE_OWNER_PID *tcp_table;
122  DWORD i;
123  dbus_bool_t is_localhost = FALSE;
124 
125  getpeername (handle, (struct sockaddr *) &addr, &len);
126 
127  if (addr.ss_family == AF_INET)
128  {
129  struct sockaddr_in *s = (struct sockaddr_in *) &addr;
130  peer_port = ntohs (s->sin_port);
131  is_localhost = (htonl (s->sin_addr.s_addr) == INADDR_LOOPBACK);
132  }
133  else if (addr.ss_family == AF_INET6)
134  {
135  _dbus_verbose ("FIXME [61922]: IPV6 support not working on windows\n");
136  return 0;
137  /*
138  struct sockaddr_in6 *s = (struct sockaddr_in6 * )&addr;
139  peer_port = ntohs (s->sin6_port);
140  is_localhost = (memcmp(s->sin6_addr.s6_addr, in6addr_loopback.s6_addr, 16) == 0);
141  _dbus_verbose ("IPV6 %08x %08x\n", s->sin6_addr.s6_addr, in6addr_loopback.s6_addr);
142  */
143  }
144  else
145  {
146  _dbus_verbose ("no idea what address family %d is\n", addr.ss_family);
147  return 0;
148  }
149 
150  if (!is_localhost)
151  {
152  _dbus_verbose ("could not fetch process id from remote process\n");
153  return 0;
154  }
155 
156  if (peer_port == 0)
157  {
158  _dbus_verbose
159  ("Error not been able to fetch tcp peer port from connection\n");
160  return 0;
161  }
162 
163  if ((result =
164  GetExtendedTcpTable (NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0)) == ERROR_INSUFFICIENT_BUFFER)
165  {
166  tcp_table = (MIB_TCPTABLE_OWNER_PID *) dbus_malloc (size);
167  if (tcp_table == NULL)
168  {
169  _dbus_verbose ("Error allocating memory\n");
170  return 0;
171  }
172  }
173 
174  if ((result = GetExtendedTcpTable (tcp_table, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0)) != NO_ERROR)
175  {
176  _dbus_verbose ("Error fetching tcp table %d\n", result);
177  dbus_free (tcp_table);
178  return 0;
179  }
180 
181  result = 0;
182  for (i = 0; i < tcp_table->dwNumEntries; i++)
183  {
184  MIB_TCPROW_OWNER_PID *p = &tcp_table->table[i];
185  int local_port = ntohs (p->dwLocalPort);
186  if (p->dwState == MIB_TCP_STATE_ESTAB && local_port == peer_port)
187  result = p->dwOwningPid;
188  }
189 
190  _dbus_verbose ("got pid %d\n", result);
191  dbus_free (tcp_table);
192  return result;
193 }
194 
195 /* Convert GetLastError() to a dbus error. */
196 const char*
197 _dbus_win_error_from_last_error (void)
198 {
199  switch (GetLastError())
200  {
201  case 0:
202  return DBUS_ERROR_FAILED;
203 
204  case ERROR_NO_MORE_FILES:
205  case ERROR_TOO_MANY_OPEN_FILES:
206  return DBUS_ERROR_LIMITS_EXCEEDED; /* kernel out of memory */
207 
208  case ERROR_ACCESS_DENIED:
209  case ERROR_CANNOT_MAKE:
211 
212  case ERROR_NOT_ENOUGH_MEMORY:
213  return DBUS_ERROR_NO_MEMORY;
214 
215  case ERROR_FILE_EXISTS:
216  return DBUS_ERROR_FILE_EXISTS;
217 
218  case ERROR_FILE_NOT_FOUND:
219  case ERROR_PATH_NOT_FOUND:
221  }
222 
223  return DBUS_ERROR_FAILED;
224 }
225 
226 
227 char*
228 _dbus_win_error_string (int error_number)
229 {
230  char *msg;
231 
232  FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
233  FORMAT_MESSAGE_IGNORE_INSERTS |
234  FORMAT_MESSAGE_FROM_SYSTEM,
235  NULL, error_number, 0,
236  (LPSTR) &msg, 0, NULL);
237 
238  if (msg[strlen (msg) - 1] == '\n')
239  msg[strlen (msg) - 1] = '\0';
240  if (msg[strlen (msg) - 1] == '\r')
241  msg[strlen (msg) - 1] = '\0';
242 
243  return msg;
244 }
245 
246 void
247 _dbus_win_free_error_string (char *string)
248 {
249  LocalFree (string);
250 }
251 
272 int
274  DBusString *buffer,
275  int count)
276 {
277  int bytes_read;
278  int start;
279  char *data;
280 
281  _dbus_assert (count >= 0);
282 
283  start = _dbus_string_get_length (buffer);
284 
285  if (!_dbus_string_lengthen (buffer, count))
286  {
287  _dbus_win_set_errno (ENOMEM);
288  return -1;
289  }
290 
291  data = _dbus_string_get_data_len (buffer, start, count);
292 
293  again:
294 
295  _dbus_verbose ("recv: count=%d fd=%d\n", count, fd);
296  bytes_read = recv (fd, data, count, 0);
297 
298  if (bytes_read == SOCKET_ERROR)
299  {
300  DBUS_SOCKET_SET_ERRNO();
301  _dbus_verbose ("recv: failed: %s (%d)\n", _dbus_strerror (errno), errno);
302  bytes_read = -1;
303  }
304  else
305  _dbus_verbose ("recv: = %d\n", bytes_read);
306 
307  if (bytes_read < 0)
308  {
309  if (errno == EINTR)
310  goto again;
311  else
312  {
313  /* put length back (note that this doesn't actually realloc anything) */
314  _dbus_string_set_length (buffer, start);
315  return -1;
316  }
317  }
318  else
319  {
320  /* put length back (doesn't actually realloc) */
321  _dbus_string_set_length (buffer, start + bytes_read);
322 
323 #if 0
324  if (bytes_read > 0)
325  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
326 #endif
327 
328  return bytes_read;
329  }
330 }
331 
342 int
344  const DBusString *buffer,
345  int start,
346  int len)
347 {
348  const char *data;
349  int bytes_written;
350 
351  data = _dbus_string_get_const_data_len (buffer, start, len);
352 
353  again:
354 
355  _dbus_verbose ("send: len=%d fd=%d\n", len, fd);
356  bytes_written = send (fd, data, len, 0);
357 
358  if (bytes_written == SOCKET_ERROR)
359  {
360  DBUS_SOCKET_SET_ERRNO();
361  _dbus_verbose ("send: failed: %s\n", _dbus_strerror_from_errno ());
362  bytes_written = -1;
363  }
364  else
365  _dbus_verbose ("send: = %d\n", bytes_written);
366 
367  if (bytes_written < 0 && errno == EINTR)
368  goto again;
369 
370 #if 0
371  if (bytes_written > 0)
372  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
373 #endif
374 
375  return bytes_written;
376 }
377 
378 
388  DBusError *error)
389 {
390  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
391 
392  again:
393  if (closesocket (fd) == SOCKET_ERROR)
394  {
395  DBUS_SOCKET_SET_ERRNO ();
396 
397  if (errno == EINTR)
398  goto again;
399 
400  dbus_set_error (error, _dbus_error_from_errno (errno),
401  "Could not close socket: socket=%d, , %s",
403  return FALSE;
404  }
405  _dbus_verbose ("_dbus_close_socket: socket=%d, \n", fd);
406 
407  return TRUE;
408 }
409 
417 void
418 _dbus_fd_set_close_on_exec (intptr_t handle)
419 {
420  if ( !SetHandleInformation( (HANDLE) handle,
421  HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE,
422  0 /*disable both flags*/ ) )
423  {
424  _dbus_win_warn_win_error ("Disabling socket handle inheritance failed:", GetLastError());
425  }
426 }
427 
436 _dbus_set_fd_nonblocking (int handle,
437  DBusError *error)
438 {
439  u_long one = 1;
440 
441  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
442 
443  if (ioctlsocket (handle, FIONBIO, &one) == SOCKET_ERROR)
444  {
445  DBUS_SOCKET_SET_ERRNO ();
446  dbus_set_error (error, _dbus_error_from_errno (errno),
447  "Failed to set socket %d:%d to nonblocking: %s", handle,
449  return FALSE;
450  }
451 
452  return TRUE;
453 }
454 
455 
476 int
478  const DBusString *buffer1,
479  int start1,
480  int len1,
481  const DBusString *buffer2,
482  int start2,
483  int len2)
484 {
485  WSABUF vectors[2];
486  const char *data1;
487  const char *data2;
488  int rc;
489  DWORD bytes_written;
490 
491  _dbus_assert (buffer1 != NULL);
492  _dbus_assert (start1 >= 0);
493  _dbus_assert (start2 >= 0);
494  _dbus_assert (len1 >= 0);
495  _dbus_assert (len2 >= 0);
496 
497 
498  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
499 
500  if (buffer2 != NULL)
501  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
502  else
503  {
504  data2 = NULL;
505  start2 = 0;
506  len2 = 0;
507  }
508 
509  vectors[0].buf = (char*) data1;
510  vectors[0].len = len1;
511  vectors[1].buf = (char*) data2;
512  vectors[1].len = len2;
513 
514  again:
515 
516  _dbus_verbose ("WSASend: len1+2=%d+%d fd=%d\n", len1, len2, fd);
517  rc = WSASend (fd,
518  vectors,
519  data2 ? 2 : 1,
520  &bytes_written,
521  0,
522  NULL,
523  NULL);
524 
525  if (rc == SOCKET_ERROR)
526  {
527  DBUS_SOCKET_SET_ERRNO ();
528  _dbus_verbose ("WSASend: failed: %s\n", _dbus_strerror_from_errno ());
529  bytes_written = -1;
530  }
531  else
532  _dbus_verbose ("WSASend: = %ld\n", bytes_written);
533 
534  if (bytes_written < 0 && errno == EINTR)
535  goto again;
536 
537  return bytes_written;
538 }
539 
541 _dbus_socket_is_invalid (int fd)
542 {
543  return fd == INVALID_SOCKET ? TRUE : FALSE;
544 }
545 
546 #if 0
547 
556 int
557 _dbus_connect_named_pipe (const char *path,
558  DBusError *error)
559 {
560  _dbus_assert_not_reached ("not implemented");
561 }
562 
563 #endif
564 
565 
566 
567 void
568 _dbus_win_startup_winsock (void)
569 {
570  /* Straight from MSDN, deuglified */
571 
572  static dbus_bool_t beenhere = FALSE;
573 
574  WORD wVersionRequested;
575  WSADATA wsaData;
576  int err;
577 
578  if (beenhere)
579  return;
580 
581  wVersionRequested = MAKEWORD (2, 0);
582 
583  err = WSAStartup (wVersionRequested, &wsaData);
584  if (err != 0)
585  {
586  _dbus_assert_not_reached ("Could not initialize WinSock");
587  _dbus_abort ();
588  }
589 
590  /* Confirm that the WinSock DLL supports 2.0. Note that if the DLL
591  * supports versions greater than 2.0 in addition to 2.0, it will
592  * still return 2.0 in wVersion since that is the version we
593  * requested.
594  */
595  if (LOBYTE (wsaData.wVersion) != 2 ||
596  HIBYTE (wsaData.wVersion) != 0)
597  {
598  _dbus_assert_not_reached ("No usable WinSock found");
599  _dbus_abort ();
600  }
601 
602  beenhere = TRUE;
603 }
604 
605 
606 
607 
608 
609 
610 
611 
612 
613 /************************************************************************
614 
615  UTF / string code
616 
617  ************************************************************************/
618 
622 int _dbus_printf_string_upper_bound (const char *format,
623  va_list args)
624 {
625  /* MSVCRT's vsnprintf semantics are a bit different */
626  char buf[1024];
627  int bufsize;
628  int len;
629  va_list args_copy;
630 
631  bufsize = sizeof (buf);
632  DBUS_VA_COPY (args_copy, args);
633  len = _vsnprintf (buf, bufsize - 1, format, args_copy);
634  va_end (args_copy);
635 
636  while (len == -1) /* try again */
637  {
638  char *p;
639 
640  bufsize *= 2;
641 
642  p = malloc (bufsize);
643 
644  if (p == NULL)
645  return -1;
646 
647  DBUS_VA_COPY (args_copy, args);
648  len = _vsnprintf (p, bufsize - 1, format, args_copy);
649  va_end (args_copy);
650  free (p);
651  }
652 
653  return len;
654 }
655 
656 
664 wchar_t *
665 _dbus_win_utf8_to_utf16 (const char *str,
666  DBusError *error)
667 {
668  DBusString s;
669  int n;
670  wchar_t *retval;
671 
672  _dbus_string_init_const (&s, str);
673 
675  {
676  dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid UTF-8");
677  return NULL;
678  }
679 
680  n = MultiByteToWideChar (CP_UTF8, 0, str, -1, NULL, 0);
681 
682  if (n == 0)
683  {
684  _dbus_win_set_error_from_win_error (error, GetLastError ());
685  return NULL;
686  }
687 
688  retval = dbus_new (wchar_t, n);
689 
690  if (!retval)
691  {
692  _DBUS_SET_OOM (error);
693  return NULL;
694  }
695 
696  if (MultiByteToWideChar (CP_UTF8, 0, str, -1, retval, n) != n)
697  {
698  dbus_free (retval);
699  dbus_set_error_const (error, DBUS_ERROR_FAILED, "MultiByteToWideChar inconsistency");
700  return NULL;
701  }
702 
703  return retval;
704 }
705 
713 char *
714 _dbus_win_utf16_to_utf8 (const wchar_t *str,
715  DBusError *error)
716 {
717  int n;
718  char *retval;
719 
720  n = WideCharToMultiByte (CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
721 
722  if (n == 0)
723  {
724  _dbus_win_set_error_from_win_error (error, GetLastError ());
725  return NULL;
726  }
727 
728  retval = dbus_malloc (n);
729 
730  if (!retval)
731  {
732  _DBUS_SET_OOM (error);
733  return NULL;
734  }
735 
736  if (WideCharToMultiByte (CP_UTF8, 0, str, -1, retval, n, NULL, NULL) != n)
737  {
738  dbus_free (retval);
739  dbus_set_error_const (error, DBUS_ERROR_FAILED, "WideCharToMultiByte inconsistency");
740  return NULL;
741  }
742 
743  return retval;
744 }
745 
746 
747 
748 
749 
750 
751 /************************************************************************
752 
753 
754  ************************************************************************/
755 
757 _dbus_win_account_to_sid (const wchar_t *waccount,
758  void **ppsid,
759  DBusError *error)
760 {
761  dbus_bool_t retval = FALSE;
762  DWORD sid_length, wdomain_length;
763  SID_NAME_USE use;
764  wchar_t *wdomain;
765 
766  *ppsid = NULL;
767 
768  sid_length = 0;
769  wdomain_length = 0;
770  if (!LookupAccountNameW (NULL, waccount, NULL, &sid_length,
771  NULL, &wdomain_length, &use) &&
772  GetLastError () != ERROR_INSUFFICIENT_BUFFER)
773  {
774  _dbus_win_set_error_from_win_error (error, GetLastError ());
775  return FALSE;
776  }
777 
778  *ppsid = dbus_malloc (sid_length);
779  if (!*ppsid)
780  {
781  _DBUS_SET_OOM (error);
782  return FALSE;
783  }
784 
785  wdomain = dbus_new (wchar_t, wdomain_length);
786  if (!wdomain)
787  {
788  _DBUS_SET_OOM (error);
789  goto out1;
790  }
791 
792  if (!LookupAccountNameW (NULL, waccount, (PSID) *ppsid, &sid_length,
793  wdomain, &wdomain_length, &use))
794  {
795  _dbus_win_set_error_from_win_error (error, GetLastError ());
796  goto out2;
797  }
798 
799  if (!IsValidSid ((PSID) *ppsid))
800  {
801  dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID");
802  goto out2;
803  }
804 
805  retval = TRUE;
806 
807 out2:
808  dbus_free (wdomain);
809 out1:
810  if (!retval)
811  {
812  dbus_free (*ppsid);
813  *ppsid = NULL;
814  }
815 
816  return retval;
817 }
818 
828 unsigned long
830 {
831  return _dbus_getpid ();
832 }
833 
834 #ifndef DBUS_WINCE
835 
840 static dbus_bool_t
841 _dbus_getsid(char **sid, dbus_pid_t process_id)
842 {
843  HANDLE process_token = INVALID_HANDLE_VALUE;
844  TOKEN_USER *token_user = NULL;
845  DWORD n;
846  PSID psid;
847  int retval = FALSE;
848  HANDLE process_handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id);
849 
850  if (!OpenProcessToken (process_handle, TOKEN_QUERY, &process_token))
851  {
852  _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ());
853  goto failed;
854  }
855  if ((!GetTokenInformation (process_token, TokenUser, NULL, 0, &n)
856  && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
857  || (token_user = alloca (n)) == NULL
858  || !GetTokenInformation (process_token, TokenUser, token_user, n, &n))
859  {
860  _dbus_win_warn_win_error ("GetTokenInformation failed", GetLastError ());
861  goto failed;
862  }
863  psid = token_user->User.Sid;
864  if (!IsValidSid (psid))
865  {
866  _dbus_verbose("%s invalid sid\n",__FUNCTION__);
867  goto failed;
868  }
869  if (!ConvertSidToStringSidA (psid, sid))
870  {
871  _dbus_verbose("%s invalid sid\n",__FUNCTION__);
872  goto failed;
873  }
874 //okay:
875  retval = TRUE;
876 
877 failed:
878  CloseHandle (process_handle);
879  if (process_token != INVALID_HANDLE_VALUE)
880  CloseHandle (process_token);
881 
882  _dbus_verbose("_dbus_getsid() returns %d\n",retval);
883  return retval;
884 }
885 #endif
886 
887 /************************************************************************
888 
889  pipes
890 
891  ************************************************************************/
892 
905  int *fd2,
906  dbus_bool_t blocking,
907  DBusError *error)
908 {
909  SOCKET temp, socket1 = -1, socket2 = -1;
910  struct sockaddr_in saddr;
911  int len;
912  u_long arg;
913 
914  _dbus_win_startup_winsock ();
915 
916  temp = socket (AF_INET, SOCK_STREAM, 0);
917  if (temp == INVALID_SOCKET)
918  {
919  DBUS_SOCKET_SET_ERRNO ();
920  goto out0;
921  }
922 
923  _DBUS_ZERO (saddr);
924  saddr.sin_family = AF_INET;
925  saddr.sin_port = 0;
926  saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
927 
928  if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr)) == SOCKET_ERROR)
929  {
930  DBUS_SOCKET_SET_ERRNO ();
931  goto out0;
932  }
933 
934  if (listen (temp, 1) == SOCKET_ERROR)
935  {
936  DBUS_SOCKET_SET_ERRNO ();
937  goto out0;
938  }
939 
940  len = sizeof (saddr);
941  if (getsockname (temp, (struct sockaddr *)&saddr, &len) == SOCKET_ERROR)
942  {
943  DBUS_SOCKET_SET_ERRNO ();
944  goto out0;
945  }
946 
947  socket1 = socket (AF_INET, SOCK_STREAM, 0);
948  if (socket1 == INVALID_SOCKET)
949  {
950  DBUS_SOCKET_SET_ERRNO ();
951  goto out0;
952  }
953 
954  if (connect (socket1, (struct sockaddr *)&saddr, len) == SOCKET_ERROR)
955  {
956  DBUS_SOCKET_SET_ERRNO ();
957  goto out1;
958  }
959 
960  socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
961  if (socket2 == INVALID_SOCKET)
962  {
963  DBUS_SOCKET_SET_ERRNO ();
964  goto out1;
965  }
966 
967  if (!blocking)
968  {
969  arg = 1;
970  if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
971  {
972  DBUS_SOCKET_SET_ERRNO ();
973  goto out2;
974  }
975 
976  arg = 1;
977  if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
978  {
979  DBUS_SOCKET_SET_ERRNO ();
980  goto out2;
981  }
982  }
983 
984  *fd1 = socket1;
985  *fd2 = socket2;
986 
987  _dbus_verbose ("full-duplex pipe %d:%d <-> %d:%d\n",
988  *fd1, socket1, *fd2, socket2);
989 
990  closesocket (temp);
991 
992  return TRUE;
993 
994 out2:
995  closesocket (socket2);
996 out1:
997  closesocket (socket1);
998 out0:
999  closesocket (temp);
1000 
1001  dbus_set_error (error, _dbus_error_from_errno (errno),
1002  "Could not setup socket pair: %s",
1004 
1005  return FALSE;
1006 }
1007 
1016 int
1018  int n_fds,
1019  int timeout_milliseconds)
1020 {
1021 #define USE_CHRIS_IMPL 0
1022 
1023 #if USE_CHRIS_IMPL
1024 
1025 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
1026  char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
1027  char *msgp;
1028 
1029  int ret = 0;
1030  int i;
1031  struct timeval tv;
1032  int ready;
1033 
1034 #define DBUS_STACK_WSAEVENTS 256
1035  WSAEVENT eventsOnStack[DBUS_STACK_WSAEVENTS];
1036  WSAEVENT *pEvents = NULL;
1037  if (n_fds > DBUS_STACK_WSAEVENTS)
1038  pEvents = calloc(sizeof(WSAEVENT), n_fds);
1039  else
1040  pEvents = eventsOnStack;
1041 
1042 
1043 #ifdef DBUS_ENABLE_VERBOSE_MODE
1044  msgp = msg;
1045  msgp += sprintf (msgp, "WSAEventSelect: to=%d\n\t", timeout_milliseconds);
1046  for (i = 0; i < n_fds; i++)
1047  {
1048  DBusPollFD *fdp = &fds[i];
1049 
1050 
1051  if (fdp->events & _DBUS_POLLIN)
1052  msgp += sprintf (msgp, "R:%d ", fdp->fd);
1053 
1054  if (fdp->events & _DBUS_POLLOUT)
1055  msgp += sprintf (msgp, "W:%d ", fdp->fd);
1056 
1057  msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
1058 
1059  // FIXME: more robust code for long msg
1060  // create on heap when msg[] becomes too small
1061  if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
1062  {
1063  _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
1064  }
1065  }
1066 
1067  msgp += sprintf (msgp, "\n");
1068  _dbus_verbose ("%s",msg);
1069 #endif
1070  for (i = 0; i < n_fds; i++)
1071  {
1072  DBusPollFD *fdp = &fds[i];
1073  WSAEVENT ev;
1074  long lNetworkEvents = FD_OOB;
1075 
1076  ev = WSACreateEvent();
1077 
1078  if (fdp->events & _DBUS_POLLIN)
1079  lNetworkEvents |= FD_READ | FD_ACCEPT | FD_CLOSE;
1080 
1081  if (fdp->events & _DBUS_POLLOUT)
1082  lNetworkEvents |= FD_WRITE | FD_CONNECT;
1083 
1084  WSAEventSelect(fdp->fd, ev, lNetworkEvents);
1085 
1086  pEvents[i] = ev;
1087  }
1088 
1089 
1090  ready = WSAWaitForMultipleEvents (n_fds, pEvents, FALSE, timeout_milliseconds, FALSE);
1091 
1092  if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
1093  {
1094  DBUS_SOCKET_SET_ERRNO ();
1095  if (errno != WSAEWOULDBLOCK)
1096  _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", _dbus_strerror_from_errno ());
1097  ret = -1;
1098  }
1099  else if (ready == WSA_WAIT_TIMEOUT)
1100  {
1101  _dbus_verbose ("WSAWaitForMultipleEvents: WSA_WAIT_TIMEOUT\n");
1102  ret = 0;
1103  }
1104  else if (ready >= WSA_WAIT_EVENT_0 && ready < (int)(WSA_WAIT_EVENT_0 + n_fds))
1105  {
1106  msgp = msg;
1107  msgp += sprintf (msgp, "WSAWaitForMultipleEvents: =%d\n\t", ready);
1108 
1109  for (i = 0; i < n_fds; i++)
1110  {
1111  DBusPollFD *fdp = &fds[i];
1112  WSANETWORKEVENTS ne;
1113 
1114  fdp->revents = 0;
1115 
1116  WSAEnumNetworkEvents(fdp->fd, pEvents[i], &ne);
1117 
1118  if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
1119  fdp->revents |= _DBUS_POLLIN;
1120 
1121  if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
1122  fdp->revents |= _DBUS_POLLOUT;
1123 
1124  if (ne.lNetworkEvents & (FD_OOB))
1125  fdp->revents |= _DBUS_POLLERR;
1126 
1127  if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
1128  msgp += sprintf (msgp, "R:%d ", fdp->fd);
1129 
1130  if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
1131  msgp += sprintf (msgp, "W:%d ", fdp->fd);
1132 
1133  if (ne.lNetworkEvents & (FD_OOB))
1134  msgp += sprintf (msgp, "E:%d ", fdp->fd);
1135 
1136  msgp += sprintf (msgp, "lNetworkEvents:%d ", ne.lNetworkEvents);
1137 
1138  if(ne.lNetworkEvents)
1139  ret++;
1140 
1141  WSAEventSelect(fdp->fd, pEvents[i], 0);
1142  }
1143 
1144  msgp += sprintf (msgp, "\n");
1145  _dbus_verbose ("%s",msg);
1146  }
1147  else
1148  {
1149  _dbus_verbose ("WSAWaitForMultipleEvents: failed for unknown reason!");
1150  ret = -1;
1151  }
1152 
1153  for(i = 0; i < n_fds; i++)
1154  {
1155  WSACloseEvent(pEvents[i]);
1156  }
1157 
1158  if (n_fds > DBUS_STACK_WSAEVENTS)
1159  free(pEvents);
1160 
1161  return ret;
1162 
1163 #else /* USE_CHRIS_IMPL */
1164 
1165 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
1166  char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
1167  char *msgp;
1168 
1169  fd_set read_set, write_set, err_set;
1170  int max_fd = 0;
1171  int i;
1172  struct timeval tv;
1173  int ready;
1174 
1175  FD_ZERO (&read_set);
1176  FD_ZERO (&write_set);
1177  FD_ZERO (&err_set);
1178 
1179 
1180 #ifdef DBUS_ENABLE_VERBOSE_MODE
1181  msgp = msg;
1182  msgp += sprintf (msgp, "select: to=%d\n\t", timeout_milliseconds);
1183  for (i = 0; i < n_fds; i++)
1184  {
1185  DBusPollFD *fdp = &fds[i];
1186 
1187 
1188  if (fdp->events & _DBUS_POLLIN)
1189  msgp += sprintf (msgp, "R:%d ", fdp->fd);
1190 
1191  if (fdp->events & _DBUS_POLLOUT)
1192  msgp += sprintf (msgp, "W:%d ", fdp->fd);
1193 
1194  msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
1195 
1196  // FIXME: more robust code for long msg
1197  // create on heap when msg[] becomes too small
1198  if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
1199  {
1200  _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
1201  }
1202  }
1203 
1204  msgp += sprintf (msgp, "\n");
1205  _dbus_verbose ("%s",msg);
1206 #endif
1207  for (i = 0; i < n_fds; i++)
1208  {
1209  DBusPollFD *fdp = &fds[i];
1210 
1211  if (fdp->events & _DBUS_POLLIN)
1212  FD_SET (fdp->fd, &read_set);
1213 
1214  if (fdp->events & _DBUS_POLLOUT)
1215  FD_SET (fdp->fd, &write_set);
1216 
1217  FD_SET (fdp->fd, &err_set);
1218 
1219  max_fd = MAX (max_fd, fdp->fd);
1220  }
1221 
1222  // Avoid random lockups with send(), for lack of a better solution so far
1223  tv.tv_sec = timeout_milliseconds < 0 ? 1 : timeout_milliseconds / 1000;
1224  tv.tv_usec = timeout_milliseconds < 0 ? 0 : (timeout_milliseconds % 1000) * 1000;
1225 
1226  ready = select (max_fd + 1, &read_set, &write_set, &err_set, &tv);
1227 
1228  if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
1229  {
1230  DBUS_SOCKET_SET_ERRNO ();
1231  if (errno != WSAEWOULDBLOCK)
1232  _dbus_verbose ("select: failed: %s\n", _dbus_strerror_from_errno ());
1233  }
1234  else if (ready == 0)
1235  _dbus_verbose ("select: = 0\n");
1236  else
1237  if (ready > 0)
1238  {
1239 #ifdef DBUS_ENABLE_VERBOSE_MODE
1240  msgp = msg;
1241  msgp += sprintf (msgp, "select: = %d:\n\t", ready);
1242 
1243  for (i = 0; i < n_fds; i++)
1244  {
1245  DBusPollFD *fdp = &fds[i];
1246 
1247  if (FD_ISSET (fdp->fd, &read_set))
1248  msgp += sprintf (msgp, "R:%d ", fdp->fd);
1249 
1250  if (FD_ISSET (fdp->fd, &write_set))
1251  msgp += sprintf (msgp, "W:%d ", fdp->fd);
1252 
1253  if (FD_ISSET (fdp->fd, &err_set))
1254  msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
1255  }
1256  msgp += sprintf (msgp, "\n");
1257  _dbus_verbose ("%s",msg);
1258 #endif
1259 
1260  for (i = 0; i < n_fds; i++)
1261  {
1262  DBusPollFD *fdp = &fds[i];
1263 
1264  fdp->revents = 0;
1265 
1266  if (FD_ISSET (fdp->fd, &read_set))
1267  fdp->revents |= _DBUS_POLLIN;
1268 
1269  if (FD_ISSET (fdp->fd, &write_set))
1270  fdp->revents |= _DBUS_POLLOUT;
1271 
1272  if (FD_ISSET (fdp->fd, &err_set))
1273  fdp->revents |= _DBUS_POLLERR;
1274  }
1275  }
1276  return ready;
1277 #endif /* USE_CHRIS_IMPL */
1278 }
1279 
1280 
1281 
1282 
1283 /******************************************************************************
1284 
1285 Original CVS version of dbus-sysdeps.c
1286 
1287 ******************************************************************************/
1288 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
1289 /* dbus-sysdeps.c Wrappers around system/libc features (internal to D-Bus implementation)
1290  *
1291  * Copyright (C) 2002, 2003 Red Hat, Inc.
1292  * Copyright (C) 2003 CodeFactory AB
1293  * Copyright (C) 2005 Novell, Inc.
1294  *
1295  * Licensed under the Academic Free License version 2.1
1296  *
1297  * This program is free software; you can redistribute it and/or modify
1298  * it under the terms of the GNU General Public License as published by
1299  * the Free Software Foundation; either version 2 of the License, or
1300  * (at your option) any later version.
1301  *
1302  * This program is distributed in the hope that it will be useful,
1303  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1304  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1305  * GNU General Public License for more details.
1306  *
1307  * You should have received a copy of the GNU General Public License
1308  * along with this program; if not, write to the Free Software
1309  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1310  *
1311  */
1312 
1313 
1319 void
1320 _dbus_exit (int code)
1321 {
1322  _exit (code);
1323 }
1324 
1336 int
1337 _dbus_connect_tcp_socket (const char *host,
1338  const char *port,
1339  const char *family,
1340  DBusError *error)
1341 {
1342  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1343 }
1344 
1345 int
1346 _dbus_connect_tcp_socket_with_nonce (const char *host,
1347  const char *port,
1348  const char *family,
1349  const char *noncefile,
1350  DBusError *error)
1351 {
1352  int fd = -1, res;
1353  struct addrinfo hints;
1354  struct addrinfo *ai, *tmp;
1355 
1356  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1357 
1358  _dbus_win_startup_winsock ();
1359 
1360  _DBUS_ZERO (hints);
1361 
1362  if (!family)
1363  hints.ai_family = AF_UNSPEC;
1364  else if (!strcmp(family, "ipv4"))
1365  hints.ai_family = AF_INET;
1366  else if (!strcmp(family, "ipv6"))
1367  hints.ai_family = AF_INET6;
1368  else
1369  {
1370  dbus_set_error (error,
1372  "Unknown address family %s", family);
1373  return -1;
1374  }
1375  hints.ai_protocol = IPPROTO_TCP;
1376  hints.ai_socktype = SOCK_STREAM;
1377 #ifdef AI_ADDRCONFIG
1378  hints.ai_flags = AI_ADDRCONFIG;
1379 #else
1380  hints.ai_flags = 0;
1381 #endif
1382 
1383  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1384  {
1385  dbus_set_error (error,
1386  _dbus_error_from_errno (res),
1387  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1388  host, port, _dbus_strerror(res), res);
1389  return -1;
1390  }
1391 
1392  tmp = ai;
1393  while (tmp)
1394  {
1395  if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
1396  {
1397  DBUS_SOCKET_SET_ERRNO ();
1398  dbus_set_error (error,
1399  _dbus_error_from_errno (errno),
1400  "Failed to open socket: %s",
1402  freeaddrinfo(ai);
1403  return -1;
1404  }
1405  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1406 
1407  if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
1408  {
1409  DBUS_SOCKET_SET_ERRNO ();
1410  closesocket(fd);
1411  fd = -1;
1412  tmp = tmp->ai_next;
1413  continue;
1414  }
1415 
1416  break;
1417  }
1418  freeaddrinfo(ai);
1419 
1420  if (fd == -1)
1421  {
1422  dbus_set_error (error,
1423  _dbus_error_from_errno (errno),
1424  "Failed to connect to socket \"%s:%s\" %s",
1425  host, port, _dbus_strerror_from_errno ());
1426  return -1;
1427  }
1428 
1429  if (noncefile != NULL)
1430  {
1431  DBusString noncefileStr;
1432  dbus_bool_t ret;
1433  if (!_dbus_string_init (&noncefileStr) ||
1434  !_dbus_string_append(&noncefileStr, noncefile))
1435  {
1436  closesocket (fd);
1438  return -1;
1439  }
1440 
1441  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1442 
1443  _dbus_string_free (&noncefileStr);
1444 
1445  if (!ret)
1446  {
1447  closesocket (fd);
1448  return -1;
1449  }
1450  }
1451 
1453 
1454  if (!_dbus_set_fd_nonblocking (fd, error))
1455  {
1456  closesocket (fd);
1457  return -1;
1458  }
1459 
1460  return fd;
1461 }
1462 
1478 int
1479 _dbus_listen_tcp_socket (const char *host,
1480  const char *port,
1481  const char *family,
1482  DBusString *retport,
1483  int **fds_p,
1484  DBusError *error)
1485 {
1486  int nlisten_fd = 0, *listen_fd = NULL, res, i, port_num = -1;
1487  struct addrinfo hints;
1488  struct addrinfo *ai, *tmp;
1489 
1490  // On Vista, sockaddr_gen must be a sockaddr_in6, and not a sockaddr_in6_old
1491  //That's required for family == IPv6(which is the default on Vista if family is not given)
1492  //So we use our own union instead of sockaddr_gen:
1493 
1494  typedef union {
1495  struct sockaddr Address;
1496  struct sockaddr_in AddressIn;
1497  struct sockaddr_in6 AddressIn6;
1498  } mysockaddr_gen;
1499 
1500  *fds_p = NULL;
1501  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1502 
1503  _dbus_win_startup_winsock ();
1504 
1505  _DBUS_ZERO (hints);
1506 
1507  if (!family)
1508  hints.ai_family = AF_UNSPEC;
1509  else if (!strcmp(family, "ipv4"))
1510  hints.ai_family = AF_INET;
1511  else if (!strcmp(family, "ipv6"))
1512  hints.ai_family = AF_INET6;
1513  else
1514  {
1515  dbus_set_error (error,
1517  "Unknown address family %s", family);
1518  return -1;
1519  }
1520 
1521  hints.ai_protocol = IPPROTO_TCP;
1522  hints.ai_socktype = SOCK_STREAM;
1523 #ifdef AI_ADDRCONFIG
1524  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1525 #else
1526  hints.ai_flags = AI_PASSIVE;
1527 #endif
1528 
1529  redo_lookup_with_port:
1530  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1531  {
1532  dbus_set_error (error,
1533  _dbus_error_from_errno (res),
1534  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1535  host ? host : "*", port, _dbus_strerror(res), res);
1536  return -1;
1537  }
1538 
1539  tmp = ai;
1540  while (tmp)
1541  {
1542  int fd = -1, *newlisten_fd;
1543  if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
1544  {
1545  DBUS_SOCKET_SET_ERRNO ();
1546  dbus_set_error (error,
1547  _dbus_error_from_errno (errno),
1548  "Failed to open socket: %s",
1550  goto failed;
1551  }
1552  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1553 
1554  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
1555  {
1556  DBUS_SOCKET_SET_ERRNO ();
1557  dbus_set_error (error, _dbus_error_from_errno (errno),
1558  "Failed to bind socket \"%s:%s\": %s",
1559  host ? host : "*", port, _dbus_strerror_from_errno ());
1560  closesocket (fd);
1561  goto failed;
1562  }
1563 
1564  if (listen (fd, 30 /* backlog */) == SOCKET_ERROR)
1565  {
1566  DBUS_SOCKET_SET_ERRNO ();
1567  dbus_set_error (error, _dbus_error_from_errno (errno),
1568  "Failed to listen on socket \"%s:%s\": %s",
1569  host ? host : "*", port, _dbus_strerror_from_errno ());
1570  closesocket (fd);
1571  goto failed;
1572  }
1573 
1574  newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1575  if (!newlisten_fd)
1576  {
1577  closesocket (fd);
1579  "Failed to allocate file handle array");
1580  goto failed;
1581  }
1582  listen_fd = newlisten_fd;
1583  listen_fd[nlisten_fd] = fd;
1584  nlisten_fd++;
1585 
1586  if (!_dbus_string_get_length(retport))
1587  {
1588  /* If the user didn't specify a port, or used 0, then
1589  the kernel chooses a port. After the first address
1590  is bound to, we need to force all remaining addresses
1591  to use the same port */
1592  if (!port || !strcmp(port, "0"))
1593  {
1594  mysockaddr_gen addr;
1595  socklen_t addrlen = sizeof(addr);
1596  char portbuf[10];
1597 
1598  if (getsockname(fd, &addr.Address, &addrlen) == SOCKET_ERROR)
1599  {
1600  DBUS_SOCKET_SET_ERRNO ();
1601  dbus_set_error (error, _dbus_error_from_errno (errno),
1602  "Failed to resolve port \"%s:%s\": %s",
1603  host ? host : "*", port, _dbus_strerror_from_errno());
1604  goto failed;
1605  }
1606  snprintf( portbuf, sizeof( portbuf ) - 1, "%d", addr.AddressIn.sin_port );
1607  if (!_dbus_string_append(retport, portbuf))
1608  {
1610  goto failed;
1611  }
1612 
1613  /* Release current address list & redo lookup */
1614  port = _dbus_string_get_const_data(retport);
1615  freeaddrinfo(ai);
1616  goto redo_lookup_with_port;
1617  }
1618  else
1619  {
1620  if (!_dbus_string_append(retport, port))
1621  {
1623  goto failed;
1624  }
1625  }
1626  }
1627 
1628  tmp = tmp->ai_next;
1629  }
1630  freeaddrinfo(ai);
1631  ai = NULL;
1632 
1633  if (!nlisten_fd)
1634  {
1635  _dbus_win_set_errno (WSAEADDRINUSE);
1636  dbus_set_error (error, _dbus_error_from_errno (errno),
1637  "Failed to bind socket \"%s:%s\": %s",
1638  host ? host : "*", port, _dbus_strerror_from_errno ());
1639  return -1;
1640  }
1641 
1642  sscanf(_dbus_string_get_const_data(retport), "%d", &port_num);
1643 
1644  for (i = 0 ; i < nlisten_fd ; i++)
1645  {
1646  _dbus_fd_set_close_on_exec (listen_fd[i]);
1647  if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1648  {
1649  goto failed;
1650  }
1651  }
1652 
1653  *fds_p = listen_fd;
1654 
1655  return nlisten_fd;
1656 
1657  failed:
1658  if (ai)
1659  freeaddrinfo(ai);
1660  for (i = 0 ; i < nlisten_fd ; i++)
1661  closesocket (listen_fd[i]);
1662  dbus_free(listen_fd);
1663  return -1;
1664 }
1665 
1666 
1674 int
1675 _dbus_accept (int listen_fd)
1676 {
1677  int client_fd;
1678 
1679  retry:
1680  client_fd = accept (listen_fd, NULL, NULL);
1681 
1682  if (DBUS_SOCKET_IS_INVALID (client_fd))
1683  {
1684  DBUS_SOCKET_SET_ERRNO ();
1685  if (errno == EINTR)
1686  goto retry;
1687  }
1688 
1689  _dbus_verbose ("client fd %d accepted\n", client_fd);
1690 
1691  return client_fd;
1692 }
1693 
1694 
1695 
1696 
1699  DBusError *error)
1700 {
1701 /* FIXME: for the session bus credentials shouldn't matter (?), but
1702  * for the system bus they are presumably essential. A rough outline
1703  * of a way to implement the credential transfer would be this:
1704  *
1705  * client waits to *read* a byte.
1706  *
1707  * server creates a named pipe with a random name, sends a byte
1708  * contining its length, and its name.
1709  *
1710  * client reads the name, connects to it (using Win32 API).
1711  *
1712  * server waits for connection to the named pipe, then calls
1713  * ImpersonateNamedPipeClient(), notes its now-current credentials,
1714  * calls RevertToSelf(), closes its handles to the named pipe, and
1715  * is done. (Maybe there is some other way to get the SID of a named
1716  * pipe client without having to use impersonation?)
1717  *
1718  * client closes its handles and is done.
1719  *
1720  * Ralf: Why not sending credentials over the given this connection ?
1721  * Using named pipes makes it impossible to be connected from a unix client.
1722  *
1723  */
1724  int bytes_written;
1725  DBusString buf;
1726 
1727  _dbus_string_init_const_len (&buf, "\0", 1);
1728 again:
1729  bytes_written = _dbus_write_socket (handle, &buf, 0, 1 );
1730 
1731  if (bytes_written < 0 && errno == EINTR)
1732  goto again;
1733 
1734  if (bytes_written < 0)
1735  {
1736  dbus_set_error (error, _dbus_error_from_errno (errno),
1737  "Failed to write credentials byte: %s",
1739  return FALSE;
1740  }
1741  else if (bytes_written == 0)
1742  {
1744  "wrote zero bytes writing credentials byte");
1745  return FALSE;
1746  }
1747  else
1748  {
1749  _dbus_assert (bytes_written == 1);
1750  _dbus_verbose ("wrote 1 zero byte, credential sending isn't implemented yet\n");
1751  return TRUE;
1752  }
1753  return TRUE;
1754 }
1755 
1776  DBusCredentials *credentials,
1777  DBusError *error)
1778 {
1779  int bytes_read = 0;
1780  DBusString buf;
1781 
1782  char *sid = NULL;
1783  dbus_pid_t pid;
1784  int retval = FALSE;
1785 
1786  // could fail due too OOM
1787  if (_dbus_string_init (&buf))
1788  {
1789  bytes_read = _dbus_read_socket (handle, &buf, 1 );
1790 
1791  if (bytes_read > 0)
1792  _dbus_verbose ("got one zero byte from server\n");
1793 
1794  _dbus_string_free (&buf);
1795  }
1796 
1797  pid = _dbus_get_peer_pid_from_tcp_handle (handle);
1798  if (pid == 0)
1799  return TRUE;
1800 
1801  _dbus_credentials_add_pid (credentials, pid);
1802 
1803  if (_dbus_getsid (&sid, pid))
1804  {
1805  if (!_dbus_credentials_add_windows_sid (credentials, sid))
1806  goto out;
1807  }
1808 
1809  retval = TRUE;
1810 
1811 out:
1812  if (sid)
1813  LocalFree (sid);
1814 
1815  return retval;
1816 }
1817 
1828 {
1829  /* TODO */
1830  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1831  return TRUE;
1832 }
1833 
1834 
1847  const DBusString *next_component)
1848 {
1849  dbus_bool_t dir_ends_in_slash;
1850  dbus_bool_t file_starts_with_slash;
1851 
1852  if (_dbus_string_get_length (dir) == 0 ||
1853  _dbus_string_get_length (next_component) == 0)
1854  return TRUE;
1855 
1856  dir_ends_in_slash =
1857  ('/' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1) ||
1858  '\\' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1));
1859 
1860  file_starts_with_slash =
1861  ('/' == _dbus_string_get_byte (next_component, 0) ||
1862  '\\' == _dbus_string_get_byte (next_component, 0));
1863 
1864  if (dir_ends_in_slash && file_starts_with_slash)
1865  {
1866  _dbus_string_shorten (dir, 1);
1867  }
1868  else if (!(dir_ends_in_slash || file_starts_with_slash))
1869  {
1870  if (!_dbus_string_append_byte (dir, '\\'))
1871  return FALSE;
1872  }
1873 
1874  return _dbus_string_copy (next_component, 0, dir,
1875  _dbus_string_get_length (dir));
1876 }
1877 
1878 /*---------------- DBusCredentials ----------------------------------*/
1879 
1889  const DBusString *username)
1890 {
1891  return _dbus_credentials_add_windows_sid (credentials,
1892  _dbus_string_get_const_data(username));
1893 }
1894 
1905 {
1906  dbus_bool_t retval = FALSE;
1907  char *sid = NULL;
1908 
1909  if (!_dbus_getsid(&sid, _dbus_getpid()))
1910  goto failed;
1911 
1912  if (!_dbus_credentials_add_pid (credentials, _dbus_getpid()))
1913  goto failed;
1914 
1915  if (!_dbus_credentials_add_windows_sid (credentials,sid))
1916  goto failed;
1917 
1918  retval = TRUE;
1919  goto end;
1920 failed:
1921  retval = FALSE;
1922 end:
1923  if (sid)
1924  LocalFree(sid);
1925 
1926  return retval;
1927 }
1928 
1943 {
1944  dbus_bool_t retval = FALSE;
1945  char *sid = NULL;
1946 
1947  if (!_dbus_getsid(&sid, _dbus_getpid()))
1948  return FALSE;
1949 
1950  retval = _dbus_string_append (str,sid);
1951 
1952  LocalFree(sid);
1953  return retval;
1954 }
1955 
1960 dbus_pid_t
1962 {
1963  return GetCurrentProcessId ();
1964 }
1965 
1967 #define NANOSECONDS_PER_SECOND 1000000000
1968 
1969 #define MICROSECONDS_PER_SECOND 1000000
1970 
1971 #define MILLISECONDS_PER_SECOND 1000
1972 
1973 #define NANOSECONDS_PER_MILLISECOND 1000000
1974 
1975 #define MICROSECONDS_PER_MILLISECOND 1000
1976 
1981 void
1982 _dbus_sleep_milliseconds (int milliseconds)
1983 {
1984  Sleep (milliseconds);
1985 }
1986 
1987 
1995 void
1996 _dbus_get_real_time (long *tv_sec,
1997  long *tv_usec)
1998 {
1999  FILETIME ft;
2000  dbus_uint64_t time64;
2001 
2002  GetSystemTimeAsFileTime (&ft);
2003 
2004  memcpy (&time64, &ft, sizeof (time64));
2005 
2006  /* Convert from 100s of nanoseconds since 1601-01-01
2007  * to Unix epoch. Yes, this is Y2038 unsafe.
2008  */
2009  time64 -= DBUS_INT64_CONSTANT (116444736000000000);
2010  time64 /= 10;
2011 
2012  if (tv_sec)
2013  *tv_sec = time64 / 1000000;
2014 
2015  if (tv_usec)
2016  *tv_usec = time64 % 1000000;
2017 }
2018 
2026 void
2028  long *tv_usec)
2029 {
2030  /* no implementation yet, fall back to wall-clock time */
2031  _dbus_get_real_time (tv_sec, tv_usec);
2032 }
2033 
2037 void
2039 {
2040 }
2041 
2052  DBusError *error)
2053 {
2054  const char *filename_c;
2055 
2056  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2057 
2058  filename_c = _dbus_string_get_const_data (filename);
2059 
2060  if (!CreateDirectoryA (filename_c, NULL))
2061  {
2062  if (GetLastError () == ERROR_ALREADY_EXISTS)
2063  return TRUE;
2064 
2066  "Failed to create directory %s: %s\n",
2067  filename_c, _dbus_strerror_from_errno ());
2068  return FALSE;
2069  }
2070  else
2071  return TRUE;
2072 }
2073 
2074 
2085  int n_bytes)
2086 {
2087  int old_len;
2088  char *p;
2089  HCRYPTPROV hprov;
2090 
2091  old_len = _dbus_string_get_length (str);
2092 
2093  if (!_dbus_string_lengthen (str, n_bytes))
2094  return FALSE;
2095 
2096  p = _dbus_string_get_data_len (str, old_len, n_bytes);
2097 
2098  if (!CryptAcquireContext (&hprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
2099  return FALSE;
2100 
2101  if (!CryptGenRandom (hprov, n_bytes, p))
2102  {
2103  CryptReleaseContext (hprov, 0);
2104  return FALSE;
2105  }
2106 
2107  CryptReleaseContext (hprov, 0);
2108 
2109  return TRUE;
2110 }
2111 
2118 const char*
2120 {
2121  static const char* tmpdir = NULL;
2122  static char buf[1000];
2123 
2124  if (tmpdir == NULL)
2125  {
2126  char *last_slash;
2127 
2128  if (!GetTempPathA (sizeof (buf), buf))
2129  {
2130  _dbus_warn ("GetTempPath failed\n");
2131  _dbus_abort ();
2132  }
2133 
2134  /* Drop terminating backslash or slash */
2135  last_slash = _mbsrchr (buf, '\\');
2136  if (last_slash > buf && last_slash[1] == '\0')
2137  last_slash[0] = '\0';
2138  last_slash = _mbsrchr (buf, '/');
2139  if (last_slash > buf && last_slash[1] == '\0')
2140  last_slash[0] = '\0';
2141 
2142  tmpdir = buf;
2143  }
2144 
2145  _dbus_assert(tmpdir != NULL);
2146 
2147  return tmpdir;
2148 }
2149 
2150 
2161  DBusError *error)
2162 {
2163  const char *filename_c;
2164 
2165  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2166 
2167  filename_c = _dbus_string_get_const_data (filename);
2168 
2169  if (DeleteFileA (filename_c) == 0)
2170  {
2172  "Failed to delete file %s: %s\n",
2173  filename_c, _dbus_strerror_from_errno ());
2174  return FALSE;
2175  }
2176  else
2177  return TRUE;
2178 }
2179 
2180 /*
2181  * replaces the term DBUS_PREFIX in configure_time_path by the
2182  * current dbus installation directory. On unix this function is a noop
2183  *
2184  * @param configure_time_path
2185  * @return real path
2186  */
2187 const char *
2188 _dbus_replace_install_prefix (const char *configure_time_path)
2189 {
2190 #ifndef DBUS_PREFIX
2191  return configure_time_path;
2192 #else
2193  static char retval[1000];
2194  static char runtime_prefix[1000];
2195  int len = 1000;
2196  int i;
2197 
2198  if (!configure_time_path)
2199  return NULL;
2200 
2201  if ((!_dbus_get_install_root(runtime_prefix, len) ||
2202  strncmp (configure_time_path, DBUS_PREFIX "/",
2203  strlen (DBUS_PREFIX) + 1))) {
2204  strcat (retval, configure_time_path);
2205  return retval;
2206  }
2207 
2208  strcpy (retval, runtime_prefix);
2209  strcat (retval, configure_time_path + strlen (DBUS_PREFIX) + 1);
2210 
2211  /* Somehow, in some situations, backslashes get collapsed in the string.
2212  * Since windows C library accepts both forward and backslashes as
2213  * path separators, convert all backslashes to forward slashes.
2214  */
2215 
2216  for(i = 0; retval[i] != '\0'; i++) {
2217  if(retval[i] == '\\')
2218  retval[i] = '/';
2219  }
2220  return retval;
2221 #endif
2222 }
2223 
2224 #if !defined (DBUS_DISABLE_ASSERTS) || defined(DBUS_BUILD_TESTS)
2225 
2226 #if defined(_MSC_VER) || defined(DBUS_WINCE)
2227 # ifdef BACKTRACES
2228 # undef BACKTRACES
2229 # endif
2230 #else
2231 # define BACKTRACES
2232 #endif
2233 
2234 #ifdef BACKTRACES
2235 /*
2236  * Backtrace Generator
2237  *
2238  * Copyright 2004 Eric Poech
2239  * Copyright 2004 Robert Shearman
2240  *
2241  * This library is free software; you can redistribute it and/or
2242  * modify it under the terms of the GNU Lesser General Public
2243  * License as published by the Free Software Foundation; either
2244  * version 2.1 of the License, or (at your option) any later version.
2245  *
2246  * This library is distributed in the hope that it will be useful,
2247  * but WITHOUT ANY WARRANTY; without even the implied warranty of
2248  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2249  * Lesser General Public License for more details.
2250  *
2251  * You should have received a copy of the GNU Lesser General Public
2252  * License along with this library; if not, write to the Free Software
2253  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2254  */
2255 
2256 #include <winver.h>
2257 #include <imagehlp.h>
2258 #include <stdio.h>
2259 
2260 #define DPRINTF _dbus_warn
2261 
2262 #ifdef _MSC_VER
2263 #define BOOL int
2264 
2265 #define __i386__
2266 #endif
2267 
2268 //#define MAKE_FUNCPTR(f) static typeof(f) * p##f
2269 
2270 //MAKE_FUNCPTR(StackWalk);
2271 //MAKE_FUNCPTR(SymGetModuleBase);
2272 //MAKE_FUNCPTR(SymFunctionTableAccess);
2273 //MAKE_FUNCPTR(SymInitialize);
2274 //MAKE_FUNCPTR(SymGetSymFromAddr);
2275 //MAKE_FUNCPTR(SymGetModuleInfo);
2276 static BOOL (WINAPI *pStackWalk)(
2277  DWORD MachineType,
2278  HANDLE hProcess,
2279  HANDLE hThread,
2280  LPSTACKFRAME StackFrame,
2281  PVOID ContextRecord,
2282  PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
2283  PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
2284  PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
2285  PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
2286 );
2287 #ifdef _WIN64
2288 static DWORD64 (WINAPI *pSymGetModuleBase)(
2289  HANDLE hProcess,
2290  DWORD64 dwAddr
2291 );
2292 static PVOID (WINAPI *pSymFunctionTableAccess)(
2293  HANDLE hProcess,
2294  DWORD64 AddrBase
2295 );
2296 #else
2297 static DWORD (WINAPI *pSymGetModuleBase)(
2298  HANDLE hProcess,
2299  DWORD dwAddr
2300 );
2301 static PVOID (WINAPI *pSymFunctionTableAccess)(
2302  HANDLE hProcess,
2303  DWORD AddrBase
2304 );
2305 #endif
2306 static BOOL (WINAPI *pSymInitialize)(
2307  HANDLE hProcess,
2308  PSTR UserSearchPath,
2309  BOOL fInvadeProcess
2310 );
2311 static BOOL (WINAPI *pSymGetSymFromAddr)(
2312  HANDLE hProcess,
2313  DWORD Address,
2314  PDWORD Displacement,
2315  PIMAGEHLP_SYMBOL Symbol
2316 );
2317 static BOOL (WINAPI *pSymGetModuleInfo)(
2318  HANDLE hProcess,
2319  DWORD dwAddr,
2320  PIMAGEHLP_MODULE ModuleInfo
2321 );
2322 static DWORD (WINAPI *pSymSetOptions)(
2323  DWORD SymOptions
2324 );
2325 
2326 
2327 static BOOL init_backtrace()
2328 {
2329  HMODULE hmodDbgHelp = LoadLibraryA("dbghelp");
2330 /*
2331  #define GETFUNC(x) \
2332  p##x = (typeof(x)*)GetProcAddress(hmodDbgHelp, #x); \
2333  if (!p##x) \
2334  { \
2335  return FALSE; \
2336  }
2337  */
2338 
2339 
2340 // GETFUNC(StackWalk);
2341 // GETFUNC(SymGetModuleBase);
2342 // GETFUNC(SymFunctionTableAccess);
2343 // GETFUNC(SymInitialize);
2344 // GETFUNC(SymGetSymFromAddr);
2345 // GETFUNC(SymGetModuleInfo);
2346 
2347 #define FUNC(x) #x
2348 
2349  pStackWalk = (BOOL (WINAPI *)(
2350 DWORD MachineType,
2351 HANDLE hProcess,
2352 HANDLE hThread,
2353 LPSTACKFRAME StackFrame,
2354 PVOID ContextRecord,
2355 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
2356 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
2357 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
2358 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
2359 ))GetProcAddress (hmodDbgHelp, FUNC(StackWalk));
2360 #ifdef _WIN64
2361  pSymGetModuleBase=(DWORD64 (WINAPI *)(
2362  HANDLE hProcess,
2363  DWORD64 dwAddr
2364 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
2365  pSymFunctionTableAccess=(PVOID (WINAPI *)(
2366  HANDLE hProcess,
2367  DWORD64 AddrBase
2368 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
2369 #else
2370  pSymGetModuleBase=(DWORD (WINAPI *)(
2371  HANDLE hProcess,
2372  DWORD dwAddr
2373 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
2374  pSymFunctionTableAccess=(PVOID (WINAPI *)(
2375  HANDLE hProcess,
2376  DWORD AddrBase
2377 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
2378 #endif
2379  pSymInitialize = (BOOL (WINAPI *)(
2380  HANDLE hProcess,
2381  PSTR UserSearchPath,
2382  BOOL fInvadeProcess
2383 ))GetProcAddress (hmodDbgHelp, FUNC(SymInitialize));
2384  pSymGetSymFromAddr = (BOOL (WINAPI *)(
2385  HANDLE hProcess,
2386  DWORD Address,
2387  PDWORD Displacement,
2388  PIMAGEHLP_SYMBOL Symbol
2389 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetSymFromAddr));
2390  pSymGetModuleInfo = (BOOL (WINAPI *)(
2391  HANDLE hProcess,
2392  DWORD dwAddr,
2393  PIMAGEHLP_MODULE ModuleInfo
2394 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleInfo));
2395 pSymSetOptions = (DWORD (WINAPI *)(
2396 DWORD SymOptions
2397 ))GetProcAddress (hmodDbgHelp, FUNC(SymSetOptions));
2398 
2399 
2400  pSymSetOptions(SYMOPT_UNDNAME);
2401 
2402  pSymInitialize(GetCurrentProcess(), NULL, TRUE);
2403 
2404  return TRUE;
2405 }
2406 
2407 static void dump_backtrace_for_thread(HANDLE hThread)
2408 {
2409  STACKFRAME sf;
2410  CONTEXT context;
2411  DWORD dwImageType;
2412 
2413  if (!pStackWalk)
2414  if (!init_backtrace())
2415  return;
2416 
2417  /* can't use this function for current thread as GetThreadContext
2418  * doesn't support getting context from current thread */
2419  if (hThread == GetCurrentThread())
2420  return;
2421 
2422  DPRINTF("Backtrace:\n");
2423 
2424  _DBUS_ZERO(context);
2425  context.ContextFlags = CONTEXT_FULL;
2426 
2427  SuspendThread(hThread);
2428 
2429  if (!GetThreadContext(hThread, &context))
2430  {
2431  DPRINTF("Couldn't get thread context (error %ld)\n", GetLastError());
2432  ResumeThread(hThread);
2433  return;
2434  }
2435 
2436  _DBUS_ZERO(sf);
2437 
2438 #ifdef __i386__
2439  sf.AddrFrame.Offset = context.Ebp;
2440  sf.AddrFrame.Mode = AddrModeFlat;
2441  sf.AddrPC.Offset = context.Eip;
2442  sf.AddrPC.Mode = AddrModeFlat;
2443  dwImageType = IMAGE_FILE_MACHINE_I386;
2444 #elif _M_X64
2445  dwImageType = IMAGE_FILE_MACHINE_AMD64;
2446  sf.AddrPC.Offset = context.Rip;
2447  sf.AddrPC.Mode = AddrModeFlat;
2448  sf.AddrFrame.Offset = context.Rsp;
2449  sf.AddrFrame.Mode = AddrModeFlat;
2450  sf.AddrStack.Offset = context.Rsp;
2451  sf.AddrStack.Mode = AddrModeFlat;
2452 #elif _M_IA64
2453  dwImageType = IMAGE_FILE_MACHINE_IA64;
2454  sf.AddrPC.Offset = context.StIIP;
2455  sf.AddrPC.Mode = AddrModeFlat;
2456  sf.AddrFrame.Offset = context.IntSp;
2457  sf.AddrFrame.Mode = AddrModeFlat;
2458  sf.AddrBStore.Offset= context.RsBSP;
2459  sf.AddrBStore.Mode = AddrModeFlat;
2460  sf.AddrStack.Offset = context.IntSp;
2461  sf.AddrStack.Mode = AddrModeFlat;
2462 #else
2463 # error You need to fill in the STACKFRAME structure for your architecture
2464 #endif
2465 
2466  while (pStackWalk(dwImageType, GetCurrentProcess(),
2467  hThread, &sf, &context, NULL, pSymFunctionTableAccess,
2468  pSymGetModuleBase, NULL))
2469  {
2470  BYTE buffer[256];
2471  IMAGEHLP_SYMBOL * pSymbol = (IMAGEHLP_SYMBOL *)buffer;
2472  DWORD dwDisplacement;
2473 
2474  pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
2475  pSymbol->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1;
2476 
2477  if (!pSymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset,
2478  &dwDisplacement, pSymbol))
2479  {
2480  IMAGEHLP_MODULE ModuleInfo;
2481  ModuleInfo.SizeOfStruct = sizeof(ModuleInfo);
2482 
2483  if (!pSymGetModuleInfo(GetCurrentProcess(), sf.AddrPC.Offset,
2484  &ModuleInfo))
2485  DPRINTF("1\t%p\n", (void*)sf.AddrPC.Offset);
2486  else
2487  DPRINTF("2\t%s+0x%lx\n", ModuleInfo.ImageName,
2488  sf.AddrPC.Offset - ModuleInfo.BaseOfImage);
2489  }
2490  else if (dwDisplacement)
2491  DPRINTF("3\t%s+0x%lx\n", pSymbol->Name, dwDisplacement);
2492  else
2493  DPRINTF("4\t%s\n", pSymbol->Name);
2494  }
2495 
2496  ResumeThread(hThread);
2497 }
2498 
2499 static DWORD WINAPI dump_thread_proc(LPVOID lpParameter)
2500 {
2501  dump_backtrace_for_thread((HANDLE)lpParameter);
2502  return 0;
2503 }
2504 
2505 /* cannot get valid context from current thread, so we have to execute
2506  * backtrace from another thread */
2507 static void dump_backtrace()
2508 {
2509  HANDLE hCurrentThread;
2510  HANDLE hThread;
2511  DWORD dwThreadId;
2512  DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
2513  GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
2514  hThread = CreateThread(NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread,
2515  0, &dwThreadId);
2516  WaitForSingleObject(hThread, INFINITE);
2517  CloseHandle(hThread);
2518  CloseHandle(hCurrentThread);
2519 }
2520 #endif
2521 #endif /* asserts or tests enabled */
2522 
2523 #ifdef BACKTRACES
2525 {
2526  init_backtrace();
2527  dump_backtrace();
2528 }
2529 #else
2530 void _dbus_print_backtrace(void)
2531 {
2532  _dbus_verbose (" D-Bus not compiled with backtrace support\n");
2533 }
2534 #endif
2535 
2536 static dbus_uint32_t fromAscii(char ascii)
2537 {
2538  if(ascii >= '0' && ascii <= '9')
2539  return ascii - '0';
2540  if(ascii >= 'A' && ascii <= 'F')
2541  return ascii - 'A' + 10;
2542  if(ascii >= 'a' && ascii <= 'f')
2543  return ascii - 'a' + 10;
2544  return 0;
2545 }
2546 
2548  dbus_bool_t create_if_not_found,
2549  DBusError *error)
2550 {
2551 #ifdef DBUS_WINCE
2552  return TRUE;
2553  // TODO
2554 #else
2555  HW_PROFILE_INFOA info;
2556  char *lpc = &info.szHwProfileGuid[0];
2557  dbus_uint32_t u;
2558 
2559  // the hw-profile guid lives long enough
2560  if(!GetCurrentHwProfileA(&info))
2561  {
2562  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); // FIXME
2563  return FALSE;
2564  }
2565 
2566  // Form: {12340001-4980-1920-6788-123456789012}
2567  lpc++;
2568  // 12340001
2569  u = ((fromAscii(lpc[0]) << 0) |
2570  (fromAscii(lpc[1]) << 4) |
2571  (fromAscii(lpc[2]) << 8) |
2572  (fromAscii(lpc[3]) << 12) |
2573  (fromAscii(lpc[4]) << 16) |
2574  (fromAscii(lpc[5]) << 20) |
2575  (fromAscii(lpc[6]) << 24) |
2576  (fromAscii(lpc[7]) << 28));
2577  machine_id->as_uint32s[0] = u;
2578 
2579  lpc += 9;
2580  // 4980-1920
2581  u = ((fromAscii(lpc[0]) << 0) |
2582  (fromAscii(lpc[1]) << 4) |
2583  (fromAscii(lpc[2]) << 8) |
2584  (fromAscii(lpc[3]) << 12) |
2585  (fromAscii(lpc[5]) << 16) |
2586  (fromAscii(lpc[6]) << 20) |
2587  (fromAscii(lpc[7]) << 24) |
2588  (fromAscii(lpc[8]) << 28));
2589  machine_id->as_uint32s[1] = u;
2590 
2591  lpc += 10;
2592  // 6788-1234
2593  u = ((fromAscii(lpc[0]) << 0) |
2594  (fromAscii(lpc[1]) << 4) |
2595  (fromAscii(lpc[2]) << 8) |
2596  (fromAscii(lpc[3]) << 12) |
2597  (fromAscii(lpc[5]) << 16) |
2598  (fromAscii(lpc[6]) << 20) |
2599  (fromAscii(lpc[7]) << 24) |
2600  (fromAscii(lpc[8]) << 28));
2601  machine_id->as_uint32s[2] = u;
2602 
2603  lpc += 9;
2604  // 56789012
2605  u = ((fromAscii(lpc[0]) << 0) |
2606  (fromAscii(lpc[1]) << 4) |
2607  (fromAscii(lpc[2]) << 8) |
2608  (fromAscii(lpc[3]) << 12) |
2609  (fromAscii(lpc[4]) << 16) |
2610  (fromAscii(lpc[5]) << 20) |
2611  (fromAscii(lpc[6]) << 24) |
2612  (fromAscii(lpc[7]) << 28));
2613  machine_id->as_uint32s[3] = u;
2614 #endif
2615  return TRUE;
2616 }
2617 
2618 static
2619 HANDLE _dbus_global_lock (const char *mutexname)
2620 {
2621  HANDLE mutex;
2622  DWORD gotMutex;
2623 
2624  mutex = CreateMutexA( NULL, FALSE, mutexname );
2625  if( !mutex )
2626  {
2627  return FALSE;
2628  }
2629 
2630  gotMutex = WaitForSingleObject( mutex, INFINITE );
2631  switch( gotMutex )
2632  {
2633  case WAIT_ABANDONED:
2634  ReleaseMutex (mutex);
2635  CloseHandle (mutex);
2636  return 0;
2637  case WAIT_FAILED:
2638  case WAIT_TIMEOUT:
2639  return 0;
2640  }
2641 
2642  return mutex;
2643 }
2644 
2645 static
2646 void _dbus_global_unlock (HANDLE mutex)
2647 {
2648  ReleaseMutex (mutex);
2649  CloseHandle (mutex);
2650 }
2651 
2652 // for proper cleanup in dbus-daemon
2653 static HANDLE hDBusDaemonMutex = NULL;
2654 static HANDLE hDBusSharedMem = NULL;
2655 // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
2656 static const char *cUniqueDBusInitMutex = "UniqueDBusInitMutex";
2657 // sync _dbus_get_autolaunch_address
2658 static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex";
2659 // mutex to determine if dbus-daemon is already started (per user)
2660 static const char *cDBusDaemonMutex = "DBusDaemonMutex";
2661 // named shm for dbus adress info (per user)
2662 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
2663 
2664 static dbus_bool_t
2665 _dbus_get_install_root_as_hash(DBusString *out)
2666 {
2667  DBusString install_path;
2668 
2669  char path[MAX_PATH*2];
2670  int path_size = sizeof(path);
2671 
2672  if (!_dbus_get_install_root(path,path_size))
2673  return FALSE;
2674 
2675  _dbus_string_init(&install_path);
2676  _dbus_string_append(&install_path,path);
2677 
2678  _dbus_string_init(out);
2679  _dbus_string_tolower_ascii(&install_path,0,_dbus_string_get_length(&install_path));
2680 
2681  if (!_dbus_sha_compute (&install_path, out))
2682  return FALSE;
2683 
2684  return TRUE;
2685 }
2686 
2687 static dbus_bool_t
2688 _dbus_get_address_string (DBusString *out, const char *basestring, const char *scope)
2689 {
2690  _dbus_string_init(out);
2691  _dbus_string_append(out,basestring);
2692 
2693  if (!scope)
2694  {
2695  return TRUE;
2696  }
2697  else if (strcmp(scope,"*install-path") == 0
2698  // for 1.3 compatibility
2699  || strcmp(scope,"install-path") == 0)
2700  {
2701  DBusString temp;
2702  if (!_dbus_get_install_root_as_hash(&temp))
2703  {
2704  _dbus_string_free(out);
2705  return FALSE;
2706  }
2707  _dbus_string_append(out,"-");
2709  _dbus_string_free(&temp);
2710  }
2711  else if (strcmp(scope,"*user") == 0)
2712  {
2713  _dbus_string_append(out,"-");
2715  {
2716  _dbus_string_free(out);
2717  return FALSE;
2718  }
2719  }
2720  else if (strlen(scope) > 0)
2721  {
2722  _dbus_string_append(out,"-");
2723  _dbus_string_append(out,scope);
2724  return TRUE;
2725  }
2726  return TRUE;
2727 }
2728 
2729 static dbus_bool_t
2730 _dbus_get_shm_name (DBusString *out,const char *scope)
2731 {
2732  return _dbus_get_address_string (out,cDBusDaemonAddressInfo,scope);
2733 }
2734 
2735 static dbus_bool_t
2736 _dbus_get_mutex_name (DBusString *out,const char *scope)
2737 {
2738  return _dbus_get_address_string (out,cDBusDaemonMutex,scope);
2739 }
2740 
2742 _dbus_daemon_is_session_bus_address_published (const char *scope)
2743 {
2744  HANDLE lock;
2745  DBusString mutex_name;
2746 
2747  if (!_dbus_get_mutex_name(&mutex_name,scope))
2748  {
2749  _dbus_string_free( &mutex_name );
2750  return FALSE;
2751  }
2752 
2753  if (hDBusDaemonMutex)
2754  return TRUE;
2755 
2756  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
2757  lock = _dbus_global_lock( cUniqueDBusInitMutex );
2758 
2759  // we use CreateMutex instead of OpenMutex because of possible race conditions,
2760  // see http://msdn.microsoft.com/en-us/library/ms684315%28VS.85%29.aspx
2761  hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
2762 
2763  /* The client uses mutex ownership to detect a running server, so the server should do so too.
2764  Fortunally the client deletes the mutex in the lock protected area, so checking presence
2765  will work too. */
2766 
2767  _dbus_global_unlock( lock );
2768 
2769  _dbus_string_free( &mutex_name );
2770 
2771  if (hDBusDaemonMutex == NULL)
2772  return FALSE;
2773  if (GetLastError() == ERROR_ALREADY_EXISTS)
2774  {
2775  CloseHandle(hDBusDaemonMutex);
2776  hDBusDaemonMutex = NULL;
2777  return TRUE;
2778  }
2779  // mutex wasn't created before, so return false.
2780  // We leave the mutex name allocated for later reusage
2781  // in _dbus_daemon_publish_session_bus_address.
2782  return FALSE;
2783 }
2784 
2786 _dbus_daemon_publish_session_bus_address (const char* address, const char *scope)
2787 {
2788  HANDLE lock;
2789  char *shared_addr = NULL;
2790  DBusString shm_name;
2791  DBusString mutex_name;
2792 
2793  _dbus_assert (address);
2794 
2795  if (!_dbus_get_mutex_name(&mutex_name,scope))
2796  {
2797  _dbus_string_free( &mutex_name );
2798  return FALSE;
2799  }
2800 
2801  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
2802  lock = _dbus_global_lock( cUniqueDBusInitMutex );
2803 
2804  if (!hDBusDaemonMutex)
2805  {
2806  hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
2807  }
2808  _dbus_string_free( &mutex_name );
2809 
2810  // acquire the mutex
2811  if (WaitForSingleObject( hDBusDaemonMutex, 10 ) != WAIT_OBJECT_0)
2812  {
2813  _dbus_global_unlock( lock );
2814  CloseHandle( hDBusDaemonMutex );
2815  return FALSE;
2816  }
2817 
2818  if (!_dbus_get_shm_name(&shm_name,scope))
2819  {
2820  _dbus_string_free( &shm_name );
2821  _dbus_global_unlock( lock );
2822  return FALSE;
2823  }
2824 
2825  // create shm
2826  hDBusSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
2827  0, strlen( address ) + 1, _dbus_string_get_const_data(&shm_name) );
2828  _dbus_assert( hDBusSharedMem );
2829 
2830  shared_addr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
2831 
2832  _dbus_assert (shared_addr);
2833 
2834  strcpy( shared_addr, address);
2835 
2836  // cleanup
2837  UnmapViewOfFile( shared_addr );
2838 
2839  _dbus_global_unlock( lock );
2840  _dbus_verbose( "published session bus address at %s\n",_dbus_string_get_const_data (&shm_name) );
2841 
2842  _dbus_string_free( &shm_name );
2843  return TRUE;
2844 }
2845 
2846 void
2847 _dbus_daemon_unpublish_session_bus_address (void)
2848 {
2849  HANDLE lock;
2850 
2851  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
2852  lock = _dbus_global_lock( cUniqueDBusInitMutex );
2853 
2854  CloseHandle( hDBusSharedMem );
2855 
2856  hDBusSharedMem = NULL;
2857 
2858  ReleaseMutex( hDBusDaemonMutex );
2859 
2860  CloseHandle( hDBusDaemonMutex );
2861 
2862  hDBusDaemonMutex = NULL;
2863 
2864  _dbus_global_unlock( lock );
2865 }
2866 
2867 static dbus_bool_t
2868 _dbus_get_autolaunch_shm (DBusString *address, DBusString *shm_name)
2869 {
2870  HANDLE sharedMem;
2871  char *shared_addr;
2872  int i;
2873 
2874  // read shm
2875  for(i=0;i<20;++i) {
2876  // we know that dbus-daemon is available, so we wait until shm is available
2877  sharedMem = OpenFileMappingA( FILE_MAP_READ, FALSE, _dbus_string_get_const_data(shm_name));
2878  if( sharedMem == 0 )
2879  Sleep( 100 );
2880  if ( sharedMem != 0)
2881  break;
2882  }
2883 
2884  if( sharedMem == 0 )
2885  return FALSE;
2886 
2887  shared_addr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
2888 
2889  if( !shared_addr )
2890  return FALSE;
2891 
2892  _dbus_string_init( address );
2893 
2894  _dbus_string_append( address, shared_addr );
2895 
2896  // cleanup
2897  UnmapViewOfFile( shared_addr );
2898 
2899  CloseHandle( sharedMem );
2900 
2901  return TRUE;
2902 }
2903 
2904 static dbus_bool_t
2905 _dbus_daemon_already_runs (DBusString *address, DBusString *shm_name, const char *scope)
2906 {
2907  HANDLE lock;
2908  HANDLE daemon;
2909  DBusString mutex_name;
2910  dbus_bool_t bRet = TRUE;
2911 
2912  if (!_dbus_get_mutex_name(&mutex_name,scope))
2913  {
2914  _dbus_string_free( &mutex_name );
2915  return FALSE;
2916  }
2917 
2918  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
2919  lock = _dbus_global_lock( cUniqueDBusInitMutex );
2920 
2921  // do checks
2922  daemon = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
2923  if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT)
2924  {
2925  ReleaseMutex (daemon);
2926  CloseHandle (daemon);
2927 
2928  _dbus_global_unlock( lock );
2929  _dbus_string_free( &mutex_name );
2930  return FALSE;
2931  }
2932 
2933  // read shm
2934  bRet = _dbus_get_autolaunch_shm( address, shm_name );
2935 
2936  // cleanup
2937  CloseHandle ( daemon );
2938 
2939  _dbus_global_unlock( lock );
2940  _dbus_string_free( &mutex_name );
2941 
2942  return bRet;
2943 }
2944 
2946 _dbus_get_autolaunch_address (const char *scope, DBusString *address,
2947  DBusError *error)
2948 {
2949  HANDLE mutex;
2950  STARTUPINFOA si;
2951  PROCESS_INFORMATION pi;
2952  dbus_bool_t retval = FALSE;
2953  LPSTR lpFile;
2954  char dbus_exe_path[MAX_PATH];
2955  char dbus_args[MAX_PATH * 2];
2956  const char * daemon_name = DBUS_DAEMON_NAME ".exe";
2957  DBusString shm_name;
2958 
2959  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2960 
2961  if (!_dbus_get_shm_name(&shm_name,scope))
2962  {
2963  dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not determine shm name");
2964  return FALSE;
2965  }
2966 
2967  mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
2968 
2969  if (_dbus_daemon_already_runs(address,&shm_name,scope))
2970  {
2971  _dbus_verbose( "found running dbus daemon at %s\n",
2972  _dbus_string_get_const_data (&shm_name) );
2973  retval = TRUE;
2974  goto out;
2975  }
2976 
2977  if (!SearchPathA(NULL, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
2978  {
2979  // Look in directory containing dbus shared library
2980  HMODULE hmod;
2981  char dbus_module_path[MAX_PATH];
2982  DWORD rc;
2983 
2984  _dbus_verbose( "did not found dbus daemon executable on default search path, "
2985  "trying path where dbus shared library is located");
2986 
2987  hmod = _dbus_win_get_dll_hmodule();
2988  rc = GetModuleFileNameA(hmod, dbus_module_path, sizeof(dbus_module_path));
2989  if (rc <= 0)
2990  {
2991  dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not retrieve dbus shared library file name");
2992  retval = FALSE;
2993  goto out;
2994  }
2995  else
2996  {
2997  char *ext_idx = strrchr(dbus_module_path, '\\');
2998  if (ext_idx)
2999  *ext_idx = '\0';
3000  if (!SearchPathA(dbus_module_path, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
3001  {
3002  dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not find dbus-daemon executable");
3003  retval = FALSE;
3004  printf ("please add the path to %s to your PATH environment variable\n", daemon_name);
3005  printf ("or start the daemon manually\n\n");
3006  goto out;
3007  }
3008  _dbus_verbose( "found dbus daemon executable at %s",dbus_module_path);
3009  }
3010  }
3011 
3012 
3013  // Create process
3014  ZeroMemory( &si, sizeof(si) );
3015  si.cb = sizeof(si);
3016  ZeroMemory( &pi, sizeof(pi) );
3017 
3018  _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path, " --session");
3019 
3020 // argv[i] = "--config-file=bus\\session.conf";
3021 // printf("create process \"%s\" %s\n", dbus_exe_path, dbus_args);
3022  if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
3023  {
3024  CloseHandle (pi.hThread);
3025  CloseHandle (pi.hProcess);
3026  retval = _dbus_get_autolaunch_shm( address, &shm_name );
3027  if (retval == FALSE)
3028  dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to get autolaunch address from launched dbus-daemon");
3029  }
3030  else
3031  {
3032  dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to launch dbus-daemon");
3033  retval = FALSE;
3034  }
3035 
3036 out:
3037  if (retval)
3038  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3039  else
3040  _DBUS_ASSERT_ERROR_IS_SET (error);
3041 
3042  _dbus_global_unlock (mutex);
3043 
3044  return retval;
3045  }
3046 
3047 
3056  DBusError *error)
3057 {
3058  // TODO
3059  return TRUE;
3060 }
3061 
3068 static const char *
3069 _dbus_windows_get_datadir (void)
3070 {
3071  return _dbus_replace_install_prefix(DBUS_DATADIR);
3072 }
3073 
3074 #undef DBUS_DATADIR
3075 #define DBUS_DATADIR _dbus_windows_get_datadir ()
3076 
3077 
3078 #define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3079 #define DBUS_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3080 
3097 dbus_bool_t
3099 {
3100  const char *common_progs;
3101  DBusString servicedir_path;
3102 
3103  if (!_dbus_string_init (&servicedir_path))
3104  return FALSE;
3105 
3106 #ifdef DBUS_WINCE
3107  {
3108  /* On Windows CE, we adjust datadir dynamically to installation location. */
3109  const char *data_dir = _dbus_getenv ("DBUS_DATADIR");
3110 
3111  if (data_dir != NULL)
3112  {
3113  if (!_dbus_string_append (&servicedir_path, data_dir))
3114  goto oom;
3115 
3116  if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
3117  goto oom;
3118  }
3119  }
3120 #else
3121 /*
3122  the code for accessing services requires absolute base pathes
3123  in case DBUS_DATADIR is relative make it absolute
3124 */
3125 #ifdef DBUS_WIN
3126  {
3127  DBusString p;
3128 
3129  _dbus_string_init_const (&p, DBUS_DATADIR);
3130 
3131  if (!_dbus_path_is_absolute (&p))
3132  {
3133  char install_root[1000];
3134  if (_dbus_get_install_root (install_root, sizeof(install_root)))
3135  if (!_dbus_string_append (&servicedir_path, install_root))
3136  goto oom;
3137  }
3138  }
3139 #endif
3140  if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
3141  goto oom;
3142 
3143  if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
3144  goto oom;
3145 #endif
3146 
3147  common_progs = _dbus_getenv ("CommonProgramFiles");
3148 
3149  if (common_progs != NULL)
3150  {
3151  if (!_dbus_string_append (&servicedir_path, common_progs))
3152  goto oom;
3153 
3154  if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
3155  goto oom;
3156  }
3157 
3158  if (!_dbus_split_paths_and_append (&servicedir_path,
3159  DBUS_STANDARD_SESSION_SERVICEDIR,
3160  dirs))
3161  goto oom;
3162 
3163  _dbus_string_free (&servicedir_path);
3164  return TRUE;
3165 
3166  oom:
3167  _dbus_string_free (&servicedir_path);
3168  return FALSE;
3169 }
3170 
3191 {
3192  *dirs = NULL;
3193  return TRUE;
3194 }
3195 
3205 {
3206  // +/- 1 is needed here!
3207  // no volatile argument with mingw
3208  return InterlockedIncrement (&atomic->value) - 1;
3209 }
3210 
3220 {
3221  // +/- 1 is needed here!
3222  // no volatile argument with mingw
3223  return InterlockedDecrement (&atomic->value) + 1;
3224 }
3225 
3235 {
3236  /* In this situation, GLib issues a MemoryBarrier() and then returns
3237  * atomic->value. However, mingw from mingw.org (not to be confused with
3238  * mingw-w64 from mingw-w64.sf.net) does not have MemoryBarrier in its
3239  * headers, so we have to get a memory barrier some other way.
3240  *
3241  * InterlockedIncrement is older, and is documented on MSDN to be a full
3242  * memory barrier, so let's use that.
3243  */
3244  long dummy = 0;
3245 
3246  InterlockedExchange (&dummy, 1);
3247 
3248  return atomic->value;
3249 }
3250 
3258 void
3260 {
3261 }
3262 
3271 {
3272  return errno == WSAEWOULDBLOCK;
3273 }
3274 
3283 _dbus_get_install_root(char *prefix, int len)
3284 {
3285  //To find the prefix, we cut the filename and also \bin\ if present
3286  DWORD pathLength;
3287  char *lastSlash;
3288  SetLastError( 0 );
3289  pathLength = GetModuleFileNameA(_dbus_win_get_dll_hmodule(), prefix, len);
3290  if ( pathLength == 0 || GetLastError() != 0 ) {
3291  *prefix = '\0';
3292  return FALSE;
3293  }
3294  lastSlash = _mbsrchr(prefix, '\\');
3295  if (lastSlash == NULL) {
3296  *prefix = '\0';
3297  return FALSE;
3298  }
3299  //cut off binary name
3300  lastSlash[1] = 0;
3301 
3302  //cut possible "\\bin"
3303 
3304  //this fails if we are in a double-byte system codepage and the
3305  //folder's name happens to end with the *bytes*
3306  //"\\bin"... (I.e. the second byte of some Han character and then
3307  //the Latin "bin", but that is not likely I think...
3308  if (lastSlash - prefix >= 4 && strnicmp(lastSlash - 4, "\\bin", 4) == 0)
3309  lastSlash[-3] = 0;
3310  else if (lastSlash - prefix >= 10 && strnicmp(lastSlash - 10, "\\bin\\debug", 10) == 0)
3311  lastSlash[-9] = 0;
3312  else if (lastSlash - prefix >= 12 && strnicmp(lastSlash - 12, "\\bin\\release", 12) == 0)
3313  lastSlash[-11] = 0;
3314 
3315  return TRUE;
3316 }
3317 
3331 dbus_bool_t
3332 _dbus_get_config_file_name(DBusString *config_file, char *s)
3333 {
3334  char path[MAX_PATH*2];
3335  int path_size = sizeof(path);
3336 
3337  if (!_dbus_get_install_root(path,path_size))
3338  return FALSE;
3339 
3340  if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
3341  return FALSE;
3342  strcat(path,"etc\\");
3343  strcat(path,s);
3344  if (_dbus_file_exists(path))
3345  {
3346  // find path from executable
3347  if (!_dbus_string_append (config_file, path))
3348  return FALSE;
3349  }
3350  else
3351  {
3352  if (!_dbus_get_install_root(path,path_size))
3353  return FALSE;
3354  if(strlen(s) + 11 + strlen(path) > sizeof(path)-2)
3355  return FALSE;
3356  strcat(path,"etc\\dbus-1\\");
3357  strcat(path,s);
3358 
3359  if (_dbus_file_exists(path))
3360  {
3361  if (!_dbus_string_append (config_file, path))
3362  return FALSE;
3363  }
3364  else
3365  {
3366  if (!_dbus_get_install_root(path,path_size))
3367  return FALSE;
3368  if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
3369  return FALSE;
3370  strcat(path,"bus\\");
3371  strcat(path,s);
3372 
3373  if (_dbus_file_exists(path))
3374  {
3375  if (!_dbus_string_append (config_file, path))
3376  return FALSE;
3377  }
3378  }
3379  }
3380  return TRUE;
3381 }
3382 
3393 {
3394  return _dbus_get_config_file_name(str, "system.conf");
3395 }
3396 
3405 {
3406  return _dbus_get_config_file_name(str, "session.conf");
3407 }
3408 
3409 /* See comment in dbus-sysdeps-unix.c */
3412  DBusString *address,
3413  DBusError *error)
3414 {
3415  /* Probably fill this in with something based on COM? */
3416  *supported = FALSE;
3417  return TRUE;
3418 }
3419 
3435  DBusCredentials *credentials)
3436 {
3437  DBusString homedir;
3438  DBusString dotdir;
3439  const char *homepath;
3440  const char *homedrive;
3441 
3442  _dbus_assert (credentials != NULL);
3444 
3445  if (!_dbus_string_init (&homedir))
3446  return FALSE;
3447 
3448  homedrive = _dbus_getenv("HOMEDRIVE");
3449  if (homedrive != NULL && *homedrive != '\0')
3450  {
3451  _dbus_string_append(&homedir,homedrive);
3452  }
3453 
3454  homepath = _dbus_getenv("HOMEPATH");
3455  if (homepath != NULL && *homepath != '\0')
3456  {
3457  _dbus_string_append(&homedir,homepath);
3458  }
3459 
3460 #ifdef DBUS_BUILD_TESTS
3461  {
3462  const char *override;
3463 
3464  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3465  if (override != NULL && *override != '\0')
3466  {
3467  _dbus_string_set_length (&homedir, 0);
3468  if (!_dbus_string_append (&homedir, override))
3469  goto failed;
3470 
3471  _dbus_verbose ("Using fake homedir for testing: %s\n",
3472  _dbus_string_get_const_data (&homedir));
3473  }
3474  else
3475  {
3476  static dbus_bool_t already_warned = FALSE;
3477  if (!already_warned)
3478  {
3479  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3480  already_warned = TRUE;
3481  }
3482  }
3483  }
3484 #endif
3485 
3486 #ifdef DBUS_WINCE
3487  /* It's not possible to create a .something directory in Windows CE
3488  using the file explorer. */
3489 #define KEYRING_DIR "dbus-keyrings"
3490 #else
3491 #define KEYRING_DIR ".dbus-keyrings"
3492 #endif
3493 
3494  _dbus_string_init_const (&dotdir, KEYRING_DIR);
3495  if (!_dbus_concat_dir_and_file (&homedir,
3496  &dotdir))
3497  goto failed;
3498 
3499  if (!_dbus_string_copy (&homedir, 0,
3500  directory, _dbus_string_get_length (directory))) {
3501  goto failed;
3502  }
3503 
3504  _dbus_string_free (&homedir);
3505  return TRUE;
3506 
3507  failed:
3508  _dbus_string_free (&homedir);
3509  return FALSE;
3510 }
3511 
3517 dbus_bool_t
3518 _dbus_file_exists (const char *file)
3519 {
3520  DWORD attributes = GetFileAttributesA (file);
3521 
3522  if (attributes != INVALID_FILE_ATTRIBUTES && GetLastError() != ERROR_PATH_NOT_FOUND)
3523  return TRUE;
3524  else
3525  return FALSE;
3526 }
3527 
3535 const char*
3536 _dbus_strerror (int error_number)
3537 {
3538 #ifdef DBUS_WINCE
3539  // TODO
3540  return "unknown";
3541 #else
3542  const char *msg;
3543 
3544  switch (error_number)
3545  {
3546  case WSAEINTR:
3547  return "Interrupted function call";
3548  case WSAEACCES:
3549  return "Permission denied";
3550  case WSAEFAULT:
3551  return "Bad address";
3552  case WSAEINVAL:
3553  return "Invalid argument";
3554  case WSAEMFILE:
3555  return "Too many open files";
3556  case WSAEWOULDBLOCK:
3557  return "Resource temporarily unavailable";
3558  case WSAEINPROGRESS:
3559  return "Operation now in progress";
3560  case WSAEALREADY:
3561  return "Operation already in progress";
3562  case WSAENOTSOCK:
3563  return "Socket operation on nonsocket";
3564  case WSAEDESTADDRREQ:
3565  return "Destination address required";
3566  case WSAEMSGSIZE:
3567  return "Message too long";
3568  case WSAEPROTOTYPE:
3569  return "Protocol wrong type for socket";
3570  case WSAENOPROTOOPT:
3571  return "Bad protocol option";
3572  case WSAEPROTONOSUPPORT:
3573  return "Protocol not supported";
3574  case WSAESOCKTNOSUPPORT:
3575  return "Socket type not supported";
3576  case WSAEOPNOTSUPP:
3577  return "Operation not supported";
3578  case WSAEPFNOSUPPORT:
3579  return "Protocol family not supported";
3580  case WSAEAFNOSUPPORT:
3581  return "Address family not supported by protocol family";
3582  case WSAEADDRINUSE:
3583  return "Address already in use";
3584  case WSAEADDRNOTAVAIL:
3585  return "Cannot assign requested address";
3586  case WSAENETDOWN:
3587  return "Network is down";
3588  case WSAENETUNREACH:
3589  return "Network is unreachable";
3590  case WSAENETRESET:
3591  return "Network dropped connection on reset";
3592  case WSAECONNABORTED:
3593  return "Software caused connection abort";
3594  case WSAECONNRESET:
3595  return "Connection reset by peer";
3596  case WSAENOBUFS:
3597  return "No buffer space available";
3598  case WSAEISCONN:
3599  return "Socket is already connected";
3600  case WSAENOTCONN:
3601  return "Socket is not connected";
3602  case WSAESHUTDOWN:
3603  return "Cannot send after socket shutdown";
3604  case WSAETIMEDOUT:
3605  return "Connection timed out";
3606  case WSAECONNREFUSED:
3607  return "Connection refused";
3608  case WSAEHOSTDOWN:
3609  return "Host is down";
3610  case WSAEHOSTUNREACH:
3611  return "No route to host";
3612  case WSAEPROCLIM:
3613  return "Too many processes";
3614  case WSAEDISCON:
3615  return "Graceful shutdown in progress";
3616  case WSATYPE_NOT_FOUND:
3617  return "Class type not found";
3618  case WSAHOST_NOT_FOUND:
3619  return "Host not found";
3620  case WSATRY_AGAIN:
3621  return "Nonauthoritative host not found";
3622  case WSANO_RECOVERY:
3623  return "This is a nonrecoverable error";
3624  case WSANO_DATA:
3625  return "Valid name, no data record of requested type";
3626  case WSA_INVALID_HANDLE:
3627  return "Specified event object handle is invalid";
3628  case WSA_INVALID_PARAMETER:
3629  return "One or more parameters are invalid";
3630  case WSA_IO_INCOMPLETE:
3631  return "Overlapped I/O event object not in signaled state";
3632  case WSA_IO_PENDING:
3633  return "Overlapped operations will complete later";
3634  case WSA_NOT_ENOUGH_MEMORY:
3635  return "Insufficient memory available";
3636  case WSA_OPERATION_ABORTED:
3637  return "Overlapped operation aborted";
3638 #ifdef WSAINVALIDPROCTABLE
3639 
3640  case WSAINVALIDPROCTABLE:
3641  return "Invalid procedure table from service provider";
3642 #endif
3643 #ifdef WSAINVALIDPROVIDER
3644 
3645  case WSAINVALIDPROVIDER:
3646  return "Invalid service provider version number";
3647 #endif
3648 #ifdef WSAPROVIDERFAILEDINIT
3649 
3650  case WSAPROVIDERFAILEDINIT:
3651  return "Unable to initialize a service provider";
3652 #endif
3653 
3654  case WSASYSCALLFAILURE:
3655  return "System call failure";
3656  }
3657  msg = strerror (error_number);
3658  if (msg == NULL)
3659  msg = "unknown";
3660 
3661  return msg;
3662 #endif //DBUS_WINCE
3663 }
3664 
3672 void
3673 _dbus_win_set_error_from_win_error (DBusError *error,
3674  int code)
3675 {
3676  char *msg;
3677 
3678  /* As we want the English message, use the A API */
3679  FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
3680  FORMAT_MESSAGE_IGNORE_INSERTS |
3681  FORMAT_MESSAGE_FROM_SYSTEM,
3682  NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
3683  (LPSTR) &msg, 0, NULL);
3684  if (msg)
3685  {
3686  char *msg_copy;
3687 
3688  msg_copy = dbus_malloc (strlen (msg));
3689  strcpy (msg_copy, msg);
3690  LocalFree (msg);
3691 
3692  dbus_set_error (error, "win32.error", "%s", msg_copy);
3693  }
3694  else
3695  dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code);
3696 }
3697 
3698 void
3699 _dbus_win_warn_win_error (const char *message,
3700  int code)
3701 {
3702  DBusError error;
3703 
3704  dbus_error_init (&error);
3705  _dbus_win_set_error_from_win_error (&error, code);
3706  _dbus_warn ("%s: %s\n", message, error.message);
3707  dbus_error_free (&error);
3708 }
3709 
3719  DBusError *error)
3720 {
3721  const char *filename_c;
3722 
3723  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3724 
3725  filename_c = _dbus_string_get_const_data (filename);
3726 
3727  if (RemoveDirectoryA (filename_c) == 0)
3728  {
3729  char *emsg = _dbus_win_error_string (GetLastError ());
3730  dbus_set_error (error, _dbus_win_error_from_last_error (),
3731  "Failed to remove directory %s: %s",
3732  filename_c, emsg);
3733  _dbus_win_free_error_string (emsg);
3734  return FALSE;
3735  }
3736 
3737  return TRUE;
3738 }
3739 
3748 {
3749  if (_dbus_string_get_length (filename) > 0)
3750  return _dbus_string_get_byte (filename, 1) == ':'
3751  || _dbus_string_get_byte (filename, 0) == '\\'
3752  || _dbus_string_get_byte (filename, 0) == '/';
3753  else
3754  return FALSE;
3755 }
3756 
3759 {
3760  return FALSE;
3761 }
3762 
3764 /* tests in dbus-sysdeps-util.c */
3765 
dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString.
Definition: dbus-string.c:913
unsigned int dbus_uint32_t
A 32-bit unsigned integer on all platforms.
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:229
#define DBUS_ERROR_FILE_NOT_FOUND
Missing file.
#define DBUS_ERROR_FILE_EXISTS
Existing file and the operation you&#39;re using does not silently overwrite.
const char * message
public error message field
Definition: dbus-errors.h:51
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
#define NULL
A null pointer, defined appropriately for C or C++.
dbus_bool_t _dbus_append_system_config_file(DBusString *str)
Append the absolute path of the system.conf file (there is no system bus on Windows so this can just ...
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:234
dbus_bool_t _dbus_check_dir_is_private_to_user(DBusString *dir, DBusError *error)
Checks to make sure the given directory is private to the user.
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:601
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:738
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:701
dbus_bool_t _dbus_path_is_absolute(const DBusString *filename)
Checks whether the filename is an absolute path.
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:58
dbus_uint32_t as_uint32s[DBUS_UUID_LENGTH_WORDS]
guid as four uint32 values
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked...
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
dbus_bool_t _dbus_full_duplex_pipe(int *fd1, int *fd2, dbus_bool_t blocking, DBusError *error)
Creates a full-duplex pipe (as in socketpair()).
int _dbus_write_socket_two(int fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write_two() but only works on sockets and is thus available on Windows.
dbus_bool_t _dbus_check_setuid(void)
NOTE: If you modify this function, please also consider making the corresponding change in GLib...
void _dbus_string_tolower_ascii(const DBusString *str, int start, int len)
Converts the given range of the string to lower case.
Definition: dbus-string.c:2482
void dbus_error_free(DBusError *error)
Frees an error that&#39;s been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
dbus_bool_t _dbus_get_standard_session_servicedirs(DBusList **dirs)
Returns the standard directories for a session bus to look for service activation files...
A portable struct pollfd wrapper.
Definition: dbus-sysdeps.h:312
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...
int _dbus_accept(int listen_fd)
Accepts a connection on a listening socket.
unsigned char _dbus_string_get_byte(const DBusString *str, int start)
Gets the byte at the given position.
Definition: dbus-string.c:540
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:296
dbus_bool_t _dbus_file_exists(const char *file)
File interface.
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:468
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
dbus_bool_t _dbus_append_user_from_current_process(DBusString *str)
Append to the string the identity we would like to have when we authenticate, on UNIX this is the cur...
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:758
short events
Events to poll for.
Definition: dbus-sysdeps.h:315
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that&#39;s copied to the d...
Definition: dbus-string.c:1280
dbus_bool_t _dbus_read_credentials_socket(int client_fd, DBusCredentials *credentials, DBusError *error)
Reads a single byte which must be nul (an error occurs otherwise), and reads unix credentials if avai...
dbus_bool_t _dbus_credentials_add_windows_sid(DBusCredentials *credentials, const char *windows_sid)
Add a Windows user SID to the credentials.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:181
void _dbus_abort(void)
Aborts the program with SIGABRT (dumping core).
Definition: dbus-sysdeps.c:78
dbus_bool_t _dbus_get_autolaunch_address(const char *scope, DBusString *address, DBusError *error)
Returns the address of a new session bus.
const char * _dbus_error_from_errno(int error_number)
Converts a UNIX errno, or Windows errno or WinSock error value into a DBusError name.
Definition: dbus-sysdeps.c:610
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:98
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
void _dbus_fd_set_close_on_exec(intptr_t fd)
Sets the file descriptor to be close on exec.
void _dbus_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:461
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
_DBUS_GNUC_EXTENSION typedef unsigned long long dbus_uint64_t
A 64-bit unsigned integer on all platforms that support it.
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
dbus_bool_t _dbus_make_file_world_readable(const DBusString *filename, DBusError *error)
Makes the file readable by every user in the system.
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:300
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
int _dbus_string_get_length(const DBusString *str)
Gets the length of a string (not including nul termination).
Definition: dbus-string.c:717
dbus_bool_t _dbus_append_keyring_directory_for_credentials(DBusString *directory, DBusCredentials *credentials)
Appends the directory in which a keyring for the given credentials should be stored.
int _dbus_read_socket(int fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
Object representing an exception.
Definition: dbus-errors.h:48
dbus_bool_t _dbus_string_validate_utf8(const DBusString *str, int start, int len)
Checks that the given range of the string is valid UTF-8.
Definition: dbus-string.c:2552
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
dbus_bool_t _dbus_send_credentials_socket(int server_fd, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
int fd
File descriptor.
Definition: dbus-sysdeps.h:314
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
Definition: dbus-string.c:1154
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:242
dbus_bool_t _dbus_credentials_add_from_current_process(DBusCredentials *credentials)
Adds the credentials of the current process to the passed-in credentials object.
#define TRUE
Expands to &quot;1&quot;.
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
dbus_bool_t _dbus_credentials_add_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
#define DBUS_ERROR_FAILED
A generic error; &quot;something went wrong&quot; - see the error message for more.
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR, TMP, and TEMP in that order.
const char * _dbus_strerror_from_errno(void)
Get error message from errno.
Definition: dbus-sysdeps.c:765
unsigned long _dbus_pid_for_log(void)
The only reason this is separate from _dbus_getpid() is to allow it on Windows for logging but not fo...
#define DBUS_INT64_CONSTANT(val)
Declare a 64-bit signed integer constant.
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition: dbus-errors.c:188
int _dbus_write_socket(int fd, const DBusString *buffer, int start, int len)
Like _dbus_write(), but only supports sockets and is thus available on Windows.
const char * _dbus_string_get_const_data_len(const DBusString *str, int start, int len)
const version of _dbus_string_get_data_len().
Definition: dbus-string.c:492
A node in a linked list.
Definition: dbus-list.h:34
void _dbus_exit(int code)
Exit the process, returning the given value.
dbus_bool_t _dbus_split_paths_and_append(DBusString *dirs, const char *suffix, DBusList **dir_list)
Split paths into a list of char strings.
Definition: dbus-sysdeps.c:222
#define DBUS_ERROR_ACCESS_DENIED
Security restrictions don&#39;t allow doing what you&#39;re trying to do.
dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock(void)
See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently for Winsock so is abstracted) ...
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
dbus_bool_t _dbus_lookup_session_address(dbus_bool_t *supported, DBusString *address, DBusError *error)
Determines the address of the session bus by querying a platform-specific method. ...
#define FALSE
Expands to &quot;0&quot;.
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we&#39;re running on from the dbus configuration.
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
dbus_bool_t _dbus_sha_compute(const DBusString *data, DBusString *ascii_output)
Computes the ASCII hex-encoded shasum of the given data and appends it to the output string...
Definition: dbus-sha.c:483
void dbus_set_error_const(DBusError *error, const char *name, const char *message)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:243
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:780
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul...
void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
int dbus_int32_t
A 32-bit signed integer on all platforms.
dbus_bool_t _dbus_close_socket(int fd, DBusError *error)
Closes a socket.
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
dbus_bool_t _dbus_append_session_config_file(DBusString *str)
Append the absolute path of the session.conf file.
#define DBUS_ERROR_INVALID_ARGS
Invalid arguments passed to a method call.
short revents
Events that occurred.
Definition: dbus-sysdeps.h:316
const char * _dbus_string_get_const_data(const DBusString *str)
Gets the raw character buffer from a const string.
Definition: dbus-string.c:446
#define DBUS_ERROR_LIMITS_EXCEEDED
Some limited resource is exhausted.
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
Definition: dbus-string.c:210
dbus_bool_t _dbus_get_standard_system_servicedirs(DBusList **dirs)
Returns the standard directories for a system bus to look for service activation files.
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
dbus_bool_t _dbus_delete_file(const DBusString *filename, DBusError *error)
Deletes the given file.
int _dbus_connect_tcp_socket(const char *host, const char *port, const char *family, DBusError *error)
Creates a socket and connects to a socket at the given host and port.
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, int **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
dbus_bool_t _dbus_generate_random_bytes(DBusString *str, int n_bytes)
Generates the given number of random bytes, using the best mechanism we can come up with...
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:302
dbus_bool_t _dbus_credentials_add_from_user(DBusCredentials *credentials, const DBusString *username)
Adds the credentials corresponding to the given username.