00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <config.h>
00030
00031 #define STRSAFE_NO_DEPRECATE
00032
00033 #ifndef DBUS_WINCE
00034 #ifndef _WIN32_WINNT
00035 #define _WIN32_WINNT 0x0501
00036 #endif
00037 #endif
00038
00039 #include "dbus-internals.h"
00040 #include "dbus-sysdeps.h"
00041 #include "dbus-threads.h"
00042 #include "dbus-protocol.h"
00043 #include "dbus-string.h"
00044 #include "dbus-sysdeps-win.h"
00045 #include "dbus-protocol.h"
00046 #include "dbus-hash.h"
00047 #include "dbus-sockets-win.h"
00048 #include "dbus-list.h"
00049 #include "dbus-nonce.h"
00050 #include "dbus-credentials.h"
00051
00052 #include <windows.h>
00053 #include <ws2tcpip.h>
00054 #include <wincrypt.h>
00055
00056
00057 extern BOOL WINAPI ConvertStringSidToSidA (LPCSTR StringSid, PSID *Sid);
00058 extern BOOL WINAPI ConvertSidToStringSidA (PSID Sid, LPSTR *StringSid);
00059
00060 #include <stdio.h>
00061
00062 #include <string.h>
00063 #if HAVE_ERRNO_H
00064 #include <errno.h>
00065 #endif
00066 #ifndef DBUS_WINCE
00067 #include <mbstring.h>
00068 #include <sys/stat.h>
00069 #include <sys/types.h>
00070 #endif
00071
00072 #ifdef HAVE_WS2TCPIP_H
00073
00074 #include <ws2tcpip.h>
00075 #endif
00076
00077 #ifdef HAVE_WSPIAPI_H
00078
00079 #ifdef __GNUC__
00080 #define _inline
00081 #include "wspiapi.h"
00082 #else
00083 #include <wspiapi.h>
00084 #endif
00085 #endif // HAVE_WSPIAPI_H
00086
00087 #ifndef O_BINARY
00088 #define O_BINARY 0
00089 #endif
00090
00091 typedef int socklen_t;
00092
00093
00094 void
00095 _dbus_win_set_errno (int err)
00096 {
00097 #ifdef DBUS_WINCE
00098 SetLastError (err);
00099 #else
00100 errno = err;
00101 #endif
00102 }
00103
00104
00105
00106 const char*
00107 _dbus_win_error_from_last_error (void)
00108 {
00109 switch (GetLastError())
00110 {
00111 case 0:
00112 return DBUS_ERROR_FAILED;
00113
00114 case ERROR_NO_MORE_FILES:
00115 case ERROR_TOO_MANY_OPEN_FILES:
00116 return DBUS_ERROR_LIMITS_EXCEEDED;
00117
00118 case ERROR_ACCESS_DENIED:
00119 case ERROR_CANNOT_MAKE:
00120 return DBUS_ERROR_ACCESS_DENIED;
00121
00122 case ERROR_NOT_ENOUGH_MEMORY:
00123 return DBUS_ERROR_NO_MEMORY;
00124
00125 case ERROR_FILE_EXISTS:
00126 return DBUS_ERROR_FILE_EXISTS;
00127
00128 case ERROR_FILE_NOT_FOUND:
00129 case ERROR_PATH_NOT_FOUND:
00130 return DBUS_ERROR_FILE_NOT_FOUND;
00131 }
00132
00133 return DBUS_ERROR_FAILED;
00134 }
00135
00136
00137 char*
00138 _dbus_win_error_string (int error_number)
00139 {
00140 char *msg;
00141
00142 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
00143 FORMAT_MESSAGE_IGNORE_INSERTS |
00144 FORMAT_MESSAGE_FROM_SYSTEM,
00145 NULL, error_number, 0,
00146 (LPSTR) &msg, 0, NULL);
00147
00148 if (msg[strlen (msg) - 1] == '\n')
00149 msg[strlen (msg) - 1] = '\0';
00150 if (msg[strlen (msg) - 1] == '\r')
00151 msg[strlen (msg) - 1] = '\0';
00152
00153 return msg;
00154 }
00155
00156 void
00157 _dbus_win_free_error_string (char *string)
00158 {
00159 LocalFree (string);
00160 }
00161
00182 int
00183 _dbus_read_socket (int fd,
00184 DBusString *buffer,
00185 int count)
00186 {
00187 int bytes_read;
00188 int start;
00189 char *data;
00190
00191 _dbus_assert (count >= 0);
00192
00193 start = _dbus_string_get_length (buffer);
00194
00195 if (!_dbus_string_lengthen (buffer, count))
00196 {
00197 _dbus_win_set_errno (ENOMEM);
00198 return -1;
00199 }
00200
00201 data = _dbus_string_get_data_len (buffer, start, count);
00202
00203 again:
00204
00205 _dbus_verbose ("recv: count=%d fd=%d\n", count, fd);
00206 bytes_read = recv (fd, data, count, 0);
00207
00208 if (bytes_read == SOCKET_ERROR)
00209 {
00210 DBUS_SOCKET_SET_ERRNO();
00211 _dbus_verbose ("recv: failed: %s (%d)\n", _dbus_strerror (errno), errno);
00212 bytes_read = -1;
00213 }
00214 else
00215 _dbus_verbose ("recv: = %d\n", bytes_read);
00216
00217 if (bytes_read < 0)
00218 {
00219 if (errno == EINTR)
00220 goto again;
00221 else
00222 {
00223
00224 _dbus_string_set_length (buffer, start);
00225 return -1;
00226 }
00227 }
00228 else
00229 {
00230
00231 _dbus_string_set_length (buffer, start + bytes_read);
00232
00233 #if 0
00234 if (bytes_read > 0)
00235 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00236 #endif
00237
00238 return bytes_read;
00239 }
00240 }
00241
00252 int
00253 _dbus_write_socket (int fd,
00254 const DBusString *buffer,
00255 int start,
00256 int len)
00257 {
00258 const char *data;
00259 int bytes_written;
00260
00261 data = _dbus_string_get_const_data_len (buffer, start, len);
00262
00263 again:
00264
00265 _dbus_verbose ("send: len=%d fd=%d\n", len, fd);
00266 bytes_written = send (fd, data, len, 0);
00267
00268 if (bytes_written == SOCKET_ERROR)
00269 {
00270 DBUS_SOCKET_SET_ERRNO();
00271 _dbus_verbose ("send: failed: %s\n", _dbus_strerror_from_errno ());
00272 bytes_written = -1;
00273 }
00274 else
00275 _dbus_verbose ("send: = %d\n", bytes_written);
00276
00277 if (bytes_written < 0 && errno == EINTR)
00278 goto again;
00279
00280 #if 0
00281 if (bytes_written > 0)
00282 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00283 #endif
00284
00285 return bytes_written;
00286 }
00287
00288
00296 dbus_bool_t
00297 _dbus_close_socket (int fd,
00298 DBusError *error)
00299 {
00300 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00301
00302 again:
00303 if (closesocket (fd) == SOCKET_ERROR)
00304 {
00305 DBUS_SOCKET_SET_ERRNO ();
00306
00307 if (errno == EINTR)
00308 goto again;
00309
00310 dbus_set_error (error, _dbus_error_from_errno (errno),
00311 "Could not close socket: socket=%d, , %s",
00312 fd, _dbus_strerror_from_errno ());
00313 return FALSE;
00314 }
00315 _dbus_verbose ("_dbus_close_socket: socket=%d, \n", fd);
00316
00317 return TRUE;
00318 }
00319
00327 void
00328 _dbus_fd_set_close_on_exec (intptr_t handle)
00329 {
00330 if ( !SetHandleInformation( (HANDLE) handle,
00331 HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE,
00332 0 ) )
00333 {
00334 _dbus_win_warn_win_error ("Disabling socket handle inheritance failed:", GetLastError());
00335 }
00336 }
00337
00345 dbus_bool_t
00346 _dbus_set_fd_nonblocking (int handle,
00347 DBusError *error)
00348 {
00349 u_long one = 1;
00350
00351 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00352
00353 if (ioctlsocket (handle, FIONBIO, &one) == SOCKET_ERROR)
00354 {
00355 DBUS_SOCKET_SET_ERRNO ();
00356 dbus_set_error (error, _dbus_error_from_errno (errno),
00357 "Failed to set socket %d:%d to nonblocking: %s", handle,
00358 _dbus_strerror_from_errno ());
00359 return FALSE;
00360 }
00361
00362 return TRUE;
00363 }
00364
00365
00386 int
00387 _dbus_write_socket_two (int fd,
00388 const DBusString *buffer1,
00389 int start1,
00390 int len1,
00391 const DBusString *buffer2,
00392 int start2,
00393 int len2)
00394 {
00395 WSABUF vectors[2];
00396 const char *data1;
00397 const char *data2;
00398 int rc;
00399 DWORD bytes_written;
00400
00401 _dbus_assert (buffer1 != NULL);
00402 _dbus_assert (start1 >= 0);
00403 _dbus_assert (start2 >= 0);
00404 _dbus_assert (len1 >= 0);
00405 _dbus_assert (len2 >= 0);
00406
00407
00408 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00409
00410 if (buffer2 != NULL)
00411 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00412 else
00413 {
00414 data2 = NULL;
00415 start2 = 0;
00416 len2 = 0;
00417 }
00418
00419 vectors[0].buf = (char*) data1;
00420 vectors[0].len = len1;
00421 vectors[1].buf = (char*) data2;
00422 vectors[1].len = len2;
00423
00424 again:
00425
00426 _dbus_verbose ("WSASend: len1+2=%d+%d fd=%d\n", len1, len2, fd);
00427 rc = WSASend (fd,
00428 vectors,
00429 data2 ? 2 : 1,
00430 &bytes_written,
00431 0,
00432 NULL,
00433 NULL);
00434
00435 if (rc == SOCKET_ERROR)
00436 {
00437 DBUS_SOCKET_SET_ERRNO ();
00438 _dbus_verbose ("WSASend: failed: %s\n", _dbus_strerror_from_errno ());
00439 bytes_written = -1;
00440 }
00441 else
00442 _dbus_verbose ("WSASend: = %ld\n", bytes_written);
00443
00444 if (bytes_written < 0 && errno == EINTR)
00445 goto again;
00446
00447 return bytes_written;
00448 }
00449
00450 dbus_bool_t
00451 _dbus_socket_is_invalid (int fd)
00452 {
00453 return fd == INVALID_SOCKET ? TRUE : FALSE;
00454 }
00455
00456 #if 0
00457
00466 int
00467 _dbus_connect_named_pipe (const char *path,
00468 DBusError *error)
00469 {
00470 _dbus_assert_not_reached ("not implemented");
00471 }
00472
00473 #endif
00474
00475
00476
00477 void
00478 _dbus_win_startup_winsock (void)
00479 {
00480
00481
00482 static dbus_bool_t beenhere = FALSE;
00483
00484 WORD wVersionRequested;
00485 WSADATA wsaData;
00486 int err;
00487
00488 if (beenhere)
00489 return;
00490
00491 wVersionRequested = MAKEWORD (2, 0);
00492
00493 err = WSAStartup (wVersionRequested, &wsaData);
00494 if (err != 0)
00495 {
00496 _dbus_assert_not_reached ("Could not initialize WinSock");
00497 _dbus_abort ();
00498 }
00499
00500
00501
00502
00503
00504
00505 if (LOBYTE (wsaData.wVersion) != 2 ||
00506 HIBYTE (wsaData.wVersion) != 0)
00507 {
00508 _dbus_assert_not_reached ("No usable WinSock found");
00509 _dbus_abort ();
00510 }
00511
00512 beenhere = TRUE;
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00532 int _dbus_printf_string_upper_bound (const char *format,
00533 va_list args)
00534 {
00535
00536 char buf[1024];
00537 int bufsize;
00538 int len;
00539
00540 bufsize = sizeof (buf);
00541 len = _vsnprintf (buf, bufsize - 1, format, args);
00542
00543 while (len == -1)
00544 {
00545 char *p;
00546
00547 bufsize *= 2;
00548
00549 p = malloc (bufsize);
00550 len = _vsnprintf (p, bufsize - 1, format, args);
00551 free (p);
00552 }
00553
00554 return len;
00555 }
00556
00557
00565 wchar_t *
00566 _dbus_win_utf8_to_utf16 (const char *str,
00567 DBusError *error)
00568 {
00569 DBusString s;
00570 int n;
00571 wchar_t *retval;
00572
00573 _dbus_string_init_const (&s, str);
00574
00575 if (!_dbus_string_validate_utf8 (&s, 0, _dbus_string_get_length (&s)))
00576 {
00577 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid UTF-8");
00578 return NULL;
00579 }
00580
00581 n = MultiByteToWideChar (CP_UTF8, 0, str, -1, NULL, 0);
00582
00583 if (n == 0)
00584 {
00585 _dbus_win_set_error_from_win_error (error, GetLastError ());
00586 return NULL;
00587 }
00588
00589 retval = dbus_new (wchar_t, n);
00590
00591 if (!retval)
00592 {
00593 _DBUS_SET_OOM (error);
00594 return NULL;
00595 }
00596
00597 if (MultiByteToWideChar (CP_UTF8, 0, str, -1, retval, n) != n)
00598 {
00599 dbus_free (retval);
00600 dbus_set_error_const (error, DBUS_ERROR_FAILED, "MultiByteToWideChar inconsistency");
00601 return NULL;
00602 }
00603
00604 return retval;
00605 }
00606
00614 char *
00615 _dbus_win_utf16_to_utf8 (const wchar_t *str,
00616 DBusError *error)
00617 {
00618 int n;
00619 char *retval;
00620
00621 n = WideCharToMultiByte (CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
00622
00623 if (n == 0)
00624 {
00625 _dbus_win_set_error_from_win_error (error, GetLastError ());
00626 return NULL;
00627 }
00628
00629 retval = dbus_malloc (n);
00630
00631 if (!retval)
00632 {
00633 _DBUS_SET_OOM (error);
00634 return NULL;
00635 }
00636
00637 if (WideCharToMultiByte (CP_UTF8, 0, str, -1, retval, n, NULL, NULL) != n)
00638 {
00639 dbus_free (retval);
00640 dbus_set_error_const (error, DBUS_ERROR_FAILED, "WideCharToMultiByte inconsistency");
00641 return NULL;
00642 }
00643
00644 return retval;
00645 }
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 dbus_bool_t
00658 _dbus_win_account_to_sid (const wchar_t *waccount,
00659 void **ppsid,
00660 DBusError *error)
00661 {
00662 dbus_bool_t retval = FALSE;
00663 DWORD sid_length, wdomain_length;
00664 SID_NAME_USE use;
00665 wchar_t *wdomain;
00666
00667 *ppsid = NULL;
00668
00669 sid_length = 0;
00670 wdomain_length = 0;
00671 if (!LookupAccountNameW (NULL, waccount, NULL, &sid_length,
00672 NULL, &wdomain_length, &use) &&
00673 GetLastError () != ERROR_INSUFFICIENT_BUFFER)
00674 {
00675 _dbus_win_set_error_from_win_error (error, GetLastError ());
00676 return FALSE;
00677 }
00678
00679 *ppsid = dbus_malloc (sid_length);
00680 if (!*ppsid)
00681 {
00682 _DBUS_SET_OOM (error);
00683 return FALSE;
00684 }
00685
00686 wdomain = dbus_new (wchar_t, wdomain_length);
00687 if (!wdomain)
00688 {
00689 _DBUS_SET_OOM (error);
00690 goto out1;
00691 }
00692
00693 if (!LookupAccountNameW (NULL, waccount, (PSID) *ppsid, &sid_length,
00694 wdomain, &wdomain_length, &use))
00695 {
00696 _dbus_win_set_error_from_win_error (error, GetLastError ());
00697 goto out2;
00698 }
00699
00700 if (!IsValidSid ((PSID) *ppsid))
00701 {
00702 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID");
00703 goto out2;
00704 }
00705
00706 retval = TRUE;
00707
00708 out2:
00709 dbus_free (wdomain);
00710 out1:
00711 if (!retval)
00712 {
00713 dbus_free (*ppsid);
00714 *ppsid = NULL;
00715 }
00716
00717 return retval;
00718 }
00719
00729 unsigned long
00730 _dbus_pid_for_log (void)
00731 {
00732 return _dbus_getpid ();
00733 }
00734
00735
00736 #ifndef DBUS_WINCE
00737
00741 static dbus_bool_t
00742 _dbus_getsid(char **sid)
00743 {
00744 HANDLE process_token = INVALID_HANDLE_VALUE;
00745 TOKEN_USER *token_user = NULL;
00746 DWORD n;
00747 PSID psid;
00748 int retval = FALSE;
00749
00750 if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &process_token))
00751 {
00752 _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ());
00753 goto failed;
00754 }
00755 if ((!GetTokenInformation (process_token, TokenUser, NULL, 0, &n)
00756 && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
00757 || (token_user = alloca (n)) == NULL
00758 || !GetTokenInformation (process_token, TokenUser, token_user, n, &n))
00759 {
00760 _dbus_win_warn_win_error ("GetTokenInformation failed", GetLastError ());
00761 goto failed;
00762 }
00763 psid = token_user->User.Sid;
00764 if (!IsValidSid (psid))
00765 {
00766 _dbus_verbose("%s invalid sid\n",__FUNCTION__);
00767 goto failed;
00768 }
00769 if (!ConvertSidToStringSidA (psid, sid))
00770 {
00771 _dbus_verbose("%s invalid sid\n",__FUNCTION__);
00772 goto failed;
00773 }
00774
00775 retval = TRUE;
00776
00777 failed:
00778 if (process_token != INVALID_HANDLE_VALUE)
00779 CloseHandle (process_token);
00780
00781 _dbus_verbose("_dbus_getsid() returns %d\n",retval);
00782 return retval;
00783 }
00784 #endif
00785
00786
00787
00788
00789
00790
00791
00807 dbus_bool_t
00808 _dbus_full_duplex_pipe (int *fd1,
00809 int *fd2,
00810 dbus_bool_t blocking,
00811 DBusError *error)
00812 {
00813 SOCKET temp, socket1 = -1, socket2 = -1;
00814 struct sockaddr_in saddr;
00815 int len;
00816 u_long arg;
00817 fd_set read_set, write_set;
00818 struct timeval tv;
00819 int res;
00820
00821 _dbus_win_startup_winsock ();
00822
00823 temp = socket (AF_INET, SOCK_STREAM, 0);
00824 if (temp == INVALID_SOCKET)
00825 {
00826 DBUS_SOCKET_SET_ERRNO ();
00827 goto out0;
00828 }
00829
00830 _DBUS_ZERO (saddr);
00831 saddr.sin_family = AF_INET;
00832 saddr.sin_port = 0;
00833 saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
00834
00835 if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr)) == SOCKET_ERROR)
00836 {
00837 DBUS_SOCKET_SET_ERRNO ();
00838 goto out0;
00839 }
00840
00841 if (listen (temp, 1) == SOCKET_ERROR)
00842 {
00843 DBUS_SOCKET_SET_ERRNO ();
00844 goto out0;
00845 }
00846
00847 len = sizeof (saddr);
00848 if (getsockname (temp, (struct sockaddr *)&saddr, &len) == SOCKET_ERROR)
00849 {
00850 DBUS_SOCKET_SET_ERRNO ();
00851 goto out0;
00852 }
00853
00854 socket1 = socket (AF_INET, SOCK_STREAM, 0);
00855 if (socket1 == INVALID_SOCKET)
00856 {
00857 DBUS_SOCKET_SET_ERRNO ();
00858 goto out0;
00859 }
00860
00861 if (connect (socket1, (struct sockaddr *)&saddr, len) == SOCKET_ERROR)
00862 {
00863 DBUS_SOCKET_SET_ERRNO ();
00864 goto out1;
00865 }
00866
00867 socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
00868 if (socket2 == INVALID_SOCKET)
00869 {
00870 DBUS_SOCKET_SET_ERRNO ();
00871 goto out1;
00872 }
00873
00874 if (!blocking)
00875 {
00876 arg = 1;
00877 if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
00878 {
00879 DBUS_SOCKET_SET_ERRNO ();
00880 goto out2;
00881 }
00882
00883 arg = 1;
00884 if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
00885 {
00886 DBUS_SOCKET_SET_ERRNO ();
00887 goto out2;
00888 }
00889 }
00890
00891 *fd1 = socket1;
00892 *fd2 = socket2;
00893
00894 _dbus_verbose ("full-duplex pipe %d:%d <-> %d:%d\n",
00895 *fd1, socket1, *fd2, socket2);
00896
00897 closesocket (temp);
00898
00899 return TRUE;
00900
00901 out2:
00902 closesocket (socket2);
00903 out1:
00904 closesocket (socket1);
00905 out0:
00906 closesocket (temp);
00907
00908 dbus_set_error (error, _dbus_error_from_errno (errno),
00909 "Could not setup socket pair: %s",
00910 _dbus_strerror_from_errno ());
00911
00912 return FALSE;
00913 }
00914
00923 int
00924 _dbus_poll (DBusPollFD *fds,
00925 int n_fds,
00926 int timeout_milliseconds)
00927 {
00928 #define USE_CHRIS_IMPL 0
00929
00930 #if USE_CHRIS_IMPL
00931
00932 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
00933 char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
00934 char *msgp;
00935
00936 int ret = 0;
00937 int i;
00938 struct timeval tv;
00939 int ready;
00940
00941 #define DBUS_STACK_WSAEVENTS 256
00942 WSAEVENT eventsOnStack[DBUS_STACK_WSAEVENTS];
00943 WSAEVENT *pEvents = NULL;
00944 if (n_fds > DBUS_STACK_WSAEVENTS)
00945 pEvents = calloc(sizeof(WSAEVENT), n_fds);
00946 else
00947 pEvents = eventsOnStack;
00948
00949
00950 #ifdef DBUS_ENABLE_VERBOSE_MODE
00951 msgp = msg;
00952 msgp += sprintf (msgp, "WSAEventSelect: to=%d\n\t", timeout_milliseconds);
00953 for (i = 0; i < n_fds; i++)
00954 {
00955 static dbus_bool_t warned = FALSE;
00956 DBusPollFD *fdp = &fds[i];
00957
00958
00959 if (fdp->events & _DBUS_POLLIN)
00960 msgp += sprintf (msgp, "R:%d ", fdp->fd);
00961
00962 if (fdp->events & _DBUS_POLLOUT)
00963 msgp += sprintf (msgp, "W:%d ", fdp->fd);
00964
00965 msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
00966
00967
00968
00969 if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
00970 {
00971 _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
00972 }
00973 }
00974
00975 msgp += sprintf (msgp, "\n");
00976 _dbus_verbose ("%s",msg);
00977 #endif
00978 for (i = 0; i < n_fds; i++)
00979 {
00980 DBusPollFD *fdp = &fds[i];
00981 WSAEVENT ev;
00982 long lNetworkEvents = FD_OOB;
00983
00984 ev = WSACreateEvent();
00985
00986 if (fdp->events & _DBUS_POLLIN)
00987 lNetworkEvents |= FD_READ | FD_ACCEPT | FD_CLOSE;
00988
00989 if (fdp->events & _DBUS_POLLOUT)
00990 lNetworkEvents |= FD_WRITE | FD_CONNECT;
00991
00992 WSAEventSelect(fdp->fd, ev, lNetworkEvents);
00993
00994 pEvents[i] = ev;
00995 }
00996
00997
00998 ready = WSAWaitForMultipleEvents (n_fds, pEvents, FALSE, timeout_milliseconds, FALSE);
00999
01000 if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
01001 {
01002 DBUS_SOCKET_SET_ERRNO ();
01003 if (errno != WSAEWOULDBLOCK)
01004 _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", _dbus_strerror_from_errno ());
01005 ret = -1;
01006 }
01007 else if (ready == WSA_WAIT_TIMEOUT)
01008 {
01009 _dbus_verbose ("WSAWaitForMultipleEvents: WSA_WAIT_TIMEOUT\n");
01010 ret = 0;
01011 }
01012 else if (ready >= WSA_WAIT_EVENT_0 && ready < (int)(WSA_WAIT_EVENT_0 + n_fds))
01013 {
01014 msgp = msg;
01015 msgp += sprintf (msgp, "WSAWaitForMultipleEvents: =%d\n\t", ready);
01016
01017 for (i = 0; i < n_fds; i++)
01018 {
01019 DBusPollFD *fdp = &fds[i];
01020 WSANETWORKEVENTS ne;
01021
01022 fdp->revents = 0;
01023
01024 WSAEnumNetworkEvents(fdp->fd, pEvents[i], &ne);
01025
01026 if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
01027 fdp->revents |= _DBUS_POLLIN;
01028
01029 if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
01030 fdp->revents |= _DBUS_POLLOUT;
01031
01032 if (ne.lNetworkEvents & (FD_OOB))
01033 fdp->revents |= _DBUS_POLLERR;
01034
01035 if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
01036 msgp += sprintf (msgp, "R:%d ", fdp->fd);
01037
01038 if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
01039 msgp += sprintf (msgp, "W:%d ", fdp->fd);
01040
01041 if (ne.lNetworkEvents & (FD_OOB))
01042 msgp += sprintf (msgp, "E:%d ", fdp->fd);
01043
01044 msgp += sprintf (msgp, "lNetworkEvents:%d ", ne.lNetworkEvents);
01045
01046 if(ne.lNetworkEvents)
01047 ret++;
01048
01049 WSAEventSelect(fdp->fd, pEvents[i], 0);
01050 }
01051
01052 msgp += sprintf (msgp, "\n");
01053 _dbus_verbose ("%s",msg);
01054 }
01055 else
01056 {
01057 _dbus_verbose ("WSAWaitForMultipleEvents: failed for unknown reason!");
01058 ret = -1;
01059 }
01060
01061 for(i = 0; i < n_fds; i++)
01062 {
01063 WSACloseEvent(pEvents[i]);
01064 }
01065
01066 if (n_fds > DBUS_STACK_WSAEVENTS)
01067 free(pEvents);
01068
01069 return ret;
01070
01071 #else
01072
01073 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
01074 char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
01075 char *msgp;
01076
01077 fd_set read_set, write_set, err_set;
01078 int max_fd = 0;
01079 int i;
01080 struct timeval tv;
01081 int ready;
01082
01083 FD_ZERO (&read_set);
01084 FD_ZERO (&write_set);
01085 FD_ZERO (&err_set);
01086
01087
01088 #ifdef DBUS_ENABLE_VERBOSE_MODE
01089 msgp = msg;
01090 msgp += sprintf (msgp, "select: to=%d\n\t", timeout_milliseconds);
01091 for (i = 0; i < n_fds; i++)
01092 {
01093 static dbus_bool_t warned = FALSE;
01094 DBusPollFD *fdp = &fds[i];
01095
01096
01097 if (fdp->events & _DBUS_POLLIN)
01098 msgp += sprintf (msgp, "R:%d ", fdp->fd);
01099
01100 if (fdp->events & _DBUS_POLLOUT)
01101 msgp += sprintf (msgp, "W:%d ", fdp->fd);
01102
01103 msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
01104
01105
01106
01107 if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
01108 {
01109 _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
01110 }
01111 }
01112
01113 msgp += sprintf (msgp, "\n");
01114 _dbus_verbose ("%s",msg);
01115 #endif
01116 for (i = 0; i < n_fds; i++)
01117 {
01118 DBusPollFD *fdp = &fds[i];
01119
01120 if (fdp->events & _DBUS_POLLIN)
01121 FD_SET (fdp->fd, &read_set);
01122
01123 if (fdp->events & _DBUS_POLLOUT)
01124 FD_SET (fdp->fd, &write_set);
01125
01126 FD_SET (fdp->fd, &err_set);
01127
01128 max_fd = MAX (max_fd, fdp->fd);
01129 }
01130
01131
01132 tv.tv_sec = timeout_milliseconds / 1000;
01133 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
01134
01135 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
01136 timeout_milliseconds < 0 ? NULL : &tv);
01137
01138 if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
01139 {
01140 DBUS_SOCKET_SET_ERRNO ();
01141 if (errno != WSAEWOULDBLOCK)
01142 _dbus_verbose ("select: failed: %s\n", _dbus_strerror_from_errno ());
01143 }
01144 else if (ready == 0)
01145 _dbus_verbose ("select: = 0\n");
01146 else
01147 if (ready > 0)
01148 {
01149 #ifdef DBUS_ENABLE_VERBOSE_MODE
01150 msgp = msg;
01151 msgp += sprintf (msgp, "select: = %d:\n\t", ready);
01152
01153 for (i = 0; i < n_fds; i++)
01154 {
01155 DBusPollFD *fdp = &fds[i];
01156
01157 if (FD_ISSET (fdp->fd, &read_set))
01158 msgp += sprintf (msgp, "R:%d ", fdp->fd);
01159
01160 if (FD_ISSET (fdp->fd, &write_set))
01161 msgp += sprintf (msgp, "W:%d ", fdp->fd);
01162
01163 if (FD_ISSET (fdp->fd, &err_set))
01164 msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
01165 }
01166 msgp += sprintf (msgp, "\n");
01167 _dbus_verbose ("%s",msg);
01168 #endif
01169
01170 for (i = 0; i < n_fds; i++)
01171 {
01172 DBusPollFD *fdp = &fds[i];
01173
01174 fdp->revents = 0;
01175
01176 if (FD_ISSET (fdp->fd, &read_set))
01177 fdp->revents |= _DBUS_POLLIN;
01178
01179 if (FD_ISSET (fdp->fd, &write_set))
01180 fdp->revents |= _DBUS_POLLOUT;
01181
01182 if (FD_ISSET (fdp->fd, &err_set))
01183 fdp->revents |= _DBUS_POLLERR;
01184 }
01185 }
01186 return ready;
01187 #endif
01188 }
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01229 void
01230 _dbus_exit (int code)
01231 {
01232 _exit (code);
01233 }
01234
01246 int
01247 _dbus_connect_tcp_socket (const char *host,
01248 const char *port,
01249 const char *family,
01250 DBusError *error)
01251 {
01252 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01253 }
01254
01255 int
01256 _dbus_connect_tcp_socket_with_nonce (const char *host,
01257 const char *port,
01258 const char *family,
01259 const char *noncefile,
01260 DBusError *error)
01261 {
01262 int fd = -1, res;
01263 struct addrinfo hints;
01264 struct addrinfo *ai, *tmp;
01265
01266 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01267
01268 _dbus_win_startup_winsock ();
01269
01270 _DBUS_ZERO (hints);
01271
01272 if (!family)
01273 hints.ai_family = AF_UNSPEC;
01274 else if (!strcmp(family, "ipv4"))
01275 hints.ai_family = AF_INET;
01276 else if (!strcmp(family, "ipv6"))
01277 hints.ai_family = AF_INET6;
01278 else
01279 {
01280 dbus_set_error (error,
01281 DBUS_ERROR_INVALID_ARGS,
01282 "Unknown address family %s", family);
01283 return -1;
01284 }
01285 hints.ai_protocol = IPPROTO_TCP;
01286 hints.ai_socktype = SOCK_STREAM;
01287 #ifdef AI_ADDRCONFIG
01288 hints.ai_flags = AI_ADDRCONFIG;
01289 #else
01290 hints.ai_flags = 0;
01291 #endif
01292
01293 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01294 {
01295 dbus_set_error (error,
01296 _dbus_error_from_errno (res),
01297 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01298 host, port, _dbus_strerror(res), res);
01299 return -1;
01300 }
01301
01302 tmp = ai;
01303 while (tmp)
01304 {
01305 if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
01306 {
01307 DBUS_SOCKET_SET_ERRNO ();
01308 dbus_set_error (error,
01309 _dbus_error_from_errno (errno),
01310 "Failed to open socket: %s",
01311 _dbus_strerror_from_errno ());
01312 freeaddrinfo(ai);
01313 return -1;
01314 }
01315 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01316
01317 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
01318 {
01319 DBUS_SOCKET_SET_ERRNO ();
01320 closesocket(fd);
01321 fd = -1;
01322 tmp = tmp->ai_next;
01323 continue;
01324 }
01325
01326 break;
01327 }
01328 freeaddrinfo(ai);
01329
01330 if (fd == -1)
01331 {
01332 dbus_set_error (error,
01333 _dbus_error_from_errno (errno),
01334 "Failed to connect to socket \"%s:%s\" %s",
01335 host, port, _dbus_strerror_from_errno ());
01336 return -1;
01337 }
01338
01339 if (noncefile != NULL)
01340 {
01341 DBusString noncefileStr;
01342 dbus_bool_t ret;
01343 if (!_dbus_string_init (&noncefileStr) ||
01344 !_dbus_string_append(&noncefileStr, noncefile))
01345 {
01346 closesocket (fd);
01347 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01348 return -1;
01349 }
01350
01351 ret = _dbus_send_nonce (fd, &noncefileStr, error);
01352
01353 _dbus_string_free (&noncefileStr);
01354
01355 if (!ret)
01356 {
01357 closesocket (fd);
01358 return -1;
01359 }
01360 }
01361
01362 if (!_dbus_set_fd_nonblocking (fd, error))
01363 {
01364 closesocket (fd);
01365 return -1;
01366 }
01367
01368 return fd;
01369 }
01370
01386 int
01387 _dbus_listen_tcp_socket (const char *host,
01388 const char *port,
01389 const char *family,
01390 DBusString *retport,
01391 int **fds_p,
01392 DBusError *error)
01393 {
01394 int nlisten_fd = 0, *listen_fd = NULL, res, i, port_num = -1;
01395 struct addrinfo hints;
01396 struct addrinfo *ai, *tmp;
01397
01398
01399
01400
01401
01402 typedef union {
01403 struct sockaddr Address;
01404 struct sockaddr_in AddressIn;
01405 struct sockaddr_in6 AddressIn6;
01406 } mysockaddr_gen;
01407
01408 *fds_p = NULL;
01409 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01410
01411 _dbus_win_startup_winsock ();
01412
01413 _DBUS_ZERO (hints);
01414
01415 if (!family)
01416 hints.ai_family = AF_UNSPEC;
01417 else if (!strcmp(family, "ipv4"))
01418 hints.ai_family = AF_INET;
01419 else if (!strcmp(family, "ipv6"))
01420 hints.ai_family = AF_INET6;
01421 else
01422 {
01423 dbus_set_error (error,
01424 DBUS_ERROR_INVALID_ARGS,
01425 "Unknown address family %s", family);
01426 return -1;
01427 }
01428
01429 hints.ai_protocol = IPPROTO_TCP;
01430 hints.ai_socktype = SOCK_STREAM;
01431 #ifdef AI_ADDRCONFIG
01432 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01433 #else
01434 hints.ai_flags = AI_PASSIVE;
01435 #endif
01436
01437 redo_lookup_with_port:
01438 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01439 {
01440 dbus_set_error (error,
01441 _dbus_error_from_errno (res),
01442 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01443 host ? host : "*", port, _dbus_strerror(res), res);
01444 return -1;
01445 }
01446
01447 tmp = ai;
01448 while (tmp)
01449 {
01450 int fd = -1, *newlisten_fd;
01451 if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
01452 {
01453 DBUS_SOCKET_SET_ERRNO ();
01454 dbus_set_error (error,
01455 _dbus_error_from_errno (errno),
01456 "Failed to open socket: %s",
01457 _dbus_strerror_from_errno ());
01458 goto failed;
01459 }
01460 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01461
01462 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
01463 {
01464 DBUS_SOCKET_SET_ERRNO ();
01465 dbus_set_error (error, _dbus_error_from_errno (errno),
01466 "Failed to bind socket \"%s:%s\": %s",
01467 host ? host : "*", port, _dbus_strerror_from_errno ());
01468 closesocket (fd);
01469 goto failed;
01470 }
01471
01472 if (listen (fd, 30 ) == SOCKET_ERROR)
01473 {
01474 DBUS_SOCKET_SET_ERRNO ();
01475 dbus_set_error (error, _dbus_error_from_errno (errno),
01476 "Failed to listen on socket \"%s:%s\": %s",
01477 host ? host : "*", port, _dbus_strerror_from_errno ());
01478 closesocket (fd);
01479 goto failed;
01480 }
01481
01482 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01483 if (!newlisten_fd)
01484 {
01485 closesocket (fd);
01486 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01487 "Failed to allocate file handle array");
01488 goto failed;
01489 }
01490 listen_fd = newlisten_fd;
01491 listen_fd[nlisten_fd] = fd;
01492 nlisten_fd++;
01493
01494 if (!_dbus_string_get_length(retport))
01495 {
01496
01497
01498
01499
01500 if (!port || !strcmp(port, "0"))
01501 {
01502 mysockaddr_gen addr;
01503 socklen_t addrlen = sizeof(addr);
01504 char portbuf[10];
01505
01506 if (getsockname(fd, &addr.Address, &addrlen) == SOCKET_ERROR)
01507 {
01508 DBUS_SOCKET_SET_ERRNO ();
01509 dbus_set_error (error, _dbus_error_from_errno (errno),
01510 "Failed to resolve port \"%s:%s\": %s",
01511 host ? host : "*", port, _dbus_strerror_from_errno());
01512 goto failed;
01513 }
01514 snprintf( portbuf, sizeof( portbuf ) - 1, "%d", addr.AddressIn.sin_port );
01515 if (!_dbus_string_append(retport, portbuf))
01516 {
01517 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01518 goto failed;
01519 }
01520
01521
01522 port = _dbus_string_get_const_data(retport);
01523 freeaddrinfo(ai);
01524 goto redo_lookup_with_port;
01525 }
01526 else
01527 {
01528 if (!_dbus_string_append(retport, port))
01529 {
01530 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01531 goto failed;
01532 }
01533 }
01534 }
01535
01536 tmp = tmp->ai_next;
01537 }
01538 freeaddrinfo(ai);
01539 ai = NULL;
01540
01541 if (!nlisten_fd)
01542 {
01543 _dbus_win_set_errno (WSAEADDRINUSE);
01544 dbus_set_error (error, _dbus_error_from_errno (errno),
01545 "Failed to bind socket \"%s:%s\": %s",
01546 host ? host : "*", port, _dbus_strerror_from_errno ());
01547 return -1;
01548 }
01549
01550 sscanf(_dbus_string_get_const_data(retport), "%d", &port_num);
01551
01552 for (i = 0 ; i < nlisten_fd ; i++)
01553 {
01554 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01555 {
01556 goto failed;
01557 }
01558 }
01559
01560 *fds_p = listen_fd;
01561
01562 return nlisten_fd;
01563
01564 failed:
01565 if (ai)
01566 freeaddrinfo(ai);
01567 for (i = 0 ; i < nlisten_fd ; i++)
01568 closesocket (listen_fd[i]);
01569 dbus_free(listen_fd);
01570 return -1;
01571 }
01572
01573
01581 int
01582 _dbus_accept (int listen_fd)
01583 {
01584 int client_fd;
01585
01586 retry:
01587 client_fd = accept (listen_fd, NULL, NULL);
01588
01589 if (DBUS_SOCKET_IS_INVALID (client_fd))
01590 {
01591 DBUS_SOCKET_SET_ERRNO ();
01592 if (errno == EINTR)
01593 goto retry;
01594 }
01595
01596 _dbus_verbose ("client fd %d accepted\n", client_fd);
01597
01598 return client_fd;
01599 }
01600
01601
01602
01603
01604 dbus_bool_t
01605 _dbus_send_credentials_socket (int handle,
01606 DBusError *error)
01607 {
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631 int bytes_written;
01632 DBusString buf;
01633
01634 _dbus_string_init_const_len (&buf, "\0", 1);
01635 again:
01636 bytes_written = _dbus_write_socket (handle, &buf, 0, 1 );
01637
01638 if (bytes_written < 0 && errno == EINTR)
01639 goto again;
01640
01641 if (bytes_written < 0)
01642 {
01643 dbus_set_error (error, _dbus_error_from_errno (errno),
01644 "Failed to write credentials byte: %s",
01645 _dbus_strerror_from_errno ());
01646 return FALSE;
01647 }
01648 else if (bytes_written == 0)
01649 {
01650 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01651 "wrote zero bytes writing credentials byte");
01652 return FALSE;
01653 }
01654 else
01655 {
01656 _dbus_assert (bytes_written == 1);
01657 _dbus_verbose ("wrote 1 zero byte, credential sending isn't implemented yet\n");
01658 return TRUE;
01659 }
01660 return TRUE;
01661 }
01662
01681 dbus_bool_t
01682 _dbus_read_credentials_socket (int handle,
01683 DBusCredentials *credentials,
01684 DBusError *error)
01685 {
01686 int bytes_read = 0;
01687 DBusString buf;
01688
01689
01690 if (_dbus_string_init(&buf))
01691 {
01692 bytes_read = _dbus_read_socket(handle, &buf, 1 );
01693
01694 if (bytes_read > 0)
01695 _dbus_verbose("got one zero byte from server");
01696
01697 _dbus_string_free(&buf);
01698 }
01699
01700 _dbus_credentials_add_from_current_process (credentials);
01701 _dbus_verbose("FIXME: get faked credentials from current process");
01702
01703 return TRUE;
01704 }
01705
01714 dbus_bool_t
01715 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01716 {
01717
01718 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01719 return TRUE;
01720 }
01721
01722
01733 dbus_bool_t
01734 _dbus_concat_dir_and_file (DBusString *dir,
01735 const DBusString *next_component)
01736 {
01737 dbus_bool_t dir_ends_in_slash;
01738 dbus_bool_t file_starts_with_slash;
01739
01740 if (_dbus_string_get_length (dir) == 0 ||
01741 _dbus_string_get_length (next_component) == 0)
01742 return TRUE;
01743
01744 dir_ends_in_slash =
01745 ('/' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1) ||
01746 '\\' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1));
01747
01748 file_starts_with_slash =
01749 ('/' == _dbus_string_get_byte (next_component, 0) ||
01750 '\\' == _dbus_string_get_byte (next_component, 0));
01751
01752 if (dir_ends_in_slash && file_starts_with_slash)
01753 {
01754 _dbus_string_shorten (dir, 1);
01755 }
01756 else if (!(dir_ends_in_slash || file_starts_with_slash))
01757 {
01758 if (!_dbus_string_append_byte (dir, '\\'))
01759 return FALSE;
01760 }
01761
01762 return _dbus_string_copy (next_component, 0, dir,
01763 _dbus_string_get_length (dir));
01764 }
01765
01766
01767
01775 dbus_bool_t
01776 _dbus_credentials_add_from_user (DBusCredentials *credentials,
01777 const DBusString *username)
01778 {
01779 return _dbus_credentials_add_windows_sid (credentials,
01780 _dbus_string_get_const_data(username));
01781 }
01782
01791 dbus_bool_t
01792 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
01793 {
01794 dbus_bool_t retval = FALSE;
01795 char *sid = NULL;
01796
01797 if (!_dbus_getsid(&sid))
01798 goto failed;
01799
01800 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
01801 goto failed;
01802
01803 if (!_dbus_credentials_add_windows_sid (credentials,sid))
01804 goto failed;
01805
01806 retval = TRUE;
01807 goto end;
01808 failed:
01809 retval = FALSE;
01810 end:
01811 if (sid)
01812 LocalFree(sid);
01813
01814 return retval;
01815 }
01816
01829 dbus_bool_t
01830 _dbus_append_user_from_current_process (DBusString *str)
01831 {
01832 dbus_bool_t retval = FALSE;
01833 char *sid = NULL;
01834
01835 if (!_dbus_getsid(&sid))
01836 return FALSE;
01837
01838 retval = _dbus_string_append (str,sid);
01839
01840 LocalFree(sid);
01841 return retval;
01842 }
01843
01848 dbus_pid_t
01849 _dbus_getpid (void)
01850 {
01851 return GetCurrentProcessId ();
01852 }
01853
01855 #define NANOSECONDS_PER_SECOND 1000000000
01856
01857 #define MICROSECONDS_PER_SECOND 1000000
01858
01859 #define MILLISECONDS_PER_SECOND 1000
01860
01861 #define NANOSECONDS_PER_MILLISECOND 1000000
01862
01863 #define MICROSECONDS_PER_MILLISECOND 1000
01864
01869 void
01870 _dbus_sleep_milliseconds (int milliseconds)
01871 {
01872 Sleep (milliseconds);
01873 }
01874
01875
01882 void
01883 _dbus_get_current_time (long *tv_sec,
01884 long *tv_usec)
01885 {
01886 FILETIME ft;
01887 dbus_uint64_t time64;
01888
01889 GetSystemTimeAsFileTime (&ft);
01890
01891 memcpy (&time64, &ft, sizeof (time64));
01892
01893
01894
01895
01896 time64 -= DBUS_INT64_CONSTANT (116444736000000000);
01897 time64 /= 10;
01898
01899 if (tv_sec)
01900 *tv_sec = time64 / 1000000;
01901
01902 if (tv_usec)
01903 *tv_usec = time64 % 1000000;
01904 }
01905
01906
01910 void
01911 _dbus_disable_sigpipe (void)
01912 {
01913 }
01914
01923 dbus_bool_t
01924 _dbus_create_directory (const DBusString *filename,
01925 DBusError *error)
01926 {
01927 const char *filename_c;
01928
01929 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01930
01931 filename_c = _dbus_string_get_const_data (filename);
01932
01933 if (!CreateDirectoryA (filename_c, NULL))
01934 {
01935 if (GetLastError () == ERROR_ALREADY_EXISTS)
01936 return TRUE;
01937
01938 dbus_set_error (error, DBUS_ERROR_FAILED,
01939 "Failed to create directory %s: %s\n",
01940 filename_c, _dbus_strerror_from_errno ());
01941 return FALSE;
01942 }
01943 else
01944 return TRUE;
01945 }
01946
01947
01956 dbus_bool_t
01957 _dbus_generate_random_bytes (DBusString *str,
01958 int n_bytes)
01959 {
01960 int old_len;
01961 char *p;
01962 HCRYPTPROV hprov;
01963
01964 old_len = _dbus_string_get_length (str);
01965
01966 if (!_dbus_string_lengthen (str, n_bytes))
01967 return FALSE;
01968
01969 p = _dbus_string_get_data_len (str, old_len, n_bytes);
01970
01971 if (!CryptAcquireContext (&hprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
01972 return FALSE;
01973
01974 if (!CryptGenRandom (hprov, n_bytes, p))
01975 {
01976 CryptReleaseContext (hprov, 0);
01977 return FALSE;
01978 }
01979
01980 CryptReleaseContext (hprov, 0);
01981
01982 return TRUE;
01983 }
01984
01991 const char*
01992 _dbus_get_tmpdir(void)
01993 {
01994 static const char* tmpdir = NULL;
01995 static char buf[1000];
01996
01997 if (tmpdir == NULL)
01998 {
01999 char *last_slash;
02000
02001 if (!GetTempPathA (sizeof (buf), buf))
02002 {
02003 _dbus_warn ("GetTempPath failed\n");
02004 _dbus_abort ();
02005 }
02006
02007
02008 last_slash = _mbsrchr (buf, '\\');
02009 if (last_slash > buf && last_slash[1] == '\0')
02010 last_slash[0] = '\0';
02011 last_slash = _mbsrchr (buf, '/');
02012 if (last_slash > buf && last_slash[1] == '\0')
02013 last_slash[0] = '\0';
02014
02015 tmpdir = buf;
02016 }
02017
02018 _dbus_assert(tmpdir != NULL);
02019
02020 return tmpdir;
02021 }
02022
02023
02032 dbus_bool_t
02033 _dbus_delete_file (const DBusString *filename,
02034 DBusError *error)
02035 {
02036 const char *filename_c;
02037
02038 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02039
02040 filename_c = _dbus_string_get_const_data (filename);
02041
02042 if (DeleteFileA (filename_c) == 0)
02043 {
02044 dbus_set_error (error, DBUS_ERROR_FAILED,
02045 "Failed to delete file %s: %s\n",
02046 filename_c, _dbus_strerror_from_errno ());
02047 return FALSE;
02048 }
02049 else
02050 return TRUE;
02051 }
02052
02053
02054 static dbus_bool_t
02055 _dbus_get_install_root(char *prefix, int len);
02056
02057
02058
02059
02060
02061
02062
02063
02064 const char *
02065 _dbus_replace_install_prefix (const char *configure_time_path)
02066 {
02067 #ifndef DBUS_PREFIX
02068 return configure_time_path;
02069 #else
02070 static char retval[1000];
02071 static char runtime_prefix[1000];
02072 int len = 1000;
02073 int i;
02074
02075 if (!configure_time_path)
02076 return NULL;
02077
02078 if ((!_dbus_get_install_root(runtime_prefix, len) ||
02079 strncmp (configure_time_path, DBUS_PREFIX "/",
02080 strlen (DBUS_PREFIX) + 1))) {
02081 strcat (retval, configure_time_path);
02082 return retval;
02083 }
02084
02085 strcpy (retval, runtime_prefix);
02086 strcat (retval, configure_time_path + strlen (DBUS_PREFIX) + 1);
02087
02088
02089
02090
02091
02092
02093 for(i = 0; retval[i] != '\0'; i++) {
02094 if(retval[i] == '\\')
02095 retval[i] = '/';
02096 }
02097 return retval;
02098 #endif
02099 }
02100
02101 #if !defined (DBUS_DISABLE_ASSERTS) || defined(DBUS_BUILD_TESTS)
02102
02103 #if defined(_MSC_VER) || defined(DBUS_WINCE)
02104 # ifdef BACKTRACES
02105 # undef BACKTRACES
02106 # endif
02107 #else
02108 # define BACKTRACES
02109 #endif
02110
02111 #ifdef BACKTRACES
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133 #include <winver.h>
02134 #include <imagehlp.h>
02135 #include <stdio.h>
02136
02137 #define DPRINTF _dbus_warn
02138
02139 #ifdef _MSC_VER
02140 #define BOOL int
02141
02142 #define __i386__
02143 #endif
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153 static BOOL (WINAPI *pStackWalk)(
02154 DWORD MachineType,
02155 HANDLE hProcess,
02156 HANDLE hThread,
02157 LPSTACKFRAME StackFrame,
02158 PVOID ContextRecord,
02159 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
02160 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
02161 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
02162 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
02163 );
02164 #ifdef _WIN64
02165 static DWORD64 (WINAPI *pSymGetModuleBase)(
02166 HANDLE hProcess,
02167 DWORD64 dwAddr
02168 );
02169 static PVOID (WINAPI *pSymFunctionTableAccess)(
02170 HANDLE hProcess,
02171 DWORD64 AddrBase
02172 );
02173 #else
02174 static DWORD (WINAPI *pSymGetModuleBase)(
02175 HANDLE hProcess,
02176 DWORD dwAddr
02177 );
02178 static PVOID (WINAPI *pSymFunctionTableAccess)(
02179 HANDLE hProcess,
02180 DWORD AddrBase
02181 );
02182 #endif
02183 static BOOL (WINAPI *pSymInitialize)(
02184 HANDLE hProcess,
02185 PSTR UserSearchPath,
02186 BOOL fInvadeProcess
02187 );
02188 static BOOL (WINAPI *pSymGetSymFromAddr)(
02189 HANDLE hProcess,
02190 DWORD Address,
02191 PDWORD Displacement,
02192 PIMAGEHLP_SYMBOL Symbol
02193 );
02194 static BOOL (WINAPI *pSymGetModuleInfo)(
02195 HANDLE hProcess,
02196 DWORD dwAddr,
02197 PIMAGEHLP_MODULE ModuleInfo
02198 );
02199 static DWORD (WINAPI *pSymSetOptions)(
02200 DWORD SymOptions
02201 );
02202
02203
02204 static BOOL init_backtrace()
02205 {
02206 HMODULE hmodDbgHelp = LoadLibraryA("dbghelp");
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224 #define FUNC(x) #x
02225
02226 pStackWalk = (BOOL (WINAPI *)(
02227 DWORD MachineType,
02228 HANDLE hProcess,
02229 HANDLE hThread,
02230 LPSTACKFRAME StackFrame,
02231 PVOID ContextRecord,
02232 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
02233 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
02234 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
02235 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
02236 ))GetProcAddress (hmodDbgHelp, FUNC(StackWalk));
02237 #ifdef _WIN64
02238 pSymGetModuleBase=(DWORD64 (WINAPI *)(
02239 HANDLE hProcess,
02240 DWORD64 dwAddr
02241 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
02242 pSymFunctionTableAccess=(PVOID (WINAPI *)(
02243 HANDLE hProcess,
02244 DWORD64 AddrBase
02245 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
02246 #else
02247 pSymGetModuleBase=(DWORD (WINAPI *)(
02248 HANDLE hProcess,
02249 DWORD dwAddr
02250 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
02251 pSymFunctionTableAccess=(PVOID (WINAPI *)(
02252 HANDLE hProcess,
02253 DWORD AddrBase
02254 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
02255 #endif
02256 pSymInitialize = (BOOL (WINAPI *)(
02257 HANDLE hProcess,
02258 PSTR UserSearchPath,
02259 BOOL fInvadeProcess
02260 ))GetProcAddress (hmodDbgHelp, FUNC(SymInitialize));
02261 pSymGetSymFromAddr = (BOOL (WINAPI *)(
02262 HANDLE hProcess,
02263 DWORD Address,
02264 PDWORD Displacement,
02265 PIMAGEHLP_SYMBOL Symbol
02266 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetSymFromAddr));
02267 pSymGetModuleInfo = (BOOL (WINAPI *)(
02268 HANDLE hProcess,
02269 DWORD dwAddr,
02270 PIMAGEHLP_MODULE ModuleInfo
02271 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleInfo));
02272 pSymSetOptions = (DWORD (WINAPI *)(
02273 DWORD SymOptions
02274 ))GetProcAddress (hmodDbgHelp, FUNC(SymSetOptions));
02275
02276
02277 pSymSetOptions(SYMOPT_UNDNAME);
02278
02279 pSymInitialize(GetCurrentProcess(), NULL, TRUE);
02280
02281 return TRUE;
02282 }
02283
02284 static void dump_backtrace_for_thread(HANDLE hThread)
02285 {
02286 STACKFRAME sf;
02287 CONTEXT context;
02288 DWORD dwImageType;
02289
02290 if (!pStackWalk)
02291 if (!init_backtrace())
02292 return;
02293
02294
02295
02296 if (hThread == GetCurrentThread())
02297 return;
02298
02299 DPRINTF("Backtrace:\n");
02300
02301 _DBUS_ZERO(context);
02302 context.ContextFlags = CONTEXT_FULL;
02303
02304 SuspendThread(hThread);
02305
02306 if (!GetThreadContext(hThread, &context))
02307 {
02308 DPRINTF("Couldn't get thread context (error %ld)\n", GetLastError());
02309 ResumeThread(hThread);
02310 return;
02311 }
02312
02313 _DBUS_ZERO(sf);
02314
02315 #ifdef __i386__
02316 sf.AddrFrame.Offset = context.Ebp;
02317 sf.AddrFrame.Mode = AddrModeFlat;
02318 sf.AddrPC.Offset = context.Eip;
02319 sf.AddrPC.Mode = AddrModeFlat;
02320 dwImageType = IMAGE_FILE_MACHINE_I386;
02321 #elif _M_X64
02322 dwImageType = IMAGE_FILE_MACHINE_AMD64;
02323 sf.AddrPC.Offset = context.Rip;
02324 sf.AddrPC.Mode = AddrModeFlat;
02325 sf.AddrFrame.Offset = context.Rsp;
02326 sf.AddrFrame.Mode = AddrModeFlat;
02327 sf.AddrStack.Offset = context.Rsp;
02328 sf.AddrStack.Mode = AddrModeFlat;
02329 #elif _M_IA64
02330 dwImageType = IMAGE_FILE_MACHINE_IA64;
02331 sf.AddrPC.Offset = context.StIIP;
02332 sf.AddrPC.Mode = AddrModeFlat;
02333 sf.AddrFrame.Offset = context.IntSp;
02334 sf.AddrFrame.Mode = AddrModeFlat;
02335 sf.AddrBStore.Offset= context.RsBSP;
02336 sf.AddrBStore.Mode = AddrModeFlat;
02337 sf.AddrStack.Offset = context.IntSp;
02338 sf.AddrStack.Mode = AddrModeFlat;
02339 #else
02340 # error You need to fill in the STACKFRAME structure for your architecture
02341 #endif
02342
02343 while (pStackWalk(dwImageType, GetCurrentProcess(),
02344 hThread, &sf, &context, NULL, pSymFunctionTableAccess,
02345 pSymGetModuleBase, NULL))
02346 {
02347 BYTE buffer[256];
02348 IMAGEHLP_SYMBOL * pSymbol = (IMAGEHLP_SYMBOL *)buffer;
02349 DWORD dwDisplacement;
02350
02351 pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
02352 pSymbol->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1;
02353
02354 if (!pSymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset,
02355 &dwDisplacement, pSymbol))
02356 {
02357 IMAGEHLP_MODULE ModuleInfo;
02358 ModuleInfo.SizeOfStruct = sizeof(ModuleInfo);
02359
02360 if (!pSymGetModuleInfo(GetCurrentProcess(), sf.AddrPC.Offset,
02361 &ModuleInfo))
02362 DPRINTF("1\t%p\n", (void*)sf.AddrPC.Offset);
02363 else
02364 DPRINTF("2\t%s+0x%lx\n", ModuleInfo.ImageName,
02365 sf.AddrPC.Offset - ModuleInfo.BaseOfImage);
02366 }
02367 else if (dwDisplacement)
02368 DPRINTF("3\t%s+0x%lx\n", pSymbol->Name, dwDisplacement);
02369 else
02370 DPRINTF("4\t%s\n", pSymbol->Name);
02371 }
02372
02373 ResumeThread(hThread);
02374 }
02375
02376 static DWORD WINAPI dump_thread_proc(LPVOID lpParameter)
02377 {
02378 dump_backtrace_for_thread((HANDLE)lpParameter);
02379 return 0;
02380 }
02381
02382
02383
02384 static void dump_backtrace()
02385 {
02386 HANDLE hCurrentThread;
02387 HANDLE hThread;
02388 DWORD dwThreadId;
02389 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
02390 GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
02391 hThread = CreateThread(NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread,
02392 0, &dwThreadId);
02393 WaitForSingleObject(hThread, INFINITE);
02394 CloseHandle(hThread);
02395 CloseHandle(hCurrentThread);
02396 }
02397 #endif
02398 #endif
02399
02400 #ifdef BACKTRACES
02401 void _dbus_print_backtrace(void)
02402 {
02403 init_backtrace();
02404 dump_backtrace();
02405 }
02406 #else
02407 void _dbus_print_backtrace(void)
02408 {
02409 _dbus_verbose (" D-Bus not compiled with backtrace support\n");
02410 }
02411 #endif
02412
02413 static dbus_uint32_t fromAscii(char ascii)
02414 {
02415 if(ascii >= '0' && ascii <= '9')
02416 return ascii - '0';
02417 if(ascii >= 'A' && ascii <= 'F')
02418 return ascii - 'A' + 10;
02419 if(ascii >= 'a' && ascii <= 'f')
02420 return ascii - 'a' + 10;
02421 return 0;
02422 }
02423
02424 dbus_bool_t _dbus_read_local_machine_uuid (DBusGUID *machine_id,
02425 dbus_bool_t create_if_not_found,
02426 DBusError *error)
02427 {
02428 #ifdef DBUS_WINCE
02429 return TRUE;
02430
02431 #else
02432 HW_PROFILE_INFOA info;
02433 char *lpc = &info.szHwProfileGuid[0];
02434 dbus_uint32_t u;
02435
02436
02437 if(!GetCurrentHwProfileA(&info))
02438 {
02439 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02440 return FALSE;
02441 }
02442
02443
02444 lpc++;
02445
02446 u = ((fromAscii(lpc[0]) << 0) |
02447 (fromAscii(lpc[1]) << 4) |
02448 (fromAscii(lpc[2]) << 8) |
02449 (fromAscii(lpc[3]) << 12) |
02450 (fromAscii(lpc[4]) << 16) |
02451 (fromAscii(lpc[5]) << 20) |
02452 (fromAscii(lpc[6]) << 24) |
02453 (fromAscii(lpc[7]) << 28));
02454 machine_id->as_uint32s[0] = u;
02455
02456 lpc += 9;
02457
02458 u = ((fromAscii(lpc[0]) << 0) |
02459 (fromAscii(lpc[1]) << 4) |
02460 (fromAscii(lpc[2]) << 8) |
02461 (fromAscii(lpc[3]) << 12) |
02462 (fromAscii(lpc[5]) << 16) |
02463 (fromAscii(lpc[6]) << 20) |
02464 (fromAscii(lpc[7]) << 24) |
02465 (fromAscii(lpc[8]) << 28));
02466 machine_id->as_uint32s[1] = u;
02467
02468 lpc += 10;
02469
02470 u = ((fromAscii(lpc[0]) << 0) |
02471 (fromAscii(lpc[1]) << 4) |
02472 (fromAscii(lpc[2]) << 8) |
02473 (fromAscii(lpc[3]) << 12) |
02474 (fromAscii(lpc[5]) << 16) |
02475 (fromAscii(lpc[6]) << 20) |
02476 (fromAscii(lpc[7]) << 24) |
02477 (fromAscii(lpc[8]) << 28));
02478 machine_id->as_uint32s[2] = u;
02479
02480 lpc += 9;
02481
02482 u = ((fromAscii(lpc[0]) << 0) |
02483 (fromAscii(lpc[1]) << 4) |
02484 (fromAscii(lpc[2]) << 8) |
02485 (fromAscii(lpc[3]) << 12) |
02486 (fromAscii(lpc[4]) << 16) |
02487 (fromAscii(lpc[5]) << 20) |
02488 (fromAscii(lpc[6]) << 24) |
02489 (fromAscii(lpc[7]) << 28));
02490 machine_id->as_uint32s[3] = u;
02491 #endif
02492 return TRUE;
02493 }
02494
02495 static
02496 HANDLE _dbus_global_lock (const char *mutexname)
02497 {
02498 HANDLE mutex;
02499 DWORD gotMutex;
02500
02501 mutex = CreateMutexA( NULL, FALSE, mutexname );
02502 if( !mutex )
02503 {
02504 return FALSE;
02505 }
02506
02507 gotMutex = WaitForSingleObject( mutex, INFINITE );
02508 switch( gotMutex )
02509 {
02510 case WAIT_ABANDONED:
02511 ReleaseMutex (mutex);
02512 CloseHandle (mutex);
02513 return 0;
02514 case WAIT_FAILED:
02515 case WAIT_TIMEOUT:
02516 return 0;
02517 }
02518
02519 return mutex;
02520 }
02521
02522 static
02523 void _dbus_global_unlock (HANDLE mutex)
02524 {
02525 ReleaseMutex (mutex);
02526 CloseHandle (mutex);
02527 }
02528
02529
02530 static HANDLE hDBusDaemonMutex = NULL;
02531 static HANDLE hDBusSharedMem = NULL;
02532
02533 static const char *cUniqueDBusInitMutex = "UniqueDBusInitMutex";
02534
02535 static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex";
02536
02537 static const char *cDBusDaemonMutex = "DBusDaemonMutex";
02538
02539 #ifdef _DEBUG
02540 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfoDebug";
02541 #else
02542 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
02543 #endif
02544
02545
02546 void
02547 _dbus_daemon_publish_session_bus_address (const char* address)
02548 {
02549 HANDLE lock;
02550 char *shared_addr = NULL;
02551 DWORD ret;
02552
02553 _dbus_assert (address);
02554
02555 hDBusDaemonMutex = CreateMutexA( NULL, FALSE, cDBusDaemonMutex );
02556 ret = WaitForSingleObject( hDBusDaemonMutex, 1000 );
02557 if ( ret != WAIT_OBJECT_0 ) {
02558 _dbus_warn("Could not lock mutex %s (return code %ld). daemon already running? Bus address not published.\n", cDBusDaemonMutex, ret );
02559 return;
02560 }
02561
02562
02563 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02564
02565
02566 hDBusSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
02567 0, strlen( address ) + 1, cDBusDaemonAddressInfo );
02568 _dbus_assert( hDBusSharedMem );
02569
02570 shared_addr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
02571
02572 _dbus_assert (shared_addr);
02573
02574 strcpy( shared_addr, address);
02575
02576
02577 UnmapViewOfFile( shared_addr );
02578
02579 _dbus_global_unlock( lock );
02580 }
02581
02582 void
02583 _dbus_daemon_unpublish_session_bus_address (void)
02584 {
02585 HANDLE lock;
02586
02587
02588 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02589
02590 CloseHandle( hDBusSharedMem );
02591
02592 hDBusSharedMem = NULL;
02593
02594 ReleaseMutex( hDBusDaemonMutex );
02595
02596 CloseHandle( hDBusDaemonMutex );
02597
02598 hDBusDaemonMutex = NULL;
02599
02600 _dbus_global_unlock( lock );
02601 }
02602
02603 static dbus_bool_t
02604 _dbus_get_autolaunch_shm (DBusString *address)
02605 {
02606 HANDLE sharedMem;
02607 char *shared_addr;
02608 int i;
02609
02610
02611 for(i=0;i<20;++i) {
02612
02613 sharedMem = OpenFileMappingA( FILE_MAP_READ, FALSE, cDBusDaemonAddressInfo );
02614 if( sharedMem == 0 )
02615 Sleep( 100 );
02616 if ( sharedMem != 0)
02617 break;
02618 }
02619
02620 if( sharedMem == 0 )
02621 return FALSE;
02622
02623 shared_addr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
02624
02625 if( !shared_addr )
02626 return FALSE;
02627
02628 _dbus_string_init( address );
02629
02630 _dbus_string_append( address, shared_addr );
02631
02632
02633 UnmapViewOfFile( shared_addr );
02634
02635 CloseHandle( sharedMem );
02636
02637 return TRUE;
02638 }
02639
02640 static dbus_bool_t
02641 _dbus_daemon_already_runs (DBusString *address)
02642 {
02643 HANDLE lock;
02644 HANDLE daemon;
02645 dbus_bool_t bRet = TRUE;
02646
02647
02648 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02649
02650
02651 daemon = CreateMutexA( NULL, FALSE, cDBusDaemonMutex );
02652 if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT)
02653 {
02654 ReleaseMutex (daemon);
02655 CloseHandle (daemon);
02656
02657 _dbus_global_unlock( lock );
02658 return FALSE;
02659 }
02660
02661
02662 bRet = _dbus_get_autolaunch_shm( address );
02663
02664
02665 CloseHandle ( daemon );
02666
02667 _dbus_global_unlock( lock );
02668
02669 return bRet;
02670 }
02671
02672 dbus_bool_t
02673 _dbus_get_autolaunch_address (DBusString *address,
02674 DBusError *error)
02675 {
02676 HANDLE mutex;
02677 STARTUPINFOA si;
02678 PROCESS_INFORMATION pi;
02679 dbus_bool_t retval = FALSE;
02680 LPSTR lpFile;
02681 char dbus_exe_path[MAX_PATH];
02682 char dbus_args[MAX_PATH * 2];
02683 const char * daemon_name = DBUS_DAEMON_NAME ".exe";
02684
02685 mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
02686
02687 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02688
02689 if (_dbus_daemon_already_runs(address))
02690 {
02691 _dbus_verbose("found already running dbus daemon\n");
02692 retval = TRUE;
02693 goto out;
02694 }
02695
02696 if (!SearchPathA(NULL, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
02697 {
02698 printf ("please add the path to %s to your PATH environment variable\n", daemon_name);
02699 printf ("or start the daemon manually\n\n");
02700 goto out;
02701 }
02702
02703
02704 ZeroMemory( &si, sizeof(si) );
02705 si.cb = sizeof(si);
02706 ZeroMemory( &pi, sizeof(pi) );
02707
02708 _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path, " --session");
02709
02710
02711
02712 if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
02713 {
02714 CloseHandle (pi.hThread);
02715 CloseHandle (pi.hProcess);
02716 retval = _dbus_get_autolaunch_shm( address );
02717 }
02718
02719 if (retval == FALSE)
02720 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to launch dbus-daemon");
02721
02722 out:
02723 if (retval)
02724 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02725 else
02726 _DBUS_ASSERT_ERROR_IS_SET (error);
02727
02728 _dbus_global_unlock (mutex);
02729
02730 return retval;
02731 }
02732
02733
02740 dbus_bool_t
02741 _dbus_make_file_world_readable(const DBusString *filename,
02742 DBusError *error)
02743 {
02744
02745 return TRUE;
02746 }
02747
02754 static const char *
02755 _dbus_windows_get_datadir (void)
02756 {
02757 return _dbus_replace_install_prefix(DBUS_DATADIR);
02758 }
02759
02760 #undef DBUS_DATADIR
02761 #define DBUS_DATADIR _dbus_windows_get_datadir ()
02762
02763
02764 #define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
02765 #define DBUS_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
02766
02783 dbus_bool_t
02784 _dbus_get_standard_session_servicedirs (DBusList **dirs)
02785 {
02786 const char *common_progs;
02787 DBusString servicedir_path;
02788
02789 if (!_dbus_string_init (&servicedir_path))
02790 return FALSE;
02791
02792 #ifdef DBUS_WINCE
02793 {
02794
02795 const char *data_dir = _dbus_getenv ("DBUS_DATADIR");
02796
02797 if (data_dir != NULL)
02798 {
02799 if (!_dbus_string_append (&servicedir_path, data_dir))
02800 goto oom;
02801
02802 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
02803 goto oom;
02804 }
02805 }
02806 #else
02807 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
02808 goto oom;
02809
02810 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
02811 goto oom;
02812 #endif
02813
02814 common_progs = _dbus_getenv ("CommonProgramFiles");
02815
02816 if (common_progs != NULL)
02817 {
02818 if (!_dbus_string_append (&servicedir_path, common_progs))
02819 goto oom;
02820
02821 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
02822 goto oom;
02823 }
02824
02825 if (!_dbus_split_paths_and_append (&servicedir_path,
02826 DBUS_STANDARD_SESSION_SERVICEDIR,
02827 dirs))
02828 goto oom;
02829
02830 _dbus_string_free (&servicedir_path);
02831 return TRUE;
02832
02833 oom:
02834 _dbus_string_free (&servicedir_path);
02835 return FALSE;
02836 }
02837
02856 dbus_bool_t
02857 _dbus_get_standard_system_servicedirs (DBusList **dirs)
02858 {
02859 *dirs = NULL;
02860 return TRUE;
02861 }
02862
02863 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
02864
02872 dbus_int32_t
02873 _dbus_atomic_inc (DBusAtomic *atomic)
02874 {
02875
02876
02877 return InterlockedIncrement (&atomic->value) - 1;
02878 }
02879
02887 dbus_int32_t
02888 _dbus_atomic_dec (DBusAtomic *atomic)
02889 {
02890
02891
02892 return InterlockedDecrement (&atomic->value) + 1;
02893 }
02894
02902 void
02903 _dbus_flush_caches (void)
02904 {
02905 }
02906
02913 dbus_bool_t
02914 _dbus_get_is_errno_eagain_or_ewouldblock (void)
02915 {
02916 return errno == WSAEWOULDBLOCK;
02917 }
02918
02926 static dbus_bool_t
02927 _dbus_get_install_root(char *prefix, int len)
02928 {
02929
02930 char* p = 0;
02931 int i;
02932 DWORD pathLength;
02933 char *lastSlash;
02934 SetLastError( 0 );
02935 pathLength = GetModuleFileNameA(_dbus_win_get_dll_hmodule(), prefix, len);
02936 if ( pathLength == 0 || GetLastError() != 0 ) {
02937 *prefix = '\0';
02938 return FALSE;
02939 }
02940 lastSlash = _mbsrchr(prefix, '\\');
02941 if (lastSlash == NULL) {
02942 *prefix = '\0';
02943 return FALSE;
02944 }
02945
02946 lastSlash[1] = 0;
02947
02948
02949
02950
02951
02952
02953
02954 if (lastSlash - prefix >= 4 && strnicmp(lastSlash - 4, "\\bin", 4) == 0)
02955 lastSlash[-3] = 0;
02956 else if (lastSlash - prefix >= 10 && strnicmp(lastSlash - 10, "\\bin\\debug", 10) == 0)
02957 lastSlash[-9] = 0;
02958 else if (lastSlash - prefix >= 12 && strnicmp(lastSlash - 12, "\\bin\\release", 12) == 0)
02959 lastSlash[-11] = 0;
02960
02961 return TRUE;
02962 }
02963
02977 dbus_bool_t
02978 _dbus_get_config_file_name(DBusString *config_file, char *s)
02979 {
02980 char path[MAX_PATH*2];
02981 int path_size = sizeof(path);
02982
02983 if (!_dbus_get_install_root(path,path_size))
02984 return FALSE;
02985
02986 if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
02987 return FALSE;
02988 strcat(path,"etc\\");
02989 strcat(path,s);
02990 if (_dbus_file_exists(path))
02991 {
02992
02993 if (!_dbus_string_append (config_file, path))
02994 return FALSE;
02995 }
02996 else
02997 {
02998 if (!_dbus_get_install_root(path,path_size))
02999 return FALSE;
03000 if(strlen(s) + 11 + strlen(path) > sizeof(path)-2)
03001 return FALSE;
03002 strcat(path,"etc\\dbus-1\\");
03003 strcat(path,s);
03004
03005 if (_dbus_file_exists(path))
03006 {
03007 if (!_dbus_string_append (config_file, path))
03008 return FALSE;
03009 }
03010 else
03011 {
03012 if (!_dbus_get_install_root(path,path_size))
03013 return FALSE;
03014 if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
03015 return FALSE;
03016 strcat(path,"bus\\");
03017 strcat(path,s);
03018
03019 if (_dbus_file_exists(path))
03020 {
03021 if (!_dbus_string_append (config_file, path))
03022 return FALSE;
03023 }
03024 }
03025 }
03026 return TRUE;
03027 }
03028
03037 dbus_bool_t
03038 _dbus_append_system_config_file (DBusString *str)
03039 {
03040 return _dbus_get_config_file_name(str, "system.conf");
03041 }
03042
03049 dbus_bool_t
03050 _dbus_append_session_config_file (DBusString *str)
03051 {
03052 return _dbus_get_config_file_name(str, "session.conf");
03053 }
03054
03055
03056 dbus_bool_t
03057 _dbus_lookup_session_address (dbus_bool_t *supported,
03058 DBusString *address,
03059 DBusError *error)
03060 {
03061
03062 *supported = FALSE;
03063 return TRUE;
03064 }
03065
03079 dbus_bool_t
03080 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03081 DBusCredentials *credentials)
03082 {
03083 DBusString homedir;
03084 DBusString dotdir;
03085 dbus_uid_t uid;
03086 const char *homepath;
03087 const char *homedrive;
03088
03089 _dbus_assert (credentials != NULL);
03090 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03091
03092 if (!_dbus_string_init (&homedir))
03093 return FALSE;
03094
03095 homedrive = _dbus_getenv("HOMEDRIVE");
03096 if (homedrive != NULL && *homedrive != '\0')
03097 {
03098 _dbus_string_append(&homedir,homedrive);
03099 }
03100
03101 homepath = _dbus_getenv("HOMEPATH");
03102 if (homepath != NULL && *homepath != '\0')
03103 {
03104 _dbus_string_append(&homedir,homepath);
03105 }
03106
03107 #ifdef DBUS_BUILD_TESTS
03108 {
03109 const char *override;
03110
03111 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03112 if (override != NULL && *override != '\0')
03113 {
03114 _dbus_string_set_length (&homedir, 0);
03115 if (!_dbus_string_append (&homedir, override))
03116 goto failed;
03117
03118 _dbus_verbose ("Using fake homedir for testing: %s\n",
03119 _dbus_string_get_const_data (&homedir));
03120 }
03121 else
03122 {
03123 static dbus_bool_t already_warned = FALSE;
03124 if (!already_warned)
03125 {
03126 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03127 already_warned = TRUE;
03128 }
03129 }
03130 }
03131 #endif
03132
03133 #ifdef DBUS_WINCE
03134
03135
03136 #define KEYRING_DIR "dbus-keyrings"
03137 #else
03138 #define KEYRING_DIR ".dbus-keyrings"
03139 #endif
03140
03141 _dbus_string_init_const (&dotdir, KEYRING_DIR);
03142 if (!_dbus_concat_dir_and_file (&homedir,
03143 &dotdir))
03144 goto failed;
03145
03146 if (!_dbus_string_copy (&homedir, 0,
03147 directory, _dbus_string_get_length (directory))) {
03148 goto failed;
03149 }
03150
03151 _dbus_string_free (&homedir);
03152 return TRUE;
03153
03154 failed:
03155 _dbus_string_free (&homedir);
03156 return FALSE;
03157 }
03158
03164 dbus_bool_t
03165 _dbus_file_exists (const char *file)
03166 {
03167 DWORD attributes = GetFileAttributesA (file);
03168
03169 if (attributes != INVALID_FILE_ATTRIBUTES && GetLastError() != ERROR_PATH_NOT_FOUND)
03170 return TRUE;
03171 else
03172 return FALSE;
03173 }
03174
03182 const char*
03183 _dbus_strerror (int error_number)
03184 {
03185 #ifdef DBUS_WINCE
03186
03187 return "unknown";
03188 #else
03189 const char *msg;
03190
03191 switch (error_number)
03192 {
03193 case WSAEINTR:
03194 return "Interrupted function call";
03195 case WSAEACCES:
03196 return "Permission denied";
03197 case WSAEFAULT:
03198 return "Bad address";
03199 case WSAEINVAL:
03200 return "Invalid argument";
03201 case WSAEMFILE:
03202 return "Too many open files";
03203 case WSAEWOULDBLOCK:
03204 return "Resource temporarily unavailable";
03205 case WSAEINPROGRESS:
03206 return "Operation now in progress";
03207 case WSAEALREADY:
03208 return "Operation already in progress";
03209 case WSAENOTSOCK:
03210 return "Socket operation on nonsocket";
03211 case WSAEDESTADDRREQ:
03212 return "Destination address required";
03213 case WSAEMSGSIZE:
03214 return "Message too long";
03215 case WSAEPROTOTYPE:
03216 return "Protocol wrong type for socket";
03217 case WSAENOPROTOOPT:
03218 return "Bad protocol option";
03219 case WSAEPROTONOSUPPORT:
03220 return "Protocol not supported";
03221 case WSAESOCKTNOSUPPORT:
03222 return "Socket type not supported";
03223 case WSAEOPNOTSUPP:
03224 return "Operation not supported";
03225 case WSAEPFNOSUPPORT:
03226 return "Protocol family not supported";
03227 case WSAEAFNOSUPPORT:
03228 return "Address family not supported by protocol family";
03229 case WSAEADDRINUSE:
03230 return "Address already in use";
03231 case WSAEADDRNOTAVAIL:
03232 return "Cannot assign requested address";
03233 case WSAENETDOWN:
03234 return "Network is down";
03235 case WSAENETUNREACH:
03236 return "Network is unreachable";
03237 case WSAENETRESET:
03238 return "Network dropped connection on reset";
03239 case WSAECONNABORTED:
03240 return "Software caused connection abort";
03241 case WSAECONNRESET:
03242 return "Connection reset by peer";
03243 case WSAENOBUFS:
03244 return "No buffer space available";
03245 case WSAEISCONN:
03246 return "Socket is already connected";
03247 case WSAENOTCONN:
03248 return "Socket is not connected";
03249 case WSAESHUTDOWN:
03250 return "Cannot send after socket shutdown";
03251 case WSAETIMEDOUT:
03252 return "Connection timed out";
03253 case WSAECONNREFUSED:
03254 return "Connection refused";
03255 case WSAEHOSTDOWN:
03256 return "Host is down";
03257 case WSAEHOSTUNREACH:
03258 return "No route to host";
03259 case WSAEPROCLIM:
03260 return "Too many processes";
03261 case WSAEDISCON:
03262 return "Graceful shutdown in progress";
03263 case WSATYPE_NOT_FOUND:
03264 return "Class type not found";
03265 case WSAHOST_NOT_FOUND:
03266 return "Host not found";
03267 case WSATRY_AGAIN:
03268 return "Nonauthoritative host not found";
03269 case WSANO_RECOVERY:
03270 return "This is a nonrecoverable error";
03271 case WSANO_DATA:
03272 return "Valid name, no data record of requested type";
03273 case WSA_INVALID_HANDLE:
03274 return "Specified event object handle is invalid";
03275 case WSA_INVALID_PARAMETER:
03276 return "One or more parameters are invalid";
03277 case WSA_IO_INCOMPLETE:
03278 return "Overlapped I/O event object not in signaled state";
03279 case WSA_IO_PENDING:
03280 return "Overlapped operations will complete later";
03281 case WSA_NOT_ENOUGH_MEMORY:
03282 return "Insufficient memory available";
03283 case WSA_OPERATION_ABORTED:
03284 return "Overlapped operation aborted";
03285 #ifdef WSAINVALIDPROCTABLE
03286
03287 case WSAINVALIDPROCTABLE:
03288 return "Invalid procedure table from service provider";
03289 #endif
03290 #ifdef WSAINVALIDPROVIDER
03291
03292 case WSAINVALIDPROVIDER:
03293 return "Invalid service provider version number";
03294 #endif
03295 #ifdef WSAPROVIDERFAILEDINIT
03296
03297 case WSAPROVIDERFAILEDINIT:
03298 return "Unable to initialize a service provider";
03299 #endif
03300
03301 case WSASYSCALLFAILURE:
03302 return "System call failure";
03303 }
03304 msg = strerror (error_number);
03305 if (msg == NULL)
03306 msg = "unknown";
03307
03308 return msg;
03309 #endif //DBUS_WINCE
03310 }
03311
03319 void
03320 _dbus_win_set_error_from_win_error (DBusError *error,
03321 int code)
03322 {
03323 char *msg;
03324
03325
03326 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
03327 FORMAT_MESSAGE_IGNORE_INSERTS |
03328 FORMAT_MESSAGE_FROM_SYSTEM,
03329 NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
03330 (LPSTR) &msg, 0, NULL);
03331 if (msg)
03332 {
03333 char *msg_copy;
03334
03335 msg_copy = dbus_malloc (strlen (msg));
03336 strcpy (msg_copy, msg);
03337 LocalFree (msg);
03338
03339 dbus_set_error (error, "win32.error", "%s", msg_copy);
03340 }
03341 else
03342 dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code);
03343 }
03344
03345 void
03346 _dbus_win_warn_win_error (const char *message,
03347 int code)
03348 {
03349 DBusError error;
03350
03351 dbus_error_init (&error);
03352 _dbus_win_set_error_from_win_error (&error, code);
03353 _dbus_warn ("%s: %s\n", message, error.message);
03354 dbus_error_free (&error);
03355 }
03356
03364 dbus_bool_t
03365 _dbus_delete_directory (const DBusString *filename,
03366 DBusError *error)
03367 {
03368 const char *filename_c;
03369
03370 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03371
03372 filename_c = _dbus_string_get_const_data (filename);
03373
03374 if (RemoveDirectoryA (filename_c) == 0)
03375 {
03376 char *emsg = _dbus_win_error_string (GetLastError ());
03377 dbus_set_error (error, _dbus_win_error_from_last_error (),
03378 "Failed to remove directory %s: %s",
03379 filename_c, emsg);
03380 _dbus_win_free_error_string (emsg);
03381 return FALSE;
03382 }
03383
03384 return TRUE;
03385 }
03386
03388
03389