1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-sysdeps.c Wrappers around system/libc features (internal to D-BUS implementation)
4 * Copyright (C) 2002, 2003 Red Hat, Inc.
5 * Copyright (C) 2003 CodeFactory AB
6 * Copyright (C) 2005 Novell, Inc.
7 * Copyright (C) 2006 Ralf Habacker <ralf.habacker@freenet.de>
8 * Copyright (C) 2006 Peter Kümmel <syntheticpp@gmx.net>
9 * Copyright (C) 2006 Christian Ehrlicher <ch.ehrlicher@gmx.de>
11 * Licensed under the Academic Free License version 2.1
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 /* #define ENABLE_DBUSUSERINFO */
31 struct DBusCredentials{
39 #define STRSAFE_NO_DEPRECATE
42 #define _WIN32_WINNT 0x0500
45 #include "dbus-internals.h"
46 #include "dbus-sysdeps.h"
47 #include "dbus-threads.h"
48 #include "dbus-protocol.h"
49 #include "dbus-string.h"
50 #include "dbus-sysdeps-win.h"
51 #include "dbus-protocol.h"
52 #include "dbus-hash.h"
53 #include "dbus-sockets-win.h"
54 #include "dbus-list.h"
55 #include "dbus-credentials.h"
62 #include <sys/types.h>
68 #ifndef HAVE_SOCKLEN_T
72 #ifdef ENABLE_DBUSSOCKET
73 _DBUS_DEFINE_GLOBAL_LOCK (win_fds);
76 #ifdef ENABLE_UID_TO_SID
77 _DBUS_DEFINE_GLOBAL_LOCK (sid_atom_cache);
80 #ifdef ENABLE_DBUSUSERINFO
85 dbus_gid_t *group_ids;
91 #ifdef ENABLE_DBUSSOCKET
96 _dbus_assert (win_fds!=0);
102 _dbus_unlock_sockets()
104 _dbus_assert (win_fds!=0);
105 _DBUS_UNLOCK (win_fds);
109 #ifdef _DBUS_WIN_USE_RANDOMIZER
110 static int win_encap_randomizer;
113 #ifdef ENABLE_UID_TO_SID
114 static DBusHashTable *sid_atom_cache = NULL;
117 static DBusString dbusdir;
118 static int working_dir_init = 0;
120 int _dbus_init_working_dir(char *s)
122 /* change working directory to one level above
123 of dbus-daemon executable path.
124 This allows the usage of relative path in
125 config files or command line parameters */
126 DBusString daemon_path,bin_path;
128 if (!_dbus_string_init (&daemon_path))
131 if (!_dbus_string_init (&bin_path))
134 if (!_dbus_string_init (&dbusdir))
137 _dbus_string_append(&daemon_path,s);
138 _dbus_string_get_dirname(&daemon_path,&bin_path);
139 _dbus_string_get_dirname(&bin_path,&dbusdir);
140 chdir(_dbus_string_get_const_data(&dbusdir));
141 _dbus_verbose ("Change working path to %s\n",_dbus_string_get_const_data (&dbusdir));
142 working_dir_init = 1;
146 DBusString *_dbus_get_working_dir(void)
148 if (!working_dir_init)
151 _dbus_verbose ("retrieving working path %s\n",_dbus_string_get_const_data (&dbusdir));
160 _dbus_file_open (DBusFile *file,
161 const char *filename,
166 file->FDATA = _open (filename, oflag, pmode);
168 file->FDATA = _open (filename, oflag);
169 if (file->FDATA >= 0)
179 _dbus_file_close (DBusFile *file,
182 const int fd = file->FDATA;
184 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
186 _dbus_assert (fd >= 0);
188 if (_close (fd) == -1)
190 dbus_set_error (error, _dbus_error_from_errno (errno),
191 "Could not close fd %d: %s", fd,
192 _dbus_strerror (errno));
197 _dbus_verbose ("closed C file descriptor %d:\n",fd);
203 _dbus_file_read(DBusFile *file,
207 const int fd = file->FDATA;
211 _dbus_assert (count >= 0);
213 start = _dbus_string_get_length (buffer);
215 if (!_dbus_string_lengthen (buffer, count))
221 data = _dbus_string_get_data_len (buffer, start, count);
223 _dbus_assert (fd >= 0);
225 _dbus_verbose ("read: count=%d fd=%d\n", count, fd);
226 bytes_read = read (fd, data, count);
228 if (bytes_read == -1)
229 _dbus_verbose ("read: failed: %s\n", _dbus_strerror (errno));
231 _dbus_verbose ("read: = %d\n", bytes_read);
235 /* put length back (note that this doesn't actually realloc anything) */
236 _dbus_string_set_length (buffer, start);
241 /* put length back (doesn't actually realloc) */
242 _dbus_string_set_length (buffer, start + bytes_read);
247 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
255 _dbus_file_write (DBusFile *file,
256 const DBusString *buffer,
260 const int fd = file->FDATA;
264 data = _dbus_string_get_const_data_len (buffer, start, len);
266 _dbus_assert (fd >= 0);
268 _dbus_verbose ("write: len=%d fd=%d\n", len, fd);
269 bytes_written = write (fd, data, len);
271 if (bytes_written == -1)
272 _dbus_verbose ("write: failed: %s\n", _dbus_strerror (errno));
274 _dbus_verbose ("write: = %d\n", bytes_written);
278 if (bytes_written > 0)
279 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
282 return bytes_written;
286 _dbus_is_valid_file (DBusFile* file)
288 return file->FDATA >= 0;
291 dbus_bool_t _dbus_fstat (DBusFile *file,
294 return fstat(file->FDATA, sb) >= 0;
298 * write data to a pipe.
300 * @param pipe the pipe instance
301 * @param buffer the buffer to write data from
302 * @param start the first byte in the buffer to write
303 * @param len the number of bytes to try to write
304 * @param error error return
305 * @returns the number of bytes written or -1 on error
308 _dbus_pipe_write (DBusPipe *pipe,
309 const DBusString *buffer,
316 file.FDATA = pipe->fd_or_handle;
317 written = _dbus_file_write (&file, buffer, start, len);
320 dbus_set_error (error, DBUS_ERROR_FAILED,
321 "Writing to pipe: %s\n",
322 _dbus_strerror (errno));
330 * @param pipe the pipe instance
331 * @param error return location for an error
332 * @returns #FALSE if error is set
335 _dbus_pipe_close (DBusPipe *pipe,
339 file.FDATA = pipe->fd_or_handle;
340 if (_dbus_file_close (&file, error) < 0)
346 _dbus_pipe_invalidate (pipe);
358 #ifdef ENABLE_DBUSSOCKET
359 static DBusSocket *win_fds = NULL;
360 static int win_n_fds = 0; // is this the size? rename to win_fds_size? #
364 #define TO_HANDLE(n) ((n)^win32_encap_randomizer)
365 #define FROM_HANDLE(n) ((n)^win32_encap_randomizer)
367 #define TO_HANDLE(n) ((n)+0x10000000)
368 #define FROM_HANDLE(n) ((n)-0x10000000)
369 #define IS_HANDLE(n) ((n)&0x10000000)
375 _dbus_win_deallocate_fd (int fd)
377 _DBUS_LOCK (win_fds);
378 win_fds[FROM_HANDLE (fd)].is_used = 0;
379 _DBUS_UNLOCK (win_fds);
384 _dbus_win_allocate_fd (void)
388 _DBUS_LOCK (win_fds);
392 #ifdef _DBUS_WIN_USE_RANDOMIZER
397 /* Use malloc to avoid memory leak failure in dbus-test */
398 win_fds = malloc (win_n_fds * sizeof (*win_fds));
400 _dbus_assert (win_fds != NULL);
402 for (i = 0; i < win_n_fds; i++)
403 win_fds[i].is_used = 0;
405 #ifdef _DBUS_WIN_USE_RANDOMIZER
407 _dbus_string_init (&random);
408 _dbus_generate_random_bytes (&random, sizeof (int));
409 memmove (&win_encap_randomizer, _dbus_string_get_const_data (&random), sizeof (int));
410 win_encap_randomizer &= 0xFF;
411 _dbus_string_free (&random);
416 for (i = 0; i < win_n_fds && win_fds[i].is_used != 0; i++)
421 int oldn = win_n_fds;
425 win_fds = realloc (win_fds, win_n_fds * sizeof (*win_fds));
427 _dbus_assert (win_fds != NULL);
429 for (j = oldn; j < win_n_fds; j++)
430 win_fds[i].is_used = 0;
433 memset(&win_fds[i], 0, sizeof(win_fds[i]));
435 win_fds[i].is_used = 1;
437 win_fds[i].port_file_fd = -1;
438 win_fds[i].close_on_exec = FALSE;
439 win_fds[i].non_blocking = FALSE;
441 _DBUS_UNLOCK (win_fds);
448 _dbus_create_handle_from_socket (int s)
453 // check: parameter must be a valid value
454 _dbus_assert(s != -1);
455 _dbus_assert(!IS_HANDLE(s));
457 // get index of a new position in the map
458 i = _dbus_win_allocate_fd ();
460 // fill new posiiton in the map: value->index
462 win_fds[i].is_used = 1;
464 // create handle from the index: index->handle
465 handle = TO_HANDLE (i);
467 _dbus_verbose ("_dbus_create_handle_from_value, value: %d, handle: %d\n", s, handle);
473 _dbus_socket_to_handle (DBusSocket *s)
478 // check: parameter must be a valid socket
479 _dbus_assert(s != NULL);
480 _dbus_assert(s->fd != -1);
481 _dbus_assert(!IS_HANDLE(s->fd));
483 _DBUS_LOCK (win_fds);
485 // at the first call there is no win_fds
486 // will be constructed _dbus_create_handle_from_socket
487 // because handle = -1
490 // search for the value in the map
491 // find the index of the value: value->index
492 for (i = 0; i < win_n_fds; i++)
493 if (win_fds[i].is_used == 1 && win_fds[i].fd == s->fd)
495 // create handle from the index: index->handle
496 handle = TO_HANDLE (i);
500 _DBUS_UNLOCK (win_fds);
505 handle = _dbus_create_handle_from_socket(s->fd);
508 _dbus_assert(handle != -1);
515 _dbus_handle_to_socket_unlocked (int handle,
520 // check: parameter must be a valid handle
521 _dbus_assert(handle != -1);
522 _dbus_assert(IS_HANDLE(handle));
523 _dbus_assert(ptr != NULL);
525 // map from handle to index: handle->index
526 i = FROM_HANDLE (handle);
528 _dbus_assert (win_fds != NULL);
529 _dbus_assert (i >= 0 && i < win_n_fds);
531 // check for if fd is valid
532 _dbus_assert (win_fds[i].is_used == 1);
534 // get socket from index: index->socket
537 _dbus_verbose ("_dbus_socket_to_handle_unlocked: socket=%d, handle=%d, index=%d\n", (*ptr)->fd, handle, i);
541 _dbus_handle_to_socket (int handle,
544 _dbus_lock_sockets();
545 _dbus_handle_to_socket_unlocked (handle, ptr);
546 _dbus_unlock_sockets();
553 #define FROM_HANDLE(n) 1==DBUS_WIN_DONT_USE__FROM_HANDLE__DIRECTLY
554 #define win_fds 1==DBUS_WIN_DONT_USE_win_fds_DIRECTLY
560 * Thin wrapper around the read() system call that appends
561 * the data it reads to the DBusString buffer. It appends
562 * up to the given count, and returns the same value
563 * and same errno as read(). The only exception is that
564 * _dbus_read() handles EINTR for you. _dbus_read() can
565 * return ENOMEM, even though regular UNIX read doesn't.
567 * @param fd the file descriptor to read from
568 * @param buffer the buffer to append data to
569 * @param count the amount of data to read
570 * @returns the number of bytes read or -1
573 _dbus_read_socket (int handle,
577 #ifdef ENABLE_DBUSSOCKET
584 _dbus_assert (count >= 0);
586 start = _dbus_string_get_length (buffer);
588 if (!_dbus_string_lengthen (buffer, count))
594 data = _dbus_string_get_data_len (buffer, start, count);
596 #ifdef ENABLE_DBUSSOCKET
597 _dbus_handle_to_socket(handle, &s);
601 _dbus_verbose ("recv: count=%d socket=%d\n", count, s->fd);
602 bytes_read = recv (s->fd, data, count, 0);
606 _dbus_verbose ("recv: count=%d socket=%d\n", count, handle);
607 bytes_read = recv (handle, data, count, 0);
609 if (bytes_read == SOCKET_ERROR)
611 DBUS_SOCKET_SET_ERRNO();
612 _dbus_verbose ("recv: failed: %s\n", _dbus_strerror (errno));
616 _dbus_verbose ("recv: = %d\n", bytes_read);
620 _dbus_assert_not_reached ("no valid socket");
625 /* put length back (note that this doesn't actually realloc anything) */
626 _dbus_string_set_length (buffer, start);
631 /* put length back (doesn't actually realloc) */
632 _dbus_string_set_length (buffer, start + bytes_read);
637 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
645 * Thin wrapper around the write() system call that writes a part of a
646 * DBusString and handles EINTR for you.
648 * @param fd the file descriptor to write
649 * @param buffer the buffer to write data from
650 * @param start the first byte in the buffer to write
651 * @param len the number of bytes to try to write
652 * @returns the number of bytes written or -1 on error
655 _dbus_write_socket (int handle,
656 const DBusString *buffer,
660 #ifdef ENABLE_DBUSSOCKET
667 data = _dbus_string_get_const_data_len (buffer, start, len);
669 #ifdef ENABLE_DBUSSOCKET
670 _dbus_handle_to_socket(handle, &s);
674 _dbus_verbose ("send: len=%d socket=%d\n", len, s->fd);
675 bytes_written = send (s->fd, data, len, 0);
679 _dbus_verbose ("send: len=%d socket=%d\n", len, handle);
680 bytes_written = send (handle, data, len, 0);
682 if (bytes_written == SOCKET_ERROR)
684 DBUS_SOCKET_SET_ERRNO();
685 _dbus_verbose ("send: failed: %s\n", _dbus_strerror (errno));
689 _dbus_verbose ("send: = %d\n", bytes_written);
693 _dbus_assert_not_reached ("unhandled fd type");
697 if (bytes_written > 0)
698 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
701 return bytes_written;
706 * Closes a file descriptor.
708 * @param fd the file descriptor
709 * @param error error object
710 * @returns #FALSE if error set
713 _dbus_close_socket (int handle,
716 #ifdef ENABLE_DBUSSOCKET
719 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
721 _dbus_lock_sockets();
723 _dbus_handle_to_socket_unlocked (handle, &s);
728 if (s->port_file_fd >= 0)
730 _chsize (s->port_file_fd, 0);
731 close (s->port_file_fd);
732 s->port_file_fd = -1;
733 unlink (_dbus_string_get_const_data (&s->port_file));
734 free ((char *) _dbus_string_get_const_data (&s->port_file));
737 if (closesocket (s->fd) == SOCKET_ERROR)
739 DBUS_SOCKET_SET_ERRNO ();
740 dbus_set_error (error, _dbus_error_from_errno (errno),
741 "Could not close socket: socket=%d, handle=%d, %s",
742 s->fd, handle, _dbus_strerror (errno));
743 _dbus_unlock_sockets();
746 _dbus_verbose ("_dbus_close_socket: socket=%d, handle=%d\n",
751 _dbus_assert_not_reached ("unhandled fd type");
754 _dbus_unlock_sockets();
756 _dbus_win_deallocate_fd (handle);
762 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
767 if (closesocket (handle) == SOCKET_ERROR)
769 DBUS_SOCKET_SET_ERRNO ();
770 dbus_set_error (error, _dbus_error_from_errno (errno),
771 "Could not close socket: socket=%d, , %s",
772 handle, _dbus_strerror (errno));
775 _dbus_verbose ("_dbus_close_socket: socket=%d, \n",
780 _dbus_assert_not_reached ("unhandled fd type");
789 * Sets the file descriptor to be close
790 * on exec. Should be called for all file
791 * descriptors in D-Bus code.
793 * @param fd the file descriptor
796 _dbus_fd_set_close_on_exec (int handle)
798 #ifdef ENABLE_DBUSSOCKET
803 _dbus_lock_sockets();
805 _dbus_handle_to_socket_unlocked (handle, &s);
806 s->close_on_exec = TRUE;
808 _dbus_unlock_sockets();
813 val = fcntl (fd, F_GETFD, 0);
820 fcntl (fd, F_SETFD, val);
826 * Sets a file descriptor to be nonblocking.
828 * @param fd the file descriptor.
829 * @param error address of error location.
830 * @returns #TRUE on success.
833 _dbus_set_fd_nonblocking (int handle,
836 #ifdef ENABLE_DBUSSOCKET
840 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
842 _dbus_lock_sockets();
844 _dbus_handle_to_socket_unlocked(handle, &s);
848 if (ioctlsocket (s->fd, FIONBIO, &one) == SOCKET_ERROR)
850 dbus_set_error (error, _dbus_error_from_errno (WSAGetLastError ()),
851 "Failed to set socket %d:%d to nonblocking: %s", s->fd,
852 _dbus_strerror (WSAGetLastError ()));
853 _dbus_unlock_sockets();
859 _dbus_assert_not_reached ("unhandled fd type");
862 _dbus_unlock_sockets();
868 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
872 if (ioctlsocket (handle, FIONBIO, &one) == SOCKET_ERROR)
874 dbus_set_error (error, _dbus_error_from_errno (WSAGetLastError ()),
875 "Failed to set socket %d:%d to nonblocking: %s", handle,
876 _dbus_strerror (WSAGetLastError ()));
882 _dbus_assert_not_reached ("unhandled fd type");
890 * Like _dbus_write() but will use writev() if possible
891 * to write both buffers in sequence. The return value
892 * is the number of bytes written in the first buffer,
893 * plus the number written in the second. If the first
894 * buffer is written successfully and an error occurs
895 * writing the second, the number of bytes in the first
896 * is returned (i.e. the error is ignored), on systems that
897 * don't have writev. Handles EINTR for you.
898 * The second buffer may be #NULL.
900 * @param fd the file descriptor
901 * @param buffer1 first buffer
902 * @param start1 first byte to write in first buffer
903 * @param len1 number of bytes to write from first buffer
904 * @param buffer2 second buffer, or #NULL
905 * @param start2 first byte to write in second buffer
906 * @param len2 number of bytes to write in second buffer
907 * @returns total bytes written from both buffers, or -1 on error
910 _dbus_write_socket_two (int handle,
911 const DBusString *buffer1,
914 const DBusString *buffer2,
918 #ifdef ENABLE_DBUSSOCKET
927 _dbus_assert (buffer1 != NULL);
928 _dbus_assert (start1 >= 0);
929 _dbus_assert (start2 >= 0);
930 _dbus_assert (len1 >= 0);
931 _dbus_assert (len2 >= 0);
933 _dbus_handle_to_socket(handle, &s);
935 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
938 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
948 vectors[0].buf = (char*) data1;
949 vectors[0].len = len1;
950 vectors[1].buf = (char*) data2;
951 vectors[1].len = len2;
953 _dbus_verbose ("WSASend: len1+2=%d+%d socket=%d\n", len1, len2, s->fd);
954 rc = WSASend (s->fd, vectors, data2 ? 2 : 1, &bytes_written,
958 DBUS_SOCKET_SET_ERRNO ();
959 _dbus_verbose ("WSASend: failed: %s\n", _dbus_strerror (errno));
963 _dbus_verbose ("WSASend: = %ld\n", bytes_written);
964 return bytes_written;
968 _dbus_assert_not_reached ("unhandled fd type");
979 _dbus_assert (buffer1 != NULL);
980 _dbus_assert (start1 >= 0);
981 _dbus_assert (start2 >= 0);
982 _dbus_assert (len1 >= 0);
983 _dbus_assert (len2 >= 0);
986 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
989 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
999 vectors[0].buf = (char*) data1;
1000 vectors[0].len = len1;
1001 vectors[1].buf = (char*) data2;
1002 vectors[1].len = len2;
1004 _dbus_verbose ("WSASend: len1+2=%d+%d socket=%d\n", len1, len2, handle);
1005 rc = WSASend (handle, vectors, data2 ? 2 : 1, &bytes_written,
1009 DBUS_SOCKET_SET_ERRNO ();
1010 _dbus_verbose ("WSASend: failed: %s\n", _dbus_strerror (errno));
1014 _dbus_verbose ("WSASend: = %ld\n", bytes_written);
1015 return bytes_written;
1019 _dbus_assert_not_reached ("unhandled fd type");
1028 * Opens the client side of a Windows named pipe. The connection D-BUS
1029 * file descriptor index is returned. It is set up as nonblocking.
1031 * @param path the path to named pipe socket
1032 * @param error return location for error code
1033 * @returns connection D-BUS file descriptor or -1 on error
1036 _dbus_connect_named_pipe (const char *path,
1039 _dbus_assert_not_reached ("not implemented");
1045 #ifdef ENABLE_DBUSUSERINFO
1047 _dbus_account_to_win_sid (const wchar_t *waccount,
1051 dbus_bool_t retval = FALSE;
1052 DWORD sid_length, wdomain_length;
1060 if (!LookupAccountNameW (NULL, waccount, NULL, &sid_length,
1061 NULL, &wdomain_length, &use)
1062 && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
1064 _dbus_win_set_error_from_win_error (error, GetLastError ());
1068 *ppsid = dbus_malloc (sid_length);
1071 _DBUS_SET_OOM (error);
1075 wdomain = dbus_new (wchar_t, wdomain_length);
1078 _DBUS_SET_OOM (error);
1082 if (!LookupAccountNameW (NULL, waccount, (PSID) *ppsid, &sid_length,
1083 wdomain, &wdomain_length, &use))
1085 _dbus_win_set_error_from_win_error (error, GetLastError ());
1089 if (!IsValidSid ((PSID) *ppsid))
1091 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID");
1098 dbus_free (wdomain);
1110 fill_win_user_info_name_and_groups (wchar_t *wname,
1118 dbus_bool_t retval = FALSE;
1119 char *name, *domain;
1120 LPLOCALGROUP_USERS_INFO_0 local_groups = NULL;
1121 LPGROUP_USERS_INFO_0 global_groups = NULL;
1122 DWORD nread, ntotal;
1124 name = _dbus_win_utf16_to_utf8 (wname, error);
1128 domain = _dbus_win_utf16_to_utf8 (wdomain, error);
1132 info->username = dbus_malloc (strlen (domain) + 1 + strlen (name) + 1);
1133 if (!info->username)
1135 _DBUS_SET_OOM (error);
1139 strcpy (info->username, domain);
1140 strcat (info->username, "\\");
1141 strcat (info->username, name);
1143 info->n_group_ids = 0;
1144 if (NetUserGetLocalGroups (NULL, wname, 0, LG_INCLUDE_INDIRECT,
1145 (LPBYTE *) &local_groups, MAX_PREFERRED_LENGTH,
1146 &nread, &ntotal) == NERR_Success)
1151 info->group_ids = dbus_new (dbus_gid_t, nread);
1152 if (!info->group_ids)
1154 _DBUS_SET_OOM (error);
1158 for (i = n = 0; i < nread; i++)
1161 if (_dbus_account_to_win_sid (local_groups[i].lgrui0_name,
1164 info->group_ids[n++] = _dbus_win_sid_to_uid_t (group_sid);
1165 dbus_free (group_sid);
1168 info->n_group_ids = n;
1171 if (NetUserGetGroups (NULL, wname, 0,
1172 (LPBYTE *) &global_groups, MAX_PREFERRED_LENGTH,
1173 &nread, &ntotal) == NERR_Success)
1176 int n = info->n_group_ids;
1178 info->group_ids = dbus_realloc (info->group_ids, (n + nread) * sizeof (dbus_gid_t));
1179 if (!info->group_ids)
1181 _DBUS_SET_OOM (error);
1185 for (i = 0; i < nread; i++)
1188 if (_dbus_account_to_win_sid (global_groups[i].grui0_name,
1191 info->group_ids[n++] = _dbus_win_sid_to_uid_t (group_sid);
1192 dbus_free (group_sid);
1195 info->n_group_ids = n;
1198 if (info->n_group_ids > 0)
1200 /* FIXME: find out actual primary group */
1201 info->primary_gid = info->group_ids[0];
1205 info->group_ids = dbus_new (dbus_gid_t, 1);
1206 info->n_group_ids = 1;
1207 info->group_ids[0] = DBUS_GID_UNSET;
1208 info->primary_gid = DBUS_GID_UNSET;
1214 if (global_groups != NULL)
1215 NetApiBufferFree (global_groups);
1217 if (local_groups != NULL)
1218 NetApiBufferFree (local_groups);
1229 fill_win_user_info_homedir (wchar_t *wname,
1238 dbus_bool_t retval = FALSE;
1239 USER_INFO_1 *user_info = NULL;
1240 wchar_t wcomputername[MAX_COMPUTERNAME_LENGTH + 1];
1241 DWORD wcomputername_length = MAX_COMPUTERNAME_LENGTH + 1;
1242 dbus_bool_t local_computer;
1244 NET_API_STATUS ret = 0;
1246 /* If the domain is this computer's name, assume it's a local user.
1247 * Otherwise look up a DC for the domain, and ask it.
1250 GetComputerNameW (wcomputername, &wcomputername_length);
1251 local_computer = (wcsicmp (wcomputername, wdomain) == 0);
1253 if (!local_computer)
1255 ret = NetGetAnyDCName (NULL, wdomain, (LPBYTE *) &dc);
1256 if (ret != NERR_Success)
1258 info->homedir = _dbus_strdup ("\\");
1259 _dbus_verbose("NetGetAnyDCName() failed with errorcode %d '%s'\n",ret,_dbus_lm_strerror(ret));
1264 /* No way to find out the profile of another user, let's try the
1265 * "home directory" from NetUserGetInfo's USER_INFO_1.
1267 ret = NetUserGetInfo (dc, wname, 1, (LPBYTE *) &user_info);
1268 if (ret == NERR_Success )
1269 if(user_info->usri1_home_dir != NULL &&
1270 user_info->usri1_home_dir != (LPWSTR)0xfeeefeee && /* freed memory http://www.gamedev.net/community/forums/topic.asp?topic_id=158402 */
1271 user_info->usri1_home_dir[0] != '\0')
1273 info->homedir = _dbus_win_utf16_to_utf8 (user_info->usri1_home_dir, error);
1279 _dbus_verbose("NetUserGetInfo() returned no home dir entry\n");
1280 /* Not set, so use something random. */
1281 info->homedir = _dbus_strdup ("\\");
1285 char *dc_string = _dbus_win_utf16_to_utf8(dc,error);
1286 char *user_name = _dbus_win_utf16_to_utf8(wname,error);
1287 _dbus_verbose("NetUserGetInfo() for user '%s' failed with errorcode %d '%s', %s\n",user_name, ret,_dbus_lm_strerror(ret),dc_string);
1288 dbus_free(user_name);
1289 dbus_free(dc_string);
1290 /* Not set, so use something random. */
1291 info->homedir = _dbus_strdup ("\\");
1298 NetApiBufferFree (dc);
1299 if (user_info != NULL)
1300 NetApiBufferFree (user_info);
1307 fill_win_user_info_from_name (wchar_t *wname,
1315 dbus_bool_t retval = FALSE;
1318 DWORD sid_length, wdomain_length;
1323 if (!LookupAccountNameW (NULL, wname, NULL, &sid_length,
1324 NULL, &wdomain_length, &use) &&
1325 GetLastError () != ERROR_INSUFFICIENT_BUFFER)
1327 _dbus_win_set_error_from_win_error (error, GetLastError ());
1331 sid = dbus_malloc (sid_length);
1334 _DBUS_SET_OOM (error);
1338 wdomain = dbus_new (wchar_t, wdomain_length);
1341 _DBUS_SET_OOM (error);
1345 if (!LookupAccountNameW (NULL, wname, sid, &sid_length,
1346 wdomain, &wdomain_length, &use))
1348 _dbus_win_set_error_from_win_error (error, GetLastError ());
1352 if (!IsValidSid (sid))
1354 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID");
1358 info->uid = _dbus_win_sid_to_uid_t (sid);
1360 if (!fill_win_user_info_name_and_groups (wname, wdomain, info, error))
1363 if (!fill_win_user_info_homedir (wname, wdomain, info, error))
1369 dbus_free (wdomain);
1378 _dbus_win_sid_to_name_and_domain (dbus_uid_t uid,
1388 DWORD wname_length, wdomain_length;
1391 if (!_dbus_uid_t_to_win_sid (uid, &sid))
1393 _dbus_win_set_error_from_win_error (error, GetLastError ());
1399 if (!LookupAccountSidW (NULL, sid, NULL, &wname_length,
1400 NULL, &wdomain_length, &use) &&
1401 GetLastError () != ERROR_INSUFFICIENT_BUFFER)
1403 _dbus_win_set_error_from_win_error (error, GetLastError ());
1407 *wname = dbus_new (wchar_t, wname_length);
1410 _DBUS_SET_OOM (error);
1414 *wdomain = dbus_new (wchar_t, wdomain_length);
1417 _DBUS_SET_OOM (error);
1421 if (!LookupAccountSidW (NULL, sid, *wname, &wname_length,
1422 *wdomain, &wdomain_length, &use))
1424 _dbus_win_set_error_from_win_error (error, GetLastError ());
1431 dbus_free (*wdomain);
1444 fill_win_user_info_from_uid (dbus_uid_t uid,
1453 dbus_bool_t retval = FALSE;
1454 wchar_t *wname, *wdomain;
1458 if (!_dbus_win_sid_to_name_and_domain (uid, &wname, &wdomain, error))
1460 _dbus_verbose("%s after _dbus_win_sid_to_name_and_domain\n",__FUNCTION__);
1464 if (!fill_win_user_info_name_and_groups (wname, wdomain, info, error))
1466 _dbus_verbose("%s after fill_win_user_info_name_and_groups\n",__FUNCTION__);
1471 if (!fill_win_user_info_homedir (wname, wdomain, info, error))
1473 _dbus_verbose("%s after fill_win_user_info_homedir\n",__FUNCTION__);
1480 dbus_free (wdomain);
1491 _dbus_win_startup_winsock (void)
1493 /* Straight from MSDN, deuglified */
1495 static dbus_bool_t beenhere = FALSE;
1497 WORD wVersionRequested;
1504 wVersionRequested = MAKEWORD (2, 0);
1506 err = WSAStartup (wVersionRequested, &wsaData);
1509 _dbus_assert_not_reached ("Could not initialize WinSock");
1513 /* Confirm that the WinSock DLL supports 2.0. Note that if the DLL
1514 * supports versions greater than 2.0 in addition to 2.0, it will
1515 * still return 2.0 in wVersion since that is the version we
1518 if (LOBYTE (wsaData.wVersion) != 2 ||
1519 HIBYTE (wsaData.wVersion) != 0)
1521 _dbus_assert_not_reached ("No usable WinSock found");
1536 /************************************************************************
1540 ************************************************************************/
1543 * Measure the message length without terminating nul
1545 int _dbus_printf_string_upper_bound (const char *format,
1548 /* MSVCRT's vsnprintf semantics are a bit different */
1549 /* The C library source in the Platform SDK indicates that this
1550 * would work, but alas, it doesn't. At least not on Windows
1551 * 2000. Presumably those sources correspond to the C library on
1552 * some newer or even future Windows version.
1554 len = _vsnprintf (NULL, _DBUS_INT_MAX, format, args);
1558 len = _vsnprintf (p, sizeof(p)-1, format, args);
1559 if (len == -1) // try again
1562 p = malloc (strlen(format)*3);
1563 len = _vsnprintf (p, sizeof(p)-1, format, args);
1571 * Returns the UTF-16 form of a UTF-8 string. The result should be
1572 * freed with dbus_free() when no longer needed.
1574 * @param str the UTF-8 string
1575 * @param error return location for error code
1578 _dbus_win_utf8_to_utf16 (const char *str,
1585 _dbus_string_init_const (&s, str);
1587 if (!_dbus_string_validate_utf8 (&s, 0, _dbus_string_get_length (&s)))
1589 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid UTF-8");
1593 n = MultiByteToWideChar (CP_UTF8, 0, str, -1, NULL, 0);
1597 _dbus_win_set_error_from_win_error (error, GetLastError ());
1601 retval = dbus_new (wchar_t, n);
1605 _DBUS_SET_OOM (error);
1609 if (MultiByteToWideChar (CP_UTF8, 0, str, -1, retval, n) != n)
1612 dbus_set_error_const (error, DBUS_ERROR_FAILED, "MultiByteToWideChar inconsistency");
1620 * Returns the UTF-8 form of a UTF-16 string. The result should be
1621 * freed with dbus_free() when no longer needed.
1623 * @param str the UTF-16 string
1624 * @param error return location for error code
1627 _dbus_win_utf16_to_utf8 (const wchar_t *str,
1633 n = WideCharToMultiByte (CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
1637 _dbus_win_set_error_from_win_error (error, GetLastError ());
1641 retval = dbus_malloc (n);
1645 _DBUS_SET_OOM (error);
1649 if (WideCharToMultiByte (CP_UTF8, 0, str, -1, retval, n, NULL, NULL) != n)
1652 dbus_set_error_const (error, DBUS_ERROR_FAILED, "WideCharToMultiByte inconsistency");
1664 /************************************************************************
1666 uid ... <-> win sid functions
1668 ************************************************************************/
1671 _dbus_win_account_to_sid (const wchar_t *waccount,
1675 dbus_bool_t retval = FALSE;
1676 DWORD sid_length, wdomain_length;
1684 if (!LookupAccountNameW (NULL, waccount, NULL, &sid_length,
1685 NULL, &wdomain_length, &use) &&
1686 GetLastError () != ERROR_INSUFFICIENT_BUFFER)
1688 _dbus_win_set_error_from_win_error (error, GetLastError ());
1692 *ppsid = dbus_malloc (sid_length);
1695 _DBUS_SET_OOM (error);
1699 wdomain = dbus_new (wchar_t, wdomain_length);
1702 _DBUS_SET_OOM (error);
1706 if (!LookupAccountNameW (NULL, waccount, (PSID) *ppsid, &sid_length,
1707 wdomain, &wdomain_length, &use))
1709 _dbus_win_set_error_from_win_error (error, GetLastError ());
1713 if (!IsValidSid ((PSID) *ppsid))
1715 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID");
1722 dbus_free (wdomain);
1733 #ifdef ENABLE_UID_TO_SID
1735 _sid_atom_cache_shutdown (void *unused)
1738 _DBUS_LOCK (sid_atom_cache);
1739 _dbus_hash_iter_init (sid_atom_cache, &iter);
1740 while (_dbus_hash_iter_next (&iter))
1743 atom = (ATOM) _dbus_hash_iter_get_value (&iter);
1744 GlobalDeleteAtom(atom);
1745 _dbus_hash_iter_remove_entry(&iter);
1747 _DBUS_UNLOCK (sid_atom_cache);
1748 _dbus_hash_table_unref (sid_atom_cache);
1749 sid_atom_cache = NULL;
1753 * Returns the 2-way associated dbus_uid_t form a SID.
1755 * @param psid pointer to the SID
1758 _dbus_win_sid_to_uid_t (PSID psid)
1765 if (!IsValidSid (psid))
1767 _dbus_verbose("%s invalid sid\n",__FUNCTION__);
1768 return DBUS_UID_UNSET;
1770 if (!ConvertSidToStringSidA (psid, &string))
1772 _dbus_verbose("%s invalid sid\n",__FUNCTION__);
1773 return DBUS_UID_UNSET;
1776 atom = GlobalAddAtom(string);
1780 _dbus_verbose("%s GlobalAddAtom failed\n",__FUNCTION__);
1782 return DBUS_UID_UNSET;
1785 _DBUS_LOCK (sid_atom_cache);
1787 if (sid_atom_cache == NULL)
1789 sid_atom_cache = _dbus_hash_table_new (DBUS_HASH_ULONG, NULL, NULL);
1790 _dbus_register_shutdown_func (_sid_atom_cache_shutdown, NULL);
1794 olduid = (dbus_uid_t) _dbus_hash_table_lookup_ulong (sid_atom_cache, uid);
1798 _dbus_verbose("%s sid with id %i found in cache\n",__FUNCTION__, olduid);
1803 _dbus_hash_table_insert_ulong (sid_atom_cache, uid, (void*) uid);
1804 _dbus_verbose("%s sid %s added with uid %i to cache\n",__FUNCTION__, string, uid);
1807 _DBUS_UNLOCK (sid_atom_cache);
1812 dbus_bool_t _dbus_uid_t_to_win_sid (dbus_uid_t uid, PSID *ppsid)
1817 atom = _dbus_hash_table_lookup_ulong (sid_atom_cache, uid);
1820 _dbus_verbose("%s uid %i not found in cache\n",__FUNCTION__,uid);
1823 memset( string, '.', sizeof(string) );
1824 if (!GlobalGetAtomNameA( (ATOM) atom, string, 255 ))
1826 _dbus_verbose("%s uid %i not found in cache\n",__FUNCTION__, uid);
1829 if (!ConvertStringSidToSidA(string, ppsid))
1831 _dbus_verbose("%s could not convert %s into sid \n",__FUNCTION__, string);
1834 _dbus_verbose("%s converted %s into sid \n",__FUNCTION__, string);
1839 /** @} end of sysdeps-win */
1843 * @returns process UID
1848 #ifndef ENABLE_UID_TO_SID
1849 return DBUS_UID_UNSET;
1851 dbus_uid_t retval = DBUS_UID_UNSET;
1852 HANDLE process_token = NULL;
1853 TOKEN_USER *token_user = NULL;
1856 if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &process_token))
1857 _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ());
1858 else if ((!GetTokenInformation (process_token, TokenUser, NULL, 0, &n)
1859 && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
1860 || (token_user = alloca (n)) == NULL
1861 || !GetTokenInformation (process_token, TokenUser, token_user, n, &n))
1862 _dbus_win_warn_win_error ("GetTokenInformation failed", GetLastError ());
1864 retval = _dbus_win_sid_to_uid_t (token_user->User.Sid);
1866 if (process_token != NULL)
1867 CloseHandle (process_token);
1869 _dbus_verbose("_dbus_getuid() returns %d\n",retval);
1875 * The only reason this is separate from _dbus_getpid() is to allow it
1876 * on Windows for logging but not for other purposes.
1878 * @returns process ID to put in log messages
1881 _dbus_pid_for_log (void)
1883 return _dbus_getpid ();
1888 #ifdef DBUS_BUILD_TESTS
1890 * @returns process GID
1895 #ifndef ENABLE_UID_TO_SID
1896 return DBUS_GID_UNSET;
1898 dbus_gid_t retval = DBUS_GID_UNSET;
1899 HANDLE process_token = NULL;
1900 TOKEN_PRIMARY_GROUP *token_primary_group = NULL;
1903 if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &process_token))
1904 _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ());
1905 else if ((!GetTokenInformation (process_token, TokenPrimaryGroup,
1907 GetLastError () != ERROR_INSUFFICIENT_BUFFER) ||
1908 (token_primary_group = alloca (n)) == NULL ||
1909 !GetTokenInformation (process_token, TokenPrimaryGroup,
1910 token_primary_group, n, &n))
1911 _dbus_win_warn_win_error ("GetTokenInformation failed", GetLastError ());
1913 retval = _dbus_win_sid_to_uid_t (token_primary_group->PrimaryGroup);
1915 if (process_token != NULL)
1916 CloseHandle (process_token);
1924 _dbus_domain_test (const char *test_data_dir)
1926 if (!_dbus_test_oom_handling ("spawn_nonexistent",
1927 check_spawn_nonexistent,
1934 #endif //DBUS_BUILD_TESTS
1936 /************************************************************************
1940 ************************************************************************/
1943 * Creates a full-duplex pipe (as in socketpair()).
1944 * Sets both ends of the pipe nonblocking.
1946 * @todo libdbus only uses this for the debug-pipe server, so in
1947 * principle it could be in dbus-sysdeps-util.c, except that
1948 * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
1949 * debug-pipe server is used.
1951 * @param fd1 return location for one end
1952 * @param fd2 return location for the other end
1953 * @param blocking #TRUE if pipe should be blocking
1954 * @param error error return
1955 * @returns #FALSE on failure (if error is set)
1958 _dbus_full_duplex_pipe (int *fd1,
1960 dbus_bool_t blocking,
1963 SOCKET temp, socket1 = -1, socket2 = -1;
1964 struct sockaddr_in saddr;
1967 fd_set read_set, write_set;
1969 #ifdef ENABLE_DBUSSOCKET
1974 _dbus_win_startup_winsock ();
1976 temp = socket (AF_INET, SOCK_STREAM, 0);
1977 if (temp == INVALID_SOCKET)
1979 DBUS_SOCKET_SET_ERRNO ();
1984 if (ioctlsocket (temp, FIONBIO, &arg) == SOCKET_ERROR)
1986 DBUS_SOCKET_SET_ERRNO ();
1991 saddr.sin_family = AF_INET;
1993 saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1995 if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr)))
1997 DBUS_SOCKET_SET_ERRNO ();
2001 if (listen (temp, 1) == SOCKET_ERROR)
2003 DBUS_SOCKET_SET_ERRNO ();
2007 len = sizeof (saddr);
2008 if (getsockname (temp, (struct sockaddr *)&saddr, &len))
2010 DBUS_SOCKET_SET_ERRNO ();
2014 socket1 = socket (AF_INET, SOCK_STREAM, 0);
2015 if (socket1 == INVALID_SOCKET)
2017 DBUS_SOCKET_SET_ERRNO ();
2022 if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
2024 DBUS_SOCKET_SET_ERRNO ();
2028 if (connect (socket1, (struct sockaddr *)&saddr, len) != SOCKET_ERROR ||
2029 WSAGetLastError () != WSAEWOULDBLOCK)
2031 DBUS_SOCKET_SET_ERRNO ();
2035 FD_ZERO (&read_set);
2036 FD_SET (temp, &read_set);
2041 if (select (0, &read_set, NULL, NULL, NULL) == SOCKET_ERROR)
2043 DBUS_SOCKET_SET_ERRNO ();
2047 _dbus_assert (FD_ISSET (temp, &read_set));
2049 socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
2050 if (socket2 == INVALID_SOCKET)
2052 DBUS_SOCKET_SET_ERRNO ();
2056 FD_ZERO (&write_set);
2057 FD_SET (socket1, &write_set);
2062 if (select (0, NULL, &write_set, NULL, NULL) == SOCKET_ERROR)
2064 DBUS_SOCKET_SET_ERRNO ();
2068 _dbus_assert (FD_ISSET (socket1, &write_set));
2073 if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
2075 DBUS_SOCKET_SET_ERRNO ();
2080 if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
2082 DBUS_SOCKET_SET_ERRNO ();
2089 if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
2091 DBUS_SOCKET_SET_ERRNO ();
2096 #ifdef ENABLE_DBUSSOCKET
2098 *fd1 = _dbus_socket_to_handle (&sock);
2100 *fd2 = _dbus_socket_to_handle (&sock);
2106 _dbus_verbose ("full-duplex pipe %d:%d <-> %d:%d\n",
2107 *fd1, socket1, *fd2, socket2);
2114 closesocket (socket2);
2116 closesocket (socket1);
2120 dbus_set_error (error, _dbus_error_from_errno (errno),
2121 "Could not setup socket pair: %s",
2122 _dbus_strerror (errno));
2128 * Wrapper for poll().
2130 * @param fds the file descriptors to poll
2131 * @param n_fds number of descriptors in the array
2132 * @param timeout_milliseconds timeout or -1 for infinite
2133 * @returns numbers of fds with revents, or <0 on error
2135 #define USE_CHRIS_IMPL 0
2138 _dbus_poll (DBusPollFD *fds,
2140 int timeout_milliseconds)
2142 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
2143 char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
2151 #define DBUS_STACK_WSAEVENTS 256
2152 WSAEVENT eventsOnStack[DBUS_STACK_WSAEVENTS];
2153 WSAEVENT *pEvents = NULL;
2154 if (n_fds > DBUS_STACK_WSAEVENTS)
2155 pEvents = calloc(sizeof(WSAEVENT), n_fds);
2157 pEvents = eventsOnStack;
2159 _dbus_lock_sockets();
2161 #ifdef DBUS_ENABLE_VERBOSE_MODE
2163 msgp += sprintf (msgp, "WSAEventSelect: to=%d\n\t", timeout_milliseconds);
2164 for (i = 0; i < n_fds; i++)
2166 static dbus_bool_t warned = FALSE;
2168 DBusPollFD *fdp = &fds[i];
2170 _dbus_handle_to_socket_unlocked(fdp->fd, &s);
2172 if (s->is_used == 0)
2174 _dbus_warn ("no valid socket");
2178 if (fdp->events & _DBUS_POLLIN)
2179 msgp += sprintf (msgp, "R:%d ", s->fd);
2181 if (fdp->events & _DBUS_POLLOUT)
2182 msgp += sprintf (msgp, "W:%d ", s->fd);
2184 msgp += sprintf (msgp, "E:%d\n\t", s->fd);
2186 // FIXME: more robust code for long msg
2187 // create on heap when msg[] becomes too small
2188 if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
2190 _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
2194 msgp += sprintf (msgp, "\n");
2195 _dbus_verbose ("%s",msg);
2197 for (i = 0; i < n_fds; i++)
2200 DBusPollFD *fdp = &fds[i];
2202 long lNetworkEvents = FD_OOB;
2204 _dbus_handle_to_socket_unlocked(fdp->fd, &s);
2206 if (s->is_used == 0)
2209 ev = WSACreateEvent();
2211 if (fdp->events & _DBUS_POLLIN)
2212 lNetworkEvents |= FD_READ | FD_ACCEPT | FD_CLOSE;
2214 if (fdp->events & _DBUS_POLLOUT)
2215 lNetworkEvents |= FD_WRITE | FD_CONNECT;
2217 WSAEventSelect(s->fd, ev, lNetworkEvents);
2222 _dbus_unlock_sockets();
2224 ready = WSAWaitForMultipleEvents (n_fds, pEvents, FALSE, timeout_milliseconds, FALSE);
2226 if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
2228 DBUS_SOCKET_SET_ERRNO ();
2229 if (errno != EWOULDBLOCK)
2230 _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", _dbus_strerror (errno));
2233 else if (ready == WSA_WAIT_TIMEOUT)
2235 _dbus_verbose ("WSAWaitForMultipleEvents: WSA_WAIT_TIMEOUT\n");
2238 else if (ready >= WSA_WAIT_EVENT_0 && ready < (int)(WSA_WAIT_EVENT_0 + n_fds))
2241 msgp += sprintf (msgp, "WSAWaitForMultipleEvents: =%d\n\t", ready);
2243 _dbus_lock_sockets();
2244 for (i = 0; i < n_fds; i++)
2247 DBusPollFD *fdp = &fds[i];
2248 WSANETWORKEVENTS ne;
2250 _dbus_handle_to_socket_unlocked(fdp->fd, &s);
2254 WSAEnumNetworkEvents(s->fd, pEvents[i], &ne);
2256 if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
2257 fdp->revents |= _DBUS_POLLIN;
2259 if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
2260 fdp->revents |= _DBUS_POLLOUT;
2262 if (ne.lNetworkEvents & (FD_OOB))
2263 fdp->revents |= _DBUS_POLLERR;
2265 if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
2266 msgp += sprintf (msgp, "R:%d ", s->fd);
2268 if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
2269 msgp += sprintf (msgp, "W:%d ", s->fd);
2271 if (ne.lNetworkEvents & (FD_OOB))
2272 msgp += sprintf (msgp, "E:%d ", s->fd);
2274 msgp += sprintf (msgp, "lNetworkEvents:%d ", ne.lNetworkEvents);
2276 if(ne.lNetworkEvents)
2279 WSAEventSelect(s->fd, pEvents[i], 0);
2281 _dbus_unlock_sockets();
2283 msgp += sprintf (msgp, "\n");
2284 _dbus_verbose ("%s",msg);
2288 _dbus_verbose ("WSAWaitForMultipleEvents: failed for unknown reason!");
2292 for(i = 0; i < n_fds; i++)
2294 WSACloseEvent(pEvents[i]);
2297 if (n_fds > DBUS_STACK_WSAEVENTS)
2303 #else // USE_CHRIS_IMPL
2305 #ifdef ENABLE_DBUSSOCKET
2308 _dbus_poll (DBusPollFD *fds,
2310 int timeout_milliseconds)
2312 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
2313 char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
2316 fd_set read_set, write_set, err_set;
2322 FD_ZERO (&read_set);
2323 FD_ZERO (&write_set);
2326 _dbus_lock_sockets();
2328 #ifdef DBUS_ENABLE_VERBOSE_MODE
2330 msgp += sprintf (msgp, "select: to=%d\n\t", timeout_milliseconds);
2331 for (i = 0; i < n_fds; i++)
2333 static dbus_bool_t warned = FALSE;
2335 DBusPollFD *fdp = &fds[i];
2337 _dbus_handle_to_socket_unlocked(fdp->fd, &s);
2339 if (s->is_used == 0)
2341 _dbus_warn ("no valid socket");
2345 if (fdp->events & _DBUS_POLLIN)
2346 msgp += sprintf (msgp, "R:%d ", s->fd);
2348 if (fdp->events & _DBUS_POLLOUT)
2349 msgp += sprintf (msgp, "W:%d ", s->fd);
2351 msgp += sprintf (msgp, "E:%d\n\t", s->fd);
2353 // FIXME: more robust code for long msg
2354 // create on heap when msg[] becomes too small
2355 if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
2357 _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
2361 msgp += sprintf (msgp, "\n");
2362 _dbus_verbose ("%s",msg);
2364 for (i = 0; i < n_fds; i++)
2367 DBusPollFD *fdp = &fds[i];
2369 _dbus_handle_to_socket_unlocked(fdp->fd, &s);
2371 if (s->is_used != 1)
2374 if (fdp->events & _DBUS_POLLIN)
2375 FD_SET (s->fd, &read_set);
2377 if (fdp->events & _DBUS_POLLOUT)
2378 FD_SET (s->fd, &write_set);
2380 FD_SET (s->fd, &err_set);
2382 max_fd = MAX (max_fd, s->fd);
2385 _dbus_unlock_sockets();
2387 tv.tv_sec = timeout_milliseconds / 1000;
2388 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2390 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2391 timeout_milliseconds < 0 ? NULL : &tv);
2393 if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
2395 DBUS_SOCKET_SET_ERRNO ();
2396 if (errno != EWOULDBLOCK)
2397 _dbus_verbose ("select: failed: %s\n", _dbus_strerror (errno));
2399 else if (ready == 0)
2400 _dbus_verbose ("select: = 0\n");
2404 #ifdef DBUS_ENABLE_VERBOSE_MODE
2406 msgp += sprintf (msgp, "select: = %d:\n\t", ready);
2407 _dbus_lock_sockets();
2408 for (i = 0; i < n_fds; i++)
2411 DBusPollFD *fdp = &fds[i];
2413 _dbus_handle_to_socket_unlocked(fdp->fd, &s);
2415 if (FD_ISSET (s->fd, &read_set))
2416 msgp += sprintf (msgp, "R:%d ", s->fd);
2418 if (FD_ISSET (s->fd, &write_set))
2419 msgp += sprintf (msgp, "W:%d ", s->fd);
2421 if (FD_ISSET (s->fd, &err_set))
2422 msgp += sprintf (msgp, "E:%d\n\t", s->fd);
2424 msgp += sprintf (msgp, "\n");
2425 _dbus_verbose ("%s",msg);
2428 for (i = 0; i < n_fds; i++)
2431 DBusPollFD *fdp = &fds[i];
2433 _dbus_handle_to_socket_unlocked(fdp->fd, &s);
2437 if (FD_ISSET (s->fd, &read_set))
2438 fdp->revents |= _DBUS_POLLIN;
2440 if (FD_ISSET (s->fd, &write_set))
2441 fdp->revents |= _DBUS_POLLOUT;
2443 if (FD_ISSET (s->fd, &err_set))
2444 fdp->revents |= _DBUS_POLLERR;
2446 _dbus_unlock_sockets();
2450 #else // ENABLE_DBUSSOCKET
2453 _dbus_poll (DBusPollFD *fds,
2455 int timeout_milliseconds)
2457 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
2458 char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
2461 fd_set read_set, write_set, err_set;
2467 FD_ZERO (&read_set);
2468 FD_ZERO (&write_set);
2472 #ifdef DBUS_ENABLE_VERBOSE_MODE
2474 msgp += sprintf (msgp, "select: to=%d\n\t", timeout_milliseconds);
2475 for (i = 0; i < n_fds; i++)
2477 static dbus_bool_t warned = FALSE;
2479 DBusPollFD *fdp = &fds[i];
2483 if (fdp->events & _DBUS_POLLIN)
2484 msgp += sprintf (msgp, "R:%d ", fd);
2486 if (fdp->events & _DBUS_POLLOUT)
2487 msgp += sprintf (msgp, "W:%d ", fd);
2489 msgp += sprintf (msgp, "E:%d\n\t", fd);
2491 // FIXME: more robust code for long msg
2492 // create on heap when msg[] becomes too small
2493 if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
2495 _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
2499 msgp += sprintf (msgp, "\n");
2500 _dbus_verbose ("%s",msg);
2502 for (i = 0; i < n_fds; i++)
2505 DBusPollFD *fdp = &fds[i];
2508 if (fdp->events & _DBUS_POLLIN)
2509 FD_SET (fd, &read_set);
2511 if (fdp->events & _DBUS_POLLOUT)
2512 FD_SET (fd, &write_set);
2514 FD_SET (fd, &err_set);
2516 max_fd = MAX (max_fd, fd);
2520 tv.tv_sec = timeout_milliseconds / 1000;
2521 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2523 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2524 timeout_milliseconds < 0 ? NULL : &tv);
2526 if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
2528 DBUS_SOCKET_SET_ERRNO ();
2529 if (errno != EWOULDBLOCK)
2530 _dbus_verbose ("select: failed: %s\n", _dbus_strerror (errno));
2532 else if (ready == 0)
2533 _dbus_verbose ("select: = 0\n");
2537 #ifdef DBUS_ENABLE_VERBOSE_MODE
2539 msgp += sprintf (msgp, "select: = %d:\n\t", ready);
2541 for (i = 0; i < n_fds; i++)
2544 DBusPollFD *fdp = &fds[i];
2547 if (FD_ISSET (fd, &read_set))
2548 msgp += sprintf (msgp, "R:%d ", fd);
2550 if (FD_ISSET (fd, &write_set))
2551 msgp += sprintf (msgp, "W:%d ", fd);
2553 if (FD_ISSET (fd, &err_set))
2554 msgp += sprintf (msgp, "E:%d\n\t", fd);
2556 msgp += sprintf (msgp, "\n");
2557 _dbus_verbose ("%s",msg);
2560 for (i = 0; i < n_fds; i++)
2563 DBusPollFD *fdp = &fds[i];
2568 if (FD_ISSET (fd, &read_set))
2569 fdp->revents |= _DBUS_POLLIN;
2571 if (FD_ISSET (fd, &write_set))
2572 fdp->revents |= _DBUS_POLLOUT;
2574 if (FD_ISSET (fd, &err_set))
2575 fdp->revents |= _DBUS_POLLERR;
2581 #endif //ENABLE_DBUSSOCKET
2583 #endif // USE_CHRIS_IMPL
2586 /************************************************************************
2590 ************************************************************************/
2594 * Assigns an error name and message corresponding to a Win32 error
2595 * code to a DBusError. Does nothing if error is #NULL.
2597 * @param error the error.
2598 * @param code the Win32 error code
2601 _dbus_win_set_error_from_win_error (DBusError *error,
2606 /* As we want the English message, use the A API */
2607 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
2608 FORMAT_MESSAGE_IGNORE_INSERTS |
2609 FORMAT_MESSAGE_FROM_SYSTEM,
2610 NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
2611 (LPTSTR) &msg, 0, NULL);
2616 msg_copy = dbus_malloc (strlen (msg));
2617 strcpy (msg_copy, msg);
2620 dbus_set_error (error, "win32.error", "%s", msg_copy);
2623 dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code);
2627 _dbus_win_warn_win_error (const char *message,
2632 dbus_error_init (&error);
2633 _dbus_win_set_error_from_win_error (&error, code);
2634 _dbus_warn ("%s: %s\n", message, error.message);
2635 dbus_error_free (&error);
2639 * A wrapper around strerror() because some platforms
2640 * may be lame and not have strerror().
2642 * @param error_number errno.
2643 * @returns error description.
2646 _dbus_strerror (int error_number)
2654 switch (error_number)
2657 return "Interrupted function call";
2659 return "Permission denied";
2661 return "Bad address";
2663 return "Invalid argument";
2665 return "Too many open files";
2666 case WSAEWOULDBLOCK:
2667 return "Resource temporarily unavailable";
2668 case WSAEINPROGRESS:
2669 return "Operation now in progress";
2671 return "Operation already in progress";
2673 return "Socket operation on nonsocket";
2674 case WSAEDESTADDRREQ:
2675 return "Destination address required";
2677 return "Message too long";
2679 return "Protocol wrong type for socket";
2680 case WSAENOPROTOOPT:
2681 return "Bad protocol option";
2682 case WSAEPROTONOSUPPORT:
2683 return "Protocol not supported";
2684 case WSAESOCKTNOSUPPORT:
2685 return "Socket type not supported";
2687 return "Operation not supported";
2688 case WSAEPFNOSUPPORT:
2689 return "Protocol family not supported";
2690 case WSAEAFNOSUPPORT:
2691 return "Address family not supported by protocol family";
2693 return "Address already in use";
2694 case WSAEADDRNOTAVAIL:
2695 return "Cannot assign requested address";
2697 return "Network is down";
2698 case WSAENETUNREACH:
2699 return "Network is unreachable";
2701 return "Network dropped connection on reset";
2702 case WSAECONNABORTED:
2703 return "Software caused connection abort";
2705 return "Connection reset by peer";
2707 return "No buffer space available";
2709 return "Socket is already connected";
2711 return "Socket is not connected";
2713 return "Cannot send after socket shutdown";
2715 return "Connection timed out";
2716 case WSAECONNREFUSED:
2717 return "Connection refused";
2719 return "Host is down";
2720 case WSAEHOSTUNREACH:
2721 return "No route to host";
2723 return "Too many processes";
2725 return "Graceful shutdown in progress";
2726 case WSATYPE_NOT_FOUND:
2727 return "Class type not found";
2728 case WSAHOST_NOT_FOUND:
2729 return "Host not found";
2731 return "Nonauthoritative host not found";
2732 case WSANO_RECOVERY:
2733 return "This is a nonrecoverable error";
2735 return "Valid name, no data record of requested type";
2736 case WSA_INVALID_HANDLE:
2737 return "Specified event object handle is invalid";
2738 case WSA_INVALID_PARAMETER:
2739 return "One or more parameters are invalid";
2740 case WSA_IO_INCOMPLETE:
2741 return "Overlapped I/O event object not in signaled state";
2742 case WSA_IO_PENDING:
2743 return "Overlapped operations will complete later";
2744 case WSA_NOT_ENOUGH_MEMORY:
2745 return "Insufficient memory available";
2746 case WSA_OPERATION_ABORTED:
2747 return "Overlapped operation aborted";
2748 #ifdef WSAINVALIDPROCTABLE
2750 case WSAINVALIDPROCTABLE:
2751 return "Invalid procedure table from service provider";
2753 #ifdef WSAINVALIDPROVIDER
2755 case WSAINVALIDPROVIDER:
2756 return "Invalid service provider version number";
2758 #ifdef WSAPROVIDERFAILEDINIT
2760 case WSAPROVIDERFAILEDINIT:
2761 return "Unable to initialize a service provider";
2764 case WSASYSCALLFAILURE:
2765 return "System call failure";
2767 msg = strerror (error_number);
2777 /* lan manager error codes */
2779 _dbus_lm_strerror(int error_number)
2786 switch (error_number)
2788 case NERR_NetNotStarted:
2789 return "The workstation driver is not installed.";
2790 case NERR_UnknownServer:
2791 return "The server could not be located.";
2793 return "An internal error occurred. The network cannot access a shared memory segment.";
2794 case NERR_NoNetworkResource:
2795 return "A network resource shortage occurred.";
2796 case NERR_RemoteOnly:
2797 return "This operation is not supported on workstations.";
2798 case NERR_DevNotRedirected:
2799 return "The device is not connected.";
2800 case NERR_ServerNotStarted:
2801 return "The Server service is not started.";
2802 case NERR_ItemNotFound:
2803 return "The queue is empty.";
2804 case NERR_UnknownDevDir:
2805 return "The device or directory does not exist.";
2806 case NERR_RedirectedPath:
2807 return "The operation is invalid on a redirected resource.";
2808 case NERR_DuplicateShare:
2809 return "The name has already been shared.";
2811 return "The server is currently out of the requested resource.";
2812 case NERR_TooManyItems:
2813 return "Requested addition of items exceeds the maximum allowed.";
2814 case NERR_InvalidMaxUsers:
2815 return "The Peer service supports only two simultaneous users.";
2816 case NERR_BufTooSmall:
2817 return "The API return buffer is too small.";
2818 case NERR_RemoteErr:
2819 return "A remote API error occurred.";
2820 case NERR_LanmanIniError:
2821 return "An error occurred when opening or reading the configuration file.";
2822 case NERR_NetworkError:
2823 return "A general network error occurred.";
2824 case NERR_WkstaInconsistentState:
2825 return "The Workstation service is in an inconsistent state. Restart the computer before restarting the Workstation service.";
2826 case NERR_WkstaNotStarted:
2827 return "The Workstation service has not been started.";
2828 case NERR_BrowserNotStarted:
2829 return "The requested information is not available.";
2830 case NERR_InternalError:
2831 return "An internal error occurred.";
2832 case NERR_BadTransactConfig:
2833 return "The server is not configured for transactions.";
2834 case NERR_InvalidAPI:
2835 return "The requested API is not supported on the remote server.";
2836 case NERR_BadEventName:
2837 return "The event name is invalid.";
2838 case NERR_DupNameReboot:
2839 return "The computer name already exists on the network. Change it and restart the computer.";
2840 case NERR_CfgCompNotFound:
2841 return "The specified component could not be found in the configuration information.";
2842 case NERR_CfgParamNotFound:
2843 return "The specified parameter could not be found in the configuration information.";
2844 case NERR_LineTooLong:
2845 return "A line in the configuration file is too long.";
2846 case NERR_QNotFound:
2847 return "The printer does not exist.";
2848 case NERR_JobNotFound:
2849 return "The print job does not exist.";
2850 case NERR_DestNotFound:
2851 return "The printer destination cannot be found.";
2852 case NERR_DestExists:
2853 return "The printer destination already exists.";
2855 return "The printer queue already exists.";
2857 return "No more printers can be added.";
2858 case NERR_JobNoRoom:
2859 return "No more print jobs can be added.";
2860 case NERR_DestNoRoom:
2861 return "No more printer destinations can be added.";
2863 return "This printer destination is idle and cannot accept control operations.";
2864 case NERR_DestInvalidOp:
2865 return "This printer destination request contains an invalid control function.";
2866 case NERR_ProcNoRespond:
2867 return "The print processor is not responding.";
2868 case NERR_SpoolerNotLoaded:
2869 return "The spooler is not running.";
2870 case NERR_DestInvalidState:
2871 return "This operation cannot be performed on the print destination in its current state.";
2872 case NERR_QInvalidState:
2873 return "This operation cannot be performed on the printer queue in its current state.";
2874 case NERR_JobInvalidState:
2875 return "This operation cannot be performed on the print job in its current state.";
2876 case NERR_SpoolNoMemory:
2877 return "A spooler memory allocation failure occurred.";
2878 case NERR_DriverNotFound:
2879 return "The device driver does not exist.";
2880 case NERR_DataTypeInvalid:
2881 return "The data type is not supported by the print processor.";
2882 case NERR_ProcNotFound:
2883 return "The print processor is not installed.";
2884 case NERR_ServiceTableLocked:
2885 return "The service database is locked.";
2886 case NERR_ServiceTableFull:
2887 return "The service table is full.";
2888 case NERR_ServiceInstalled:
2889 return "The requested service has already been started.";
2890 case NERR_ServiceEntryLocked:
2891 return "The service does not respond to control actions.";
2892 case NERR_ServiceNotInstalled:
2893 return "The service has not been started.";
2894 case NERR_BadServiceName:
2895 return "The service name is invalid.";
2896 case NERR_ServiceCtlTimeout:
2897 return "The service is not responding to the control function.";
2898 case NERR_ServiceCtlBusy:
2899 return "The service control is busy.";
2900 case NERR_BadServiceProgName:
2901 return "The configuration file contains an invalid service program name.";
2902 case NERR_ServiceNotCtrl:
2903 return "The service could not be controlled in its present state.";
2904 case NERR_ServiceKillProc:
2905 return "The service ended abnormally.";
2906 case NERR_ServiceCtlNotValid:
2907 return "The requested pause or stop is not valid for this service.";
2908 case NERR_NotInDispatchTbl:
2909 return "The service control dispatcher could not find the service name in the dispatch table.";
2910 case NERR_BadControlRecv:
2911 return "The service control dispatcher pipe read failed.";
2912 case NERR_ServiceNotStarting:
2913 return "A thread for the new service could not be created.";
2914 case NERR_AlreadyLoggedOn:
2915 return "This workstation is already logged on to the local-area network.";
2916 case NERR_NotLoggedOn:
2917 return "The workstation is not logged on to the local-area network.";
2918 case NERR_BadUsername:
2919 return "The user name or group name parameter is invalid.";
2920 case NERR_BadPassword:
2921 return "The password parameter is invalid.";
2922 case NERR_UnableToAddName_W:
2923 return "@W The logon processor did not add the message alias.";
2924 case NERR_UnableToAddName_F:
2925 return "The logon processor did not add the message alias.";
2926 case NERR_UnableToDelName_W:
2927 return "@W The logoff processor did not delete the message alias.";
2928 case NERR_UnableToDelName_F:
2929 return "The logoff processor did not delete the message alias.";
2930 case NERR_LogonsPaused:
2931 return "Network logons are paused.";
2932 case NERR_LogonServerConflict:
2933 return "A centralized logon-server conflict occurred.";
2934 case NERR_LogonNoUserPath:
2935 return "The server is configured without a valid user path.";
2936 case NERR_LogonScriptError:
2937 return "An error occurred while loading or running the logon script.";
2938 case NERR_StandaloneLogon:
2939 return "The logon server was not specified. Your computer will be logged on as STANDALONE.";
2940 case NERR_LogonServerNotFound:
2941 return "The logon server could not be found.";
2942 case NERR_LogonDomainExists:
2943 return "There is already a logon domain for this computer.";
2944 case NERR_NonValidatedLogon:
2945 return "The logon server could not validate the logon.";
2946 case NERR_ACFNotFound:
2947 return "The security database could not be found.";
2948 case NERR_GroupNotFound:
2949 return "The group name could not be found.";
2950 case NERR_UserNotFound:
2951 return "The user name could not be found.";
2952 case NERR_ResourceNotFound:
2953 return "The resource name could not be found.";
2954 case NERR_GroupExists:
2955 return "The group already exists.";
2956 case NERR_UserExists:
2957 return "The user account already exists.";
2958 case NERR_ResourceExists:
2959 return "The resource permission list already exists.";
2960 case NERR_NotPrimary:
2961 return "This operation is only allowed on the primary domain controller of the domain.";
2962 case NERR_ACFNotLoaded:
2963 return "The security database has not been started.";
2964 case NERR_ACFNoRoom:
2965 return "There are too many names in the user accounts database.";
2966 case NERR_ACFFileIOFail:
2967 return "A disk I/O failure occurred.";
2968 case NERR_ACFTooManyLists:
2969 return "The limit of 64 entries per resource was exceeded.";
2970 case NERR_UserLogon:
2971 return "Deleting a user with a session is not allowed.";
2972 case NERR_ACFNoParent:
2973 return "The parent directory could not be located.";
2974 case NERR_CanNotGrowSegment:
2975 return "Unable to add to the security database session cache segment.";
2976 case NERR_SpeGroupOp:
2977 return "This operation is not allowed on this special group.";
2978 case NERR_NotInCache:
2979 return "This user is not cached in user accounts database session cache.";
2980 case NERR_UserInGroup:
2981 return "The user already belongs to this group.";
2982 case NERR_UserNotInGroup:
2983 return "The user does not belong to this group.";
2984 case NERR_AccountUndefined:
2985 return "This user account is undefined.";
2986 case NERR_AccountExpired:
2987 return "This user account has expired.";
2988 case NERR_InvalidWorkstation:
2989 return "The user is not allowed to log on from this workstation.";
2990 case NERR_InvalidLogonHours:
2991 return "The user is not allowed to log on at this time.";
2992 case NERR_PasswordExpired:
2993 return "The password of this user has expired.";
2994 case NERR_PasswordCantChange:
2995 return "The password of this user cannot change.";
2996 case NERR_PasswordHistConflict:
2997 return "This password cannot be used now.";
2998 case NERR_PasswordTooShort:
2999 return "The password does not meet the password policy requirements. Check the minimum password length, password complexity and password history requirements.";
3000 case NERR_PasswordTooRecent:
3001 return "The password of this user is too recent to change.";
3002 case NERR_InvalidDatabase:
3003 return "The security database is corrupted.";
3004 case NERR_DatabaseUpToDate:
3005 return "No updates are necessary to this replicant network/local security database.";
3006 case NERR_SyncRequired:
3007 return "This replicant database is outdated; synchronization is required.";
3008 case NERR_UseNotFound:
3009 return "The network connection could not be found.";
3010 case NERR_BadAsgType:
3011 return "This asg_type is invalid.";
3012 case NERR_DeviceIsShared:
3013 return "This device is currently being shared.";
3014 case NERR_NoComputerName:
3015 return "The computer name could not be added as a message alias. The name may already exist on the network.";
3016 case NERR_MsgAlreadyStarted:
3017 return "The Messenger service is already started.";
3018 case NERR_MsgInitFailed:
3019 return "The Messenger service failed to start.";
3020 case NERR_NameNotFound:
3021 return "The message alias could not be found on the network.";
3022 case NERR_AlreadyForwarded:
3023 return "This message alias has already been forwarded.";
3024 case NERR_AddForwarded:
3025 return "This message alias has been added but is still forwarded.";
3026 case NERR_AlreadyExists:
3027 return "This message alias already exists locally.";
3028 case NERR_TooManyNames:
3029 return "The maximum number of added message aliases has been exceeded.";
3030 case NERR_DelComputerName:
3031 return "The computer name could not be deleted.";
3032 case NERR_LocalForward:
3033 return "Messages cannot be forwarded back to the same workstation.";
3034 case NERR_GrpMsgProcessor:
3035 return "An error occurred in the domain message processor.";
3036 case NERR_PausedRemote:
3037 return "The message was sent, but the recipient has paused the Messenger service.";
3038 case NERR_BadReceive:
3039 return "The message was sent but not received.";
3040 case NERR_NameInUse:
3041 return "The message alias is currently in use. Try again later.";
3042 case NERR_MsgNotStarted:
3043 return "The Messenger service has not been started.";
3044 case NERR_NotLocalName:
3045 return "The name is not on the local computer.";
3046 case NERR_NoForwardName:
3047 return "The forwarded message alias could not be found on the network.";
3048 case NERR_RemoteFull:
3049 return "The message alias table on the remote station is full.";
3050 case NERR_NameNotForwarded:
3051 return "Messages for this alias are not currently being forwarded.";
3052 case NERR_TruncatedBroadcast:
3053 return "The broadcast message was truncated.";
3054 case NERR_InvalidDevice:
3055 return "This is an invalid device name.";
3056 case NERR_WriteFault:
3057 return "A write fault occurred.";
3058 case NERR_DuplicateName:
3059 return "A duplicate message alias exists on the network.";
3060 case NERR_DeleteLater:
3061 return "@W This message alias will be deleted later.";
3062 case NERR_IncompleteDel:
3063 return "The message alias was not successfully deleted from all networks.";
3064 case NERR_MultipleNets:
3065 return "This operation is not supported on computers with multiple networks.";
3066 case NERR_NetNameNotFound:
3067 return "This shared resource does not exist.";
3068 case NERR_DeviceNotShared:
3069 return "This device is not shared.";
3070 case NERR_ClientNameNotFound:
3071 return "A session does not exist with that computer name.";
3072 case NERR_FileIdNotFound:
3073 return "There is not an open file with that identification number.";
3074 case NERR_ExecFailure:
3075 return "A failure occurred when executing a remote administration command.";
3077 return "A failure occurred when opening a remote temporary file.";
3078 case NERR_TooMuchData:
3079 return "The data returned from a remote administration command has been truncated to 64K.";
3080 case NERR_DeviceShareConflict:
3081 return "This device cannot be shared as both a spooled and a non-spooled resource.";
3082 case NERR_BrowserTableIncomplete:
3083 return "The information in the list of servers may be incorrect.";
3084 case NERR_NotLocalDomain:
3085 return "The computer is not active in this domain.";
3086 #ifdef NERR_IsDfsShare
3088 case NERR_IsDfsShare:
3089 return "The share must be removed from the Distributed File System before it can be deleted.";
3092 case NERR_DevInvalidOpCode:
3093 return "The operation is invalid for this device.";
3094 case NERR_DevNotFound:
3095 return "This device cannot be shared.";
3096 case NERR_DevNotOpen:
3097 return "This device was not open.";
3098 case NERR_BadQueueDevString:
3099 return "This device name list is invalid.";
3100 case NERR_BadQueuePriority:
3101 return "The queue priority is invalid.";
3102 case NERR_NoCommDevs:
3103 return "There are no shared communication devices.";
3104 case NERR_QueueNotFound:
3105 return "The queue you specified does not exist.";
3106 case NERR_BadDevString:
3107 return "This list of devices is invalid.";
3109 return "The requested device is invalid.";
3110 case NERR_InUseBySpooler:
3111 return "This device is already in use by the spooler.";
3112 case NERR_CommDevInUse:
3113 return "This device is already in use as a communication device.";
3114 case NERR_InvalidComputer:
3115 return "This computer name is invalid.";
3116 case NERR_MaxLenExceeded:
3117 return "The string and prefix specified are too long.";
3118 case NERR_BadComponent:
3119 return "This path component is invalid.";
3121 return "Could not determine the type of input.";
3122 case NERR_TooManyEntries:
3123 return "The buffer for types is not big enough.";
3124 case NERR_ProfileFileTooBig:
3125 return "Profile files cannot exceed 64K.";
3126 case NERR_ProfileOffset:
3127 return "The start offset is out of range.";
3128 case NERR_ProfileCleanup:
3129 return "The system cannot delete current connections to network resources.";
3130 case NERR_ProfileUnknownCmd:
3131 return "The system was unable to parse the command line in this file.";
3132 case NERR_ProfileLoadErr:
3133 return "An error occurred while loading the profile file.";
3134 case NERR_ProfileSaveErr:
3135 return "@W Errors occurred while saving the profile file. The profile was partially saved.";
3136 case NERR_LogOverflow:
3137 return "Log file %1 is full.";
3138 case NERR_LogFileChanged:
3139 return "This log file has changed between reads.";
3140 case NERR_LogFileCorrupt:
3141 return "Log file %1 is corrupt.";
3142 case NERR_SourceIsDir:
3143 return "The source path cannot be a directory.";
3144 case NERR_BadSource:
3145 return "The source path is illegal.";
3147 return "The destination path is illegal.";
3148 case NERR_DifferentServers:
3149 return "The source and destination paths are on different servers.";
3150 case NERR_RunSrvPaused:
3151 return "The Run server you requested is paused.";
3152 case NERR_ErrCommRunSrv:
3153 return "An error occurred when communicating with a Run server.";
3154 case NERR_ErrorExecingGhost:
3155 return "An error occurred when starting a background process.";
3156 case NERR_ShareNotFound:
3157 return "The shared resource you are connected to could not be found.";
3158 case NERR_InvalidLana:
3159 return "The LAN adapter number is invalid.";
3160 case NERR_OpenFiles:
3161 return "There are open files on the connection.";
3162 case NERR_ActiveConns:
3163 return "Active connections still exist.";
3164 case NERR_BadPasswordCore:
3165 return "This share name or password is invalid.";
3167 return "The device is being accessed by an active process.";
3168 case NERR_LocalDrive:
3169 return "The drive letter is in use locally.";
3170 case NERR_AlertExists:
3171 return "The specified client is already registered for the specified event.";
3172 case NERR_TooManyAlerts:
3173 return "The alert table is full.";
3174 case NERR_NoSuchAlert:
3175 return "An invalid or nonexistent alert name was raised.";
3176 case NERR_BadRecipient:
3177 return "The alert recipient is invalid.";
3178 case NERR_AcctLimitExceeded:
3179 return "A user's session with this server has been deleted.";
3180 case NERR_InvalidLogSeek:
3181 return "The log file does not contain the requested record number.";
3182 case NERR_BadUasConfig:
3183 return "The user accounts database is not configured correctly.";
3184 case NERR_InvalidUASOp:
3185 return "This operation is not permitted when the Netlogon service is running.";
3186 case NERR_LastAdmin:
3187 return "This operation is not allowed on the last administrative account.";
3188 case NERR_DCNotFound:
3189 return "Could not find domain controller for this domain.";
3190 case NERR_LogonTrackingError:
3191 return "Could not set logon information for this user.";
3192 case NERR_NetlogonNotStarted:
3193 return "The Netlogon service has not been started.";
3194 case NERR_CanNotGrowUASFile:
3195 return "Unable to add to the user accounts database.";
3196 case NERR_TimeDiffAtDC:
3197 return "This server's clock is not synchronized with the primary domain controller's clock.";
3198 case NERR_PasswordMismatch:
3199 return "A password mismatch has been detected.";
3200 case NERR_NoSuchServer:
3201 return "The server identification does not specify a valid server.";
3202 case NERR_NoSuchSession:
3203 return "The session identification does not specify a valid session.";
3204 case NERR_NoSuchConnection:
3205 return "The connection identification does not specify a valid connection.";
3206 case NERR_TooManyServers:
3207 return "There is no space for another entry in the table of available servers.";
3208 case NERR_TooManySessions:
3209 return "The server has reached the maximum number of sessions it supports.";
3210 case NERR_TooManyConnections:
3211 return "The server has reached the maximum number of connections it supports.";
3212 case NERR_TooManyFiles:
3213 return "The server cannot open more files because it has reached its maximum number.";
3214 case NERR_NoAlternateServers:
3215 return "There are no alternate servers registered on this server.";
3216 case NERR_TryDownLevel:
3217 return "Try down-level (remote admin protocol) version of API instead.";
3218 case NERR_UPSDriverNotStarted:
3219 return "The UPS driver could not be accessed by the UPS service.";
3220 case NERR_UPSInvalidConfig:
3221 return "The UPS service is not configured correctly.";
3222 case NERR_UPSInvalidCommPort:
3223 return "The UPS service could not access the specified Comm Port.";
3224 case NERR_UPSSignalAsserted:
3225 return "The UPS indicated a line fail or low battery situation. Service not started.";
3226 case NERR_UPSShutdownFailed:
3227 return "The UPS service failed to perform a system shut down.";
3228 case NERR_BadDosRetCode:
3229 return "The program below returned an MS-DOS error code:";
3230 case NERR_ProgNeedsExtraMem:
3231 return "The program below needs more memory:";
3232 case NERR_BadDosFunction:
3233 return "The program below called an unsupported MS-DOS function:";
3234 case NERR_RemoteBootFailed:
3235 return "The workstation failed to boot.";
3236 case NERR_BadFileCheckSum:
3237 return "The file below is corrupt.";
3238 case NERR_NoRplBootSystem:
3239 return "No loader is specified in the boot-block definition file.";
3240 case NERR_RplLoadrNetBiosErr:
3241 return "NetBIOS returned an error: The NCB and SMB are dumped above.";
3242 case NERR_RplLoadrDiskErr:
3243 return "A disk I/O error occurred.";
3244 case NERR_ImageParamErr:
3245 return "Image parameter substitution failed.";
3246 case NERR_TooManyImageParams:
3247 return "Too many image parameters cross disk sector boundaries.";
3248 case NERR_NonDosFloppyUsed:
3249 return "The image was not generated from an MS-DOS diskette formatted with /S.";
3250 case NERR_RplBootRestart:
3251 return "Remote boot will be restarted later.";
3252 case NERR_RplSrvrCallFailed:
3253 return "The call to the Remoteboot server failed.";
3254 case NERR_CantConnectRplSrvr:
3255 return "Cannot connect to the Remoteboot server.";
3256 case NERR_CantOpenImageFile:
3257 return "Cannot open image file on the Remoteboot server.";
3258 case NERR_CallingRplSrvr:
3259 return "Connecting to the Remoteboot server...";
3260 case NERR_StartingRplBoot:
3261 return "Connecting to the Remoteboot server...";
3262 case NERR_RplBootServiceTerm:
3263 return "Remote boot service was stopped; check the error log for the cause of the problem.";
3264 case NERR_RplBootStartFailed:
3265 return "Remote boot startup failed; check the error log for the cause of the problem.";
3266 case NERR_RPL_CONNECTED:
3267 return "A second connection to a Remoteboot resource is not allowed.";
3268 case NERR_BrowserConfiguredToNotRun:
3269 return "The browser service was configured with MaintainServerList=No.";
3270 case NERR_RplNoAdaptersStarted:
3271 return "Service failed to start since none of the network adapters started with this service.";
3272 case NERR_RplBadRegistry:
3273 return "Service failed to start due to bad startup information in the registry.";
3274 case NERR_RplBadDatabase:
3275 return "Service failed to start because its database is absent or corrupt.";
3276 case NERR_RplRplfilesShare:
3277 return "Service failed to start because RPLFILES share is absent.";
3278 case NERR_RplNotRplServer:
3279 return "Service failed to start because RPLUSER group is absent.";
3280 case NERR_RplCannotEnum:
3281 return "Cannot enumerate service records.";
3282 case NERR_RplWkstaInfoCorrupted:
3283 return "Workstation record information has been corrupted.";
3284 case NERR_RplWkstaNotFound:
3285 return "Workstation record was not found.";
3286 case NERR_RplWkstaNameUnavailable:
3287 return "Workstation name is in use by some other workstation.";
3288 case NERR_RplProfileInfoCorrupted:
3289 return "Profile record information has been corrupted.";
3290 case NERR_RplProfileNotFound:
3291 return "Profile record was not found.";
3292 case NERR_RplProfileNameUnavailable:
3293 return "Profile name is in use by some other profile.";
3294 case NERR_RplProfileNotEmpty:
3295 return "There are workstations using this profile.";
3296 case NERR_RplConfigInfoCorrupted:
3297 return "Configuration record information has been corrupted.";
3298 case NERR_RplConfigNotFound:
3299 return "Configuration record was not found.";
3300 case NERR_RplAdapterInfoCorrupted:
3301 return "Adapter ID record information has been corrupted.";
3302 case NERR_RplInternal:
3303 return "An internal service error has occurred.";
3304 case NERR_RplVendorInfoCorrupted:
3305 return "Vendor ID record information has been corrupted.";
3306 case NERR_RplBootInfoCorrupted:
3307 return "Boot block record information has been corrupted.";
3308 case NERR_RplWkstaNeedsUserAcct:
3309 return "The user account for this workstation record is missing.";
3310 case NERR_RplNeedsRPLUSERAcct:
3311 return "The RPLUSER local group could not be found.";
3312 case NERR_RplBootNotFound:
3313 return "Boot block record was not found.";
3314 case NERR_RplIncompatibleProfile:
3315 return "Chosen profile is incompatible with this workstation.";
3316 case NERR_RplAdapterNameUnavailable:
3317 return "Chosen network adapter ID is in use by some other workstation.";
3318 case NERR_RplConfigNotEmpty:
3319 return "There are profiles using this configuration.";
3320 case NERR_RplBootInUse:
3321 return "There are workstations, profiles, or configurations using this boot block.";
3322 case NERR_RplBackupDatabase:
3323 return "Service failed to backup Remoteboot database.";
3324 case NERR_RplAdapterNotFound:
3325 return "Adapter record was not found.";
3326 case NERR_RplVendorNotFound:
3327 return "Vendor record was not found.";
3328 case NERR_RplVendorNameUnavailable:
3329 return "Vendor name is in use by some other vendor record.";
3330 case NERR_RplBootNameUnavailable:
3331 return "(boot name, vendor ID) is in use by some other boot block record.";
3332 case NERR_RplConfigNameUnavailable:
3333 return "Configuration name is in use by some other configuration.";
3334 case NERR_DfsInternalCorruption:
3335 return "The internal database maintained by the Dfs service is corrupt.";
3336 case NERR_DfsVolumeDataCorrupt:
3337 return "One of the records in the internal Dfs database is corrupt.";
3338 case NERR_DfsNoSuchVolume:
3339 return "There is no DFS name whose entry path matches the input Entry Path.";
3340 case NERR_DfsVolumeAlreadyExists:
3341 return "A root or link with the given name already exists.";
3342 case NERR_DfsAlreadyShared:
3343 return "The server share specified is already shared in the Dfs.";
3344 case NERR_DfsNoSuchShare:
3345 return "The indicated server share does not support the indicated DFS namespace.";
3346 case NERR_DfsNotALeafVolume:
3347 return "The operation is not valid on this portion of the namespace.";
3348 case NERR_DfsLeafVolume:
3349 return "The operation is not valid on this portion of the namespace.";
3350 case NERR_DfsVolumeHasMultipleServers:
3351 return "The operation is ambiguous because the link has multiple servers.";
3352 case NERR_DfsCantCreateJunctionPoint:
3353 return "Unable to create a link.";
3354 case NERR_DfsServerNotDfsAware:
3355 return "The server is not Dfs Aware.";
3356 case NERR_DfsBadRenamePath:
3357 return "The specified rename target path is invalid.";
3358 case NERR_DfsVolumeIsOffline:
3359 return "The specified DFS link is offline.";
3360 case NERR_DfsNoSuchServer:
3361 return "The specified server is not a server for this link.";
3362 case NERR_DfsCyclicalName:
3363 return "A cycle in the Dfs name was detected.";
3364 case NERR_DfsNotSupportedInServerDfs:
3365 return "The operation is not supported on a server-based Dfs.";
3366 case NERR_DfsDuplicateService:
3367 return "This link is already supported by the specified server-share.";
3368 case NERR_DfsCantRemoveLastServerShare:
3369 return "Can't remove the last server-share supporting this root or link.";
3370 case NERR_DfsVolumeIsInterDfs:
3371 return "The operation is not supported for an Inter-DFS link.";
3372 case NERR_DfsInconsistent:
3373 return "The internal state of the Dfs Service has become inconsistent.";
3374 case NERR_DfsServerUpgraded:
3375 return "The Dfs Service has been installed on the specified server.";
3376 case NERR_DfsDataIsIdentical:
3377 return "The Dfs data being reconciled is identical.";
3378 case NERR_DfsCantRemoveDfsRoot:
3379 return "The DFS root cannot be deleted. Uninstall DFS if required.";
3380 case NERR_DfsChildOrParentInDfs:
3381 return "A child or parent directory of the share is already in a Dfs.";
3382 case NERR_DfsInternalError:
3383 return "Dfs internal error.";
3384 /* the following are not defined in mingw */
3387 case NERR_SetupAlreadyJoined:
3388 return "This machine is already joined to a domain.";
3389 case NERR_SetupNotJoined:
3390 return "This machine is not currently joined to a domain.";
3391 case NERR_SetupDomainController:
3392 return "This machine is a domain controller and cannot be unjoined from a domain.";
3393 case NERR_DefaultJoinRequired:
3394 return "The destination domain controller does not support creating machine accounts in OUs.";
3395 case NERR_InvalidWorkgroupName:
3396 return "The specified workgroup name is invalid.";
3397 case NERR_NameUsesIncompatibleCodePage:
3398 return "The specified computer name is incompatible with the default language used on the domain controller.";
3399 case NERR_ComputerAccountNotFound:
3400 return "The specified computer account could not be found.";
3401 case NERR_PersonalSku:
3402 return "This version of Windows cannot be joined to a domain.";
3403 case NERR_PasswordMustChange:
3404 return "The password must change at the next logon.";
3405 case NERR_AccountLockedOut:
3406 return "The account is locked out.";
3407 case NERR_PasswordTooLong:
3408 return "The password is too long.";
3409 case NERR_PasswordNotComplexEnough:
3410 return "The password does not meet the complexity policy.";
3411 case NERR_PasswordFilterError:
3412 return "The password does not meet the requirements of the password filter DLLs.";
3416 msg = strerror (error_number);
3432 /******************************************************************************
3434 Original CVS version of dbus-sysdeps.c
3436 ******************************************************************************/
3437 /* -*- mode: C; c-file-style: "gnu" -*- */
3438 /* dbus-sysdeps.c Wrappers around system/libc features (internal to D-Bus implementation)
3440 * Copyright (C) 2002, 2003 Red Hat, Inc.
3441 * Copyright (C) 2003 CodeFactory AB
3442 * Copyright (C) 2005 Novell, Inc.
3444 * Licensed under the Academic Free License version 2.1
3446 * This program is free software; you can redistribute it and/or modify
3447 * it under the terms of the GNU General Public License as published by
3448 * the Free Software Foundation; either version 2 of the License, or
3449 * (at your option) any later version.
3451 * This program is distributed in the hope that it will be useful,
3452 * but WITHOUT ANY WARRANTY; without even the implied warranty of
3453 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3454 * GNU General Public License for more details.
3456 * You should have received a copy of the GNU General Public License
3457 * along with this program; if not, write to the Free Software
3458 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3464 * @addtogroup DBusInternalsUtils
3468 int _dbus_mkdir (const char *path,
3471 return _mkdir(path);
3475 * Exit the process, returning the given value.
3477 * @param code the exit code
3480 _dbus_exit (int code)
3486 * Creates a socket and connects to a socket at the given host
3487 * and port. The connection fd is returned, and is set up as
3490 * @param host the host name to connect to, NULL for loopback
3491 * @param port the prot to connect to
3492 * @param error return location for error code
3493 * @returns connection file descriptor or -1 on error
3496 _dbus_connect_tcp_socket (const char *host,
3500 #ifdef ENABLE_DBUSSOCKET
3503 struct sockaddr_in addr;
3505 struct in_addr *haddr;
3508 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3510 _dbus_win_startup_winsock ();
3512 s.fd = socket (AF_INET, SOCK_STREAM, 0);
3514 if (DBUS_SOCKET_IS_INVALID (s.fd))
3516 DBUS_SOCKET_SET_ERRNO ();
3517 dbus_set_error (error,
3518 _dbus_error_from_errno (errno),
3519 "Failed to create socket: %s",
3520 _dbus_strerror (errno));
3528 ina.s_addr = htonl (INADDR_LOOPBACK);
3532 he = gethostbyname (host);
3535 DBUS_SOCKET_SET_ERRNO ();
3536 dbus_set_error (error,
3537 _dbus_error_from_errno (errno),
3538 "Failed to lookup hostname: %s",
3540 DBUS_CLOSE_SOCKET (s.fd);
3544 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
3547 memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr));
3548 addr.sin_family = AF_INET;
3549 addr.sin_port = htons (port);
3551 if (DBUS_SOCKET_API_RETURNS_ERROR
3552 (connect (s.fd, (struct sockaddr*) &addr, sizeof (addr)) < 0))
3554 DBUS_SOCKET_SET_ERRNO ();
3555 dbus_set_error (error,
3556 _dbus_error_from_errno (errno),
3557 "Failed to connect to socket %s:%d %s",
3558 host, port, _dbus_strerror (errno));
3560 DBUS_CLOSE_SOCKET (s.fd);
3566 handle = _dbus_socket_to_handle (&s);
3568 if (!_dbus_set_fd_nonblocking (handle, error))
3570 _dbus_close_socket (handle, NULL);
3579 struct sockaddr_in addr;
3581 struct in_addr *haddr;
3584 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3586 _dbus_win_startup_winsock ();
3588 fd = socket (AF_INET, SOCK_STREAM, 0);
3590 if (DBUS_SOCKET_IS_INVALID (fd))
3592 DBUS_SOCKET_SET_ERRNO ();
3593 dbus_set_error (error,
3594 _dbus_error_from_errno (errno),
3595 "Failed to create socket: %s",
3596 _dbus_strerror (errno));
3604 ina.s_addr = htonl (INADDR_LOOPBACK);
3608 he = gethostbyname (host);
3611 DBUS_SOCKET_SET_ERRNO ();
3612 dbus_set_error (error,
3613 _dbus_error_from_errno (errno),
3614 "Failed to lookup hostname: %s",
3616 DBUS_CLOSE_SOCKET (fd);
3620 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
3623 memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr));
3624 addr.sin_family = AF_INET;
3625 addr.sin_port = htons (port);
3627 if (DBUS_SOCKET_API_RETURNS_ERROR
3628 (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0))
3630 DBUS_SOCKET_SET_ERRNO ();
3631 dbus_set_error (error,
3632 _dbus_error_from_errno (errno),
3633 "Failed to connect to socket %s:%d %s",
3634 host, port, _dbus_strerror (errno));
3636 DBUS_CLOSE_SOCKET (fd);
3642 if (!_dbus_set_fd_nonblocking (fd, error))
3644 _dbus_close_socket (fd, NULL);
3655 _dbus_daemon_init(const char *host, dbus_uint32_t port);
3657 * Creates a socket and binds it to the given port,
3658 * then listens on the socket. The socket is
3659 * set to be nonblocking.
3660 * In case of port=0 a random free port is used and
3661 * returned in the port parameter.
3663 * @param host the interface to listen on, NULL for loopback, empty for any
3664 * @param port the port to listen on, if zero a free port will be used
3665 * @param error return location for errors
3666 * @returns the listening file descriptor or -1 on error
3670 _dbus_listen_tcp_socket (const char *host,
3671 dbus_uint32_t *port,
3672 dbus_bool_t inaddr_any,
3675 #ifdef ENABLE_DBUSSOCKET
3678 struct sockaddr_in addr;
3680 struct in_addr *haddr;
3681 socklen_t len = (socklen_t) sizeof (struct sockaddr);
3685 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3687 _dbus_win_startup_winsock ();
3689 slisten.fd = socket (AF_INET, SOCK_STREAM, 0);
3691 if (DBUS_SOCKET_IS_INVALID (slisten.fd))
3693 DBUS_SOCKET_SET_ERRNO ();
3694 dbus_set_error (error, _dbus_error_from_errno (errno),
3695 "Failed to create socket \"%s:%d\": %s",
3696 host, port, _dbus_strerror (errno));
3702 ina.s_addr = htonl (INADDR_LOOPBACK);
3707 ina.s_addr = htonl (INADDR_ANY);
3712 he = gethostbyname (host);
3715 DBUS_SOCKET_SET_ERRNO ();
3716 dbus_set_error (error,
3717 _dbus_error_from_errno (errno),
3718 "Failed to lookup hostname: %s",
3720 DBUS_CLOSE_SOCKET (slisten.fd);
3724 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
3728 memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
3729 addr.sin_family = AF_INET;
3730 addr.sin_port = htons (*port);
3732 if (bind (slisten.fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
3734 DBUS_SOCKET_SET_ERRNO ();
3735 dbus_set_error (error, _dbus_error_from_errno (errno),
3736 "Failed to bind socket \"%s:%d\": %s",
3737 host, *port, _dbus_strerror (errno));
3738 DBUS_CLOSE_SOCKET (slisten.fd);
3742 if (DBUS_SOCKET_API_RETURNS_ERROR (listen (slisten.fd, 30 /* backlog */)))
3744 DBUS_SOCKET_SET_ERRNO ();
3745 dbus_set_error (error, _dbus_error_from_errno (errno),
3746 "Failed to listen on socket \"%s:%d\": %s",
3747 host, *port, _dbus_strerror (errno));
3748 DBUS_CLOSE_SOCKET (slisten.fd);
3752 getsockname(slisten.fd, (struct sockaddr*) &addr, &len);
3753 *port = (dbus_uint32_t) ntohs(addr.sin_port);
3755 _dbus_daemon_init(host, ntohs(addr.sin_port));
3757 handle = _dbus_socket_to_handle (&slisten);
3759 if (!_dbus_set_fd_nonblocking (handle, error))
3761 _dbus_close_socket (handle, NULL);
3768 struct sockaddr_in addr;
3770 struct in_addr *haddr;
3771 socklen_t len = (socklen_t) sizeof (struct sockaddr);
3775 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3777 _dbus_win_startup_winsock ();
3779 fd = socket (AF_INET, SOCK_STREAM, 0);
3781 if (DBUS_SOCKET_IS_INVALID (fd))
3783 DBUS_SOCKET_SET_ERRNO ();
3784 dbus_set_error (error, _dbus_error_from_errno (errno),
3785 "Failed to create socket \"%s:%d\": %s",
3786 host, port, _dbus_strerror (errno));
3792 ina.s_addr = htonl (INADDR_LOOPBACK);
3797 ina.s_addr = htonl (INADDR_ANY);
3802 he = gethostbyname (host);
3805 DBUS_SOCKET_SET_ERRNO ();
3806 dbus_set_error (error,
3807 _dbus_error_from_errno (errno),
3808 "Failed to lookup hostname: %s",
3810 DBUS_CLOSE_SOCKET (fd);
3814 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
3818 memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
3819 addr.sin_family = AF_INET;
3820 addr.sin_port = htons (*port);
3822 if (bind (fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
3824 DBUS_SOCKET_SET_ERRNO ();
3825 dbus_set_error (error, _dbus_error_from_errno (errno),
3826 "Failed to bind socket \"%s:%d\": %s",
3827 host, *port, _dbus_strerror (errno));
3828 DBUS_CLOSE_SOCKET (fd);
3832 if (DBUS_SOCKET_API_RETURNS_ERROR (listen (fd, 30 /* backlog */)))
3834 DBUS_SOCKET_SET_ERRNO ();
3835 dbus_set_error (error, _dbus_error_from_errno (errno),
3836 "Failed to listen on socket \"%s:%d\": %s",
3837 host, *port, _dbus_strerror (errno));
3838 DBUS_CLOSE_SOCKET (fd);
3842 getsockname(fd, (struct sockaddr*) &addr, &len);
3843 *port = (dbus_uint32_t) ntohs(addr.sin_port);
3845 _dbus_daemon_init(host, ntohs(addr.sin_port));
3847 if (!_dbus_set_fd_nonblocking (fd, error))
3849 _dbus_close_socket (fd, NULL);
3859 * Accepts a connection on a listening socket.
3860 * Handles EINTR for you.
3862 * @param listen_fd the listen file descriptor
3863 * @returns the connection fd of the client, or -1 on error
3866 _dbus_accept (int listen_handle)
3868 #ifdef ENABLE_DBUSSOCKET
3869 DBusSocket *slisten;
3871 struct sockaddr addr;
3874 _dbus_handle_to_socket(listen_handle, &slisten);
3876 addrlen = sizeof (addr);
3878 //FIXME: why do we not try it again on Windows?
3879 #if !defined(DBUS_WIN) && !defined(DBUS_WINCE)
3883 sclient.fd = accept (slisten->fd, &addr, &addrlen);
3885 if (DBUS_SOCKET_IS_INVALID (sclient.fd))
3887 DBUS_SOCKET_SET_ERRNO ();
3888 #if !defined(DBUS_WIN) && !defined(DBUS_WINCE)
3896 return _dbus_socket_to_handle (&sclient);
3900 struct sockaddr addr;
3905 addrlen = sizeof (addr);
3907 //FIXME: why do we not try it again on Windows?
3908 #if !defined(DBUS_WIN) && !defined(DBUS_WINCE)
3912 sclient = accept (fd, &addr, &addrlen);
3914 if (DBUS_SOCKET_IS_INVALID (sclient))
3916 DBUS_SOCKET_SET_ERRNO ();
3917 #if !defined(DBUS_WIN) && !defined(DBUS_WINCE)
3933 _dbus_send_credentials_socket (int handle,
3936 /* FIXME: for the session bus credentials shouldn't matter (?), but
3937 * for the system bus they are presumably essential. A rough outline
3938 * of a way to implement the credential transfer would be this:
3940 * client waits to *read* a byte.
3942 * server creates a named pipe with a random name, sends a byte
3943 * contining its length, and its name.
3945 * client reads the name, connects to it (using Win32 API).
3947 * server waits for connection to the named pipe, then calls
3948 * ImpersonateNamedPipeClient(), notes its now-current credentials,
3949 * calls RevertToSelf(), closes its handles to the named pipe, and
3950 * is done. (Maybe there is some other way to get the SID of a named
3951 * pipe client without having to use impersonation?)
3953 * client closes its handles and is done.
3955 * Ralf: Why not sending credentials over the given this connection ?
3956 * Using named pipes makes it impossible to be connected from a unix client.
3962 _dbus_string_init_const_len (&buf, "\0", 1);
3964 bytes_written = _dbus_write_socket (handle, &buf, 0, 1 );
3966 if (bytes_written < 0 && errno == EINTR)
3969 if (bytes_written < 0)
3971 dbus_set_error (error, _dbus_error_from_errno (errno),
3972 "Failed to write credentials byte: %s",
3973 _dbus_strerror (errno));
3976 else if (bytes_written == 0)
3978 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
3979 "wrote zero bytes writing credentials byte");
3984 _dbus_assert (bytes_written == 1);
3985 _dbus_verbose ("wrote 1 zero byte, credential sending isn't implemented yet\n");
3992 * Gets the credentials of the current process.
3994 * @param credentials credentials to fill in.
3997 _dbus_credentials_from_current_process (DBusCredentials *credentials)
3999 credentials->pid = _dbus_getpid ();
4000 credentials->uid = _dbus_getuid ();
4001 credentials->gid = _dbus_getgid ();
4005 * Reads a single byte which must be nul (an error occurs otherwise),
4006 * and reads unix credentials if available. Fills in pid/uid/gid with
4007 * -1 if no credentials are available. Return value indicates whether
4008 * a byte was read, not whether we got valid credentials. On some
4009 * systems, such as Linux, reading/writing the byte isn't actually
4010 * required, but we do it anyway just to avoid multiple codepaths.
4012 * Fails if no byte is available, so you must select() first.
4014 * The point of the byte is that on some systems we have to
4015 * use sendmsg()/recvmsg() to transmit credentials.
4017 * @param client_fd the client file descriptor
4018 * @param credentials struct to fill with credentials of client
4019 * @param error location to store error code
4020 * @returns #TRUE on success
4023 _dbus_read_credentials_socket (int handle,
4024 DBusCredentials *credentials,
4029 _dbus_string_init(&buf);
4031 bytes_read = _dbus_read_socket(handle, &buf, 1 );
4034 _dbus_verbose("got one zero byte from server");
4037 _dbus_string_free(&buf);
4038 _dbus_credentials_from_current_process (credentials);
4039 _dbus_verbose("FIXME: get faked credentials from current process");
4045 * Checks to make sure the given directory is
4046 * private to the user
4048 * @param dir the name of the directory
4049 * @param error error return
4050 * @returns #FALSE on failure
4053 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
4055 const char *directory;
4058 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4063 #ifdef ENABLE_DBUSUSERINFO
4065 fill_user_info (DBusUserInfo *info,
4067 const DBusString *username,
4070 const char *username_c;
4072 /* exactly one of username/uid provided */
4073 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
4074 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
4076 info->uid = DBUS_UID_UNSET;
4077 info->primary_gid = DBUS_GID_UNSET;
4078 info->group_ids = NULL;
4079 info->n_group_ids = 0;
4080 info->username = NULL;
4081 info->homedir = NULL;
4083 if (username != NULL)
4084 username_c = _dbus_string_get_const_data (username);
4088 if (uid != DBUS_UID_UNSET)
4090 if (!fill_win_user_info_from_uid (uid, info, error))
4092 _dbus_verbose("%s after fill_win_user_info_from_uid\n",__FUNCTION__);
4098 wchar_t *wname = _dbus_win_utf8_to_utf16 (username_c, error);
4103 if (!fill_win_user_info_from_name (wname, info, error))
4114 * Gets user info for the given user ID.
4116 * @param info user info object to initialize
4117 * @param uid the user ID
4118 * @param error error return
4119 * @returns #TRUE on success
4122 _dbus_user_info_fill_uid (DBusUserInfo *info,
4126 return fill_user_info (info, uid,
4132 * Gets user info for the given username.
4134 * @param info user info object to initialize
4135 * @param username the username
4136 * @param error error return
4137 * @returns #TRUE on success
4140 _dbus_user_info_fill (DBusUserInfo *info,
4141 const DBusString *username,
4144 return fill_user_info (info, DBUS_UID_UNSET,
4150 * Appends the given filename to the given directory.
4152 * @todo it might be cute to collapse multiple '/' such as "foo//"
4155 * @param dir the directory name
4156 * @param next_component the filename
4157 * @returns #TRUE on success
4160 _dbus_concat_dir_and_file (DBusString *dir,
4161 const DBusString *next_component)
4163 dbus_bool_t dir_ends_in_slash;
4164 dbus_bool_t file_starts_with_slash;
4166 if (_dbus_string_get_length (dir) == 0 ||
4167 _dbus_string_get_length (next_component) == 0)
4171 ('/' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1) ||
4172 '\\' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1));
4174 file_starts_with_slash =
4175 ('/' == _dbus_string_get_byte (next_component, 0) ||
4176 '\\' == _dbus_string_get_byte (next_component, 0));
4178 if (dir_ends_in_slash && file_starts_with_slash)
4180 _dbus_string_shorten (dir, 1);
4182 else if (!(dir_ends_in_slash || file_starts_with_slash))
4184 if (!_dbus_string_append_byte (dir, '\\'))
4188 return _dbus_string_copy (next_component, 0, dir,
4189 _dbus_string_get_length (dir));
4193 * Adds the credentials of the current process to the
4194 * passed-in credentials object.
4196 * @param credentials credentials to add to
4197 * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
4201 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
4203 credentials->pid = _dbus_getpid();
4204 credentials->uid = _dbus_getuid();
4210 * Gets a UID from a UID string.
4212 * @param uid_str the UID in string form
4213 * @param uid UID to fill in
4214 * @returns #TRUE if successfully filled in UID
4217 _dbus_parse_uid (const DBusString *uid_str,
4223 if (_dbus_string_get_length (uid_str) == 0)
4225 _dbus_verbose ("UID string was zero length\n");
4231 if (!_dbus_string_parse_int (uid_str, 0, &val,
4234 _dbus_verbose ("could not parse string as a UID\n");
4238 if (end != _dbus_string_get_length (uid_str))
4240 _dbus_verbose ("string contained trailing stuff after UID\n");
4250 * Parses a desired identity provided from a client in the auth protocol.
4251 * On UNIX this means parsing a UID.
4253 * @todo this is broken because it treats OOM and parse error
4254 * the same way. Needs a #DBusError.
4256 * @param credentials the credentials to add what we parse to
4257 * @param desired_identity the string to parse
4258 * @returns #TRUE if we successfully parsed something
4261 _dbus_credentials_parse_and_add_desired (DBusCredentials *credentials,
4262 const DBusString *desired_identity)
4266 if (!_dbus_parse_uid (desired_identity, &uid))
4269 if (!_dbus_credentials_add_unix_uid (credentials, uid))
4276 * Adds the credentials corresponding to the given username.
4278 * @param credentials credentials to fill in
4279 * @param username the username
4280 * @returns #TRUE if the username existed and we got some credentials
4283 _dbus_credentials_add_from_user (DBusCredentials *credentials,
4284 const DBusString *username)
4286 _dbus_verbose("_dbus_credentials_add_from_user is not implemented");
4291 * Append to the string the identity we would like to have when we
4292 * authenticate, on UNIX this is the current process UID and on
4293 * Windows something else, probably a Windows SID string. No escaping
4294 * is required, that is done in dbus-auth.c. The username here
4295 * need not be anything human-readable, it can be the machine-readable
4296 * form i.e. a user id.
4298 * @param str the string to append to
4299 * @returns #FALSE on no memory
4302 _dbus_append_user_from_current_process (DBusString *str)
4304 return _dbus_string_append_uint (str,
4309 * Gets the home directory for the given user.
4311 * @param username the username
4312 * @param homedir string to append home directory to
4313 * @returns #TRUE if user existed and we appended their homedir
4316 _dbus_homedir_from_username (const DBusString *username,
4317 DBusString *homedir)
4319 _dbus_string_append (homedir, "/");
4324 * Gets homedir of user owning current process. The returned string
4325 * is valid until dbus_shutdown() is called.
4327 * @param homedir place to store pointer to homedir
4328 * @returns #FALSE if no memory
4331 _dbus_homedir_from_current_process (const DBusString **homedir)
4333 char *s = getenv("HOMEPATH");
4335 _dbus_string_init(dir);
4336 _dbus_string_append (dir, s);
4342 * Append to the string the identity we would like to have when we authenticate,
4343 * on UNIX this is the current process UID and on Windows something else.
4344 * No escaping is required, that is done in dbus-auth.c.
4346 * @param str the string to append to
4347 * @returns #FALSE on no memory
4350 _dbus_append_desired_identity (DBusString *str)
4353 return _dbus_string_append_uint (str,
4358 * Gets our process ID
4359 * @returns process ID
4364 return GetCurrentProcessId ();
4367 /** nanoseconds in a second */
4368 #define NANOSECONDS_PER_SECOND 1000000000
4369 /** microseconds in a second */
4370 #define MICROSECONDS_PER_SECOND 1000000
4371 /** milliseconds in a second */
4372 #define MILLISECONDS_PER_SECOND 1000
4373 /** nanoseconds in a millisecond */
4374 #define NANOSECONDS_PER_MILLISECOND 1000000
4375 /** microseconds in a millisecond */
4376 #define MICROSECONDS_PER_MILLISECOND 1000
4379 * Sleeps the given number of milliseconds.
4380 * @param milliseconds number of milliseconds
4383 _dbus_sleep_milliseconds (int milliseconds)
4385 Sleep (milliseconds);
4390 * Get current time, as in gettimeofday().
4392 * @param tv_sec return location for number of seconds
4393 * @param tv_usec return location for number of microseconds
4396 _dbus_get_current_time (long *tv_sec,
4400 dbus_uint64_t *time64 = (dbus_uint64_t *) &ft;
4402 GetSystemTimeAsFileTime (&ft);
4404 /* Convert from 100s of nanoseconds since 1601-01-01
4405 * to Unix epoch. Yes, this is Y2038 unsafe.
4407 *time64 -= DBUS_INT64_CONSTANT (116444736000000000);
4411 *tv_sec = *time64 / 1000000;
4414 *tv_usec = *time64 % 1000000;
4419 * signal (SIGPIPE, SIG_IGN);
4422 _dbus_disable_sigpipe (void)
4424 _dbus_verbose("FIXME: implement _dbus_disable_sigpipe (void)\n");
4429 * Appends the contents of the given file to the string,
4430 * returning error code. At the moment, won't open a file
4431 * more than a megabyte in size.
4433 * @param str the string to append to
4434 * @param filename filename to load
4435 * @param error place to set an error
4436 * @returns #FALSE if error was set
4439 _dbus_file_get_contents (DBusString *str,
4440 const DBusString *filename,
4447 const char *filename_c;
4449 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4451 filename_c = _dbus_string_get_const_data (filename);
4453 /* O_BINARY useful on Cygwin and Win32 */
4454 if (!_dbus_file_open (&file, filename_c, O_RDONLY | O_BINARY, -1))
4456 dbus_set_error (error, _dbus_error_from_errno (errno),
4457 "Failed to open \"%s\": %s",
4459 _dbus_strerror (errno));
4463 if (!_dbus_fstat (&file, &sb))
4465 dbus_set_error (error, _dbus_error_from_errno (errno),
4466 "Failed to stat \"%s\": %s",
4468 _dbus_strerror (errno));
4470 _dbus_verbose ("fstat() failed: %s",
4471 _dbus_strerror (errno));
4473 _dbus_file_close (&file, NULL);
4478 if (sb.st_size > _DBUS_ONE_MEGABYTE)
4480 dbus_set_error (error, DBUS_ERROR_FAILED,
4481 "File size %lu of \"%s\" is too large.",
4482 (unsigned long) sb.st_size, filename_c);
4483 _dbus_file_close (&file, NULL);
4488 orig_len = _dbus_string_get_length (str);
4489 if (sb.st_size > 0 && S_ISREG (sb.st_mode))
4493 while (total < (int) sb.st_size)
4495 bytes_read = _dbus_file_read (&file, str,
4496 sb.st_size - total);
4497 if (bytes_read <= 0)
4499 dbus_set_error (error, _dbus_error_from_errno (errno),
4500 "Error reading \"%s\": %s",
4502 _dbus_strerror (errno));
4504 _dbus_verbose ("read() failed: %s",
4505 _dbus_strerror (errno));
4507 _dbus_file_close (&file, NULL);
4508 _dbus_string_set_length (str, orig_len);
4512 total += bytes_read;
4515 _dbus_file_close (&file, NULL);
4518 else if (sb.st_size != 0)
4520 _dbus_verbose ("Can only open regular files at the moment.\n");
4521 dbus_set_error (error, DBUS_ERROR_FAILED,
4522 "\"%s\" is not a regular file",
4524 _dbus_file_close (&file, NULL);
4529 _dbus_file_close (&file, NULL);
4535 * Writes a string out to a file. If the file exists,
4536 * it will be atomically overwritten by the new data.
4538 * @param str the string to write out
4539 * @param filename the file to save string to
4540 * @param error error to be filled in on failure
4541 * @returns #FALSE on failure
4544 _dbus_string_save_to_file (const DBusString *str,
4545 const DBusString *filename,
4550 const char *filename_c;
4551 DBusString tmp_filename;
4552 const char *tmp_filename_c;
4554 dbus_bool_t need_unlink;
4557 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4560 need_unlink = FALSE;
4562 if (!_dbus_string_init (&tmp_filename))
4564 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4568 if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
4570 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4571 _dbus_string_free (&tmp_filename);
4575 if (!_dbus_string_append (&tmp_filename, "."))
4577 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4578 _dbus_string_free (&tmp_filename);
4582 #define N_TMP_FILENAME_RANDOM_BYTES 8
4583 if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
4585 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
4586 _dbus_string_free (&tmp_filename);
4590 filename_c = _dbus_string_get_const_data (filename);
4591 tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
4593 if (!_dbus_file_open (&file, tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
4596 dbus_set_error (error, _dbus_error_from_errno (errno),
4597 "Could not create %s: %s", tmp_filename_c,
4598 _dbus_strerror (errno));
4605 bytes_to_write = _dbus_string_get_length (str);
4607 while (total < bytes_to_write)
4611 bytes_written = _dbus_file_write (&file, str, total,
4612 bytes_to_write - total);
4614 if (bytes_written <= 0)
4616 dbus_set_error (error, _dbus_error_from_errno (errno),
4617 "Could not write to %s: %s", tmp_filename_c,
4618 _dbus_strerror (errno));
4623 total += bytes_written;
4626 if (!_dbus_file_close (&file, NULL))
4628 dbus_set_error (error, _dbus_error_from_errno (errno),
4629 "Could not close file %s: %s",
4630 tmp_filename_c, _dbus_strerror (errno));
4636 if ((unlink (filename_c) == -1 && errno != ENOENT) ||
4637 rename (tmp_filename_c, filename_c) < 0)
4639 dbus_set_error (error, _dbus_error_from_errno (errno),
4640 "Could not rename %s to %s: %s",
4641 tmp_filename_c, filename_c,
4642 _dbus_strerror (errno));
4647 need_unlink = FALSE;
4652 /* close first, then unlink, to prevent ".nfs34234235" garbage
4656 if (_dbus_is_valid_file(&file))
4657 _dbus_file_close (&file, NULL);
4659 if (need_unlink && unlink (tmp_filename_c) < 0)
4660 _dbus_verbose ("Failed to unlink temp file %s: %s\n",
4661 tmp_filename_c, _dbus_strerror (errno));
4663 _dbus_string_free (&tmp_filename);
4666 _DBUS_ASSERT_ERROR_IS_SET (error);
4672 /** Creates the given file, failing if the file already exists.
4674 * @param filename the filename
4675 * @param error error location
4676 * @returns #TRUE if we created the file and it didn't exist
4679 _dbus_create_file_exclusively (const DBusString *filename,
4683 const char *filename_c;
4685 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4687 filename_c = _dbus_string_get_const_data (filename);
4689 if (!_dbus_file_open (&file, filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
4692 dbus_set_error (error,
4694 "Could not create file %s: %s\n",
4696 _dbus_strerror (errno));
4700 if (!_dbus_file_close (&file, NULL))
4702 dbus_set_error (error,
4704 "Could not close file %s: %s\n",
4706 _dbus_strerror (errno));
4715 * Creates a directory; succeeds if the directory
4716 * is created or already existed.
4718 * @param filename directory filename
4719 * @param error initialized error object
4720 * @returns #TRUE on success
4723 _dbus_create_directory (const DBusString *filename,
4726 const char *filename_c;
4728 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4730 filename_c = _dbus_string_get_const_data (filename);
4732 if (_dbus_mkdir (filename_c, 0700) < 0)
4734 if (errno == EEXIST)
4737 dbus_set_error (error, DBUS_ERROR_FAILED,
4738 "Failed to create directory %s: %s\n",
4739 filename_c, _dbus_strerror (errno));
4748 pseudorandom_generate_random_bytes_buffer (char *buffer,
4754 /* fall back to pseudorandom */
4755 _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
4758 _dbus_get_current_time (NULL, &tv_usec);
4768 b = (r / (double) RAND_MAX) * 255.0;
4777 pseudorandom_generate_random_bytes (DBusString *str,
4783 old_len = _dbus_string_get_length (str);
4785 if (!_dbus_string_lengthen (str, n_bytes))
4788 p = _dbus_string_get_data_len (str, old_len, n_bytes);
4790 pseudorandom_generate_random_bytes_buffer (p, n_bytes);
4796 * Gets the temporary files directory by inspecting the environment variables
4797 * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
4799 * @returns location of temp directory
4802 _dbus_get_tmpdir(void)
4804 static const char* tmpdir = NULL;
4809 tmpdir = getenv("TMP");
4811 tmpdir = getenv("TEMP");
4813 tmpdir = getenv("TMPDIR");
4815 tmpdir = "C:\\Temp";
4818 _dbus_assert(tmpdir != NULL);
4825 * Deletes the given file.
4827 * @param filename the filename
4828 * @param error error location
4830 * @returns #TRUE if unlink() succeeded
4833 _dbus_delete_file (const DBusString *filename,
4836 const char *filename_c;
4838 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4840 filename_c = _dbus_string_get_const_data (filename);
4842 if (unlink (filename_c) < 0)
4844 dbus_set_error (error, DBUS_ERROR_FAILED,
4845 "Failed to delete file %s: %s\n",
4846 filename_c, _dbus_strerror (errno));
4854 * Generates the given number of random bytes,
4855 * using the best mechanism we can come up with.
4857 * @param str the string
4858 * @param n_bytes the number of random bytes to append to string
4859 * @returns #TRUE on success, #FALSE if no memory
4862 _dbus_generate_random_bytes (DBusString *str,
4865 return pseudorandom_generate_random_bytes (str, n_bytes);
4868 #if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_BUILD_TESTS)
4880 * Backtrace Generator
4882 * Copyright 2004 Eric Poech
4883 * Copyright 2004 Robert Shearman
4885 * This library is free software; you can redistribute it and/or
4886 * modify it under the terms of the GNU Lesser General Public
4887 * License as published by the Free Software Foundation; either
4888 * version 2.1 of the License, or (at your option) any later version.
4890 * This library is distributed in the hope that it will be useful,
4891 * but WITHOUT ANY WARRANTY; without even the implied warranty of
4892 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4893 * Lesser General Public License for more details.
4895 * You should have received a copy of the GNU Lesser General Public
4896 * License along with this library; if not, write to the Free Software
4897 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4901 #include <imagehlp.h>
4904 #define DPRINTF _dbus_warn
4912 //#define MAKE_FUNCPTR(f) static typeof(f) * p##f
4914 //MAKE_FUNCPTR(StackWalk);
4915 //MAKE_FUNCPTR(SymGetModuleBase);
4916 //MAKE_FUNCPTR(SymFunctionTableAccess);
4917 //MAKE_FUNCPTR(SymInitialize);
4918 //MAKE_FUNCPTR(SymGetSymFromAddr);
4919 //MAKE_FUNCPTR(SymGetModuleInfo);
4920 static BOOL (WINAPI *pStackWalk)(
4924 LPSTACKFRAME StackFrame,
4925 PVOID ContextRecord,
4926 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
4927 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
4928 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
4929 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
4931 static DWORD (WINAPI *pSymGetModuleBase)(
4935 static PVOID (WINAPI *pSymFunctionTableAccess)(
4939 static BOOL (WINAPI *pSymInitialize)(
4941 PSTR UserSearchPath,
4944 static BOOL (WINAPI *pSymGetSymFromAddr)(
4947 PDWORD Displacement,
4948 PIMAGEHLP_SYMBOL Symbol
4950 static BOOL (WINAPI *pSymGetModuleInfo)(
4953 PIMAGEHLP_MODULE ModuleInfo
4955 static DWORD (WINAPI *pSymSetOptions)(
4960 static BOOL init_backtrace()
4962 HMODULE hmodDbgHelp = LoadLibraryA("dbghelp");
4964 #define GETFUNC(x) \
4965 p##x = (typeof(x)*)GetProcAddress(hmodDbgHelp, #x); \
4973 // GETFUNC(StackWalk);
4974 // GETFUNC(SymGetModuleBase);
4975 // GETFUNC(SymFunctionTableAccess);
4976 // GETFUNC(SymInitialize);
4977 // GETFUNC(SymGetSymFromAddr);
4978 // GETFUNC(SymGetModuleInfo);
4982 pStackWalk = (BOOL (WINAPI *)(
4986 LPSTACKFRAME StackFrame,
4987 PVOID ContextRecord,
4988 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
4989 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
4990 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
4991 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
4992 ))GetProcAddress (hmodDbgHelp, FUNC(StackWalk));
4993 pSymGetModuleBase=(DWORD (WINAPI *)(
4996 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
4997 pSymFunctionTableAccess=(PVOID (WINAPI *)(
5000 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
5001 pSymInitialize = (BOOL (WINAPI *)(
5003 PSTR UserSearchPath,
5005 ))GetProcAddress (hmodDbgHelp, FUNC(SymInitialize));
5006 pSymGetSymFromAddr = (BOOL (WINAPI *)(
5009 PDWORD Displacement,
5010 PIMAGEHLP_SYMBOL Symbol
5011 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetSymFromAddr));
5012 pSymGetModuleInfo = (BOOL (WINAPI *)(
5015 PIMAGEHLP_MODULE ModuleInfo
5016 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleInfo));
5017 pSymSetOptions = (DWORD (WINAPI *)(
5019 ))GetProcAddress (hmodDbgHelp, FUNC(SymSetOptions));
5022 pSymSetOptions(SYMOPT_UNDNAME);
5024 pSymInitialize(GetCurrentProcess(), NULL, TRUE);
5029 static void dump_backtrace_for_thread(HANDLE hThread)
5036 if (!init_backtrace())
5039 /* can't use this function for current thread as GetThreadContext
5040 * doesn't support getting context from current thread */
5041 if (hThread == GetCurrentThread())
5044 DPRINTF("Backtrace:\n");
5046 memset(&context, 0, sizeof(context));
5047 context.ContextFlags = CONTEXT_FULL;
5049 SuspendThread(hThread);
5051 if (!GetThreadContext(hThread, &context))
5053 DPRINTF("Couldn't get thread context (error %ld)\n", GetLastError());
5054 ResumeThread(hThread);
5058 memset(&sf, 0, sizeof(sf));
5061 sf.AddrFrame.Offset = context.Ebp;
5062 sf.AddrFrame.Mode = AddrModeFlat;
5063 sf.AddrPC.Offset = context.Eip;
5064 sf.AddrPC.Mode = AddrModeFlat;
5065 dwImageType = IMAGE_FILE_MACHINE_I386;
5067 # error You need to fill in the STACKFRAME structure for your architecture
5070 while (pStackWalk(dwImageType, GetCurrentProcess(),
5071 hThread, &sf, &context, NULL, pSymFunctionTableAccess,
5072 pSymGetModuleBase, NULL))
5075 IMAGEHLP_SYMBOL * pSymbol = (IMAGEHLP_SYMBOL *)buffer;
5076 DWORD dwDisplacement;
5078 pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
5079 pSymbol->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1;
5081 if (!pSymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset,
5082 &dwDisplacement, pSymbol))
5084 IMAGEHLP_MODULE ModuleInfo;
5085 ModuleInfo.SizeOfStruct = sizeof(ModuleInfo);
5087 if (!pSymGetModuleInfo(GetCurrentProcess(), sf.AddrPC.Offset,
5089 DPRINTF("1\t%p\n", (void*)sf.AddrPC.Offset);
5091 DPRINTF("2\t%s+0x%lx\n", ModuleInfo.ImageName,
5092 sf.AddrPC.Offset - ModuleInfo.BaseOfImage);
5094 else if (dwDisplacement)
5095 DPRINTF("3\t%s+0x%lx\n", pSymbol->Name, dwDisplacement);
5097 DPRINTF("4\t%s\n", pSymbol->Name);
5100 ResumeThread(hThread);
5103 static DWORD WINAPI dump_thread_proc(LPVOID lpParameter)
5105 dump_backtrace_for_thread((HANDLE)lpParameter);
5109 /* cannot get valid context from current thread, so we have to execute
5110 * backtrace from another thread */
5111 static void dump_backtrace()
5113 HANDLE hCurrentThread;
5116 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
5117 GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
5118 hThread = CreateThread(NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread,
5120 WaitForSingleObject(hThread, INFINITE);
5121 CloseHandle(hThread);
5122 CloseHandle(hCurrentThread);
5125 void _dbus_print_backtrace(void)
5131 void _dbus_print_backtrace(void)
5133 _dbus_verbose (" D-Bus not compiled with backtrace support\n");
5137 static dbus_uint32_t fromAscii(char ascii)
5139 if(ascii >= '0' && ascii <= '9')
5141 if(ascii >= 'A' && ascii <= 'F')
5142 return ascii - 'A' + 10;
5143 if(ascii >= 'a' && ascii <= 'f')
5144 return ascii - 'a' + 10;
5148 dbus_bool_t _dbus_read_local_machine_uuid (DBusGUID *machine_id,
5149 dbus_bool_t create_if_not_found,
5156 HW_PROFILE_INFOA info;
5157 char *lpc = &info.szHwProfileGuid[0];
5160 // the hw-profile guid lives long enough
5161 if(!GetCurrentHwProfileA(&info))
5163 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); // FIXME
5167 // Form: {12340001-4980-1920-6788-123456789012}
5170 u = ((fromAscii(lpc[0]) << 0) |
5171 (fromAscii(lpc[1]) << 4) |
5172 (fromAscii(lpc[2]) << 8) |
5173 (fromAscii(lpc[3]) << 12) |
5174 (fromAscii(lpc[4]) << 16) |
5175 (fromAscii(lpc[5]) << 20) |
5176 (fromAscii(lpc[6]) << 24) |
5177 (fromAscii(lpc[7]) << 28));
5178 machine_id->as_uint32s[0] = u;
5182 u = ((fromAscii(lpc[0]) << 0) |
5183 (fromAscii(lpc[1]) << 4) |
5184 (fromAscii(lpc[2]) << 8) |
5185 (fromAscii(lpc[3]) << 12) |
5186 (fromAscii(lpc[5]) << 16) |
5187 (fromAscii(lpc[6]) << 20) |
5188 (fromAscii(lpc[7]) << 24) |
5189 (fromAscii(lpc[8]) << 28));
5190 machine_id->as_uint32s[1] = u;
5194 u = ((fromAscii(lpc[0]) << 0) |
5195 (fromAscii(lpc[1]) << 4) |
5196 (fromAscii(lpc[2]) << 8) |
5197 (fromAscii(lpc[3]) << 12) |
5198 (fromAscii(lpc[5]) << 16) |
5199 (fromAscii(lpc[6]) << 20) |
5200 (fromAscii(lpc[7]) << 24) |
5201 (fromAscii(lpc[8]) << 28));
5202 machine_id->as_uint32s[2] = u;
5206 u = ((fromAscii(lpc[0]) << 0) |
5207 (fromAscii(lpc[1]) << 4) |
5208 (fromAscii(lpc[2]) << 8) |
5209 (fromAscii(lpc[3]) << 12) |
5210 (fromAscii(lpc[4]) << 16) |
5211 (fromAscii(lpc[5]) << 20) |
5212 (fromAscii(lpc[6]) << 24) |
5213 (fromAscii(lpc[7]) << 28));
5214 machine_id->as_uint32s[3] = u;
5220 HANDLE _dbus_global_lock (const char *mutexname)
5225 mutex = CreateMutex( NULL, FALSE, mutexname );
5231 gotMutex = WaitForSingleObject( mutex, INFINITE );
5234 case WAIT_ABANDONED:
5235 ReleaseMutex (mutex);
5236 CloseHandle (mutex);
5247 void _dbus_global_unlock (HANDLE mutex)
5249 ReleaseMutex (mutex);
5250 CloseHandle (mutex);
5253 // for proper cleanup in dbus-daemon
5254 static HANDLE hDBusDaemonMutex = NULL;
5255 static HANDLE hDBusSharedMem = NULL;
5256 // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs
5257 static const char *cUniqueDBusInitMutex = "UniqueDBusInitMutex";
5258 // sync _dbus_get_autolaunch_address
5259 static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex";
5260 // mutex to determine if dbus-daemon is already started (per user)
5261 static const char *cDBusDaemonMutex = "DBusDaemonMutex";
5262 // named shm for dbus adress info (per user)
5263 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
5266 _dbus_daemon_init(const char *host, dbus_uint32_t port)
5269 const char *adr = NULL;
5270 char szUserName[64];
5271 DWORD dwUserNameSize = sizeof(szUserName);
5272 char szDBusDaemonMutex[128];
5273 char szDBusDaemonAddressInfo[128];
5274 char szAddress[128];
5279 _snprintf(szAddress, sizeof(szAddress) - 1, "tcp:host=%s,port=%d", host, port);
5281 _dbus_assert( GetUserName(szUserName, &dwUserNameSize) != 0);
5282 _snprintf(szDBusDaemonMutex, sizeof(szDBusDaemonMutex) - 1, "%s:%s",
5283 cDBusDaemonMutex, szUserName);
5284 _snprintf(szDBusDaemonAddressInfo, sizeof(szDBusDaemonAddressInfo) - 1, "%s:%s",
5285 cDBusDaemonAddressInfo, szUserName);
5287 // before _dbus_global_lock to keep correct lock/release order
5288 hDBusDaemonMutex = CreateMutex( NULL, FALSE, szDBusDaemonMutex );
5290 _dbus_assert(WaitForSingleObject( hDBusDaemonMutex, 1000 ) == WAIT_OBJECT_0);
5292 // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs
5293 lock = _dbus_global_lock( cUniqueDBusInitMutex );
5296 hDBusSharedMem = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
5297 0, strlen( szAddress ) + 1, szDBusDaemonAddressInfo );
5298 _dbus_assert( hDBusSharedMem );
5300 adr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
5302 _dbus_assert( adr );
5304 strcpy(adr, szAddress);
5307 UnmapViewOfFile( adr );
5309 _dbus_global_unlock( lock );
5313 _dbus_daemon_release()
5317 // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs
5318 lock = _dbus_global_lock( cUniqueDBusInitMutex );
5320 CloseHandle( hDBusSharedMem );
5322 hDBusSharedMem = NULL;
5324 ReleaseMutex( hDBusDaemonMutex );
5326 CloseHandle( hDBusDaemonMutex );
5328 hDBusDaemonMutex = NULL;
5330 _dbus_global_unlock( lock );
5334 _dbus_get_autolaunch_shm(DBusString *adress)
5338 char szUserName[64];
5339 DWORD dwUserNameSize = sizeof(szUserName);
5340 char szDBusDaemonAddressInfo[128];
5342 if( !GetUserName(szUserName, &dwUserNameSize) )
5344 _snprintf(szDBusDaemonAddressInfo, sizeof(szDBusDaemonAddressInfo) - 1, "%s:%s",
5345 cDBusDaemonAddressInfo, szUserName);
5349 // we know that dbus-daemon is available, so we wait until shm is available
5350 sharedMem = OpenFileMapping( FILE_MAP_READ, FALSE, szDBusDaemonAddressInfo );
5351 if( sharedMem == 0 )
5353 } while( sharedMem == 0 );
5355 if( sharedMem == 0 )
5358 adr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
5363 _dbus_string_init( adress );
5365 _dbus_string_append( adress, adr );
5368 UnmapViewOfFile( adr );
5370 CloseHandle( sharedMem );
5376 _dbus_daemon_already_runs (DBusString *adress)
5380 dbus_bool_t bRet = TRUE;
5381 char szUserName[64];
5382 DWORD dwUserNameSize = sizeof(szUserName);
5383 char szDBusDaemonMutex[128];
5385 // sync _dbus_daemon_init, _dbus_daemon_uninit and _dbus_daemon_already_runs
5386 lock = _dbus_global_lock( cUniqueDBusInitMutex );
5388 if( !GetUserName(szUserName, &dwUserNameSize) )
5390 _snprintf(szDBusDaemonMutex, sizeof(szDBusDaemonMutex) - 1, "%s:%s",
5391 cDBusDaemonMutex, szUserName);
5394 daemon = CreateMutex( NULL, FALSE, szDBusDaemonMutex );
5395 if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT)
5397 ReleaseMutex (daemon);
5398 CloseHandle (daemon);
5400 _dbus_global_unlock( lock );
5405 bRet = _dbus_get_autolaunch_shm( adress );
5408 CloseHandle ( daemon );
5410 _dbus_global_unlock( lock );
5416 _dbus_get_autolaunch_address (DBusString *address,
5421 PROCESS_INFORMATION pi;
5422 dbus_bool_t retval = FALSE;
5424 char dbus_exe_path[MAX_PATH];
5425 char dbus_args[MAX_PATH * 2];
5427 mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
5429 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
5431 if (_dbus_daemon_already_runs(address))
5433 printf("dbus daemon already exists\n");
5438 if (!SearchPathA(NULL, "dbus-daemon.exe", NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
5440 printf ("could not find dbus-daemon executable\n");
5445 ZeroMemory( &si, sizeof(si) );
5447 ZeroMemory( &pi, sizeof(pi) );
5449 _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path, " --session");
5451 // argv[i] = "--config-file=bus\\session.conf";
5452 printf("create process \"%s\" %s\n", dbus_exe_path, dbus_args);
5453 if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
5457 // Wait until started (see _dbus_get_autolaunch_shm())
5458 WaitForInputIdle(pi.hProcess, INFINITE);
5460 retval = _dbus_get_autolaunch_shm( address );
5467 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
5469 _DBUS_ASSERT_ERROR_IS_SET (error);
5471 _dbus_global_unlock (mutex);
5477 /** Makes the file readable by every user in the system.
5479 * @param filename the filename
5480 * @param error error location
5481 * @returns #TRUE if the file's permissions could be changed.
5484 _dbus_make_file_world_readable(const DBusString *filename,
5492 #define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
5496 * Returns the standard directories for a session bus to look for service
5499 * On Windows this should be data directories:
5501 * %CommonProgramFiles%/dbus
5507 * @param dirs the directory list we are returning
5508 * @returns #FALSE on OOM
5512 _dbus_get_standard_session_servicedirs (DBusList **dirs)
5514 const char *common_progs;
5515 DBusString servicedir_path;
5517 if (!_dbus_string_init (&servicedir_path))
5520 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR _DBUS_PATH_SEPARATOR))
5523 common_progs = _dbus_getenv ("CommonProgramFiles");
5525 if (common_progs != NULL)
5527 if (!_dbus_string_append (&servicedir_path, common_progs))
5530 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
5534 if (!_dbus_split_paths_and_append (&servicedir_path,
5535 DBUS_STANDARD_SESSION_SERVICEDIR,
5539 _dbus_string_free (&servicedir_path);
5543 _dbus_string_free (&servicedir_path);
5547 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
5550 * Atomically increments an integer
5552 * @param atomic pointer to the integer to increment
5553 * @returns the value before incrementing
5557 _dbus_atomic_inc (DBusAtomic *atomic)
5559 // +/- 1 is needed here!
5560 return InterlockedIncrement (&atomic->value) - 1;
5564 * Atomically decrement an integer
5566 * @param atomic pointer to the integer to decrement
5567 * @returns the value before decrementing
5571 _dbus_atomic_dec (DBusAtomic *atomic)
5573 // +/- 1 is needed here!
5574 return InterlockedDecrement (&atomic->value) + 1;
5577 #endif /* asserts or tests enabled */
5580 * Called when the bus daemon is signaled to reload its configuration; any
5581 * caches should be nuked. Of course any caches that need explicit reload
5582 * are probably broken, but c'est la vie.
5587 _dbus_flush_caches (void)
5592 dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid)
5598 * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
5599 * for Winsock so is abstracted)
5601 * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
5604 _dbus_get_is_errno_eagain_or_ewouldblock (void)
5606 return errno == EAGAIN || errno == EWOULDBLOCK;
5610 * return the absolute path of the dbus installation
5612 * @param s buffer for installation path
5613 * @param len length of buffer
5614 * @returns #FALSE on failure
5617 _dbus_get_install_root(char *s, int len)
5620 int ret = GetModuleFileName(NULL,s,len);
5622 || ret == len && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
5627 else if ((p = strstr(s,"\\bin\\")))
5640 find config file either from installation or build root according to
5641 the following path layout
5643 bin/dbus-daemon[d].exe
5644 etc/<config-file>.conf
5647 bin/dbus-daemon[d].exe
5648 bus/<config-file>.conf
5651 _dbus_get_config_file_name(DBusString *config_file, char *s)
5653 char path[MAX_PATH*2];
5654 int path_size = sizeof(path);
5656 if (!_dbus_get_install_root(path,path_size))
5659 strcat_s(path,path_size,"etc\\");
5660 strcat_s(path,path_size,s);
5661 if (_dbus_file_exists(path))
5663 // find path from executable
5664 if (!_dbus_string_append (config_file, path))
5669 if (!_dbus_get_install_root(path,path_size))
5671 strcat_s(path,path_size,"bus\\");
5672 strcat_s(path,path_size,s);
5674 if (_dbus_file_exists(path))
5676 if (!_dbus_string_append (config_file, path))
5684 * Append the absolute path of the system.conf file
5685 * (there is no system bus on Windows so this can just
5686 * return FALSE and print a warning or something)
5688 * @param str the string to append to
5689 * @returns #FALSE if no memory
5692 _dbus_append_system_config_file (DBusString *str)
5694 return _dbus_get_config_file_name(str, "system.conf");
5698 * Append the absolute path of the session.conf file.
5700 * @param str the string to append to
5701 * @returns #FALSE if no memory
5704 _dbus_append_session_config_file (DBusString *str)
5706 return _dbus_get_config_file_name(str, "session.conf");
5710 * Appends the directory in which a keyring for the given credentials
5711 * should be stored. The credentials should have either a Windows or
5712 * UNIX user in them. The directory should be an absolute path.
5714 * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
5715 * be something else, since the dotfile convention is not normal on Windows.
5717 * @param directory string to append directory to
5718 * @param credentials credentials the directory should be for
5720 * @returns #FALSE on no memory
5723 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
5724 DBusCredentials *credentials)
5729 const char *homepath;
5731 _dbus_assert (credentials != NULL);
5732 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
5734 if (!_dbus_string_init (&homedir))
5737 homepath = _dbus_getenv("HOMEPATH");
5738 if (homepath != NULL && *homepath != '\0')
5740 _dbus_string_append(&homedir,homepath);
5743 #ifdef DBUS_BUILD_TESTS
5745 const char *override;
5747 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
5748 if (override != NULL && *override != '\0')
5750 _dbus_string_set_length (&homedir, 0);
5751 if (!_dbus_string_append (&homedir, override))
5754 _dbus_verbose ("Using fake homedir for testing: %s\n",
5755 _dbus_string_get_const_data (&homedir));
5759 static dbus_bool_t already_warned = FALSE;
5760 if (!already_warned)
5762 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
5763 already_warned = TRUE;
5769 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
5770 if (!_dbus_concat_dir_and_file (&homedir,
5774 if (!_dbus_string_copy (&homedir, 0,
5775 directory, _dbus_string_get_length (directory))) {
5779 _dbus_string_free (&homedir);
5783 _dbus_string_free (&homedir);
5787 /** @} end of sysdeps-win */
5788 /* tests in dbus-sysdeps-util.c */