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