D-Bus  1.13.7
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 #include "dbus-internals.h"
34 #include "dbus-sha.h"
35 #include "dbus-sysdeps.h"
36 #include "dbus-threads.h"
37 #include "dbus-protocol.h"
38 #include "dbus-string.h"
39 #include "dbus-sysdeps.h"
40 #include "dbus-sysdeps-win.h"
41 #include "dbus-protocol.h"
42 #include "dbus-hash.h"
43 #include "dbus-sockets-win.h"
44 #include "dbus-list.h"
45 #include "dbus-nonce.h"
46 #include "dbus-credentials.h"
47 
48 #include <windows.h>
49 #include <wincrypt.h>
50 #include <iphlpapi.h>
51 
52 /* Declarations missing in mingw's and windows sdk 7.0 headers */
53 extern BOOL WINAPI ConvertStringSidToSidA (LPCSTR StringSid, PSID *Sid);
54 extern BOOL WINAPI ConvertSidToStringSidA (PSID Sid, LPSTR *StringSid);
55 
56 #include <stdio.h>
57 #include <stdlib.h>
58 
59 #include <string.h>
60 #if HAVE_ERRNO_H
61 #include <errno.h>
62 #endif
63 #ifndef DBUS_WINCE
64 #include <mbstring.h>
65 #include <sys/stat.h>
66 #include <sys/types.h>
67 #endif
68 
69 #ifdef HAVE_WS2TCPIP_H
70 /* getaddrinfo for Windows CE (and Windows). */
71 #include <ws2tcpip.h>
72 #endif
73 
74 #ifndef O_BINARY
75 #define O_BINARY 0
76 #endif
77 
78 #ifndef PROCESS_QUERY_LIMITED_INFORMATION
79 /* MinGW32 < 4 does not define this value in its headers */
80 #define PROCESS_QUERY_LIMITED_INFORMATION (0x1000)
81 #endif
82 
83 typedef int socklen_t;
84 
85 
86 void
87 _dbus_win_set_errno (int err)
88 {
89 #ifdef DBUS_WINCE
90  SetLastError (err);
91 #else
92  errno = err;
93 #endif
94 }
95 
96 static BOOL is_winxp_sp3_or_lower (void);
97 
98 /*
99  * _MIB_TCPROW_EX and friends are not available in system headers
100  * and are mapped to attribute identical ...OWNER_PID typedefs.
101  */
102 typedef MIB_TCPROW_OWNER_PID _MIB_TCPROW_EX;
103 typedef MIB_TCPTABLE_OWNER_PID MIB_TCPTABLE_EX;
104 typedef PMIB_TCPTABLE_OWNER_PID PMIB_TCPTABLE_EX;
105 typedef DWORD (WINAPI *ProcAllocateAndGetTcpExtTableFromStack)(PMIB_TCPTABLE_EX*,BOOL,HANDLE,DWORD,DWORD);
106 static ProcAllocateAndGetTcpExtTableFromStack lpfnAllocateAndGetTcpExTableFromStack = NULL;
107 
113 static BOOL
114 load_ex_ip_helper_procedures(void)
115 {
116  HMODULE hModule = LoadLibrary ("iphlpapi.dll");
117  if (hModule == NULL)
118  {
119  _dbus_verbose ("could not load iphlpapi.dll\n");
120  return FALSE;
121  }
122 
123  lpfnAllocateAndGetTcpExTableFromStack = (ProcAllocateAndGetTcpExtTableFromStack)GetProcAddress (hModule, "AllocateAndGetTcpExTableFromStack");
124  if (lpfnAllocateAndGetTcpExTableFromStack == NULL)
125  {
126  _dbus_verbose ("could not find function AllocateAndGetTcpExTableFromStack in iphlpapi.dll\n");
127  return FALSE;
128  }
129  return TRUE;
130 }
131 
138 static dbus_pid_t
139 get_pid_from_extended_tcp_table(int peer_port)
140 {
141  dbus_pid_t result;
142  DWORD errorCode, size = 0, i;
143  MIB_TCPTABLE_OWNER_PID *tcp_table;
144 
145  if ((errorCode =
146  GetExtendedTcpTable (NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0)) == ERROR_INSUFFICIENT_BUFFER)
147  {
148  tcp_table = (MIB_TCPTABLE_OWNER_PID *) dbus_malloc (size);
149  if (tcp_table == NULL)
150  {
151  _dbus_verbose ("Error allocating memory\n");
152  return 0;
153  }
154  }
155  else
156  {
157  _dbus_win_warn_win_error ("unexpected error returned from GetExtendedTcpTable", errorCode);
158  return 0;
159  }
160 
161  if ((errorCode = GetExtendedTcpTable (tcp_table, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0)) != NO_ERROR)
162  {
163  _dbus_verbose ("Error fetching tcp table %d\n", (int)errorCode);
164  dbus_free (tcp_table);
165  return 0;
166  }
167 
168  result = 0;
169  for (i = 0; i < tcp_table->dwNumEntries; i++)
170  {
171  MIB_TCPROW_OWNER_PID *p = &tcp_table->table[i];
172  int local_address = ntohl (p->dwLocalAddr);
173  int local_port = ntohs (p->dwLocalPort);
174  if (p->dwState == MIB_TCP_STATE_ESTAB
175  && local_address == INADDR_LOOPBACK && local_port == peer_port)
176  result = p->dwOwningPid;
177  }
178 
179  dbus_free (tcp_table);
180  _dbus_verbose ("got pid %lu\n", result);
181  return result;
182 }
183 
191 static dbus_pid_t
192 get_pid_from_tcp_ex_table(int peer_port)
193 {
194  dbus_pid_t result;
195  DWORD errorCode, i;
196  PMIB_TCPTABLE_EX tcp_table = NULL;
197 
198  if (!load_ex_ip_helper_procedures ())
199  {
200  _dbus_verbose
201  ("Error not been able to load iphelper procedures\n");
202  return 0;
203  }
204 
205  errorCode = lpfnAllocateAndGetTcpExTableFromStack (&tcp_table, TRUE, GetProcessHeap(), 0, 2);
206 
207  if (errorCode != NO_ERROR)
208  {
209  _dbus_verbose
210  ("Error not been able to call AllocateAndGetTcpExTableFromStack()\n");
211  return 0;
212  }
213 
214  result = 0;
215  for (i = 0; i < tcp_table->dwNumEntries; i++)
216  {
217  _MIB_TCPROW_EX *p = &tcp_table->table[i];
218  int local_port = ntohs (p->dwLocalPort);
219  int local_address = ntohl (p->dwLocalAddr);
220  if (local_address == INADDR_LOOPBACK && local_port == peer_port)
221  {
222  result = p->dwOwningPid;
223  break;
224  }
225  }
226 
227  HeapFree (GetProcessHeap(), 0, tcp_table);
228  _dbus_verbose ("got pid %lu\n", result);
229  return result;
230 }
231 
237 static dbus_pid_t
238 _dbus_get_peer_pid_from_tcp_handle (int handle)
239 {
240  struct sockaddr_storage addr;
241  socklen_t len = sizeof (addr);
242  int peer_port;
243 
244  dbus_pid_t result;
245  dbus_bool_t is_localhost = FALSE;
246 
247  getpeername (handle, (struct sockaddr *) &addr, &len);
248 
249  if (addr.ss_family == AF_INET)
250  {
251  struct sockaddr_in *s = (struct sockaddr_in *) &addr;
252  peer_port = ntohs (s->sin_port);
253  is_localhost = (ntohl (s->sin_addr.s_addr) == INADDR_LOOPBACK);
254  }
255  else if (addr.ss_family == AF_INET6)
256  {
257  _dbus_verbose ("FIXME [61922]: IPV6 support not working on windows\n");
258  return 0;
259  /*
260  struct sockaddr_in6 *s = (struct sockaddr_in6 * )&addr;
261  peer_port = ntohs (s->sin6_port);
262  is_localhost = (memcmp(s->sin6_addr.s6_addr, in6addr_loopback.s6_addr, 16) == 0);
263  _dbus_verbose ("IPV6 %08x %08x\n", s->sin6_addr.s6_addr, in6addr_loopback.s6_addr);
264  */
265  }
266  else
267  {
268  _dbus_verbose ("no idea what address family %d is\n", addr.ss_family);
269  return 0;
270  }
271 
272  if (!is_localhost)
273  {
274  _dbus_verbose ("could not fetch process id from remote process\n");
275  return 0;
276  }
277 
278  if (peer_port == 0)
279  {
280  _dbus_verbose
281  ("Error not been able to fetch tcp peer port from connection\n");
282  return 0;
283  }
284 
285  _dbus_verbose ("trying to get peer's pid\n");
286 
287  result = get_pid_from_extended_tcp_table (peer_port);
288  if (result > 0)
289  return result;
290  result = get_pid_from_tcp_ex_table (peer_port);
291  return result;
292 }
293 
294 /* Convert GetLastError() to a dbus error. */
295 const char*
296 _dbus_win_error_from_last_error (void)
297 {
298  switch (GetLastError())
299  {
300  case 0:
301  return DBUS_ERROR_FAILED;
302 
303  case ERROR_NO_MORE_FILES:
304  case ERROR_TOO_MANY_OPEN_FILES:
305  return DBUS_ERROR_LIMITS_EXCEEDED; /* kernel out of memory */
306 
307  case ERROR_ACCESS_DENIED:
308  case ERROR_CANNOT_MAKE:
310 
311  case ERROR_NOT_ENOUGH_MEMORY:
312  return DBUS_ERROR_NO_MEMORY;
313 
314  case ERROR_FILE_EXISTS:
315  return DBUS_ERROR_FILE_EXISTS;
316 
317  case ERROR_FILE_NOT_FOUND:
318  case ERROR_PATH_NOT_FOUND:
320 
321  default:
322  return DBUS_ERROR_FAILED;
323  }
324 }
325 
326 
327 char*
328 _dbus_win_error_string (int error_number)
329 {
330  char *msg;
331 
332  FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
333  FORMAT_MESSAGE_IGNORE_INSERTS |
334  FORMAT_MESSAGE_FROM_SYSTEM,
335  NULL, error_number, 0,
336  (LPSTR) &msg, 0, NULL);
337 
338  if (msg[strlen (msg) - 1] == '\n')
339  msg[strlen (msg) - 1] = '\0';
340  if (msg[strlen (msg) - 1] == '\r')
341  msg[strlen (msg) - 1] = '\0';
342 
343  return msg;
344 }
345 
346 void
347 _dbus_win_free_error_string (char *string)
348 {
349  LocalFree (string);
350 }
351 
372 int
374  DBusString *buffer,
375  int count)
376 {
377  int bytes_read;
378  int start;
379  char *data;
380 
381  _dbus_assert (count >= 0);
382 
383  start = _dbus_string_get_length (buffer);
384 
385  if (!_dbus_string_lengthen (buffer, count))
386  {
387  _dbus_win_set_errno (ENOMEM);
388  return -1;
389  }
390 
391  data = _dbus_string_get_data_len (buffer, start, count);
392 
393  again:
394 
395  _dbus_verbose ("recv: count=%d fd=%Iu\n", count, fd.sock);
396  bytes_read = recv (fd.sock, data, count, 0);
397 
398  if (bytes_read == SOCKET_ERROR)
399  {
400  DBUS_SOCKET_SET_ERRNO();
401  _dbus_verbose ("recv: failed: %s (%d)\n", _dbus_strerror (errno), errno);
402  bytes_read = -1;
403  }
404  else
405  _dbus_verbose ("recv: = %d\n", bytes_read);
406 
407  if (bytes_read < 0)
408  {
409  if (errno == EINTR)
410  goto again;
411  else
412  {
413  /* put length back (note that this doesn't actually realloc anything) */
414  _dbus_string_set_length (buffer, start);
415  return -1;
416  }
417  }
418  else
419  {
420  /* put length back (doesn't actually realloc) */
421  _dbus_string_set_length (buffer, start + bytes_read);
422 
423 #if 0
424  if (bytes_read > 0)
425  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
426 #endif
427 
428  return bytes_read;
429  }
430 }
431 
442 int
444  const DBusString *buffer,
445  int start,
446  int len)
447 {
448  const char *data;
449  int bytes_written;
450 
451  data = _dbus_string_get_const_data_len (buffer, start, len);
452 
453  again:
454 
455  _dbus_verbose ("send: len=%d fd=%Iu\n", len, fd.sock);
456  bytes_written = send (fd.sock, data, len, 0);
457 
458  if (bytes_written == SOCKET_ERROR)
459  {
460  DBUS_SOCKET_SET_ERRNO();
461  _dbus_verbose ("send: failed: %s\n", _dbus_strerror_from_errno ());
462  bytes_written = -1;
463  }
464  else
465  _dbus_verbose ("send: = %d\n", bytes_written);
466 
467  if (bytes_written < 0 && errno == EINTR)
468  goto again;
469 
470 #if 0
471  if (bytes_written > 0)
472  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
473 #endif
474 
475  return bytes_written;
476 }
477 
478 
488  DBusError *error)
489 {
490  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
491 
492  again:
493  if (closesocket (fd.sock) == SOCKET_ERROR)
494  {
495  DBUS_SOCKET_SET_ERRNO ();
496 
497  if (errno == EINTR)
498  goto again;
499 
500  dbus_set_error (error, _dbus_error_from_errno (errno),
501  "Could not close socket: socket=%Iu, , %s",
502  fd.sock, _dbus_strerror_from_errno ());
503  return FALSE;
504  }
505  _dbus_verbose ("socket=%Iu, \n", fd.sock);
506 
507  return TRUE;
508 }
509 
517 static void
518 _dbus_win_handle_set_close_on_exec (HANDLE handle)
519 {
520  if ( !SetHandleInformation( (HANDLE) handle,
521  HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE,
522  0 /*disable both flags*/ ) )
523  {
524  _dbus_win_warn_win_error ("Disabling socket handle inheritance failed:", GetLastError());
525  }
526 }
527 
537  DBusError *error)
538 {
539  u_long one = 1;
540 
541  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
542 
543  if (ioctlsocket (handle.sock, FIONBIO, &one) == SOCKET_ERROR)
544  {
545  DBUS_SOCKET_SET_ERRNO ();
546  dbus_set_error (error, _dbus_error_from_errno (errno),
547  "Failed to set socket %Iu to nonblocking: %s",
548  handle.sock, _dbus_strerror_from_errno ());
549  return FALSE;
550  }
551 
552  return TRUE;
553 }
554 
555 
576 int
578  const DBusString *buffer1,
579  int start1,
580  int len1,
581  const DBusString *buffer2,
582  int start2,
583  int len2)
584 {
585  WSABUF vectors[2];
586  const char *data1;
587  const char *data2;
588  int rc;
589  DWORD bytes_written;
590 
591  _dbus_assert (buffer1 != NULL);
592  _dbus_assert (start1 >= 0);
593  _dbus_assert (start2 >= 0);
594  _dbus_assert (len1 >= 0);
595  _dbus_assert (len2 >= 0);
596 
597 
598  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
599 
600  if (buffer2 != NULL)
601  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
602  else
603  {
604  data2 = NULL;
605  start2 = 0;
606  len2 = 0;
607  }
608 
609  vectors[0].buf = (char*) data1;
610  vectors[0].len = len1;
611  vectors[1].buf = (char*) data2;
612  vectors[1].len = len2;
613 
614  again:
615 
616  _dbus_verbose ("WSASend: len1+2=%d+%d fd=%Iu\n", len1, len2, fd.sock);
617  rc = WSASend (fd.sock,
618  vectors,
619  data2 ? 2 : 1,
620  &bytes_written,
621  0,
622  NULL,
623  NULL);
624 
625  if (rc == SOCKET_ERROR)
626  {
627  DBUS_SOCKET_SET_ERRNO ();
628  _dbus_verbose ("WSASend: failed: %s\n", _dbus_strerror_from_errno ());
629  bytes_written = (DWORD) -1;
630  }
631  else
632  _dbus_verbose ("WSASend: = %ld\n", bytes_written);
633 
634  if (bytes_written == (DWORD) -1 && errno == EINTR)
635  goto again;
636 
637  return bytes_written;
638 }
639 
640 #if 0
641 
650 int
651 _dbus_connect_named_pipe (const char *path,
652  DBusError *error)
653 {
654  _dbus_assert_not_reached ("not implemented");
655 }
656 
657 #endif
658 
663 _dbus_win_startup_winsock (void)
664 {
665  /* Straight from MSDN, deuglified */
666 
667  /* Protected by _DBUS_LOCK_sysdeps */
668  static dbus_bool_t beenhere = FALSE;
669 
670  WORD wVersionRequested;
671  WSADATA wsaData;
672  int err;
673 
674  if (!_DBUS_LOCK (sysdeps))
675  return FALSE;
676 
677  if (beenhere)
678  goto out;
679 
680  wVersionRequested = MAKEWORD (2, 0);
681 
682  err = WSAStartup (wVersionRequested, &wsaData);
683  if (err != 0)
684  {
685  _dbus_assert_not_reached ("Could not initialize WinSock");
686  _dbus_abort ();
687  }
688 
689  /* Confirm that the WinSock DLL supports 2.0. Note that if the DLL
690  * supports versions greater than 2.0 in addition to 2.0, it will
691  * still return 2.0 in wVersion since that is the version we
692  * requested.
693  */
694  if (LOBYTE (wsaData.wVersion) != 2 ||
695  HIBYTE (wsaData.wVersion) != 0)
696  {
697  _dbus_assert_not_reached ("No usable WinSock found");
698  _dbus_abort ();
699  }
700 
701  beenhere = TRUE;
702 
703 out:
704  _DBUS_UNLOCK (sysdeps);
705  return TRUE;
706 }
707 
708 
709 
710 
711 
712 
713 
714 
715 
716 /************************************************************************
717 
718  UTF / string code
719 
720  ************************************************************************/
721 
725 int _dbus_printf_string_upper_bound (const char *format,
726  va_list args)
727 {
728  /* MSVCRT's vsnprintf semantics are a bit different */
729  char buf[1024];
730  int bufsize;
731  int len;
732  va_list args_copy;
733 
734  bufsize = sizeof (buf);
735  DBUS_VA_COPY (args_copy, args);
736  len = _vsnprintf (buf, bufsize - 1, format, args_copy);
737  va_end (args_copy);
738 
739  while (len == -1) /* try again */
740  {
741  char *p;
742 
743  bufsize *= 2;
744 
745  p = malloc (bufsize);
746 
747  if (p == NULL)
748  return -1;
749 
750  DBUS_VA_COPY (args_copy, args);
751  len = _vsnprintf (p, bufsize - 1, format, args_copy);
752  va_end (args_copy);
753  free (p);
754  }
755 
756  return len;
757 }
758 
759 
767 wchar_t *
768 _dbus_win_utf8_to_utf16 (const char *str,
769  DBusError *error)
770 {
771  DBusString s;
772  int n;
773  wchar_t *retval;
774 
775  _dbus_string_init_const (&s, str);
776 
777  if (!_dbus_string_validate_utf8 (&s, 0, _dbus_string_get_length (&s)))
778  {
779  dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid UTF-8");
780  return NULL;
781  }
782 
783  n = MultiByteToWideChar (CP_UTF8, 0, str, -1, NULL, 0);
784 
785  if (n == 0)
786  {
787  _dbus_win_set_error_from_win_error (error, GetLastError ());
788  return NULL;
789  }
790 
791  retval = dbus_new (wchar_t, n);
792 
793  if (!retval)
794  {
795  _DBUS_SET_OOM (error);
796  return NULL;
797  }
798 
799  if (MultiByteToWideChar (CP_UTF8, 0, str, -1, retval, n) != n)
800  {
801  dbus_free (retval);
802  dbus_set_error_const (error, DBUS_ERROR_FAILED, "MultiByteToWideChar inconsistency");
803  return NULL;
804  }
805 
806  return retval;
807 }
808 
816 char *
817 _dbus_win_utf16_to_utf8 (const wchar_t *str,
818  DBusError *error)
819 {
820  int n;
821  char *retval;
822 
823  n = WideCharToMultiByte (CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
824 
825  if (n == 0)
826  {
827  _dbus_win_set_error_from_win_error (error, GetLastError ());
828  return NULL;
829  }
830 
831  retval = dbus_malloc (n);
832 
833  if (!retval)
834  {
835  _DBUS_SET_OOM (error);
836  return NULL;
837  }
838 
839  if (WideCharToMultiByte (CP_UTF8, 0, str, -1, retval, n, NULL, NULL) != n)
840  {
841  dbus_free (retval);
842  dbus_set_error_const (error, DBUS_ERROR_FAILED, "WideCharToMultiByte inconsistency");
843  return NULL;
844  }
845 
846  return retval;
847 }
848 
849 
850 
851 
852 
853 
854 /************************************************************************
855 
856 
857  ************************************************************************/
858 
860 _dbus_win_account_to_sid (const wchar_t *waccount,
861  void **ppsid,
862  DBusError *error)
863 {
864  dbus_bool_t retval = FALSE;
865  DWORD sid_length, wdomain_length;
866  SID_NAME_USE use;
867  wchar_t *wdomain;
868 
869  *ppsid = NULL;
870 
871  sid_length = 0;
872  wdomain_length = 0;
873  if (!LookupAccountNameW (NULL, waccount, NULL, &sid_length,
874  NULL, &wdomain_length, &use) &&
875  GetLastError () != ERROR_INSUFFICIENT_BUFFER)
876  {
877  _dbus_win_set_error_from_win_error (error, GetLastError ());
878  return FALSE;
879  }
880 
881  *ppsid = dbus_malloc (sid_length);
882  if (!*ppsid)
883  {
884  _DBUS_SET_OOM (error);
885  return FALSE;
886  }
887 
888  wdomain = dbus_new (wchar_t, wdomain_length);
889  if (!wdomain)
890  {
891  _DBUS_SET_OOM (error);
892  goto out1;
893  }
894 
895  if (!LookupAccountNameW (NULL, waccount, (PSID) *ppsid, &sid_length,
896  wdomain, &wdomain_length, &use))
897  {
898  _dbus_win_set_error_from_win_error (error, GetLastError ());
899  goto out2;
900  }
901 
902  if (!IsValidSid ((PSID) *ppsid))
903  {
904  dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID");
905  goto out2;
906  }
907 
908  retval = TRUE;
909 
910 out2:
911  dbus_free (wdomain);
912 out1:
913  if (!retval)
914  {
915  dbus_free (*ppsid);
916  *ppsid = NULL;
917  }
918 
919  return retval;
920 }
921 
931 unsigned long
933 {
934  return _dbus_getpid ();
935 }
936 
937 #ifndef DBUS_WINCE
938 
939 static BOOL
940 is_winxp_sp3_or_lower (void)
941 {
942  OSVERSIONINFOEX osvi;
943  DWORDLONG dwlConditionMask = 0;
944  int op=VER_LESS_EQUAL;
945 
946  // Initialize the OSVERSIONINFOEX structure.
947 
948  ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
949  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
950  osvi.dwMajorVersion = 5;
951  osvi.dwMinorVersion = 1;
952  osvi.wServicePackMajor = 3;
953  osvi.wServicePackMinor = 0;
954 
955  // Initialize the condition mask.
956 
957  VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, op );
958  VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION, op );
959  VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMAJOR, op );
960  VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMINOR, op );
961 
962  // Perform the test.
963 
964  return VerifyVersionInfo(
965  &osvi,
966  VER_MAJORVERSION | VER_MINORVERSION |
967  VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
968  dwlConditionMask);
969 }
970 
977 _dbus_getsid(char **sid, dbus_pid_t process_id)
978 {
979  HANDLE process_token = INVALID_HANDLE_VALUE;
980  TOKEN_USER *token_user = NULL;
981  DWORD n;
982  PSID psid;
983  int retval = FALSE;
984 
985  HANDLE process_handle;
986  if (process_id == 0)
987  process_handle = GetCurrentProcess();
988  else if (is_winxp_sp3_or_lower())
989  process_handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, process_id);
990  else
991  process_handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id);
992 
993  if (!OpenProcessToken (process_handle, TOKEN_QUERY, &process_token))
994  {
995  _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ());
996  goto failed;
997  }
998  if ((!GetTokenInformation (process_token, TokenUser, NULL, 0, &n)
999  && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
1000  || (token_user = alloca (n)) == NULL
1001  || !GetTokenInformation (process_token, TokenUser, token_user, n, &n))
1002  {
1003  _dbus_win_warn_win_error ("GetTokenInformation failed", GetLastError ());
1004  goto failed;
1005  }
1006  psid = token_user->User.Sid;
1007  if (!IsValidSid (psid))
1008  {
1009  _dbus_verbose("%s invalid sid\n",__FUNCTION__);
1010  goto failed;
1011  }
1012  if (!ConvertSidToStringSidA (psid, sid))
1013  {
1014  _dbus_verbose("%s invalid sid\n",__FUNCTION__);
1015  goto failed;
1016  }
1017 //okay:
1018  retval = TRUE;
1019 
1020 failed:
1021  CloseHandle (process_handle);
1022  if (process_token != INVALID_HANDLE_VALUE)
1023  CloseHandle (process_token);
1024 
1025  _dbus_verbose("_dbus_getsid() got '%s' and returns %d\n", *sid, retval);
1026  return retval;
1027 }
1028 #endif
1029 
1030 /************************************************************************
1031 
1032  pipes
1033 
1034  ************************************************************************/
1035 
1050  DBusSocket *fd2,
1051  dbus_bool_t blocking,
1052  DBusError *error)
1053 {
1054  SOCKET temp, socket1 = -1, socket2 = -1;
1055  struct sockaddr_in saddr;
1056  int len;
1057  u_long arg;
1058 
1059  if (!_dbus_win_startup_winsock ())
1060  {
1061  _DBUS_SET_OOM (error);
1062  return FALSE;
1063  }
1064 
1065  temp = socket (AF_INET, SOCK_STREAM, 0);
1066  if (temp == INVALID_SOCKET)
1067  {
1068  DBUS_SOCKET_SET_ERRNO ();
1069  goto out0;
1070  }
1071 
1072  _DBUS_ZERO (saddr);
1073  saddr.sin_family = AF_INET;
1074  saddr.sin_port = 0;
1075  saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1076 
1077  if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr)) == SOCKET_ERROR)
1078  {
1079  DBUS_SOCKET_SET_ERRNO ();
1080  goto out0;
1081  }
1082 
1083  if (listen (temp, 1) == SOCKET_ERROR)
1084  {
1085  DBUS_SOCKET_SET_ERRNO ();
1086  goto out0;
1087  }
1088 
1089  len = sizeof (saddr);
1090  if (getsockname (temp, (struct sockaddr *)&saddr, &len) == SOCKET_ERROR)
1091  {
1092  DBUS_SOCKET_SET_ERRNO ();
1093  goto out0;
1094  }
1095 
1096  socket1 = socket (AF_INET, SOCK_STREAM, 0);
1097  if (socket1 == INVALID_SOCKET)
1098  {
1099  DBUS_SOCKET_SET_ERRNO ();
1100  goto out0;
1101  }
1102 
1103  if (connect (socket1, (struct sockaddr *)&saddr, len) == SOCKET_ERROR)
1104  {
1105  DBUS_SOCKET_SET_ERRNO ();
1106  goto out1;
1107  }
1108 
1109  socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
1110  if (socket2 == INVALID_SOCKET)
1111  {
1112  DBUS_SOCKET_SET_ERRNO ();
1113  goto out1;
1114  }
1115 
1116  if (!blocking)
1117  {
1118  arg = 1;
1119  if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
1120  {
1121  DBUS_SOCKET_SET_ERRNO ();
1122  goto out2;
1123  }
1124 
1125  arg = 1;
1126  if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
1127  {
1128  DBUS_SOCKET_SET_ERRNO ();
1129  goto out2;
1130  }
1131  }
1132 
1133  fd1->sock = socket1;
1134  fd2->sock = socket2;
1135 
1136  _dbus_verbose ("full-duplex pipe %Iu:%Iu <-> %Iu:%Iu\n",
1137  fd1->sock, socket1, fd2->sock, socket2);
1138 
1139  closesocket (temp);
1140 
1141  return TRUE;
1142 
1143 out2:
1144  closesocket (socket2);
1145 out1:
1146  closesocket (socket1);
1147 out0:
1148  closesocket (temp);
1149 
1150  dbus_set_error (error, _dbus_error_from_errno (errno),
1151  "Could not setup socket pair: %s",
1153 
1154  return FALSE;
1155 }
1156 
1165 int
1167  int n_fds,
1168  int timeout_milliseconds)
1169 {
1170 #define USE_CHRIS_IMPL 0
1171 
1172 #if USE_CHRIS_IMPL
1173 
1174 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
1175  char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
1176  char *msgp;
1177 
1178  int ret = 0;
1179  int i;
1180  struct timeval tv;
1181  int ready;
1182 
1183 #define DBUS_STACK_WSAEVENTS 256
1184  WSAEVENT eventsOnStack[DBUS_STACK_WSAEVENTS];
1185  WSAEVENT *pEvents = NULL;
1186  if (n_fds > DBUS_STACK_WSAEVENTS)
1187  pEvents = calloc(sizeof(WSAEVENT), n_fds);
1188  else
1189  pEvents = eventsOnStack;
1190 
1191 
1192 #ifdef DBUS_ENABLE_VERBOSE_MODE
1193  msgp = msg;
1194  msgp += sprintf (msgp, "WSAEventSelect: to=%d\n\t", timeout_milliseconds);
1195  for (i = 0; i < n_fds; i++)
1196  {
1197  DBusPollFD *fdp = &fds[i];
1198 
1199 
1200  if (fdp->events & _DBUS_POLLIN)
1201  msgp += sprintf (msgp, "R:%Iu ", fdp->fd.sock);
1202 
1203  if (fdp->events & _DBUS_POLLOUT)
1204  msgp += sprintf (msgp, "W:%Iu ", fdp->fd.sock);
1205 
1206  msgp += sprintf (msgp, "E:%Iu\n\t", fdp->fd.sock);
1207 
1208  // FIXME: more robust code for long msg
1209  // create on heap when msg[] becomes too small
1210  if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
1211  {
1212  _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
1213  }
1214  }
1215 
1216  msgp += sprintf (msgp, "\n");
1217  _dbus_verbose ("%s",msg);
1218 #endif
1219  for (i = 0; i < n_fds; i++)
1220  {
1221  DBusPollFD *fdp = &fds[i];
1222  WSAEVENT ev;
1223  long lNetworkEvents = FD_OOB;
1224 
1225  ev = WSACreateEvent();
1226 
1227  if (fdp->events & _DBUS_POLLIN)
1228  lNetworkEvents |= FD_READ | FD_ACCEPT | FD_CLOSE;
1229 
1230  if (fdp->events & _DBUS_POLLOUT)
1231  lNetworkEvents |= FD_WRITE | FD_CONNECT;
1232 
1233  WSAEventSelect(fdp->fd.sock, ev, lNetworkEvents);
1234 
1235  pEvents[i] = ev;
1236  }
1237 
1238 
1239  ready = WSAWaitForMultipleEvents (n_fds, pEvents, FALSE, timeout_milliseconds, FALSE);
1240 
1241  if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
1242  {
1243  DBUS_SOCKET_SET_ERRNO ();
1244  if (errno != WSAEWOULDBLOCK)
1245  _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", _dbus_strerror_from_errno ());
1246  ret = -1;
1247  }
1248  else if (ready == WSA_WAIT_TIMEOUT)
1249  {
1250  _dbus_verbose ("WSAWaitForMultipleEvents: WSA_WAIT_TIMEOUT\n");
1251  ret = 0;
1252  }
1253  else if (ready >= WSA_WAIT_EVENT_0 && ready < (int)(WSA_WAIT_EVENT_0 + n_fds))
1254  {
1255  msgp = msg;
1256  msgp += sprintf (msgp, "WSAWaitForMultipleEvents: =%d\n\t", ready);
1257 
1258  for (i = 0; i < n_fds; i++)
1259  {
1260  DBusPollFD *fdp = &fds[i];
1261  WSANETWORKEVENTS ne;
1262 
1263  fdp->revents = 0;
1264 
1265  WSAEnumNetworkEvents(fdp->fd.sock, pEvents[i], &ne);
1266 
1267  if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
1268  fdp->revents |= _DBUS_POLLIN;
1269 
1270  if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
1271  fdp->revents |= _DBUS_POLLOUT;
1272 
1273  if (ne.lNetworkEvents & (FD_OOB))
1274  fdp->revents |= _DBUS_POLLERR;
1275 
1276  if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
1277  msgp += sprintf (msgp, "R:%Iu ", fdp->fd.sock);
1278 
1279  if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
1280  msgp += sprintf (msgp, "W:%Iu ", fdp->fd.sock);
1281 
1282  if (ne.lNetworkEvents & (FD_OOB))
1283  msgp += sprintf (msgp, "E:%Iu ", fdp->fd.sock);
1284 
1285  msgp += sprintf (msgp, "lNetworkEvents:%d ", ne.lNetworkEvents);
1286 
1287  if(ne.lNetworkEvents)
1288  ret++;
1289 
1290  WSAEventSelect(fdp->fd.sock, pEvents[i], 0);
1291  }
1292 
1293  msgp += sprintf (msgp, "\n");
1294  _dbus_verbose ("%s",msg);
1295  }
1296  else
1297  {
1298  _dbus_verbose ("WSAWaitForMultipleEvents: failed for unknown reason!");
1299  ret = -1;
1300  }
1301 
1302  for(i = 0; i < n_fds; i++)
1303  {
1304  WSACloseEvent(pEvents[i]);
1305  }
1306 
1307  if (n_fds > DBUS_STACK_WSAEVENTS)
1308  free(pEvents);
1309 
1310  return ret;
1311 
1312 #else /* USE_CHRIS_IMPL */
1313 
1314 #ifdef DBUS_ENABLE_VERBOSE_MODE
1315 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
1316  char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
1317  char *msgp;
1318 #endif
1319 
1320  fd_set read_set, write_set, err_set;
1321  SOCKET max_fd = 0;
1322  int i;
1323  struct timeval tv;
1324  int ready;
1325 
1326  FD_ZERO (&read_set);
1327  FD_ZERO (&write_set);
1328  FD_ZERO (&err_set);
1329 
1330 
1331 #ifdef DBUS_ENABLE_VERBOSE_MODE
1332  msgp = msg;
1333  msgp += sprintf (msgp, "select: to=%d\n\t", timeout_milliseconds);
1334  for (i = 0; i < n_fds; i++)
1335  {
1336  DBusPollFD *fdp = &fds[i];
1337 
1338 
1339  if (fdp->events & _DBUS_POLLIN)
1340  msgp += sprintf (msgp, "R:%Iu ", fdp->fd.sock);
1341 
1342  if (fdp->events & _DBUS_POLLOUT)
1343  msgp += sprintf (msgp, "W:%Iu ", fdp->fd.sock);
1344 
1345  msgp += sprintf (msgp, "E:%Iu\n\t", fdp->fd.sock);
1346 
1347  // FIXME: more robust code for long msg
1348  // create on heap when msg[] becomes too small
1349  if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
1350  {
1351  _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
1352  }
1353  }
1354 
1355  msgp += sprintf (msgp, "\n");
1356  _dbus_verbose ("%s",msg);
1357 #endif
1358  for (i = 0; i < n_fds; i++)
1359  {
1360  DBusPollFD *fdp = &fds[i];
1361 
1362  if (fdp->events & _DBUS_POLLIN)
1363  FD_SET (fdp->fd.sock, &read_set);
1364 
1365  if (fdp->events & _DBUS_POLLOUT)
1366  FD_SET (fdp->fd.sock, &write_set);
1367 
1368  FD_SET (fdp->fd.sock, &err_set);
1369 
1370  max_fd = MAX (max_fd, fdp->fd.sock);
1371  }
1372 
1373  // Avoid random lockups with send(), for lack of a better solution so far
1374  tv.tv_sec = timeout_milliseconds < 0 ? 1 : timeout_milliseconds / 1000;
1375  tv.tv_usec = timeout_milliseconds < 0 ? 0 : (timeout_milliseconds % 1000) * 1000;
1376 
1377  ready = select (max_fd + 1, &read_set, &write_set, &err_set, &tv);
1378 
1379  if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
1380  {
1381  DBUS_SOCKET_SET_ERRNO ();
1382  if (errno != WSAEWOULDBLOCK)
1383  _dbus_verbose ("select: failed: %s\n", _dbus_strerror_from_errno ());
1384  }
1385  else if (ready == 0)
1386  _dbus_verbose ("select: = 0\n");
1387  else
1388  if (ready > 0)
1389  {
1390 #ifdef DBUS_ENABLE_VERBOSE_MODE
1391  msgp = msg;
1392  msgp += sprintf (msgp, "select: = %d:\n\t", ready);
1393 
1394  for (i = 0; i < n_fds; i++)
1395  {
1396  DBusPollFD *fdp = &fds[i];
1397 
1398  if (FD_ISSET (fdp->fd.sock, &read_set))
1399  msgp += sprintf (msgp, "R:%Iu ", fdp->fd.sock);
1400 
1401  if (FD_ISSET (fdp->fd.sock, &write_set))
1402  msgp += sprintf (msgp, "W:%Iu ", fdp->fd.sock);
1403 
1404  if (FD_ISSET (fdp->fd.sock, &err_set))
1405  msgp += sprintf (msgp, "E:%Iu\n\t", fdp->fd.sock);
1406  }
1407  msgp += sprintf (msgp, "\n");
1408  _dbus_verbose ("%s",msg);
1409 #endif
1410 
1411  for (i = 0; i < n_fds; i++)
1412  {
1413  DBusPollFD *fdp = &fds[i];
1414 
1415  fdp->revents = 0;
1416 
1417  if (FD_ISSET (fdp->fd.sock, &read_set))
1418  fdp->revents |= _DBUS_POLLIN;
1419 
1420  if (FD_ISSET (fdp->fd.sock, &write_set))
1421  fdp->revents |= _DBUS_POLLOUT;
1422 
1423  if (FD_ISSET (fdp->fd.sock, &err_set))
1424  fdp->revents |= _DBUS_POLLERR;
1425  }
1426  }
1427  return ready;
1428 #endif /* USE_CHRIS_IMPL */
1429 }
1430 
1431 
1432 
1433 
1434 /******************************************************************************
1435 
1436 Original CVS version of dbus-sysdeps.c
1437 
1438 ******************************************************************************/
1439 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
1440 /* dbus-sysdeps.c Wrappers around system/libc features (internal to D-Bus implementation)
1441  *
1442  * Copyright (C) 2002, 2003 Red Hat, Inc.
1443  * Copyright (C) 2003 CodeFactory AB
1444  * Copyright (C) 2005 Novell, Inc.
1445  *
1446  * Licensed under the Academic Free License version 2.1
1447  *
1448  * This program is free software; you can redistribute it and/or modify
1449  * it under the terms of the GNU General Public License as published by
1450  * the Free Software Foundation; either version 2 of the License, or
1451  * (at your option) any later version.
1452  *
1453  * This program is distributed in the hope that it will be useful,
1454  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1455  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1456  * GNU General Public License for more details.
1457  *
1458  * You should have received a copy of the GNU General Public License
1459  * along with this program; if not, write to the Free Software
1460  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1461  *
1462  */
1463 
1464 
1470 void
1471 _dbus_exit (int code)
1472 {
1473  _exit (code);
1474 }
1475 
1487 DBusSocket
1488 _dbus_connect_tcp_socket (const char *host,
1489  const char *port,
1490  const char *family,
1491  DBusError *error)
1492 {
1493  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1494 }
1495 
1496 DBusSocket
1497 _dbus_connect_tcp_socket_with_nonce (const char *host,
1498  const char *port,
1499  const char *family,
1500  const char *noncefile,
1501  DBusError *error)
1502 {
1503  int saved_errno = 0;
1504  DBusList *connect_errors = NULL;
1505  DBusSocket fd = DBUS_SOCKET_INIT;
1506  int res;
1507  struct addrinfo hints;
1508  struct addrinfo *ai, *tmp;
1509  DBusError *connect_error;
1510 
1511  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1512 
1513  if (!_dbus_win_startup_winsock ())
1514  {
1515  _DBUS_SET_OOM (error);
1516  return _dbus_socket_get_invalid ();
1517  }
1518 
1519  _DBUS_ZERO (hints);
1520 
1521  if (!family)
1522  hints.ai_family = AF_UNSPEC;
1523  else if (!strcmp(family, "ipv4"))
1524  hints.ai_family = AF_INET;
1525  else if (!strcmp(family, "ipv6"))
1526  hints.ai_family = AF_INET6;
1527  else
1528  {
1529  dbus_set_error (error,
1531  "Unknown address family %s", family);
1532  return _dbus_socket_get_invalid ();
1533  }
1534  hints.ai_protocol = IPPROTO_TCP;
1535  hints.ai_socktype = SOCK_STREAM;
1536 #ifdef AI_ADDRCONFIG
1537  hints.ai_flags = AI_ADDRCONFIG;
1538 #else
1539  hints.ai_flags = 0;
1540 #endif
1541 
1542  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1543  {
1544  dbus_set_error (error,
1545  _dbus_error_from_errno (res),
1546  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1547  host, port, _dbus_strerror (res), res);
1548  goto out;
1549  }
1550 
1551  tmp = ai;
1552  while (tmp)
1553  {
1554  if ((fd.sock = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
1555  {
1556  saved_errno = _dbus_get_low_level_socket_errno ();
1557  dbus_set_error (error,
1558  _dbus_error_from_errno (saved_errno),
1559  "Failed to open socket: %s",
1560  _dbus_strerror (saved_errno));
1561  freeaddrinfo(ai);
1562  _dbus_socket_invalidate (&fd);
1563  goto out;
1564  }
1565  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1566 
1567  if (connect (fd.sock, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
1568  {
1569  saved_errno = _dbus_get_low_level_socket_errno ();
1570  closesocket(fd.sock);
1571  _dbus_socket_invalidate (&fd);
1572 
1573  connect_error = dbus_new0 (DBusError, 1);
1574 
1575  if (connect_error == NULL)
1576  {
1577  _DBUS_SET_OOM (error);
1578  goto out;
1579  }
1580 
1581  dbus_error_init (connect_error);
1582  _dbus_set_error_with_inet_sockaddr (connect_error,
1583  tmp->ai_addr, tmp->ai_addrlen,
1584  "Failed to connect to socket",
1585  saved_errno);
1586 
1587  if (!_dbus_list_append (&connect_errors, connect_error))
1588  {
1589  dbus_error_free (connect_error);
1590  dbus_free (connect_error);
1591  _DBUS_SET_OOM (error);
1592  goto out;
1593  }
1594 
1595  tmp = tmp->ai_next;
1596  continue;
1597  }
1598 
1599  break;
1600  }
1601  freeaddrinfo(ai);
1602 
1603  if (!_dbus_socket_is_valid (fd))
1604  {
1605  _dbus_combine_tcp_errors (&connect_errors, "Failed to connect",
1606  host, port, error);
1607  goto out;
1608  }
1609 
1610  if (noncefile != NULL)
1611  {
1612  DBusString noncefileStr;
1613  dbus_bool_t ret;
1614  _dbus_string_init_const (&noncefileStr, noncefile);
1615  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1616 
1617  if (!ret)
1618  {
1619  closesocket (fd.sock);
1620  _dbus_socket_invalidate (&fd);
1621  goto out;
1622  }
1623  }
1624 
1625  /* Every SOCKET is also a HANDLE. */
1626  _dbus_win_handle_set_close_on_exec ((HANDLE) fd.sock);
1627 
1628  if (!_dbus_set_socket_nonblocking (fd, error))
1629  {
1630  closesocket (fd.sock);
1631  _dbus_socket_invalidate (&fd);
1632  goto out;
1633  }
1634 
1635 out:
1636  while ((connect_error = _dbus_list_pop_first (&connect_errors)))
1637  {
1638  dbus_error_free (connect_error);
1639  dbus_free (connect_error);
1640  }
1641 
1642  return fd;
1643 }
1644 
1660 int
1661 _dbus_listen_tcp_socket (const char *host,
1662  const char *port,
1663  const char *family,
1664  DBusString *retport,
1665  const char **retfamily,
1666  DBusSocket **fds_p,
1667  DBusError *error)
1668 {
1669  int saved_errno;
1670  int nlisten_fd = 0, res, i, port_num = -1;
1671  DBusList *bind_errors = NULL;
1672  DBusError *bind_error = NULL;
1673  DBusSocket *listen_fd = NULL;
1674  struct addrinfo hints;
1675  struct addrinfo *ai, *tmp;
1676  dbus_bool_t have_ipv4 = FALSE;
1677  dbus_bool_t have_ipv6 = FALSE;
1678 
1679  // On Vista, sockaddr_gen must be a sockaddr_in6, and not a sockaddr_in6_old
1680  //That's required for family == IPv6(which is the default on Vista if family is not given)
1681  //So we use our own union instead of sockaddr_gen:
1682 
1683  typedef union {
1684  struct sockaddr Address;
1685  struct sockaddr_in AddressIn;
1686  struct sockaddr_in6 AddressIn6;
1687  } mysockaddr_gen;
1688 
1689  *fds_p = NULL;
1690  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1691 
1692  if (!_dbus_win_startup_winsock ())
1693  {
1694  _DBUS_SET_OOM (error);
1695  return -1;
1696  }
1697 
1698  _DBUS_ZERO (hints);
1699 
1700  if (!family)
1701  hints.ai_family = AF_UNSPEC;
1702  else if (!strcmp(family, "ipv4"))
1703  hints.ai_family = AF_INET;
1704  else if (!strcmp(family, "ipv6"))
1705  hints.ai_family = AF_INET6;
1706  else
1707  {
1708  dbus_set_error (error,
1710  "Unknown address family %s", family);
1711  return -1;
1712  }
1713 
1714  hints.ai_protocol = IPPROTO_TCP;
1715  hints.ai_socktype = SOCK_STREAM;
1716 #ifdef AI_ADDRCONFIG
1717  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1718 #else
1719  hints.ai_flags = AI_PASSIVE;
1720 #endif
1721 
1722  redo_lookup_with_port:
1723  ai = NULL;
1724  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1725  {
1726  dbus_set_error (error,
1727  _dbus_error_from_errno (res),
1728  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1729  host ? host : "*", port, _dbus_strerror(res), res);
1730  return -1;
1731  }
1732 
1733  tmp = ai;
1734  while (tmp)
1735  {
1736  const int reuseaddr = 1, tcp_nodelay_on = 1;
1737  DBusSocket fd = DBUS_SOCKET_INIT, *newlisten_fd;
1738 
1739  if ((fd.sock = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
1740  {
1741  saved_errno = _dbus_get_low_level_socket_errno ();
1742  dbus_set_error (error,
1743  _dbus_error_from_errno (saved_errno),
1744  "Failed to open socket: %s",
1745  _dbus_strerror (saved_errno));
1746  goto failed;
1747  }
1748  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1749 
1750  if (setsockopt (fd.sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuseaddr, sizeof(reuseaddr)) == SOCKET_ERROR)
1751  {
1752  saved_errno = _dbus_get_low_level_socket_errno ();
1753  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1754  host ? host : "*", port, _dbus_strerror (saved_errno));
1755  }
1756 
1757  /* Nagle's algorithm imposes a huge delay on the initial messages
1758  going over TCP. */
1759  if (setsockopt (fd.sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&tcp_nodelay_on, sizeof (tcp_nodelay_on)) == SOCKET_ERROR)
1760  {
1761  saved_errno = _dbus_get_low_level_socket_errno ();
1762  _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1763  host ? host : "*", port, _dbus_strerror (saved_errno));
1764  }
1765 
1766  if (bind (fd.sock, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
1767  {
1768  saved_errno = _dbus_get_low_level_socket_errno ();
1769  closesocket (fd.sock);
1770 
1771  /*
1772  * We don't treat this as a fatal error, because there might be
1773  * other addresses that we can listen on. In particular:
1774  *
1775  * - If saved_errno is WSAEADDRINUSE after we
1776  * "goto redo_lookup_with_port" after binding a port on one of the
1777  * possible addresses, we will try to bind that same port on
1778  * every address, including the same address again for a second
1779  * time, which will fail with WSAEADDRINUSE .
1780  *
1781  * - If saved_errno is WSAEADDRINUSE, it might be because binding to
1782  * an IPv6 address implicitly binds to a corresponding IPv4
1783  * address or vice versa.
1784  *
1785  * - If saved_errno is WSAEADDRNOTAVAIL when we asked for family
1786  * AF_UNSPEC, it might be because IPv6 is disabled for this
1787  * particular interface.
1788  */
1789  bind_error = dbus_new0 (DBusError, 1);
1790 
1791  if (bind_error == NULL)
1792  {
1793  _DBUS_SET_OOM (error);
1794  goto failed;
1795  }
1796 
1797  dbus_error_init (bind_error);
1798  _dbus_set_error_with_inet_sockaddr (bind_error, tmp->ai_addr, tmp->ai_addrlen,
1799  "Failed to bind socket",
1800  saved_errno);
1801 
1802  if (!_dbus_list_append (&bind_errors, bind_error))
1803  {
1804  dbus_error_free (bind_error);
1805  dbus_free (bind_error);
1806  _DBUS_SET_OOM (error);
1807  goto failed;
1808  }
1809 
1810  /* Try the next address, maybe it will work better */
1811  tmp = tmp->ai_next;
1812  continue;
1813  }
1814 
1815  if (listen (fd.sock, 30 /* backlog */) == SOCKET_ERROR)
1816  {
1817  saved_errno = _dbus_get_low_level_socket_errno ();
1818  closesocket (fd.sock);
1819  _dbus_set_error_with_inet_sockaddr (error, tmp->ai_addr, tmp->ai_addrlen,
1820  "Failed to listen on socket",
1821  saved_errno);
1822  goto failed;
1823  }
1824 
1825  newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1826  if (!newlisten_fd)
1827  {
1828  closesocket (fd.sock);
1830  "Failed to allocate file handle array");
1831  goto failed;
1832  }
1833  listen_fd = newlisten_fd;
1834  listen_fd[nlisten_fd] = fd;
1835  nlisten_fd++;
1836 
1837  if (tmp->ai_addr->sa_family == AF_INET)
1838  have_ipv4 = TRUE;
1839  else if (tmp->ai_addr->sa_family == AF_INET6)
1840  have_ipv6 = TRUE;
1841 
1842  if (!_dbus_string_get_length(retport))
1843  {
1844  /* If the user didn't specify a port, or used 0, then
1845  the kernel chooses a port. After the first address
1846  is bound to, we need to force all remaining addresses
1847  to use the same port */
1848  if (!port || !strcmp(port, "0"))
1849  {
1850  mysockaddr_gen addr;
1851  socklen_t addrlen = sizeof(addr);
1852  char portbuf[NI_MAXSERV];
1853 
1854  if (getsockname (fd.sock, &addr.Address, &addrlen) == SOCKET_ERROR ||
1855  (res = getnameinfo (&addr.Address, addrlen, NULL, 0,
1856  portbuf, sizeof(portbuf),
1857  NI_NUMERICSERV)) != 0)
1858  {
1859  saved_errno = _dbus_get_low_level_socket_errno ();
1860  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1861  "Failed to resolve port \"%s:%s\": %s",
1862  host ? host : "*", port, _dbus_strerror (saved_errno));
1863  goto failed;
1864  }
1865  if (!_dbus_string_append(retport, portbuf))
1866  {
1868  goto failed;
1869  }
1870 
1871  /* Release current address list & redo lookup */
1872  port = _dbus_string_get_const_data(retport);
1873  freeaddrinfo(ai);
1874  goto redo_lookup_with_port;
1875  }
1876  else
1877  {
1878  if (!_dbus_string_append(retport, port))
1879  {
1881  goto failed;
1882  }
1883  }
1884  }
1885 
1886  tmp = tmp->ai_next;
1887  }
1888  freeaddrinfo(ai);
1889  ai = NULL;
1890 
1891  if (!nlisten_fd)
1892  {
1893  _dbus_combine_tcp_errors (&bind_errors, "Failed to bind", host, port, error);
1894  goto failed;
1895  }
1896 
1897  if (have_ipv4 && !have_ipv6)
1898  *retfamily = "ipv4";
1899  else if (!have_ipv4 && have_ipv6)
1900  *retfamily = "ipv6";
1901 
1902  sscanf(_dbus_string_get_const_data(retport), "%d", &port_num);
1903 
1904  for (i = 0 ; i < nlisten_fd ; i++)
1905  {
1906  _dbus_win_handle_set_close_on_exec ((HANDLE) listen_fd[i].sock);
1907  if (!_dbus_set_socket_nonblocking (listen_fd[i], error))
1908  {
1909  goto failed;
1910  }
1911  }
1912 
1913  *fds_p = listen_fd;
1914 
1915  /* This list might be non-empty even on success, because we might be
1916  * ignoring WSAEADDRINUSE or WSAEADDRNOTAVAIL */
1917  while ((bind_error = _dbus_list_pop_first (&bind_errors)))
1918  {
1919  dbus_error_free (bind_error);
1920  dbus_free (bind_error);
1921  }
1922  return nlisten_fd;
1923 
1924  failed:
1925  if (ai)
1926  freeaddrinfo(ai);
1927  for (i = 0 ; i < nlisten_fd ; i++)
1928  closesocket (listen_fd[i].sock);
1929 
1930  while ((bind_error = _dbus_list_pop_first (&bind_errors)))
1931  {
1932  dbus_error_free (bind_error);
1933  dbus_free (bind_error);
1934  }
1935 
1936  dbus_free(listen_fd);
1937  return -1;
1938 }
1939 
1940 
1948 DBusSocket
1950 {
1951  DBusSocket client_fd;
1952 
1953  retry:
1954  client_fd.sock = accept (listen_fd.sock, NULL, NULL);
1955 
1956  if (!_dbus_socket_is_valid (client_fd))
1957  {
1958  DBUS_SOCKET_SET_ERRNO ();
1959  if (errno == EINTR)
1960  goto retry;
1961  }
1962 
1963  _dbus_verbose ("client fd %Iu accepted\n", client_fd.sock);
1964 
1965  return client_fd;
1966 }
1967 
1968 
1969 
1970 
1973  DBusError *error)
1974 {
1975 /* FIXME: for the session bus credentials shouldn't matter (?), but
1976  * for the system bus they are presumably essential. A rough outline
1977  * of a way to implement the credential transfer would be this:
1978  *
1979  * client waits to *read* a byte.
1980  *
1981  * server creates a named pipe with a random name, sends a byte
1982  * contining its length, and its name.
1983  *
1984  * client reads the name, connects to it (using Win32 API).
1985  *
1986  * server waits for connection to the named pipe, then calls
1987  * ImpersonateNamedPipeClient(), notes its now-current credentials,
1988  * calls RevertToSelf(), closes its handles to the named pipe, and
1989  * is done. (Maybe there is some other way to get the SID of a named
1990  * pipe client without having to use impersonation?)
1991  *
1992  * client closes its handles and is done.
1993  *
1994  * Ralf: Why not sending credentials over the given this connection ?
1995  * Using named pipes makes it impossible to be connected from a unix client.
1996  *
1997  */
1998  int bytes_written;
1999  DBusString buf;
2000 
2001  _dbus_string_init_const_len (&buf, "\0", 1);
2002 again:
2003  bytes_written = _dbus_write_socket (handle, &buf, 0, 1 );
2004 
2005  if (bytes_written < 0 && errno == EINTR)
2006  goto again;
2007 
2008  if (bytes_written < 0)
2009  {
2010  dbus_set_error (error, _dbus_error_from_errno (errno),
2011  "Failed to write credentials byte: %s",
2013  return FALSE;
2014  }
2015  else if (bytes_written == 0)
2016  {
2018  "wrote zero bytes writing credentials byte");
2019  return FALSE;
2020  }
2021  else
2022  {
2023  _dbus_assert (bytes_written == 1);
2024  _dbus_verbose ("wrote 1 zero byte, credential sending isn't implemented yet\n");
2025  return TRUE;
2026  }
2027  return TRUE;
2028 }
2029 
2050  DBusCredentials *credentials,
2051  DBusError *error)
2052 {
2053  int bytes_read = 0;
2054  DBusString buf;
2055 
2056  char *sid = NULL;
2057  dbus_pid_t pid;
2058  int retval = FALSE;
2059 
2060  // could fail due too OOM
2061  if (_dbus_string_init (&buf))
2062  {
2063  bytes_read = _dbus_read_socket (handle, &buf, 1 );
2064 
2065  if (bytes_read > 0)
2066  _dbus_verbose ("got one zero byte from server\n");
2067 
2068  _dbus_string_free (&buf);
2069  }
2070 
2071  pid = _dbus_get_peer_pid_from_tcp_handle (handle.sock);
2072  if (pid == 0)
2073  return TRUE;
2074 
2075  _dbus_credentials_add_pid (credentials, pid);
2076 
2077  if (_dbus_getsid (&sid, pid))
2078  {
2079  if (!_dbus_credentials_add_windows_sid (credentials, sid))
2080  goto out;
2081  }
2082 
2083  retval = TRUE;
2084 
2085 out:
2086  if (sid)
2087  LocalFree (sid);
2088 
2089  return retval;
2090 }
2091 
2102 {
2103  /* TODO */
2104  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2105  return TRUE;
2106 }
2107 
2108 
2121  const DBusString *next_component)
2122 {
2123  dbus_bool_t dir_ends_in_slash;
2124  dbus_bool_t file_starts_with_slash;
2125 
2126  if (_dbus_string_get_length (dir) == 0 ||
2127  _dbus_string_get_length (next_component) == 0)
2128  return TRUE;
2129 
2130  dir_ends_in_slash =
2131  ('/' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1) ||
2132  '\\' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1));
2133 
2134  file_starts_with_slash =
2135  ('/' == _dbus_string_get_byte (next_component, 0) ||
2136  '\\' == _dbus_string_get_byte (next_component, 0));
2137 
2138  if (dir_ends_in_slash && file_starts_with_slash)
2139  {
2140  _dbus_string_shorten (dir, 1);
2141  }
2142  else if (!(dir_ends_in_slash || file_starts_with_slash))
2143  {
2144  if (!_dbus_string_append_byte (dir, '\\'))
2145  return FALSE;
2146  }
2147 
2148  return _dbus_string_copy (next_component, 0, dir,
2149  _dbus_string_get_length (dir));
2150 }
2151 
2152 /*---------------- DBusCredentials ----------------------------------*/
2153 
2163  const DBusString *username,
2164  DBusCredentialsAddFlags flags,
2165  DBusError *error)
2166 {
2167  if (!_dbus_credentials_add_windows_sid (credentials,
2168  _dbus_string_get_const_data (username)))
2169  {
2170  _DBUS_SET_OOM (error);
2171  return FALSE;
2172  }
2173 
2174  return TRUE;
2175 }
2176 
2187 {
2188  dbus_bool_t retval = FALSE;
2189  char *sid = NULL;
2190 
2191  if (!_dbus_getsid(&sid, _dbus_getpid()))
2192  goto failed;
2193 
2194  if (!_dbus_credentials_add_pid (credentials, _dbus_getpid()))
2195  goto failed;
2196 
2197  if (!_dbus_credentials_add_windows_sid (credentials,sid))
2198  goto failed;
2199 
2200  retval = TRUE;
2201  goto end;
2202 failed:
2203  retval = FALSE;
2204 end:
2205  if (sid)
2206  LocalFree(sid);
2207 
2208  return retval;
2209 }
2210 
2225 {
2226  dbus_bool_t retval = FALSE;
2227  char *sid = NULL;
2228 
2229  if (!_dbus_getsid(&sid, _dbus_getpid()))
2230  return FALSE;
2231 
2232  retval = _dbus_string_append (str,sid);
2233 
2234  LocalFree(sid);
2235  return retval;
2236 }
2237 
2242 dbus_pid_t
2244 {
2245  return GetCurrentProcessId ();
2246 }
2247 
2251 dbus_uid_t
2253 {
2254  return DBUS_UID_UNSET;
2255 }
2256 
2258 #define NANOSECONDS_PER_SECOND 1000000000
2259 
2260 #define MICROSECONDS_PER_SECOND 1000000
2261 
2262 #define MILLISECONDS_PER_SECOND 1000
2263 
2264 #define NANOSECONDS_PER_MILLISECOND 1000000
2265 
2266 #define MICROSECONDS_PER_MILLISECOND 1000
2267 
2272 void
2273 _dbus_sleep_milliseconds (int milliseconds)
2274 {
2275  Sleep (milliseconds);
2276 }
2277 
2278 
2286 void
2287 _dbus_get_real_time (long *tv_sec,
2288  long *tv_usec)
2289 {
2290  FILETIME ft;
2291  dbus_uint64_t time64;
2292 
2293  GetSystemTimeAsFileTime (&ft);
2294 
2295  memcpy (&time64, &ft, sizeof (time64));
2296 
2297  /* Convert from 100s of nanoseconds since 1601-01-01
2298  * to Unix epoch. Yes, this is Y2038 unsafe.
2299  */
2300  time64 -= DBUS_INT64_CONSTANT (116444736000000000);
2301  time64 /= 10;
2302 
2303  if (tv_sec)
2304  *tv_sec = time64 / 1000000;
2305 
2306  if (tv_usec)
2307  *tv_usec = time64 % 1000000;
2308 }
2309 
2317 void
2319  long *tv_usec)
2320 {
2321  /* no implementation yet, fall back to wall-clock time */
2322  _dbus_get_real_time (tv_sec, tv_usec);
2323 }
2324 
2328 void
2330 {
2331 }
2332 
2343  DBusError *error)
2344 {
2345  const char *filename_c;
2346 
2347  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2348 
2349  filename_c = _dbus_string_get_const_data (filename);
2350 
2351  if (!CreateDirectoryA (filename_c, NULL))
2352  {
2354  "Failed to create directory %s: %s\n",
2355  filename_c, _dbus_strerror_from_errno ());
2356  return FALSE;
2357  }
2358  else
2359  return TRUE;
2360 }
2361 
2372  DBusError *error)
2373 {
2374  const char *filename_c;
2375 
2376  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2377 
2378  filename_c = _dbus_string_get_const_data (filename);
2379 
2380  if (!CreateDirectoryA (filename_c, NULL))
2381  {
2382  if (GetLastError () == ERROR_ALREADY_EXISTS)
2383  return TRUE;
2384 
2386  "Failed to create directory %s: %s\n",
2387  filename_c, _dbus_strerror_from_errno ());
2388  return FALSE;
2389  }
2390  else
2391  return TRUE;
2392 }
2393 
2394 
2406  int n_bytes,
2407  DBusError *error)
2408 {
2409  int old_len;
2410  unsigned char *p;
2411  HCRYPTPROV hprov;
2412 
2413  old_len = _dbus_string_get_length (str);
2414 
2415  if (!_dbus_string_lengthen (str, n_bytes))
2416  {
2417  _DBUS_SET_OOM (error);
2418  return FALSE;
2419  }
2420 
2421  p = _dbus_string_get_udata_len (str, old_len, n_bytes);
2422 
2423  if (!CryptAcquireContext (&hprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
2424  {
2425  _DBUS_SET_OOM (error);
2426  return FALSE;
2427  }
2428 
2429  if (!CryptGenRandom (hprov, n_bytes, p))
2430  {
2431  _DBUS_SET_OOM (error);
2432  CryptReleaseContext (hprov, 0);
2433  return FALSE;
2434  }
2435 
2436  CryptReleaseContext (hprov, 0);
2437 
2438  return TRUE;
2439 }
2440 
2447 const char*
2449 {
2450  /* Protected by _DBUS_LOCK_sysdeps */
2451  static const char* tmpdir = NULL;
2452  static char buf[1000];
2453 
2454  if (!_DBUS_LOCK (sysdeps))
2455  return NULL;
2456 
2457  if (tmpdir == NULL)
2458  {
2459  unsigned char *last_slash;
2460  unsigned char *p = (unsigned char *)buf;
2461 
2462  if (!GetTempPathA (sizeof (buf), buf))
2463  {
2464  _dbus_warn ("GetTempPath failed");
2465  _dbus_abort ();
2466  }
2467 
2468  /* Drop terminating backslash or slash */
2469  last_slash = _mbsrchr (p, '\\');
2470  if (last_slash > p && last_slash[1] == '\0')
2471  last_slash[0] = '\0';
2472  last_slash = _mbsrchr (p, '/');
2473  if (last_slash > p && last_slash[1] == '\0')
2474  last_slash[0] = '\0';
2475 
2476  tmpdir = buf;
2477  }
2478 
2479  _DBUS_UNLOCK (sysdeps);
2480 
2481  _dbus_assert(tmpdir != NULL);
2482 
2483  return tmpdir;
2484 }
2485 
2486 
2497  DBusError *error)
2498 {
2499  const char *filename_c;
2500 
2501  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2502 
2503  filename_c = _dbus_string_get_const_data (filename);
2504 
2505  if (DeleteFileA (filename_c) == 0)
2506  {
2508  "Failed to delete file %s: %s\n",
2509  filename_c, _dbus_strerror_from_errno ());
2510  return FALSE;
2511  }
2512  else
2513  return TRUE;
2514 }
2515 
2516 #if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_ENABLE_EMBEDDED_TESTS)
2517 
2518 #if defined(_MSC_VER) || defined(DBUS_WINCE)
2519 # ifdef BACKTRACES
2520 # undef BACKTRACES
2521 # endif
2522 #else
2523 # define BACKTRACES
2524 #endif
2525 
2526 #ifdef BACKTRACES
2527 /*
2528  * Backtrace Generator
2529  *
2530  * Copyright 2004 Eric Poech
2531  * Copyright 2004 Robert Shearman
2532  *
2533  * This library is free software; you can redistribute it and/or
2534  * modify it under the terms of the GNU Lesser General Public
2535  * License as published by the Free Software Foundation; either
2536  * version 2.1 of the License, or (at your option) any later version.
2537  *
2538  * This library is distributed in the hope that it will be useful,
2539  * but WITHOUT ANY WARRANTY; without even the implied warranty of
2540  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2541  * Lesser General Public License for more details.
2542  *
2543  * You should have received a copy of the GNU Lesser General Public
2544  * License along with this library; if not, write to the Free Software
2545  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2546  */
2547 
2548 #include <winver.h>
2549 #include <imagehlp.h>
2550 #include <stdio.h>
2551 
2552 #define DPRINTF(fmt, ...) fprintf (stderr, fmt, ##__VA_ARGS__)
2553 
2554 #ifdef _MSC_VER
2555 #define BOOL int
2556 
2557 #define __i386__
2558 #endif
2559 
2560 static void dump_backtrace_for_thread (HANDLE hThread)
2561 {
2562  ADDRESS old_address;
2563  STACKFRAME sf;
2564  CONTEXT context;
2565  DWORD dwImageType;
2566  int i = 0;
2567 
2568  SymSetOptions (SYMOPT_UNDNAME | SYMOPT_LOAD_LINES);
2569  SymInitialize (GetCurrentProcess (), NULL, TRUE);
2570 
2571 
2572  /* can't use this function for current thread as GetThreadContext
2573  * doesn't support getting context from current thread */
2574  if (hThread == GetCurrentThread())
2575  return;
2576 
2577  DPRINTF ("Backtrace:\n");
2578 
2579  _DBUS_ZERO (old_address);
2580  _DBUS_ZERO (context);
2581  context.ContextFlags = CONTEXT_FULL;
2582 
2583  SuspendThread (hThread);
2584 
2585  if (!GetThreadContext (hThread, &context))
2586  {
2587  DPRINTF ("Couldn't get thread context (error %ld)\n", GetLastError ());
2588  ResumeThread (hThread);
2589  return;
2590  }
2591 
2592  _DBUS_ZERO (sf);
2593 
2594 #ifdef __i386__
2595  dwImageType = IMAGE_FILE_MACHINE_I386;
2596  sf.AddrFrame.Offset = context.Ebp;
2597  sf.AddrFrame.Mode = AddrModeFlat;
2598  sf.AddrPC.Offset = context.Eip;
2599  sf.AddrPC.Mode = AddrModeFlat;
2600 #elif defined(_M_X64)
2601  dwImageType = IMAGE_FILE_MACHINE_AMD64;
2602  sf.AddrPC.Offset = context.Rip;
2603  sf.AddrPC.Mode = AddrModeFlat;
2604  sf.AddrFrame.Offset = context.Rsp;
2605  sf.AddrFrame.Mode = AddrModeFlat;
2606  sf.AddrStack.Offset = context.Rsp;
2607  sf.AddrStack.Mode = AddrModeFlat;
2608 #elif defined(_M_IA64)
2609  dwImageType = IMAGE_FILE_MACHINE_IA64;
2610  sf.AddrPC.Offset = context.StIIP;
2611  sf.AddrPC.Mode = AddrModeFlat;
2612  sf.AddrFrame.Offset = context.IntSp;
2613  sf.AddrFrame.Mode = AddrModeFlat;
2614  sf.AddrBStore.Offset= context.RsBSP;
2615  sf.AddrBStore.Mode = AddrModeFlat;
2616  sf.AddrStack.Offset = context.IntSp;
2617  sf.AddrStack.Mode = AddrModeFlat;
2618 #else
2619 # error You need to fill in the STACKFRAME structure for your architecture
2620 #endif
2621 
2622  /*
2623  backtrace format
2624  <level> <address> <symbol>[+offset] [ '[' <file> ':' <line> ']' ] [ 'in' <module> ]
2625  example:
2626  6 0xf75ade6b wine_switch_to_stack+0x2a [/usr/src/debug/wine-snapshot/libs/wine/port.c:59] in libwine.so.1
2627  */
2628  while (StackWalk (dwImageType, GetCurrentProcess (),
2629  hThread, &sf, &context, NULL, SymFunctionTableAccess,
2630  SymGetModuleBase, NULL))
2631  {
2632  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
2633  PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
2634  DWORD64 displacement;
2635  IMAGEHLP_LINE line;
2636  DWORD dwDisplacement;
2637  IMAGEHLP_MODULE moduleInfo;
2638 
2639  /*
2640  on Wine64 version 1.7.54, we get an infinite number of stack entries
2641  pointing to the same stack frame (_start+0x29 in <wine-loader>)
2642  see bug https://bugs.winehq.org/show_bug.cgi?id=39606
2643  */
2644 #ifndef __i386__
2645  if (old_address.Offset == sf.AddrPC.Offset)
2646  {
2647  break;
2648  }
2649 #endif
2650 
2651  pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
2652  pSymbol->MaxNameLen = MAX_SYM_NAME;
2653 
2654  if (SymFromAddr (GetCurrentProcess (), sf.AddrPC.Offset, &displacement, pSymbol))
2655  {
2656  if (displacement)
2657  DPRINTF ("%3d %s+0x%I64x", i++, pSymbol->Name, displacement);
2658  else
2659  DPRINTF ("%3d %s", i++, pSymbol->Name);
2660  }
2661  else
2662  DPRINTF ("%3d 0x%Ix", i++, sf.AddrPC.Offset);
2663 
2664  line.SizeOfStruct = sizeof(IMAGEHLP_LINE);
2665  if (SymGetLineFromAddr (GetCurrentProcess (), sf.AddrPC.Offset, &dwDisplacement, &line))
2666  {
2667  DPRINTF (" [%s:%ld]", line.FileName, line.LineNumber);
2668  }
2669 
2670  moduleInfo.SizeOfStruct = sizeof(moduleInfo);
2671  if (SymGetModuleInfo (GetCurrentProcess (), sf.AddrPC.Offset, &moduleInfo))
2672  {
2673  DPRINTF (" in %s", moduleInfo.ModuleName);
2674  }
2675  DPRINTF ("\n");
2676  old_address = sf.AddrPC;
2677  }
2678  ResumeThread (hThread);
2679 }
2680 
2681 static DWORD WINAPI dump_thread_proc (LPVOID lpParameter)
2682 {
2683  dump_backtrace_for_thread ((HANDLE) lpParameter);
2684  return 0;
2685 }
2686 
2687 /* cannot get valid context from current thread, so we have to execute
2688  * backtrace from another thread */
2689 static void
2690 dump_backtrace (void)
2691 {
2692  HANDLE hCurrentThread;
2693  HANDLE hThread;
2694  DWORD dwThreadId;
2695  DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
2696  GetCurrentProcess (), &hCurrentThread,
2697  0, FALSE, DUPLICATE_SAME_ACCESS);
2698  hThread = CreateThread (NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread,
2699  0, &dwThreadId);
2700  WaitForSingleObject (hThread, INFINITE);
2701  CloseHandle (hThread);
2702  CloseHandle (hCurrentThread);
2703 }
2704 #endif
2705 #endif /* asserts or tests enabled */
2706 
2707 #ifdef BACKTRACES
2709 {
2710  dump_backtrace ();
2711 }
2712 #else
2713 void _dbus_print_backtrace (void)
2714 {
2715  _dbus_verbose (" D-Bus not compiled with backtrace support\n");
2716 }
2717 #endif
2718 
2719 static dbus_uint32_t fromAscii(char ascii)
2720 {
2721  if(ascii >= '0' && ascii <= '9')
2722  return ascii - '0';
2723  if(ascii >= 'A' && ascii <= 'F')
2724  return ascii - 'A' + 10;
2725  if(ascii >= 'a' && ascii <= 'f')
2726  return ascii - 'a' + 10;
2727  return 0;
2728 }
2729 
2731  dbus_bool_t create_if_not_found,
2732  DBusError *error)
2733 {
2734 #ifdef DBUS_WINCE
2735  return TRUE;
2736  // TODO
2737 #else
2738  HW_PROFILE_INFOA info;
2739  char *lpc = &info.szHwProfileGuid[0];
2740  dbus_uint32_t u;
2741 
2742  // the hw-profile guid lives long enough
2743  if(!GetCurrentHwProfileA(&info))
2744  {
2745  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); // FIXME
2746  return FALSE;
2747  }
2748 
2749  // Form: {12340001-4980-1920-6788-123456789012}
2750  lpc++;
2751  // 12340001
2752  u = ((fromAscii(lpc[0]) << 0) |
2753  (fromAscii(lpc[1]) << 4) |
2754  (fromAscii(lpc[2]) << 8) |
2755  (fromAscii(lpc[3]) << 12) |
2756  (fromAscii(lpc[4]) << 16) |
2757  (fromAscii(lpc[5]) << 20) |
2758  (fromAscii(lpc[6]) << 24) |
2759  (fromAscii(lpc[7]) << 28));
2760  machine_id->as_uint32s[0] = u;
2761 
2762  lpc += 9;
2763  // 4980-1920
2764  u = ((fromAscii(lpc[0]) << 0) |
2765  (fromAscii(lpc[1]) << 4) |
2766  (fromAscii(lpc[2]) << 8) |
2767  (fromAscii(lpc[3]) << 12) |
2768  (fromAscii(lpc[5]) << 16) |
2769  (fromAscii(lpc[6]) << 20) |
2770  (fromAscii(lpc[7]) << 24) |
2771  (fromAscii(lpc[8]) << 28));
2772  machine_id->as_uint32s[1] = u;
2773 
2774  lpc += 10;
2775  // 6788-1234
2776  u = ((fromAscii(lpc[0]) << 0) |
2777  (fromAscii(lpc[1]) << 4) |
2778  (fromAscii(lpc[2]) << 8) |
2779  (fromAscii(lpc[3]) << 12) |
2780  (fromAscii(lpc[5]) << 16) |
2781  (fromAscii(lpc[6]) << 20) |
2782  (fromAscii(lpc[7]) << 24) |
2783  (fromAscii(lpc[8]) << 28));
2784  machine_id->as_uint32s[2] = u;
2785 
2786  lpc += 9;
2787  // 56789012
2788  u = ((fromAscii(lpc[0]) << 0) |
2789  (fromAscii(lpc[1]) << 4) |
2790  (fromAscii(lpc[2]) << 8) |
2791  (fromAscii(lpc[3]) << 12) |
2792  (fromAscii(lpc[4]) << 16) |
2793  (fromAscii(lpc[5]) << 20) |
2794  (fromAscii(lpc[6]) << 24) |
2795  (fromAscii(lpc[7]) << 28));
2796  machine_id->as_uint32s[3] = u;
2797 #endif
2798  return TRUE;
2799 }
2800 
2801 static
2802 HANDLE _dbus_global_lock (const char *mutexname)
2803 {
2804  HANDLE mutex;
2805  DWORD gotMutex;
2806 
2807  mutex = CreateMutexA( NULL, FALSE, mutexname );
2808  if( !mutex )
2809  {
2810  return FALSE;
2811  }
2812 
2813  gotMutex = WaitForSingleObject( mutex, INFINITE );
2814  switch( gotMutex )
2815  {
2816  case WAIT_ABANDONED:
2817  ReleaseMutex (mutex);
2818  CloseHandle (mutex);
2819  return 0;
2820  case WAIT_FAILED:
2821  case WAIT_TIMEOUT:
2822  return 0;
2823  default:
2824  return mutex;
2825  }
2826 }
2827 
2828 static
2829 void _dbus_global_unlock (HANDLE mutex)
2830 {
2831  ReleaseMutex (mutex);
2832  CloseHandle (mutex);
2833 }
2834 
2835 // for proper cleanup in dbus-daemon
2836 static HANDLE hDBusDaemonMutex = NULL;
2837 static HANDLE hDBusSharedMem = NULL;
2838 // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
2839 static const char *cUniqueDBusInitMutex = "UniqueDBusInitMutex";
2840 // sync _dbus_get_autolaunch_address
2841 static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex";
2842 // mutex to determine if dbus-daemon is already started (per user)
2843 static const char *cDBusDaemonMutex = "DBusDaemonMutex";
2844 // named shm for dbus adress info (per user)
2845 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
2846 
2847 static dbus_bool_t
2848 _dbus_get_install_root_as_hash(DBusString *out)
2849 {
2850  DBusString install_path;
2851 
2852  _dbus_string_init(&install_path);
2853 
2854  if (!_dbus_get_install_root (&install_path) ||
2855  _dbus_string_get_length (&install_path) == 0)
2856  return FALSE;
2857 
2858  _dbus_string_init(out);
2859  _dbus_string_tolower_ascii(&install_path,0,_dbus_string_get_length(&install_path));
2860 
2861  if (!_dbus_sha_compute (&install_path, out))
2862  return FALSE;
2863 
2864  return TRUE;
2865 }
2866 
2867 static dbus_bool_t
2868 _dbus_get_address_string (DBusString *out, const char *basestring, const char *scope)
2869 {
2870  _dbus_string_init(out);
2871  _dbus_string_append(out,basestring);
2872 
2873  if (!scope)
2874  {
2875  return TRUE;
2876  }
2877  else if (strcmp(scope,"*install-path") == 0
2878  // for 1.3 compatibility
2879  || strcmp(scope,"install-path") == 0)
2880  {
2881  DBusString temp;
2882  if (!_dbus_get_install_root_as_hash(&temp))
2883  {
2884  _dbus_string_free(out);
2885  return FALSE;
2886  }
2887  _dbus_string_append(out,"-");
2888  _dbus_string_append(out,_dbus_string_get_const_data(&temp));
2889  _dbus_string_free(&temp);
2890  }
2891  else if (strcmp(scope,"*user") == 0)
2892  {
2893  _dbus_string_append(out,"-");
2895  {
2896  _dbus_string_free(out);
2897  return FALSE;
2898  }
2899  }
2900  else if (strlen(scope) > 0)
2901  {
2902  _dbus_string_append(out,"-");
2903  _dbus_string_append(out,scope);
2904  return TRUE;
2905  }
2906  return TRUE;
2907 }
2908 
2909 static dbus_bool_t
2910 _dbus_get_shm_name (DBusString *out,const char *scope)
2911 {
2912  return _dbus_get_address_string (out,cDBusDaemonAddressInfo,scope);
2913 }
2914 
2915 static dbus_bool_t
2916 _dbus_get_mutex_name (DBusString *out,const char *scope)
2917 {
2918  return _dbus_get_address_string (out,cDBusDaemonMutex,scope);
2919 }
2920 
2922 _dbus_daemon_is_session_bus_address_published (const char *scope)
2923 {
2924  HANDLE lock;
2925  DBusString mutex_name;
2926 
2927  if (!_dbus_get_mutex_name(&mutex_name,scope))
2928  {
2929  _dbus_string_free( &mutex_name );
2930  return FALSE;
2931  }
2932 
2933  if (hDBusDaemonMutex)
2934  return TRUE;
2935 
2936  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
2937  lock = _dbus_global_lock( cUniqueDBusInitMutex );
2938 
2939  // we use CreateMutex instead of OpenMutex because of possible race conditions,
2940  // see http://msdn.microsoft.com/en-us/library/ms684315%28VS.85%29.aspx
2941  hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
2942 
2943  /* The client uses mutex ownership to detect a running server, so the server should do so too.
2944  Fortunally the client deletes the mutex in the lock protected area, so checking presence
2945  will work too. */
2946 
2947  _dbus_global_unlock( lock );
2948 
2949  _dbus_string_free( &mutex_name );
2950 
2951  if (hDBusDaemonMutex == NULL)
2952  return FALSE;
2953  if (GetLastError() == ERROR_ALREADY_EXISTS)
2954  {
2955  CloseHandle(hDBusDaemonMutex);
2956  hDBusDaemonMutex = NULL;
2957  return TRUE;
2958  }
2959  // mutex wasn't created before, so return false.
2960  // We leave the mutex name allocated for later reusage
2961  // in _dbus_daemon_publish_session_bus_address.
2962  return FALSE;
2963 }
2964 
2966 _dbus_daemon_publish_session_bus_address (const char* address, const char *scope)
2967 {
2968  HANDLE lock;
2969  char *shared_addr = NULL;
2970  DBusString shm_name;
2971  DBusString mutex_name;
2972  dbus_uint64_t len;
2973 
2974  _dbus_assert (address);
2975 
2976  if (!_dbus_get_mutex_name(&mutex_name,scope))
2977  {
2978  _dbus_string_free( &mutex_name );
2979  return FALSE;
2980  }
2981 
2982  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
2983  lock = _dbus_global_lock( cUniqueDBusInitMutex );
2984 
2985  if (!hDBusDaemonMutex)
2986  {
2987  hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
2988  }
2989  _dbus_string_free( &mutex_name );
2990 
2991  // acquire the mutex
2992  if (WaitForSingleObject( hDBusDaemonMutex, 10 ) != WAIT_OBJECT_0)
2993  {
2994  _dbus_global_unlock( lock );
2995  CloseHandle( hDBusDaemonMutex );
2996  return FALSE;
2997  }
2998 
2999  if (!_dbus_get_shm_name(&shm_name,scope))
3000  {
3001  _dbus_string_free( &shm_name );
3002  _dbus_global_unlock( lock );
3003  return FALSE;
3004  }
3005 
3006  // create shm
3007  len = strlen (address) + 1;
3008 
3009  hDBusSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
3010  len >> 32, len & 0xffffffffu,
3011  _dbus_string_get_const_data(&shm_name) );
3012  _dbus_assert( hDBusSharedMem );
3013 
3014  shared_addr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
3015 
3016  _dbus_assert (shared_addr);
3017 
3018  strcpy( shared_addr, address);
3019 
3020  // cleanup
3021  UnmapViewOfFile( shared_addr );
3022 
3023  _dbus_global_unlock( lock );
3024  _dbus_verbose( "published session bus address at %s\n",_dbus_string_get_const_data (&shm_name) );
3025 
3026  _dbus_string_free( &shm_name );
3027  return TRUE;
3028 }
3029 
3030 void
3031 _dbus_daemon_unpublish_session_bus_address (void)
3032 {
3033  HANDLE lock;
3034 
3035  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
3036  lock = _dbus_global_lock( cUniqueDBusInitMutex );
3037 
3038  CloseHandle( hDBusSharedMem );
3039 
3040  hDBusSharedMem = NULL;
3041 
3042  ReleaseMutex( hDBusDaemonMutex );
3043 
3044  CloseHandle( hDBusDaemonMutex );
3045 
3046  hDBusDaemonMutex = NULL;
3047 
3048  _dbus_global_unlock( lock );
3049 }
3050 
3051 static dbus_bool_t
3052 _dbus_get_autolaunch_shm (DBusString *address, DBusString *shm_name)
3053 {
3054  HANDLE sharedMem;
3055  char *shared_addr;
3056  int i;
3057 
3058  // read shm
3059  for(i=0;i<20;++i) {
3060  // we know that dbus-daemon is available, so we wait until shm is available
3061  sharedMem = OpenFileMappingA( FILE_MAP_READ, FALSE, _dbus_string_get_const_data(shm_name));
3062  if( sharedMem == 0 )
3063  Sleep( 100 );
3064  if ( sharedMem != 0)
3065  break;
3066  }
3067 
3068  if( sharedMem == 0 )
3069  return FALSE;
3070 
3071  shared_addr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
3072 
3073  if( !shared_addr )
3074  return FALSE;
3075 
3076  _dbus_string_init( address );
3077 
3078  _dbus_string_append( address, shared_addr );
3079 
3080  // cleanup
3081  UnmapViewOfFile( shared_addr );
3082 
3083  CloseHandle( sharedMem );
3084 
3085  return TRUE;
3086 }
3087 
3088 static dbus_bool_t
3089 _dbus_daemon_already_runs (DBusString *address, DBusString *shm_name, const char *scope)
3090 {
3091  HANDLE lock;
3092  HANDLE daemon;
3093  DBusString mutex_name;
3094  dbus_bool_t bRet = TRUE;
3095 
3096  if (!_dbus_get_mutex_name(&mutex_name,scope))
3097  {
3098  _dbus_string_free( &mutex_name );
3099  return FALSE;
3100  }
3101 
3102  // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs
3103  lock = _dbus_global_lock( cUniqueDBusInitMutex );
3104 
3105  // do checks
3106  daemon = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
3107  if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT)
3108  {
3109  ReleaseMutex (daemon);
3110  CloseHandle (daemon);
3111 
3112  _dbus_global_unlock( lock );
3113  _dbus_string_free( &mutex_name );
3114  return FALSE;
3115  }
3116 
3117  // read shm
3118  bRet = _dbus_get_autolaunch_shm( address, shm_name );
3119 
3120  // cleanup
3121  CloseHandle ( daemon );
3122 
3123  _dbus_global_unlock( lock );
3124  _dbus_string_free( &mutex_name );
3125 
3126  return bRet;
3127 }
3128 
3130 _dbus_get_autolaunch_address (const char *scope, DBusString *address,
3131  DBusError *error)
3132 {
3133  HANDLE mutex;
3134  STARTUPINFOA si;
3135  PROCESS_INFORMATION pi;
3136  dbus_bool_t retval = FALSE;
3137  LPSTR lpFile;
3138  char dbus_exe_path[MAX_PATH];
3139  char dbus_args[MAX_PATH * 2];
3140  const char * daemon_name = DBUS_DAEMON_NAME ".exe";
3141  DBusString shm_name;
3142 
3143  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3144 
3145  if (!_dbus_get_shm_name(&shm_name,scope))
3146  {
3147  dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not determine shm name");
3148  return FALSE;
3149  }
3150 
3151  mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
3152 
3153  if (_dbus_daemon_already_runs(address,&shm_name,scope))
3154  {
3155  _dbus_verbose( "found running dbus daemon for scope '%s' at %s\n",
3156  scope ? scope : "", _dbus_string_get_const_data (&shm_name) );
3157  retval = TRUE;
3158  goto out;
3159  }
3160 
3161  if (!SearchPathA(NULL, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
3162  {
3163  // Look in directory containing dbus shared library
3164  HMODULE hmod;
3165  char dbus_module_path[MAX_PATH];
3166  DWORD rc;
3167 
3168  _dbus_verbose( "did not found dbus daemon executable on default search path, "
3169  "trying path where dbus shared library is located");
3170 
3171  hmod = _dbus_win_get_dll_hmodule();
3172  rc = GetModuleFileNameA(hmod, dbus_module_path, sizeof(dbus_module_path));
3173  if (rc <= 0)
3174  {
3175  dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not retrieve dbus shared library file name");
3176  retval = FALSE;
3177  goto out;
3178  }
3179  else
3180  {
3181  char *ext_idx = strrchr(dbus_module_path, '\\');
3182  if (ext_idx)
3183  *ext_idx = '\0';
3184  if (!SearchPathA(dbus_module_path, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
3185  {
3186  dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not find dbus-daemon executable");
3187  retval = FALSE;
3188  fprintf (stderr, "please add the path to %s to your PATH environment variable\n", daemon_name);
3189  fprintf (stderr, "or start the daemon manually\n\n");
3190  goto out;
3191  }
3192  _dbus_verbose( "found dbus daemon executable at %s",dbus_module_path);
3193  }
3194  }
3195 
3196 
3197  // Create process
3198  ZeroMemory( &si, sizeof(si) );
3199  si.cb = sizeof(si);
3200  ZeroMemory( &pi, sizeof(pi) );
3201 
3202  _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path, " --session");
3203 
3204 // argv[i] = "--config-file=bus\\session.conf";
3205  if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
3206  {
3207  CloseHandle (pi.hThread);
3208  CloseHandle (pi.hProcess);
3209  retval = _dbus_get_autolaunch_shm( address, &shm_name );
3210  if (retval == FALSE)
3211  dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to get autolaunch address from launched dbus-daemon");
3212  }
3213  else
3214  {
3215  dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to launch dbus-daemon");
3216  retval = FALSE;
3217  }
3218 
3219 out:
3220  _DBUS_ASSERT_ERROR_XOR_BOOL (error, retval);
3221  _dbus_global_unlock (mutex);
3222  _dbus_string_free (&shm_name);
3223 
3224  return retval;
3225  }
3226 
3227 
3236  DBusError *error)
3237 {
3238  // TODO
3239  return TRUE;
3240 }
3241 
3249 dbus_int32_t
3251 {
3252  // +/- 1 is needed here!
3253  // no volatile argument with mingw
3254  return InterlockedIncrement (&atomic->value) - 1;
3255 }
3256 
3264 dbus_int32_t
3266 {
3267  // +/- 1 is needed here!
3268  // no volatile argument with mingw
3269  return InterlockedDecrement (&atomic->value) + 1;
3270 }
3271 
3279 dbus_int32_t
3281 {
3282  /* In this situation, GLib issues a MemoryBarrier() and then returns
3283  * atomic->value. However, mingw from mingw.org (not to be confused with
3284  * mingw-w64 from mingw-w64.sf.net) does not have MemoryBarrier in its
3285  * headers, so we have to get a memory barrier some other way.
3286  *
3287  * InterlockedIncrement is older, and is documented on MSDN to be a full
3288  * memory barrier, so let's use that.
3289  */
3290  long dummy = 0;
3291 
3292  InterlockedExchange (&dummy, 1);
3293 
3294  return atomic->value;
3295 }
3296 
3304 void
3306 {
3307 }
3308 
3317 {
3318  return e == WSAEWOULDBLOCK;
3319 }
3320 
3329 _dbus_get_install_root (DBusString *str)
3330 {
3331  /* this is just an initial guess */
3332  DWORD pathLength = MAX_PATH;
3333  unsigned char *lastSlash;
3334  unsigned char *prefix;
3335 
3336  do
3337  {
3338  /* allocate enough space for our best guess at the length */
3339  if (!_dbus_string_set_length (str, pathLength))
3340  {
3341  _dbus_string_set_length (str, 0);
3342  return FALSE;
3343  }
3344 
3345  SetLastError (0);
3346  pathLength = GetModuleFileNameA (_dbus_win_get_dll_hmodule (),
3347  _dbus_string_get_data (str), _dbus_string_get_length (str));
3348 
3349  if (pathLength == 0 || GetLastError () != 0)
3350  {
3351  /* failed, but not OOM */
3352  _dbus_string_set_length (str, 0);
3353  return TRUE;
3354  }
3355 
3356  /* if the return is strictly less than the buffer size, it has
3357  * not been truncated, so we can continue */
3358  if (pathLength < (DWORD) _dbus_string_get_length (str))
3359  {
3360  /* reduce the length to match what Windows filled in */
3361  if (!_dbus_string_set_length (str, pathLength))
3362  {
3363  _dbus_string_set_length (str, 0);
3364  return FALSE;
3365  }
3366 
3367  break;
3368  }
3369 
3370  /* else it may have been truncated; try with a larger buffer */
3371  pathLength *= 2;
3372  }
3373  while (TRUE);
3374 
3375  /* the rest of this function works by direct byte manipulation of the
3376  * underlying buffer */
3377  prefix = _dbus_string_get_udata (str);
3378 
3379  lastSlash = _mbsrchr (prefix, '\\');
3380  if (lastSlash == NULL) {
3381  /* failed, but not OOM */
3382  _dbus_string_set_length (str, 0);
3383  return TRUE;
3384  }
3385  //cut off binary name
3386  lastSlash[1] = 0;
3387 
3388  //cut possible "\\bin"
3389  //this fails if we are in a double-byte system codepage and the
3390  //folder's name happens to end with the *bytes*
3391  //"\\bin"... (I.e. the second byte of some Han character and then
3392  //the Latin "bin", but that is not likely I think...
3393  if (lastSlash - prefix >= 4 && _mbsnicmp (lastSlash - 4, (const unsigned char *)"\\bin", 4) == 0)
3394  lastSlash[-3] = 0;
3395  else if (lastSlash - prefix >= 10 && _mbsnicmp (lastSlash - 10, (const unsigned char *)"\\bin\\debug", 10) == 0)
3396  lastSlash[-9] = 0;
3397  else if (lastSlash - prefix >= 12 && _mbsnicmp (lastSlash - 12, (const unsigned char *)"\\bin\\release", 12) == 0)
3398  lastSlash[-11] = 0;
3399 
3400  /* fix up the length to match the byte-manipulation */
3401  _dbus_string_set_length (str, strlen ((char *) prefix));
3402 
3403  return TRUE;
3404 }
3405 
3406 /* See comment in dbus-sysdeps-unix.c */
3409  DBusString *address,
3410  DBusError *error)
3411 {
3412  /* Probably fill this in with something based on COM? */
3413  *supported = FALSE;
3414  return TRUE;
3415 }
3416 
3432  DBusCredentials *credentials)
3433 {
3434  DBusString homedir;
3435  DBusString dotdir;
3436  const char *homepath;
3437  const char *homedrive;
3438 
3439  _dbus_assert (credentials != NULL);
3441 
3442  if (!_dbus_string_init (&homedir))
3443  return FALSE;
3444 
3445  homedrive = _dbus_getenv("HOMEDRIVE");
3446  if (homedrive != NULL && *homedrive != '\0')
3447  {
3448  _dbus_string_append(&homedir,homedrive);
3449  }
3450 
3451  homepath = _dbus_getenv("HOMEPATH");
3452  if (homepath != NULL && *homepath != '\0')
3453  {
3454  _dbus_string_append(&homedir,homepath);
3455  }
3456 
3457 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3458  {
3459  const char *override;
3460 
3461  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3462  if (override != NULL && *override != '\0')
3463  {
3464  _dbus_string_set_length (&homedir, 0);
3465  if (!_dbus_string_append (&homedir, override))
3466  goto failed;
3467 
3468  _dbus_verbose ("Using fake homedir for testing: %s\n",
3469  _dbus_string_get_const_data (&homedir));
3470  }
3471  else
3472  {
3473  /* Not strictly thread-safe, but if we fail at thread-safety here,
3474  * the worst that will happen is some extra warnings. */
3475  static dbus_bool_t already_warned = FALSE;
3476  if (!already_warned)
3477  {
3478  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid");
3479  already_warned = TRUE;
3480  }
3481  }
3482  }
3483 #endif
3484 
3485 #ifdef DBUS_WINCE
3486  /* It's not possible to create a .something directory in Windows CE
3487  using the file explorer. */
3488 #define KEYRING_DIR "dbus-keyrings"
3489 #else
3490 #define KEYRING_DIR ".dbus-keyrings"
3491 #endif
3492 
3493  _dbus_string_init_const (&dotdir, KEYRING_DIR);
3494  if (!_dbus_concat_dir_and_file (&homedir,
3495  &dotdir))
3496  goto failed;
3497 
3498  if (!_dbus_string_copy (&homedir, 0,
3499  directory, _dbus_string_get_length (directory))) {
3500  goto failed;
3501  }
3502 
3503  _dbus_string_free (&homedir);
3504  return TRUE;
3505 
3506  failed:
3507  _dbus_string_free (&homedir);
3508  return FALSE;
3509 }
3510 
3516 dbus_bool_t
3517 _dbus_file_exists (const char *file)
3518 {
3519  DWORD attributes = GetFileAttributesA (file);
3520 
3521  if (attributes != INVALID_FILE_ATTRIBUTES && GetLastError() != ERROR_PATH_NOT_FOUND)
3522  return TRUE;
3523  else
3524  return FALSE;
3525 }
3526 
3534 const char*
3535 _dbus_strerror (int error_number)
3536 {
3537 #ifdef DBUS_WINCE
3538  // TODO
3539  return "unknown";
3540 #else
3541  const char *msg;
3542 
3543  switch (error_number)
3544  {
3545  case WSAEINTR:
3546  return "Interrupted function call";
3547  case WSAEACCES:
3548  return "Permission denied";
3549  case WSAEFAULT:
3550  return "Bad address";
3551  case WSAEINVAL:
3552  return "Invalid argument";
3553  case WSAEMFILE:
3554  return "Too many open files";
3555  case WSAEWOULDBLOCK:
3556  return "Resource temporarily unavailable";
3557  case WSAEINPROGRESS:
3558  return "Operation now in progress";
3559  case WSAEALREADY:
3560  return "Operation already in progress";
3561  case WSAENOTSOCK:
3562  return "Socket operation on nonsocket";
3563  case WSAEDESTADDRREQ:
3564  return "Destination address required";
3565  case WSAEMSGSIZE:
3566  return "Message too long";
3567  case WSAEPROTOTYPE:
3568  return "Protocol wrong type for socket";
3569  case WSAENOPROTOOPT:
3570  return "Bad protocol option";
3571  case WSAEPROTONOSUPPORT:
3572  return "Protocol not supported";
3573  case WSAESOCKTNOSUPPORT:
3574  return "Socket type not supported";
3575  case WSAEOPNOTSUPP:
3576  return "Operation not supported";
3577  case WSAEPFNOSUPPORT:
3578  return "Protocol family not supported";
3579  case WSAEAFNOSUPPORT:
3580  return "Address family not supported by protocol family";
3581  case WSAEADDRINUSE:
3582  return "Address already in use";
3583  case WSAEADDRNOTAVAIL:
3584  return "Cannot assign requested address";
3585  case WSAENETDOWN:
3586  return "Network is down";
3587  case WSAENETUNREACH:
3588  return "Network is unreachable";
3589  case WSAENETRESET:
3590  return "Network dropped connection on reset";
3591  case WSAECONNABORTED:
3592  return "Software caused connection abort";
3593  case WSAECONNRESET:
3594  return "Connection reset by peer";
3595  case WSAENOBUFS:
3596  return "No buffer space available";
3597  case WSAEISCONN:
3598  return "Socket is already connected";
3599  case WSAENOTCONN:
3600  return "Socket is not connected";
3601  case WSAESHUTDOWN:
3602  return "Cannot send after socket shutdown";
3603  case WSAETIMEDOUT:
3604  return "Connection timed out";
3605  case WSAECONNREFUSED:
3606  return "Connection refused";
3607  case WSAEHOSTDOWN:
3608  return "Host is down";
3609  case WSAEHOSTUNREACH:
3610  return "No route to host";
3611  case WSAEPROCLIM:
3612  return "Too many processes";
3613  case WSAEDISCON:
3614  return "Graceful shutdown in progress";
3615  case WSATYPE_NOT_FOUND:
3616  return "Class type not found";
3617  case WSAHOST_NOT_FOUND:
3618  return "Host not found";
3619  case WSATRY_AGAIN:
3620  return "Nonauthoritative host not found";
3621  case WSANO_RECOVERY:
3622  return "This is a nonrecoverable error";
3623  case WSANO_DATA:
3624  return "Valid name, no data record of requested type";
3625  case WSA_INVALID_HANDLE:
3626  return "Specified event object handle is invalid";
3627  case WSA_INVALID_PARAMETER:
3628  return "One or more parameters are invalid";
3629  case WSA_IO_INCOMPLETE:
3630  return "Overlapped I/O event object not in signaled state";
3631  case WSA_IO_PENDING:
3632  return "Overlapped operations will complete later";
3633  case WSA_NOT_ENOUGH_MEMORY:
3634  return "Insufficient memory available";
3635  case WSA_OPERATION_ABORTED:
3636  return "Overlapped operation aborted";
3637 #ifdef WSAINVALIDPROCTABLE
3638 
3639  case WSAINVALIDPROCTABLE:
3640  return "Invalid procedure table from service provider";
3641 #endif
3642 #ifdef WSAINVALIDPROVIDER
3643 
3644  case WSAINVALIDPROVIDER:
3645  return "Invalid service provider version number";
3646 #endif
3647 #ifdef WSAPROVIDERFAILEDINIT
3648 
3649  case WSAPROVIDERFAILEDINIT:
3650  return "Unable to initialize a service provider";
3651 #endif
3652 
3653  case WSASYSCALLFAILURE:
3654  return "System call failure";
3655 
3656  default:
3657  msg = strerror (error_number);
3658 
3659  if (msg == NULL)
3660  msg = "unknown";
3661 
3662  return msg;
3663  }
3664 #endif //DBUS_WINCE
3665 }
3666 
3674 void
3675 _dbus_win_set_error_from_win_error (DBusError *error,
3676  int code)
3677 {
3678  char *msg;
3679 
3680  /* As we want the English message, use the A API */
3681  FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
3682  FORMAT_MESSAGE_IGNORE_INSERTS |
3683  FORMAT_MESSAGE_FROM_SYSTEM,
3684  NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
3685  (LPSTR) &msg, 0, NULL);
3686  if (msg)
3687  {
3688  dbus_set_error (error, "win32.error", "%s", msg);
3689  LocalFree (msg);
3690  }
3691  else
3692  dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code);
3693 }
3694 
3695 void
3696 _dbus_win_warn_win_error (const char *message,
3697  unsigned long code)
3698 {
3699  DBusError error;
3700 
3701  dbus_error_init (&error);
3702  _dbus_win_set_error_from_win_error (&error, code);
3703  _dbus_warn ("%s: %s", message, error.message);
3704  dbus_error_free (&error);
3705 }
3706 
3716  DBusError *error)
3717 {
3718  const char *filename_c;
3719 
3720  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3721 
3722  filename_c = _dbus_string_get_const_data (filename);
3723 
3724  if (RemoveDirectoryA (filename_c) == 0)
3725  {
3726  char *emsg = _dbus_win_error_string (GetLastError ());
3727  dbus_set_error (error, _dbus_win_error_from_last_error (),
3728  "Failed to remove directory %s: %s",
3729  filename_c, emsg);
3730  _dbus_win_free_error_string (emsg);
3731  return FALSE;
3732  }
3733 
3734  return TRUE;
3735 }
3736 
3745 {
3746  if (_dbus_string_get_length (filename) > 0)
3747  return _dbus_string_get_byte (filename, 1) == ':'
3748  || _dbus_string_get_byte (filename, 0) == '\\'
3749  || _dbus_string_get_byte (filename, 0) == '/';
3750  else
3751  return FALSE;
3752 }
3753 
3756 {
3757  return FALSE;
3758 }
3759 
3760 int
3761 _dbus_save_socket_errno (void)
3762 {
3763  return errno;
3764 }
3765 
3766 void
3767 _dbus_restore_socket_errno (int saved_errno)
3768 {
3769  _dbus_win_set_errno (saved_errno);
3770 }
3771 
3772 static const char *log_tag = "dbus";
3773 static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
3774 
3785 void
3786 _dbus_init_system_log (const char *tag,
3787  DBusLogFlags flags)
3788 {
3789  /* We never want to turn off logging completely */
3790  _dbus_assert (
3791  (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
3792 
3793  log_tag = tag;
3794  log_flags = flags;
3795 }
3796 
3804 void
3805 _dbus_logv (DBusSystemLogSeverity severity,
3806  const char *msg,
3807  va_list args)
3808 {
3809  const char *s = "";
3810  va_list tmp;
3811 
3812  switch(severity)
3813  {
3814  case DBUS_SYSTEM_LOG_INFO: s = "info"; break;
3815  case DBUS_SYSTEM_LOG_WARNING: s = "warning"; break;
3816  case DBUS_SYSTEM_LOG_SECURITY: s = "security"; break;
3817  case DBUS_SYSTEM_LOG_ERROR: s = "error"; break;
3818  default: _dbus_assert_not_reached ("invalid log severity");
3819  }
3820 
3821  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
3822  {
3823  char buf[1024];
3824  char format[1024];
3825 
3826  DBUS_VA_COPY (tmp, args);
3827  snprintf (format, sizeof (format), "%s: %s", s, msg);
3828  vsnprintf(buf, sizeof(buf), format, tmp);
3829  OutputDebugStringA(buf);
3830  va_end (tmp);
3831  }
3832 
3833  if (log_flags & DBUS_LOG_FLAGS_STDERR)
3834  {
3835  DBUS_VA_COPY (tmp, args);
3836  fprintf (stderr, "%s[%lu]: %s: ", log_tag, _dbus_pid_for_log (), s);
3837  vfprintf (stderr, msg, tmp);
3838  fprintf (stderr, "\n");
3839  va_end (tmp);
3840  }
3841 }
3842 
3843 /*
3844  * Return the low-level representation of a socket error, as used by
3845  * cross-platform socket APIs like inet_ntop(), send() and recv(). This
3846  * is the standard errno on Unix, but is WSAGetLastError() on Windows.
3847  *
3848  * Some libdbus internal functions copy this into errno, but with
3849  * hindsight that was probably a design flaw.
3850  */
3851 int
3852 _dbus_get_low_level_socket_errno (void)
3853 {
3854  return WSAGetLastError ();
3855 }
3856 
3858 /* tests in dbus-sysdeps-util.c */
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:952
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:323
#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
#define NULL
A null pointer, defined appropriately for C or C++.
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:328
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.
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_abort(void)
Aborts the program with SIGABRT (dumping core).
Definition: dbus-sysdeps.c:87
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:777
dbus_bool_t _dbus_ensure_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:703
dbus_bool_t _dbus_socketpair(DBusSocket *fd1, DBusSocket *fd2, dbus_bool_t blocking, DBusError *error)
Creates pair of connect sockets (as in socketpair()).
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:57
dbus_bool_t _dbus_path_is_absolute(const DBusString *filename)
Checks whether the filename is an absolute path.
dbus_uint32_t as_uint32s[DBUS_UUID_LENGTH_WORDS]
guid as four uint32 values
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
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:2502
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
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:422
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_file_exists(const char *file)
Checks if a file exists.
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:507
int _dbus_read_socket(DBusSocket fd, DBusString *buffer, int count)
Socket interface.
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
#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:797
short events
Events to poll for.
Definition: dbus-sysdeps.h:417
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:1300
dbus_bool_t _dbus_credentials_add_windows_sid(DBusCredentials *credentials, const char *windows_sid)
Add a Windows user SID to the credentials.
dbus_bool_t _dbus_send_credentials_socket(DBusSocket handle, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
dbus_bool_t _dbus_close_socket(DBusSocket fd, DBusError *error)
Closes a file descriptor.
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:141
dbus_bool_t _dbus_delete_file(const DBusString *filename, DBusError *error)
Deletes the given file.
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:599
dbus_bool_t _dbus_credentials_add_from_user(DBusCredentials *credentials, const DBusString *username, DBusCredentialsAddFlags flags, DBusError *error)
Adds the credentials corresponding to the given username.
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:132
Socket interface.
Definition: dbus-sysdeps.h:178
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:463
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_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:58
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock(int e)
See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently for Winsock so is abstracted) ...
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_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:426
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
int _dbus_write_socket_two(DBusSocket fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write() but will use writev() if possible to write both buffers in sequence.
DBusSocket _dbus_accept(DBusSocket listen_fd)
Accepts a connection on a listening socket.
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:271
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
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.
dbus_bool_t _dbus_read_credentials_socket(DBusSocket handle, 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_create_directory(const DBusString *filename, DBusError *error)
Creates a directory.
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
Object representing an exception.
Definition: dbus-errors.h:48
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
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:2572
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:677
#define DBUS_ERROR_BAD_ADDRESS
A D-Bus bus address was malformed.
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
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked...
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR, TMP, and TEMP in that order.
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:1174
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(), and fills it with the same contents as #_DBUS_STRING_I...
Definition: dbus-string.c:264
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 "1".
DBusPollable fd
File descriptor.
Definition: dbus-sysdeps.h:416
#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; "something went wrong" - see the error message for more.
void _dbus_exit(int code)
Exit the process, returning the given value.
const char * _dbus_strerror_from_errno(void)
Get error message from errno.
Definition: dbus-sysdeps.c:758
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...
DBusSocket _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.
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition: dbus-errors.c:188
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
A node in a linked list.
Definition: dbus-list.h:34
#define DBUS_ERROR_ACCESS_DENIED
Security restrictions don&#39;t allow doing what you&#39;re trying to do.
dbus_uid_t _dbus_getuid(void)
Gets our Unix UID.
void _dbus_init_system_log(const char *tag, DBusLogFlags flags)
Initialize the system log.
dbus_bool_t _dbus_generate_random_bytes(DBusString *str, int n_bytes, DBusError *error)
Generates the given number of random bytes, using the best mechanism we can come up with...
dbus_bool_t _dbus_set_socket_nonblocking(DBusSocket handle, DBusError *error)
Sets a file descriptor to be nonblocking.
#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. ...
void _dbus_logv(DBusSystemLogSeverity severity, const char *msg, va_list args)
Log a message to the system log file (e.g.
#define FALSE
Expands to "0".
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:484
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:819
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
int _dbus_write_socket(DBusSocket fd, const DBusString *buffer, int start, int len)
Thin wrapper around the write() system call that writes a part of a DBusString and handles EINTR for ...
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
DBUS_PRIVATE_EXPORT void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
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:603
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the message length without terminating nul.
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, const char **retfamily, DBusSocket **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:195
#define DBUS_ERROR_INVALID_ARGS
Invalid arguments passed to a method call.
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:134
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
short revents
Events that occurred.
Definition: dbus-sysdeps.h:418
#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
void _dbus_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:428