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 va_list args_copy;
00542
00543 bufsize = sizeof (buf);
00544 DBUS_VA_COPY (args_copy, args);
00545 len = _vsnprintf (buf, bufsize - 1, format, args_copy);
00546 va_end (args_copy);
00547
00548 while (len == -1)
00549 {
00550 char *p;
00551
00552 bufsize *= 2;
00553
00554 p = malloc (bufsize);
00555
00556 if (p == NULL)
00557 return -1;
00558
00559 DBUS_VA_COPY (args_copy, args);
00560 len = _vsnprintf (p, bufsize - 1, format, args_copy);
00561 va_end (args_copy);
00562 free (p);
00563 }
00564
00565 return len;
00566 }
00567
00568
00576 wchar_t *
00577 _dbus_win_utf8_to_utf16 (const char *str,
00578 DBusError *error)
00579 {
00580 DBusString s;
00581 int n;
00582 wchar_t *retval;
00583
00584 _dbus_string_init_const (&s, str);
00585
00586 if (!_dbus_string_validate_utf8 (&s, 0, _dbus_string_get_length (&s)))
00587 {
00588 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid UTF-8");
00589 return NULL;
00590 }
00591
00592 n = MultiByteToWideChar (CP_UTF8, 0, str, -1, NULL, 0);
00593
00594 if (n == 0)
00595 {
00596 _dbus_win_set_error_from_win_error (error, GetLastError ());
00597 return NULL;
00598 }
00599
00600 retval = dbus_new (wchar_t, n);
00601
00602 if (!retval)
00603 {
00604 _DBUS_SET_OOM (error);
00605 return NULL;
00606 }
00607
00608 if (MultiByteToWideChar (CP_UTF8, 0, str, -1, retval, n) != n)
00609 {
00610 dbus_free (retval);
00611 dbus_set_error_const (error, DBUS_ERROR_FAILED, "MultiByteToWideChar inconsistency");
00612 return NULL;
00613 }
00614
00615 return retval;
00616 }
00617
00625 char *
00626 _dbus_win_utf16_to_utf8 (const wchar_t *str,
00627 DBusError *error)
00628 {
00629 int n;
00630 char *retval;
00631
00632 n = WideCharToMultiByte (CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
00633
00634 if (n == 0)
00635 {
00636 _dbus_win_set_error_from_win_error (error, GetLastError ());
00637 return NULL;
00638 }
00639
00640 retval = dbus_malloc (n);
00641
00642 if (!retval)
00643 {
00644 _DBUS_SET_OOM (error);
00645 return NULL;
00646 }
00647
00648 if (WideCharToMultiByte (CP_UTF8, 0, str, -1, retval, n, NULL, NULL) != n)
00649 {
00650 dbus_free (retval);
00651 dbus_set_error_const (error, DBUS_ERROR_FAILED, "WideCharToMultiByte inconsistency");
00652 return NULL;
00653 }
00654
00655 return retval;
00656 }
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 dbus_bool_t
00669 _dbus_win_account_to_sid (const wchar_t *waccount,
00670 void **ppsid,
00671 DBusError *error)
00672 {
00673 dbus_bool_t retval = FALSE;
00674 DWORD sid_length, wdomain_length;
00675 SID_NAME_USE use;
00676 wchar_t *wdomain;
00677
00678 *ppsid = NULL;
00679
00680 sid_length = 0;
00681 wdomain_length = 0;
00682 if (!LookupAccountNameW (NULL, waccount, NULL, &sid_length,
00683 NULL, &wdomain_length, &use) &&
00684 GetLastError () != ERROR_INSUFFICIENT_BUFFER)
00685 {
00686 _dbus_win_set_error_from_win_error (error, GetLastError ());
00687 return FALSE;
00688 }
00689
00690 *ppsid = dbus_malloc (sid_length);
00691 if (!*ppsid)
00692 {
00693 _DBUS_SET_OOM (error);
00694 return FALSE;
00695 }
00696
00697 wdomain = dbus_new (wchar_t, wdomain_length);
00698 if (!wdomain)
00699 {
00700 _DBUS_SET_OOM (error);
00701 goto out1;
00702 }
00703
00704 if (!LookupAccountNameW (NULL, waccount, (PSID) *ppsid, &sid_length,
00705 wdomain, &wdomain_length, &use))
00706 {
00707 _dbus_win_set_error_from_win_error (error, GetLastError ());
00708 goto out2;
00709 }
00710
00711 if (!IsValidSid ((PSID) *ppsid))
00712 {
00713 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID");
00714 goto out2;
00715 }
00716
00717 retval = TRUE;
00718
00719 out2:
00720 dbus_free (wdomain);
00721 out1:
00722 if (!retval)
00723 {
00724 dbus_free (*ppsid);
00725 *ppsid = NULL;
00726 }
00727
00728 return retval;
00729 }
00730
00740 unsigned long
00741 _dbus_pid_for_log (void)
00742 {
00743 return _dbus_getpid ();
00744 }
00745
00746
00747 #ifndef DBUS_WINCE
00748
00752 static dbus_bool_t
00753 _dbus_getsid(char **sid)
00754 {
00755 HANDLE process_token = INVALID_HANDLE_VALUE;
00756 TOKEN_USER *token_user = NULL;
00757 DWORD n;
00758 PSID psid;
00759 int retval = FALSE;
00760
00761 if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &process_token))
00762 {
00763 _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ());
00764 goto failed;
00765 }
00766 if ((!GetTokenInformation (process_token, TokenUser, NULL, 0, &n)
00767 && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
00768 || (token_user = alloca (n)) == NULL
00769 || !GetTokenInformation (process_token, TokenUser, token_user, n, &n))
00770 {
00771 _dbus_win_warn_win_error ("GetTokenInformation failed", GetLastError ());
00772 goto failed;
00773 }
00774 psid = token_user->User.Sid;
00775 if (!IsValidSid (psid))
00776 {
00777 _dbus_verbose("%s invalid sid\n",__FUNCTION__);
00778 goto failed;
00779 }
00780 if (!ConvertSidToStringSidA (psid, sid))
00781 {
00782 _dbus_verbose("%s invalid sid\n",__FUNCTION__);
00783 goto failed;
00784 }
00785
00786 retval = TRUE;
00787
00788 failed:
00789 if (process_token != INVALID_HANDLE_VALUE)
00790 CloseHandle (process_token);
00791
00792 _dbus_verbose("_dbus_getsid() returns %d\n",retval);
00793 return retval;
00794 }
00795 #endif
00796
00797
00798
00799
00800
00801
00802
00813 dbus_bool_t
00814 _dbus_full_duplex_pipe (int *fd1,
00815 int *fd2,
00816 dbus_bool_t blocking,
00817 DBusError *error)
00818 {
00819 SOCKET temp, socket1 = -1, socket2 = -1;
00820 struct sockaddr_in saddr;
00821 int len;
00822 u_long arg;
00823
00824 _dbus_win_startup_winsock ();
00825
00826 temp = socket (AF_INET, SOCK_STREAM, 0);
00827 if (temp == INVALID_SOCKET)
00828 {
00829 DBUS_SOCKET_SET_ERRNO ();
00830 goto out0;
00831 }
00832
00833 _DBUS_ZERO (saddr);
00834 saddr.sin_family = AF_INET;
00835 saddr.sin_port = 0;
00836 saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
00837
00838 if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr)) == SOCKET_ERROR)
00839 {
00840 DBUS_SOCKET_SET_ERRNO ();
00841 goto out0;
00842 }
00843
00844 if (listen (temp, 1) == SOCKET_ERROR)
00845 {
00846 DBUS_SOCKET_SET_ERRNO ();
00847 goto out0;
00848 }
00849
00850 len = sizeof (saddr);
00851 if (getsockname (temp, (struct sockaddr *)&saddr, &len) == SOCKET_ERROR)
00852 {
00853 DBUS_SOCKET_SET_ERRNO ();
00854 goto out0;
00855 }
00856
00857 socket1 = socket (AF_INET, SOCK_STREAM, 0);
00858 if (socket1 == INVALID_SOCKET)
00859 {
00860 DBUS_SOCKET_SET_ERRNO ();
00861 goto out0;
00862 }
00863
00864 if (connect (socket1, (struct sockaddr *)&saddr, len) == SOCKET_ERROR)
00865 {
00866 DBUS_SOCKET_SET_ERRNO ();
00867 goto out1;
00868 }
00869
00870 socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
00871 if (socket2 == INVALID_SOCKET)
00872 {
00873 DBUS_SOCKET_SET_ERRNO ();
00874 goto out1;
00875 }
00876
00877 if (!blocking)
00878 {
00879 arg = 1;
00880 if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
00881 {
00882 DBUS_SOCKET_SET_ERRNO ();
00883 goto out2;
00884 }
00885
00886 arg = 1;
00887 if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
00888 {
00889 DBUS_SOCKET_SET_ERRNO ();
00890 goto out2;
00891 }
00892 }
00893
00894 *fd1 = socket1;
00895 *fd2 = socket2;
00896
00897 _dbus_verbose ("full-duplex pipe %d:%d <-> %d:%d\n",
00898 *fd1, socket1, *fd2, socket2);
00899
00900 closesocket (temp);
00901
00902 return TRUE;
00903
00904 out2:
00905 closesocket (socket2);
00906 out1:
00907 closesocket (socket1);
00908 out0:
00909 closesocket (temp);
00910
00911 dbus_set_error (error, _dbus_error_from_errno (errno),
00912 "Could not setup socket pair: %s",
00913 _dbus_strerror_from_errno ());
00914
00915 return FALSE;
00916 }
00917
00926 int
00927 _dbus_poll (DBusPollFD *fds,
00928 int n_fds,
00929 int timeout_milliseconds)
00930 {
00931 #define USE_CHRIS_IMPL 0
00932
00933 #if USE_CHRIS_IMPL
00934
00935 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
00936 char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
00937 char *msgp;
00938
00939 int ret = 0;
00940 int i;
00941 struct timeval tv;
00942 int ready;
00943
00944 #define DBUS_STACK_WSAEVENTS 256
00945 WSAEVENT eventsOnStack[DBUS_STACK_WSAEVENTS];
00946 WSAEVENT *pEvents = NULL;
00947 if (n_fds > DBUS_STACK_WSAEVENTS)
00948 pEvents = calloc(sizeof(WSAEVENT), n_fds);
00949 else
00950 pEvents = eventsOnStack;
00951
00952
00953 #ifdef DBUS_ENABLE_VERBOSE_MODE
00954 msgp = msg;
00955 msgp += sprintf (msgp, "WSAEventSelect: to=%d\n\t", timeout_milliseconds);
00956 for (i = 0; i < n_fds; i++)
00957 {
00958 DBusPollFD *fdp = &fds[i];
00959
00960
00961 if (fdp->events & _DBUS_POLLIN)
00962 msgp += sprintf (msgp, "R:%d ", fdp->fd);
00963
00964 if (fdp->events & _DBUS_POLLOUT)
00965 msgp += sprintf (msgp, "W:%d ", fdp->fd);
00966
00967 msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
00968
00969
00970
00971 if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
00972 {
00973 _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
00974 }
00975 }
00976
00977 msgp += sprintf (msgp, "\n");
00978 _dbus_verbose ("%s",msg);
00979 #endif
00980 for (i = 0; i < n_fds; i++)
00981 {
00982 DBusPollFD *fdp = &fds[i];
00983 WSAEVENT ev;
00984 long lNetworkEvents = FD_OOB;
00985
00986 ev = WSACreateEvent();
00987
00988 if (fdp->events & _DBUS_POLLIN)
00989 lNetworkEvents |= FD_READ | FD_ACCEPT | FD_CLOSE;
00990
00991 if (fdp->events & _DBUS_POLLOUT)
00992 lNetworkEvents |= FD_WRITE | FD_CONNECT;
00993
00994 WSAEventSelect(fdp->fd, ev, lNetworkEvents);
00995
00996 pEvents[i] = ev;
00997 }
00998
00999
01000 ready = WSAWaitForMultipleEvents (n_fds, pEvents, FALSE, timeout_milliseconds, FALSE);
01001
01002 if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
01003 {
01004 DBUS_SOCKET_SET_ERRNO ();
01005 if (errno != WSAEWOULDBLOCK)
01006 _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", _dbus_strerror_from_errno ());
01007 ret = -1;
01008 }
01009 else if (ready == WSA_WAIT_TIMEOUT)
01010 {
01011 _dbus_verbose ("WSAWaitForMultipleEvents: WSA_WAIT_TIMEOUT\n");
01012 ret = 0;
01013 }
01014 else if (ready >= WSA_WAIT_EVENT_0 && ready < (int)(WSA_WAIT_EVENT_0 + n_fds))
01015 {
01016 msgp = msg;
01017 msgp += sprintf (msgp, "WSAWaitForMultipleEvents: =%d\n\t", ready);
01018
01019 for (i = 0; i < n_fds; i++)
01020 {
01021 DBusPollFD *fdp = &fds[i];
01022 WSANETWORKEVENTS ne;
01023
01024 fdp->revents = 0;
01025
01026 WSAEnumNetworkEvents(fdp->fd, pEvents[i], &ne);
01027
01028 if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
01029 fdp->revents |= _DBUS_POLLIN;
01030
01031 if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
01032 fdp->revents |= _DBUS_POLLOUT;
01033
01034 if (ne.lNetworkEvents & (FD_OOB))
01035 fdp->revents |= _DBUS_POLLERR;
01036
01037 if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
01038 msgp += sprintf (msgp, "R:%d ", fdp->fd);
01039
01040 if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
01041 msgp += sprintf (msgp, "W:%d ", fdp->fd);
01042
01043 if (ne.lNetworkEvents & (FD_OOB))
01044 msgp += sprintf (msgp, "E:%d ", fdp->fd);
01045
01046 msgp += sprintf (msgp, "lNetworkEvents:%d ", ne.lNetworkEvents);
01047
01048 if(ne.lNetworkEvents)
01049 ret++;
01050
01051 WSAEventSelect(fdp->fd, pEvents[i], 0);
01052 }
01053
01054 msgp += sprintf (msgp, "\n");
01055 _dbus_verbose ("%s",msg);
01056 }
01057 else
01058 {
01059 _dbus_verbose ("WSAWaitForMultipleEvents: failed for unknown reason!");
01060 ret = -1;
01061 }
01062
01063 for(i = 0; i < n_fds; i++)
01064 {
01065 WSACloseEvent(pEvents[i]);
01066 }
01067
01068 if (n_fds > DBUS_STACK_WSAEVENTS)
01069 free(pEvents);
01070
01071 return ret;
01072
01073 #else
01074
01075 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
01076 char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
01077 char *msgp;
01078
01079 fd_set read_set, write_set, err_set;
01080 int max_fd = 0;
01081 int i;
01082 struct timeval tv;
01083 int ready;
01084
01085 FD_ZERO (&read_set);
01086 FD_ZERO (&write_set);
01087 FD_ZERO (&err_set);
01088
01089
01090 #ifdef DBUS_ENABLE_VERBOSE_MODE
01091 msgp = msg;
01092 msgp += sprintf (msgp, "select: to=%d\n\t", timeout_milliseconds);
01093 for (i = 0; i < n_fds; i++)
01094 {
01095 DBusPollFD *fdp = &fds[i];
01096
01097
01098 if (fdp->events & _DBUS_POLLIN)
01099 msgp += sprintf (msgp, "R:%d ", fdp->fd);
01100
01101 if (fdp->events & _DBUS_POLLOUT)
01102 msgp += sprintf (msgp, "W:%d ", fdp->fd);
01103
01104 msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
01105
01106
01107
01108 if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
01109 {
01110 _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
01111 }
01112 }
01113
01114 msgp += sprintf (msgp, "\n");
01115 _dbus_verbose ("%s",msg);
01116 #endif
01117 for (i = 0; i < n_fds; i++)
01118 {
01119 DBusPollFD *fdp = &fds[i];
01120
01121 if (fdp->events & _DBUS_POLLIN)
01122 FD_SET (fdp->fd, &read_set);
01123
01124 if (fdp->events & _DBUS_POLLOUT)
01125 FD_SET (fdp->fd, &write_set);
01126
01127 FD_SET (fdp->fd, &err_set);
01128
01129 max_fd = MAX (max_fd, fdp->fd);
01130 }
01131
01132
01133 tv.tv_sec = timeout_milliseconds < 0 ? 1 : timeout_milliseconds / 1000;
01134 tv.tv_usec = timeout_milliseconds < 0 ? 0 : (timeout_milliseconds % 1000) * 1000;
01135
01136 ready = select (max_fd + 1, &read_set, &write_set, &err_set, &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 _dbus_fd_set_close_on_exec (fd);
01363
01364 if (!_dbus_set_fd_nonblocking (fd, error))
01365 {
01366 closesocket (fd);
01367 return -1;
01368 }
01369
01370 return fd;
01371 }
01372
01388 int
01389 _dbus_listen_tcp_socket (const char *host,
01390 const char *port,
01391 const char *family,
01392 DBusString *retport,
01393 int **fds_p,
01394 DBusError *error)
01395 {
01396 int nlisten_fd = 0, *listen_fd = NULL, res, i, port_num = -1;
01397 struct addrinfo hints;
01398 struct addrinfo *ai, *tmp;
01399
01400
01401
01402
01403
01404 typedef union {
01405 struct sockaddr Address;
01406 struct sockaddr_in AddressIn;
01407 struct sockaddr_in6 AddressIn6;
01408 } mysockaddr_gen;
01409
01410 *fds_p = NULL;
01411 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01412
01413 _dbus_win_startup_winsock ();
01414
01415 _DBUS_ZERO (hints);
01416
01417 if (!family)
01418 hints.ai_family = AF_UNSPEC;
01419 else if (!strcmp(family, "ipv4"))
01420 hints.ai_family = AF_INET;
01421 else if (!strcmp(family, "ipv6"))
01422 hints.ai_family = AF_INET6;
01423 else
01424 {
01425 dbus_set_error (error,
01426 DBUS_ERROR_INVALID_ARGS,
01427 "Unknown address family %s", family);
01428 return -1;
01429 }
01430
01431 hints.ai_protocol = IPPROTO_TCP;
01432 hints.ai_socktype = SOCK_STREAM;
01433 #ifdef AI_ADDRCONFIG
01434 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01435 #else
01436 hints.ai_flags = AI_PASSIVE;
01437 #endif
01438
01439 redo_lookup_with_port:
01440 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01441 {
01442 dbus_set_error (error,
01443 _dbus_error_from_errno (res),
01444 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01445 host ? host : "*", port, _dbus_strerror(res), res);
01446 return -1;
01447 }
01448
01449 tmp = ai;
01450 while (tmp)
01451 {
01452 int fd = -1, *newlisten_fd;
01453 if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
01454 {
01455 DBUS_SOCKET_SET_ERRNO ();
01456 dbus_set_error (error,
01457 _dbus_error_from_errno (errno),
01458 "Failed to open socket: %s",
01459 _dbus_strerror_from_errno ());
01460 goto failed;
01461 }
01462 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01463
01464 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
01465 {
01466 DBUS_SOCKET_SET_ERRNO ();
01467 dbus_set_error (error, _dbus_error_from_errno (errno),
01468 "Failed to bind socket \"%s:%s\": %s",
01469 host ? host : "*", port, _dbus_strerror_from_errno ());
01470 closesocket (fd);
01471 goto failed;
01472 }
01473
01474 if (listen (fd, 30 ) == SOCKET_ERROR)
01475 {
01476 DBUS_SOCKET_SET_ERRNO ();
01477 dbus_set_error (error, _dbus_error_from_errno (errno),
01478 "Failed to listen on socket \"%s:%s\": %s",
01479 host ? host : "*", port, _dbus_strerror_from_errno ());
01480 closesocket (fd);
01481 goto failed;
01482 }
01483
01484 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01485 if (!newlisten_fd)
01486 {
01487 closesocket (fd);
01488 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01489 "Failed to allocate file handle array");
01490 goto failed;
01491 }
01492 listen_fd = newlisten_fd;
01493 listen_fd[nlisten_fd] = fd;
01494 nlisten_fd++;
01495
01496 if (!_dbus_string_get_length(retport))
01497 {
01498
01499
01500
01501
01502 if (!port || !strcmp(port, "0"))
01503 {
01504 mysockaddr_gen addr;
01505 socklen_t addrlen = sizeof(addr);
01506 char portbuf[10];
01507
01508 if (getsockname(fd, &addr.Address, &addrlen) == SOCKET_ERROR)
01509 {
01510 DBUS_SOCKET_SET_ERRNO ();
01511 dbus_set_error (error, _dbus_error_from_errno (errno),
01512 "Failed to resolve port \"%s:%s\": %s",
01513 host ? host : "*", port, _dbus_strerror_from_errno());
01514 goto failed;
01515 }
01516 snprintf( portbuf, sizeof( portbuf ) - 1, "%d", addr.AddressIn.sin_port );
01517 if (!_dbus_string_append(retport, portbuf))
01518 {
01519 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01520 goto failed;
01521 }
01522
01523
01524 port = _dbus_string_get_const_data(retport);
01525 freeaddrinfo(ai);
01526 goto redo_lookup_with_port;
01527 }
01528 else
01529 {
01530 if (!_dbus_string_append(retport, port))
01531 {
01532 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01533 goto failed;
01534 }
01535 }
01536 }
01537
01538 tmp = tmp->ai_next;
01539 }
01540 freeaddrinfo(ai);
01541 ai = NULL;
01542
01543 if (!nlisten_fd)
01544 {
01545 _dbus_win_set_errno (WSAEADDRINUSE);
01546 dbus_set_error (error, _dbus_error_from_errno (errno),
01547 "Failed to bind socket \"%s:%s\": %s",
01548 host ? host : "*", port, _dbus_strerror_from_errno ());
01549 return -1;
01550 }
01551
01552 sscanf(_dbus_string_get_const_data(retport), "%d", &port_num);
01553
01554 for (i = 0 ; i < nlisten_fd ; i++)
01555 {
01556 _dbus_fd_set_close_on_exec (listen_fd[i]);
01557 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01558 {
01559 goto failed;
01560 }
01561 }
01562
01563 *fds_p = listen_fd;
01564
01565 return nlisten_fd;
01566
01567 failed:
01568 if (ai)
01569 freeaddrinfo(ai);
01570 for (i = 0 ; i < nlisten_fd ; i++)
01571 closesocket (listen_fd[i]);
01572 dbus_free(listen_fd);
01573 return -1;
01574 }
01575
01576
01584 int
01585 _dbus_accept (int listen_fd)
01586 {
01587 int client_fd;
01588
01589 retry:
01590 client_fd = accept (listen_fd, NULL, NULL);
01591
01592 if (DBUS_SOCKET_IS_INVALID (client_fd))
01593 {
01594 DBUS_SOCKET_SET_ERRNO ();
01595 if (errno == EINTR)
01596 goto retry;
01597 }
01598
01599 _dbus_verbose ("client fd %d accepted\n", client_fd);
01600
01601 return client_fd;
01602 }
01603
01604
01605
01606
01607 dbus_bool_t
01608 _dbus_send_credentials_socket (int handle,
01609 DBusError *error)
01610 {
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634 int bytes_written;
01635 DBusString buf;
01636
01637 _dbus_string_init_const_len (&buf, "\0", 1);
01638 again:
01639 bytes_written = _dbus_write_socket (handle, &buf, 0, 1 );
01640
01641 if (bytes_written < 0 && errno == EINTR)
01642 goto again;
01643
01644 if (bytes_written < 0)
01645 {
01646 dbus_set_error (error, _dbus_error_from_errno (errno),
01647 "Failed to write credentials byte: %s",
01648 _dbus_strerror_from_errno ());
01649 return FALSE;
01650 }
01651 else if (bytes_written == 0)
01652 {
01653 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01654 "wrote zero bytes writing credentials byte");
01655 return FALSE;
01656 }
01657 else
01658 {
01659 _dbus_assert (bytes_written == 1);
01660 _dbus_verbose ("wrote 1 zero byte, credential sending isn't implemented yet\n");
01661 return TRUE;
01662 }
01663 return TRUE;
01664 }
01665
01684 dbus_bool_t
01685 _dbus_read_credentials_socket (int handle,
01686 DBusCredentials *credentials,
01687 DBusError *error)
01688 {
01689 int bytes_read = 0;
01690 DBusString buf;
01691
01692
01693 if (_dbus_string_init(&buf))
01694 {
01695 bytes_read = _dbus_read_socket(handle, &buf, 1 );
01696
01697 if (bytes_read > 0)
01698 _dbus_verbose("got one zero byte from server");
01699
01700 _dbus_string_free(&buf);
01701 }
01702
01703 _dbus_credentials_add_from_current_process (credentials);
01704 _dbus_verbose("FIXME: get faked credentials from current process");
01705
01706 return TRUE;
01707 }
01708
01717 dbus_bool_t
01718 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01719 {
01720
01721 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01722 return TRUE;
01723 }
01724
01725
01736 dbus_bool_t
01737 _dbus_concat_dir_and_file (DBusString *dir,
01738 const DBusString *next_component)
01739 {
01740 dbus_bool_t dir_ends_in_slash;
01741 dbus_bool_t file_starts_with_slash;
01742
01743 if (_dbus_string_get_length (dir) == 0 ||
01744 _dbus_string_get_length (next_component) == 0)
01745 return TRUE;
01746
01747 dir_ends_in_slash =
01748 ('/' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1) ||
01749 '\\' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1));
01750
01751 file_starts_with_slash =
01752 ('/' == _dbus_string_get_byte (next_component, 0) ||
01753 '\\' == _dbus_string_get_byte (next_component, 0));
01754
01755 if (dir_ends_in_slash && file_starts_with_slash)
01756 {
01757 _dbus_string_shorten (dir, 1);
01758 }
01759 else if (!(dir_ends_in_slash || file_starts_with_slash))
01760 {
01761 if (!_dbus_string_append_byte (dir, '\\'))
01762 return FALSE;
01763 }
01764
01765 return _dbus_string_copy (next_component, 0, dir,
01766 _dbus_string_get_length (dir));
01767 }
01768
01769
01770
01778 dbus_bool_t
01779 _dbus_credentials_add_from_user (DBusCredentials *credentials,
01780 const DBusString *username)
01781 {
01782 return _dbus_credentials_add_windows_sid (credentials,
01783 _dbus_string_get_const_data(username));
01784 }
01785
01794 dbus_bool_t
01795 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
01796 {
01797 dbus_bool_t retval = FALSE;
01798 char *sid = NULL;
01799
01800 if (!_dbus_getsid(&sid))
01801 goto failed;
01802
01803 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
01804 goto failed;
01805
01806 if (!_dbus_credentials_add_windows_sid (credentials,sid))
01807 goto failed;
01808
01809 retval = TRUE;
01810 goto end;
01811 failed:
01812 retval = FALSE;
01813 end:
01814 if (sid)
01815 LocalFree(sid);
01816
01817 return retval;
01818 }
01819
01832 dbus_bool_t
01833 _dbus_append_user_from_current_process (DBusString *str)
01834 {
01835 dbus_bool_t retval = FALSE;
01836 char *sid = NULL;
01837
01838 if (!_dbus_getsid(&sid))
01839 return FALSE;
01840
01841 retval = _dbus_string_append (str,sid);
01842
01843 LocalFree(sid);
01844 return retval;
01845 }
01846
01851 dbus_pid_t
01852 _dbus_getpid (void)
01853 {
01854 return GetCurrentProcessId ();
01855 }
01856
01858 #define NANOSECONDS_PER_SECOND 1000000000
01859
01860 #define MICROSECONDS_PER_SECOND 1000000
01861
01862 #define MILLISECONDS_PER_SECOND 1000
01863
01864 #define NANOSECONDS_PER_MILLISECOND 1000000
01865
01866 #define MICROSECONDS_PER_MILLISECOND 1000
01867
01872 void
01873 _dbus_sleep_milliseconds (int milliseconds)
01874 {
01875 Sleep (milliseconds);
01876 }
01877
01878
01886 void
01887 _dbus_get_real_time (long *tv_sec,
01888 long *tv_usec)
01889 {
01890 FILETIME ft;
01891 dbus_uint64_t time64;
01892
01893 GetSystemTimeAsFileTime (&ft);
01894
01895 memcpy (&time64, &ft, sizeof (time64));
01896
01897
01898
01899
01900 time64 -= DBUS_INT64_CONSTANT (116444736000000000);
01901 time64 /= 10;
01902
01903 if (tv_sec)
01904 *tv_sec = time64 / 1000000;
01905
01906 if (tv_usec)
01907 *tv_usec = time64 % 1000000;
01908 }
01909
01917 void
01918 _dbus_get_monotonic_time (long *tv_sec,
01919 long *tv_usec)
01920 {
01921
01922 _dbus_get_real_time (tv_sec, tv_usec);
01923 }
01924
01928 void
01929 _dbus_disable_sigpipe (void)
01930 {
01931 }
01932
01941 dbus_bool_t
01942 _dbus_create_directory (const DBusString *filename,
01943 DBusError *error)
01944 {
01945 const char *filename_c;
01946
01947 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01948
01949 filename_c = _dbus_string_get_const_data (filename);
01950
01951 if (!CreateDirectoryA (filename_c, NULL))
01952 {
01953 if (GetLastError () == ERROR_ALREADY_EXISTS)
01954 return TRUE;
01955
01956 dbus_set_error (error, DBUS_ERROR_FAILED,
01957 "Failed to create directory %s: %s\n",
01958 filename_c, _dbus_strerror_from_errno ());
01959 return FALSE;
01960 }
01961 else
01962 return TRUE;
01963 }
01964
01965
01974 dbus_bool_t
01975 _dbus_generate_random_bytes (DBusString *str,
01976 int n_bytes)
01977 {
01978 int old_len;
01979 char *p;
01980 HCRYPTPROV hprov;
01981
01982 old_len = _dbus_string_get_length (str);
01983
01984 if (!_dbus_string_lengthen (str, n_bytes))
01985 return FALSE;
01986
01987 p = _dbus_string_get_data_len (str, old_len, n_bytes);
01988
01989 if (!CryptAcquireContext (&hprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
01990 return FALSE;
01991
01992 if (!CryptGenRandom (hprov, n_bytes, p))
01993 {
01994 CryptReleaseContext (hprov, 0);
01995 return FALSE;
01996 }
01997
01998 CryptReleaseContext (hprov, 0);
01999
02000 return TRUE;
02001 }
02002
02009 const char*
02010 _dbus_get_tmpdir(void)
02011 {
02012 static const char* tmpdir = NULL;
02013 static char buf[1000];
02014
02015 if (tmpdir == NULL)
02016 {
02017 char *last_slash;
02018
02019 if (!GetTempPathA (sizeof (buf), buf))
02020 {
02021 _dbus_warn ("GetTempPath failed\n");
02022 _dbus_abort ();
02023 }
02024
02025
02026 last_slash = _mbsrchr (buf, '\\');
02027 if (last_slash > buf && last_slash[1] == '\0')
02028 last_slash[0] = '\0';
02029 last_slash = _mbsrchr (buf, '/');
02030 if (last_slash > buf && last_slash[1] == '\0')
02031 last_slash[0] = '\0';
02032
02033 tmpdir = buf;
02034 }
02035
02036 _dbus_assert(tmpdir != NULL);
02037
02038 return tmpdir;
02039 }
02040
02041
02050 dbus_bool_t
02051 _dbus_delete_file (const DBusString *filename,
02052 DBusError *error)
02053 {
02054 const char *filename_c;
02055
02056 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02057
02058 filename_c = _dbus_string_get_const_data (filename);
02059
02060 if (DeleteFileA (filename_c) == 0)
02061 {
02062 dbus_set_error (error, DBUS_ERROR_FAILED,
02063 "Failed to delete file %s: %s\n",
02064 filename_c, _dbus_strerror_from_errno ());
02065 return FALSE;
02066 }
02067 else
02068 return TRUE;
02069 }
02070
02071
02072
02073
02074
02075
02076
02077
02078 const char *
02079 _dbus_replace_install_prefix (const char *configure_time_path)
02080 {
02081 #ifndef DBUS_PREFIX
02082 return configure_time_path;
02083 #else
02084 static char retval[1000];
02085 static char runtime_prefix[1000];
02086 int len = 1000;
02087 int i;
02088
02089 if (!configure_time_path)
02090 return NULL;
02091
02092 if ((!_dbus_get_install_root(runtime_prefix, len) ||
02093 strncmp (configure_time_path, DBUS_PREFIX "/",
02094 strlen (DBUS_PREFIX) + 1))) {
02095 strcat (retval, configure_time_path);
02096 return retval;
02097 }
02098
02099 strcpy (retval, runtime_prefix);
02100 strcat (retval, configure_time_path + strlen (DBUS_PREFIX) + 1);
02101
02102
02103
02104
02105
02106
02107 for(i = 0; retval[i] != '\0'; i++) {
02108 if(retval[i] == '\\')
02109 retval[i] = '/';
02110 }
02111 return retval;
02112 #endif
02113 }
02114
02115 #if !defined (DBUS_DISABLE_ASSERTS) || defined(DBUS_BUILD_TESTS)
02116
02117 #if defined(_MSC_VER) || defined(DBUS_WINCE)
02118 # ifdef BACKTRACES
02119 # undef BACKTRACES
02120 # endif
02121 #else
02122 # define BACKTRACES
02123 #endif
02124
02125 #ifdef BACKTRACES
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147 #include <winver.h>
02148 #include <imagehlp.h>
02149 #include <stdio.h>
02150
02151 #define DPRINTF _dbus_warn
02152
02153 #ifdef _MSC_VER
02154 #define BOOL int
02155
02156 #define __i386__
02157 #endif
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167 static BOOL (WINAPI *pStackWalk)(
02168 DWORD MachineType,
02169 HANDLE hProcess,
02170 HANDLE hThread,
02171 LPSTACKFRAME StackFrame,
02172 PVOID ContextRecord,
02173 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
02174 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
02175 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
02176 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
02177 );
02178 #ifdef _WIN64
02179 static DWORD64 (WINAPI *pSymGetModuleBase)(
02180 HANDLE hProcess,
02181 DWORD64 dwAddr
02182 );
02183 static PVOID (WINAPI *pSymFunctionTableAccess)(
02184 HANDLE hProcess,
02185 DWORD64 AddrBase
02186 );
02187 #else
02188 static DWORD (WINAPI *pSymGetModuleBase)(
02189 HANDLE hProcess,
02190 DWORD dwAddr
02191 );
02192 static PVOID (WINAPI *pSymFunctionTableAccess)(
02193 HANDLE hProcess,
02194 DWORD AddrBase
02195 );
02196 #endif
02197 static BOOL (WINAPI *pSymInitialize)(
02198 HANDLE hProcess,
02199 PSTR UserSearchPath,
02200 BOOL fInvadeProcess
02201 );
02202 static BOOL (WINAPI *pSymGetSymFromAddr)(
02203 HANDLE hProcess,
02204 DWORD Address,
02205 PDWORD Displacement,
02206 PIMAGEHLP_SYMBOL Symbol
02207 );
02208 static BOOL (WINAPI *pSymGetModuleInfo)(
02209 HANDLE hProcess,
02210 DWORD dwAddr,
02211 PIMAGEHLP_MODULE ModuleInfo
02212 );
02213 static DWORD (WINAPI *pSymSetOptions)(
02214 DWORD SymOptions
02215 );
02216
02217
02218 static BOOL init_backtrace()
02219 {
02220 HMODULE hmodDbgHelp = LoadLibraryA("dbghelp");
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238 #define FUNC(x) #x
02239
02240 pStackWalk = (BOOL (WINAPI *)(
02241 DWORD MachineType,
02242 HANDLE hProcess,
02243 HANDLE hThread,
02244 LPSTACKFRAME StackFrame,
02245 PVOID ContextRecord,
02246 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
02247 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
02248 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
02249 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
02250 ))GetProcAddress (hmodDbgHelp, FUNC(StackWalk));
02251 #ifdef _WIN64
02252 pSymGetModuleBase=(DWORD64 (WINAPI *)(
02253 HANDLE hProcess,
02254 DWORD64 dwAddr
02255 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
02256 pSymFunctionTableAccess=(PVOID (WINAPI *)(
02257 HANDLE hProcess,
02258 DWORD64 AddrBase
02259 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
02260 #else
02261 pSymGetModuleBase=(DWORD (WINAPI *)(
02262 HANDLE hProcess,
02263 DWORD dwAddr
02264 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
02265 pSymFunctionTableAccess=(PVOID (WINAPI *)(
02266 HANDLE hProcess,
02267 DWORD AddrBase
02268 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
02269 #endif
02270 pSymInitialize = (BOOL (WINAPI *)(
02271 HANDLE hProcess,
02272 PSTR UserSearchPath,
02273 BOOL fInvadeProcess
02274 ))GetProcAddress (hmodDbgHelp, FUNC(SymInitialize));
02275 pSymGetSymFromAddr = (BOOL (WINAPI *)(
02276 HANDLE hProcess,
02277 DWORD Address,
02278 PDWORD Displacement,
02279 PIMAGEHLP_SYMBOL Symbol
02280 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetSymFromAddr));
02281 pSymGetModuleInfo = (BOOL (WINAPI *)(
02282 HANDLE hProcess,
02283 DWORD dwAddr,
02284 PIMAGEHLP_MODULE ModuleInfo
02285 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleInfo));
02286 pSymSetOptions = (DWORD (WINAPI *)(
02287 DWORD SymOptions
02288 ))GetProcAddress (hmodDbgHelp, FUNC(SymSetOptions));
02289
02290
02291 pSymSetOptions(SYMOPT_UNDNAME);
02292
02293 pSymInitialize(GetCurrentProcess(), NULL, TRUE);
02294
02295 return TRUE;
02296 }
02297
02298 static void dump_backtrace_for_thread(HANDLE hThread)
02299 {
02300 STACKFRAME sf;
02301 CONTEXT context;
02302 DWORD dwImageType;
02303
02304 if (!pStackWalk)
02305 if (!init_backtrace())
02306 return;
02307
02308
02309
02310 if (hThread == GetCurrentThread())
02311 return;
02312
02313 DPRINTF("Backtrace:\n");
02314
02315 _DBUS_ZERO(context);
02316 context.ContextFlags = CONTEXT_FULL;
02317
02318 SuspendThread(hThread);
02319
02320 if (!GetThreadContext(hThread, &context))
02321 {
02322 DPRINTF("Couldn't get thread context (error %ld)\n", GetLastError());
02323 ResumeThread(hThread);
02324 return;
02325 }
02326
02327 _DBUS_ZERO(sf);
02328
02329 #ifdef __i386__
02330 sf.AddrFrame.Offset = context.Ebp;
02331 sf.AddrFrame.Mode = AddrModeFlat;
02332 sf.AddrPC.Offset = context.Eip;
02333 sf.AddrPC.Mode = AddrModeFlat;
02334 dwImageType = IMAGE_FILE_MACHINE_I386;
02335 #elif _M_X64
02336 dwImageType = IMAGE_FILE_MACHINE_AMD64;
02337 sf.AddrPC.Offset = context.Rip;
02338 sf.AddrPC.Mode = AddrModeFlat;
02339 sf.AddrFrame.Offset = context.Rsp;
02340 sf.AddrFrame.Mode = AddrModeFlat;
02341 sf.AddrStack.Offset = context.Rsp;
02342 sf.AddrStack.Mode = AddrModeFlat;
02343 #elif _M_IA64
02344 dwImageType = IMAGE_FILE_MACHINE_IA64;
02345 sf.AddrPC.Offset = context.StIIP;
02346 sf.AddrPC.Mode = AddrModeFlat;
02347 sf.AddrFrame.Offset = context.IntSp;
02348 sf.AddrFrame.Mode = AddrModeFlat;
02349 sf.AddrBStore.Offset= context.RsBSP;
02350 sf.AddrBStore.Mode = AddrModeFlat;
02351 sf.AddrStack.Offset = context.IntSp;
02352 sf.AddrStack.Mode = AddrModeFlat;
02353 #else
02354 # error You need to fill in the STACKFRAME structure for your architecture
02355 #endif
02356
02357 while (pStackWalk(dwImageType, GetCurrentProcess(),
02358 hThread, &sf, &context, NULL, pSymFunctionTableAccess,
02359 pSymGetModuleBase, NULL))
02360 {
02361 BYTE buffer[256];
02362 IMAGEHLP_SYMBOL * pSymbol = (IMAGEHLP_SYMBOL *)buffer;
02363 DWORD dwDisplacement;
02364
02365 pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
02366 pSymbol->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1;
02367
02368 if (!pSymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset,
02369 &dwDisplacement, pSymbol))
02370 {
02371 IMAGEHLP_MODULE ModuleInfo;
02372 ModuleInfo.SizeOfStruct = sizeof(ModuleInfo);
02373
02374 if (!pSymGetModuleInfo(GetCurrentProcess(), sf.AddrPC.Offset,
02375 &ModuleInfo))
02376 DPRINTF("1\t%p\n", (void*)sf.AddrPC.Offset);
02377 else
02378 DPRINTF("2\t%s+0x%lx\n", ModuleInfo.ImageName,
02379 sf.AddrPC.Offset - ModuleInfo.BaseOfImage);
02380 }
02381 else if (dwDisplacement)
02382 DPRINTF("3\t%s+0x%lx\n", pSymbol->Name, dwDisplacement);
02383 else
02384 DPRINTF("4\t%s\n", pSymbol->Name);
02385 }
02386
02387 ResumeThread(hThread);
02388 }
02389
02390 static DWORD WINAPI dump_thread_proc(LPVOID lpParameter)
02391 {
02392 dump_backtrace_for_thread((HANDLE)lpParameter);
02393 return 0;
02394 }
02395
02396
02397
02398 static void dump_backtrace()
02399 {
02400 HANDLE hCurrentThread;
02401 HANDLE hThread;
02402 DWORD dwThreadId;
02403 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
02404 GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
02405 hThread = CreateThread(NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread,
02406 0, &dwThreadId);
02407 WaitForSingleObject(hThread, INFINITE);
02408 CloseHandle(hThread);
02409 CloseHandle(hCurrentThread);
02410 }
02411 #endif
02412 #endif
02413
02414 #ifdef BACKTRACES
02415 void _dbus_print_backtrace(void)
02416 {
02417 init_backtrace();
02418 dump_backtrace();
02419 }
02420 #else
02421 void _dbus_print_backtrace(void)
02422 {
02423 _dbus_verbose (" D-Bus not compiled with backtrace support\n");
02424 }
02425 #endif
02426
02427 static dbus_uint32_t fromAscii(char ascii)
02428 {
02429 if(ascii >= '0' && ascii <= '9')
02430 return ascii - '0';
02431 if(ascii >= 'A' && ascii <= 'F')
02432 return ascii - 'A' + 10;
02433 if(ascii >= 'a' && ascii <= 'f')
02434 return ascii - 'a' + 10;
02435 return 0;
02436 }
02437
02438 dbus_bool_t _dbus_read_local_machine_uuid (DBusGUID *machine_id,
02439 dbus_bool_t create_if_not_found,
02440 DBusError *error)
02441 {
02442 #ifdef DBUS_WINCE
02443 return TRUE;
02444
02445 #else
02446 HW_PROFILE_INFOA info;
02447 char *lpc = &info.szHwProfileGuid[0];
02448 dbus_uint32_t u;
02449
02450
02451 if(!GetCurrentHwProfileA(&info))
02452 {
02453 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02454 return FALSE;
02455 }
02456
02457
02458 lpc++;
02459
02460 u = ((fromAscii(lpc[0]) << 0) |
02461 (fromAscii(lpc[1]) << 4) |
02462 (fromAscii(lpc[2]) << 8) |
02463 (fromAscii(lpc[3]) << 12) |
02464 (fromAscii(lpc[4]) << 16) |
02465 (fromAscii(lpc[5]) << 20) |
02466 (fromAscii(lpc[6]) << 24) |
02467 (fromAscii(lpc[7]) << 28));
02468 machine_id->as_uint32s[0] = u;
02469
02470 lpc += 9;
02471
02472 u = ((fromAscii(lpc[0]) << 0) |
02473 (fromAscii(lpc[1]) << 4) |
02474 (fromAscii(lpc[2]) << 8) |
02475 (fromAscii(lpc[3]) << 12) |
02476 (fromAscii(lpc[5]) << 16) |
02477 (fromAscii(lpc[6]) << 20) |
02478 (fromAscii(lpc[7]) << 24) |
02479 (fromAscii(lpc[8]) << 28));
02480 machine_id->as_uint32s[1] = u;
02481
02482 lpc += 10;
02483
02484 u = ((fromAscii(lpc[0]) << 0) |
02485 (fromAscii(lpc[1]) << 4) |
02486 (fromAscii(lpc[2]) << 8) |
02487 (fromAscii(lpc[3]) << 12) |
02488 (fromAscii(lpc[5]) << 16) |
02489 (fromAscii(lpc[6]) << 20) |
02490 (fromAscii(lpc[7]) << 24) |
02491 (fromAscii(lpc[8]) << 28));
02492 machine_id->as_uint32s[2] = u;
02493
02494 lpc += 9;
02495
02496 u = ((fromAscii(lpc[0]) << 0) |
02497 (fromAscii(lpc[1]) << 4) |
02498 (fromAscii(lpc[2]) << 8) |
02499 (fromAscii(lpc[3]) << 12) |
02500 (fromAscii(lpc[4]) << 16) |
02501 (fromAscii(lpc[5]) << 20) |
02502 (fromAscii(lpc[6]) << 24) |
02503 (fromAscii(lpc[7]) << 28));
02504 machine_id->as_uint32s[3] = u;
02505 #endif
02506 return TRUE;
02507 }
02508
02509 static
02510 HANDLE _dbus_global_lock (const char *mutexname)
02511 {
02512 HANDLE mutex;
02513 DWORD gotMutex;
02514
02515 mutex = CreateMutexA( NULL, FALSE, mutexname );
02516 if( !mutex )
02517 {
02518 return FALSE;
02519 }
02520
02521 gotMutex = WaitForSingleObject( mutex, INFINITE );
02522 switch( gotMutex )
02523 {
02524 case WAIT_ABANDONED:
02525 ReleaseMutex (mutex);
02526 CloseHandle (mutex);
02527 return 0;
02528 case WAIT_FAILED:
02529 case WAIT_TIMEOUT:
02530 return 0;
02531 }
02532
02533 return mutex;
02534 }
02535
02536 static
02537 void _dbus_global_unlock (HANDLE mutex)
02538 {
02539 ReleaseMutex (mutex);
02540 CloseHandle (mutex);
02541 }
02542
02543
02544 static HANDLE hDBusDaemonMutex = NULL;
02545 static HANDLE hDBusSharedMem = NULL;
02546
02547 static const char *cUniqueDBusInitMutex = "UniqueDBusInitMutex";
02548
02549 static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex";
02550
02551 static const char *cDBusDaemonMutex = "DBusDaemonMutex";
02552
02553 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
02554
02555 static dbus_bool_t
02556 _dbus_get_install_root_as_hash(DBusString *out)
02557 {
02558 DBusString install_path;
02559
02560 char path[MAX_PATH*2];
02561 int path_size = sizeof(path);
02562
02563 if (!_dbus_get_install_root(path,path_size))
02564 return FALSE;
02565
02566 _dbus_string_init(&install_path);
02567 _dbus_string_append(&install_path,path);
02568
02569 _dbus_string_init(out);
02570 _dbus_string_tolower_ascii(&install_path,0,_dbus_string_get_length(&install_path));
02571
02572 if (!_dbus_sha_compute (&install_path, out))
02573 return FALSE;
02574
02575 return TRUE;
02576 }
02577
02578 static dbus_bool_t
02579 _dbus_get_address_string (DBusString *out, const char *basestring, const char *scope)
02580 {
02581 _dbus_string_init(out);
02582 _dbus_string_append(out,basestring);
02583
02584 if (!scope)
02585 {
02586 return TRUE;
02587 }
02588 else if (strcmp(scope,"*install-path") == 0
02589
02590 || strcmp(scope,"install-path") == 0)
02591 {
02592 DBusString temp;
02593 if (!_dbus_get_install_root_as_hash(&temp))
02594 {
02595 _dbus_string_free(out);
02596 return FALSE;
02597 }
02598 _dbus_string_append(out,"-");
02599 _dbus_string_append(out,_dbus_string_get_const_data(&temp));
02600 _dbus_string_free(&temp);
02601 }
02602 else if (strcmp(scope,"*user") == 0)
02603 {
02604 _dbus_string_append(out,"-");
02605 if (!_dbus_append_user_from_current_process(out))
02606 {
02607 _dbus_string_free(out);
02608 return FALSE;
02609 }
02610 }
02611 else if (strlen(scope) > 0)
02612 {
02613 _dbus_string_append(out,"-");
02614 _dbus_string_append(out,scope);
02615 return TRUE;
02616 }
02617 return TRUE;
02618 }
02619
02620 static dbus_bool_t
02621 _dbus_get_shm_name (DBusString *out,const char *scope)
02622 {
02623 return _dbus_get_address_string (out,cDBusDaemonAddressInfo,scope);
02624 }
02625
02626 static dbus_bool_t
02627 _dbus_get_mutex_name (DBusString *out,const char *scope)
02628 {
02629 return _dbus_get_address_string (out,cDBusDaemonMutex,scope);
02630 }
02631
02632 dbus_bool_t
02633 _dbus_daemon_is_session_bus_address_published (const char *scope)
02634 {
02635 HANDLE lock;
02636 DBusString mutex_name;
02637
02638 if (!_dbus_get_mutex_name(&mutex_name,scope))
02639 {
02640 _dbus_string_free( &mutex_name );
02641 return FALSE;
02642 }
02643
02644 if (hDBusDaemonMutex)
02645 return TRUE;
02646
02647
02648 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02649
02650
02651
02652 hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02653
02654
02655
02656
02657
02658 _dbus_global_unlock( lock );
02659
02660 _dbus_string_free( &mutex_name );
02661
02662 if (hDBusDaemonMutex == NULL)
02663 return FALSE;
02664 if (GetLastError() == ERROR_ALREADY_EXISTS)
02665 {
02666 CloseHandle(hDBusDaemonMutex);
02667 hDBusDaemonMutex = NULL;
02668 return TRUE;
02669 }
02670
02671
02672
02673 return FALSE;
02674 }
02675
02676 dbus_bool_t
02677 _dbus_daemon_publish_session_bus_address (const char* address, const char *scope)
02678 {
02679 HANDLE lock;
02680 char *shared_addr = NULL;
02681 DBusString shm_name;
02682 DBusString mutex_name;
02683
02684 _dbus_assert (address);
02685
02686 if (!_dbus_get_mutex_name(&mutex_name,scope))
02687 {
02688 _dbus_string_free( &mutex_name );
02689 return FALSE;
02690 }
02691
02692
02693 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02694
02695 if (!hDBusDaemonMutex)
02696 {
02697 hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02698 }
02699 _dbus_string_free( &mutex_name );
02700
02701
02702 if (WaitForSingleObject( hDBusDaemonMutex, 10 ) != WAIT_OBJECT_0)
02703 {
02704 _dbus_global_unlock( lock );
02705 CloseHandle( hDBusDaemonMutex );
02706 return FALSE;
02707 }
02708
02709 if (!_dbus_get_shm_name(&shm_name,scope))
02710 {
02711 _dbus_string_free( &shm_name );
02712 _dbus_global_unlock( lock );
02713 return FALSE;
02714 }
02715
02716
02717 hDBusSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
02718 0, strlen( address ) + 1, _dbus_string_get_const_data(&shm_name) );
02719 _dbus_assert( hDBusSharedMem );
02720
02721 shared_addr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
02722
02723 _dbus_assert (shared_addr);
02724
02725 strcpy( shared_addr, address);
02726
02727
02728 UnmapViewOfFile( shared_addr );
02729
02730 _dbus_global_unlock( lock );
02731 _dbus_verbose( "published session bus address at %s\n",_dbus_string_get_const_data (&shm_name) );
02732
02733 _dbus_string_free( &shm_name );
02734 return TRUE;
02735 }
02736
02737 void
02738 _dbus_daemon_unpublish_session_bus_address (void)
02739 {
02740 HANDLE lock;
02741
02742
02743 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02744
02745 CloseHandle( hDBusSharedMem );
02746
02747 hDBusSharedMem = NULL;
02748
02749 ReleaseMutex( hDBusDaemonMutex );
02750
02751 CloseHandle( hDBusDaemonMutex );
02752
02753 hDBusDaemonMutex = NULL;
02754
02755 _dbus_global_unlock( lock );
02756 }
02757
02758 static dbus_bool_t
02759 _dbus_get_autolaunch_shm (DBusString *address, DBusString *shm_name)
02760 {
02761 HANDLE sharedMem;
02762 char *shared_addr;
02763 int i;
02764
02765
02766 for(i=0;i<20;++i) {
02767
02768 sharedMem = OpenFileMappingA( FILE_MAP_READ, FALSE, _dbus_string_get_const_data(shm_name));
02769 if( sharedMem == 0 )
02770 Sleep( 100 );
02771 if ( sharedMem != 0)
02772 break;
02773 }
02774
02775 if( sharedMem == 0 )
02776 return FALSE;
02777
02778 shared_addr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
02779
02780 if( !shared_addr )
02781 return FALSE;
02782
02783 _dbus_string_init( address );
02784
02785 _dbus_string_append( address, shared_addr );
02786
02787
02788 UnmapViewOfFile( shared_addr );
02789
02790 CloseHandle( sharedMem );
02791
02792 return TRUE;
02793 }
02794
02795 static dbus_bool_t
02796 _dbus_daemon_already_runs (DBusString *address, DBusString *shm_name, const char *scope)
02797 {
02798 HANDLE lock;
02799 HANDLE daemon;
02800 DBusString mutex_name;
02801 dbus_bool_t bRet = TRUE;
02802
02803 if (!_dbus_get_mutex_name(&mutex_name,scope))
02804 {
02805 _dbus_string_free( &mutex_name );
02806 return FALSE;
02807 }
02808
02809
02810 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02811
02812
02813 daemon = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02814 if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT)
02815 {
02816 ReleaseMutex (daemon);
02817 CloseHandle (daemon);
02818
02819 _dbus_global_unlock( lock );
02820 _dbus_string_free( &mutex_name );
02821 return FALSE;
02822 }
02823
02824
02825 bRet = _dbus_get_autolaunch_shm( address, shm_name );
02826
02827
02828 CloseHandle ( daemon );
02829
02830 _dbus_global_unlock( lock );
02831 _dbus_string_free( &mutex_name );
02832
02833 return bRet;
02834 }
02835
02836 dbus_bool_t
02837 _dbus_get_autolaunch_address (const char *scope, DBusString *address,
02838 DBusError *error)
02839 {
02840 HANDLE mutex;
02841 STARTUPINFOA si;
02842 PROCESS_INFORMATION pi;
02843 dbus_bool_t retval = FALSE;
02844 LPSTR lpFile;
02845 char dbus_exe_path[MAX_PATH];
02846 char dbus_args[MAX_PATH * 2];
02847 const char * daemon_name = DBUS_DAEMON_NAME ".exe";
02848 DBusString shm_name;
02849
02850 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02851
02852 if (!_dbus_get_shm_name(&shm_name,scope))
02853 {
02854 dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not determine shm name");
02855 return FALSE;
02856 }
02857
02858 mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
02859
02860 if (_dbus_daemon_already_runs(address,&shm_name,scope))
02861 {
02862 _dbus_verbose( "found running dbus daemon at %s\n",
02863 _dbus_string_get_const_data (&shm_name) );
02864 retval = TRUE;
02865 goto out;
02866 }
02867
02868 if (!SearchPathA(NULL, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
02869 {
02870
02871 HMODULE hmod;
02872 char dbus_module_path[MAX_PATH];
02873 DWORD rc;
02874
02875 _dbus_verbose( "did not found dbus daemon executable on default search path, "
02876 "trying path where dbus shared library is located");
02877
02878 hmod = _dbus_win_get_dll_hmodule();
02879 rc = GetModuleFileNameA(hmod, dbus_module_path, sizeof(dbus_module_path));
02880 if (rc <= 0)
02881 {
02882 dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not retrieve dbus shared library file name");
02883 retval = FALSE;
02884 goto out;
02885 }
02886 else
02887 {
02888 char *ext_idx = strrchr(dbus_module_path, '\\');
02889 if (ext_idx)
02890 *ext_idx = '\0';
02891 if (!SearchPathA(dbus_module_path, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
02892 {
02893 dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not find dbus-daemon executable");
02894 retval = FALSE;
02895 printf ("please add the path to %s to your PATH environment variable\n", daemon_name);
02896 printf ("or start the daemon manually\n\n");
02897 goto out;
02898 }
02899 _dbus_verbose( "found dbus daemon executable at %s",dbus_module_path);
02900 }
02901 }
02902
02903
02904
02905 ZeroMemory( &si, sizeof(si) );
02906 si.cb = sizeof(si);
02907 ZeroMemory( &pi, sizeof(pi) );
02908
02909 _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path, " --session");
02910
02911
02912
02913 if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
02914 {
02915 CloseHandle (pi.hThread);
02916 CloseHandle (pi.hProcess);
02917 retval = _dbus_get_autolaunch_shm( address, &shm_name );
02918 if (retval == FALSE)
02919 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to get autolaunch address from launched dbus-daemon");
02920 }
02921 else
02922 {
02923 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to launch dbus-daemon");
02924 retval = FALSE;
02925 }
02926
02927 out:
02928 if (retval)
02929 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02930 else
02931 _DBUS_ASSERT_ERROR_IS_SET (error);
02932
02933 _dbus_global_unlock (mutex);
02934
02935 return retval;
02936 }
02937
02938
02945 dbus_bool_t
02946 _dbus_make_file_world_readable(const DBusString *filename,
02947 DBusError *error)
02948 {
02949
02950 return TRUE;
02951 }
02952
02959 static const char *
02960 _dbus_windows_get_datadir (void)
02961 {
02962 return _dbus_replace_install_prefix(DBUS_DATADIR);
02963 }
02964
02965 #undef DBUS_DATADIR
02966 #define DBUS_DATADIR _dbus_windows_get_datadir ()
02967
02968
02969 #define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
02970 #define DBUS_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
02971
02988 dbus_bool_t
02989 _dbus_get_standard_session_servicedirs (DBusList **dirs)
02990 {
02991 const char *common_progs;
02992 DBusString servicedir_path;
02993
02994 if (!_dbus_string_init (&servicedir_path))
02995 return FALSE;
02996
02997 #ifdef DBUS_WINCE
02998 {
02999
03000 const char *data_dir = _dbus_getenv ("DBUS_DATADIR");
03001
03002 if (data_dir != NULL)
03003 {
03004 if (!_dbus_string_append (&servicedir_path, data_dir))
03005 goto oom;
03006
03007 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
03008 goto oom;
03009 }
03010 }
03011 #else
03012
03013
03014
03015
03016 #ifdef DBUS_WIN
03017 {
03018 DBusString p;
03019
03020 _dbus_string_init_const (&p, DBUS_DATADIR);
03021
03022 if (!_dbus_path_is_absolute (&p))
03023 {
03024 char install_root[1000];
03025 if (_dbus_get_install_root (install_root, sizeof(install_root)))
03026 if (!_dbus_string_append (&servicedir_path, install_root))
03027 goto oom;
03028 }
03029 }
03030 #endif
03031 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
03032 goto oom;
03033
03034 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
03035 goto oom;
03036 #endif
03037
03038 common_progs = _dbus_getenv ("CommonProgramFiles");
03039
03040 if (common_progs != NULL)
03041 {
03042 if (!_dbus_string_append (&servicedir_path, common_progs))
03043 goto oom;
03044
03045 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
03046 goto oom;
03047 }
03048
03049 if (!_dbus_split_paths_and_append (&servicedir_path,
03050 DBUS_STANDARD_SESSION_SERVICEDIR,
03051 dirs))
03052 goto oom;
03053
03054 _dbus_string_free (&servicedir_path);
03055 return TRUE;
03056
03057 oom:
03058 _dbus_string_free (&servicedir_path);
03059 return FALSE;
03060 }
03061
03080 dbus_bool_t
03081 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03082 {
03083 *dirs = NULL;
03084 return TRUE;
03085 }
03086
03087 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
03088
03096 dbus_int32_t
03097 _dbus_atomic_inc (DBusAtomic *atomic)
03098 {
03099
03100
03101 return InterlockedIncrement (&atomic->value) - 1;
03102 }
03103
03111 dbus_int32_t
03112 _dbus_atomic_dec (DBusAtomic *atomic)
03113 {
03114
03115
03116 return InterlockedDecrement (&atomic->value) + 1;
03117 }
03118
03126 dbus_int32_t
03127 _dbus_atomic_get (DBusAtomic *atomic)
03128 {
03129
03130 MemoryBarrier ();
03131 return atomic->value;
03132 }
03133
03141 void
03142 _dbus_flush_caches (void)
03143 {
03144 }
03145
03152 dbus_bool_t
03153 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03154 {
03155 return errno == WSAEWOULDBLOCK;
03156 }
03157
03165 dbus_bool_t
03166 _dbus_get_install_root(char *prefix, int len)
03167 {
03168
03169 DWORD pathLength;
03170 char *lastSlash;
03171 SetLastError( 0 );
03172 pathLength = GetModuleFileNameA(_dbus_win_get_dll_hmodule(), prefix, len);
03173 if ( pathLength == 0 || GetLastError() != 0 ) {
03174 *prefix = '\0';
03175 return FALSE;
03176 }
03177 lastSlash = _mbsrchr(prefix, '\\');
03178 if (lastSlash == NULL) {
03179 *prefix = '\0';
03180 return FALSE;
03181 }
03182
03183 lastSlash[1] = 0;
03184
03185
03186
03187
03188
03189
03190
03191 if (lastSlash - prefix >= 4 && strnicmp(lastSlash - 4, "\\bin", 4) == 0)
03192 lastSlash[-3] = 0;
03193 else if (lastSlash - prefix >= 10 && strnicmp(lastSlash - 10, "\\bin\\debug", 10) == 0)
03194 lastSlash[-9] = 0;
03195 else if (lastSlash - prefix >= 12 && strnicmp(lastSlash - 12, "\\bin\\release", 12) == 0)
03196 lastSlash[-11] = 0;
03197
03198 return TRUE;
03199 }
03200
03214 dbus_bool_t
03215 _dbus_get_config_file_name(DBusString *config_file, char *s)
03216 {
03217 char path[MAX_PATH*2];
03218 int path_size = sizeof(path);
03219
03220 if (!_dbus_get_install_root(path,path_size))
03221 return FALSE;
03222
03223 if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
03224 return FALSE;
03225 strcat(path,"etc\\");
03226 strcat(path,s);
03227 if (_dbus_file_exists(path))
03228 {
03229
03230 if (!_dbus_string_append (config_file, path))
03231 return FALSE;
03232 }
03233 else
03234 {
03235 if (!_dbus_get_install_root(path,path_size))
03236 return FALSE;
03237 if(strlen(s) + 11 + strlen(path) > sizeof(path)-2)
03238 return FALSE;
03239 strcat(path,"etc\\dbus-1\\");
03240 strcat(path,s);
03241
03242 if (_dbus_file_exists(path))
03243 {
03244 if (!_dbus_string_append (config_file, path))
03245 return FALSE;
03246 }
03247 else
03248 {
03249 if (!_dbus_get_install_root(path,path_size))
03250 return FALSE;
03251 if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
03252 return FALSE;
03253 strcat(path,"bus\\");
03254 strcat(path,s);
03255
03256 if (_dbus_file_exists(path))
03257 {
03258 if (!_dbus_string_append (config_file, path))
03259 return FALSE;
03260 }
03261 }
03262 }
03263 return TRUE;
03264 }
03265
03274 dbus_bool_t
03275 _dbus_append_system_config_file (DBusString *str)
03276 {
03277 return _dbus_get_config_file_name(str, "system.conf");
03278 }
03279
03286 dbus_bool_t
03287 _dbus_append_session_config_file (DBusString *str)
03288 {
03289 return _dbus_get_config_file_name(str, "session.conf");
03290 }
03291
03292
03293 dbus_bool_t
03294 _dbus_lookup_session_address (dbus_bool_t *supported,
03295 DBusString *address,
03296 DBusError *error)
03297 {
03298
03299 *supported = FALSE;
03300 return TRUE;
03301 }
03302
03316 dbus_bool_t
03317 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03318 DBusCredentials *credentials)
03319 {
03320 DBusString homedir;
03321 DBusString dotdir;
03322 const char *homepath;
03323 const char *homedrive;
03324
03325 _dbus_assert (credentials != NULL);
03326 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03327
03328 if (!_dbus_string_init (&homedir))
03329 return FALSE;
03330
03331 homedrive = _dbus_getenv("HOMEDRIVE");
03332 if (homedrive != NULL && *homedrive != '\0')
03333 {
03334 _dbus_string_append(&homedir,homedrive);
03335 }
03336
03337 homepath = _dbus_getenv("HOMEPATH");
03338 if (homepath != NULL && *homepath != '\0')
03339 {
03340 _dbus_string_append(&homedir,homepath);
03341 }
03342
03343 #ifdef DBUS_BUILD_TESTS
03344 {
03345 const char *override;
03346
03347 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03348 if (override != NULL && *override != '\0')
03349 {
03350 _dbus_string_set_length (&homedir, 0);
03351 if (!_dbus_string_append (&homedir, override))
03352 goto failed;
03353
03354 _dbus_verbose ("Using fake homedir for testing: %s\n",
03355 _dbus_string_get_const_data (&homedir));
03356 }
03357 else
03358 {
03359 static dbus_bool_t already_warned = FALSE;
03360 if (!already_warned)
03361 {
03362 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03363 already_warned = TRUE;
03364 }
03365 }
03366 }
03367 #endif
03368
03369 #ifdef DBUS_WINCE
03370
03371
03372 #define KEYRING_DIR "dbus-keyrings"
03373 #else
03374 #define KEYRING_DIR ".dbus-keyrings"
03375 #endif
03376
03377 _dbus_string_init_const (&dotdir, KEYRING_DIR);
03378 if (!_dbus_concat_dir_and_file (&homedir,
03379 &dotdir))
03380 goto failed;
03381
03382 if (!_dbus_string_copy (&homedir, 0,
03383 directory, _dbus_string_get_length (directory))) {
03384 goto failed;
03385 }
03386
03387 _dbus_string_free (&homedir);
03388 return TRUE;
03389
03390 failed:
03391 _dbus_string_free (&homedir);
03392 return FALSE;
03393 }
03394
03400 dbus_bool_t
03401 _dbus_file_exists (const char *file)
03402 {
03403 DWORD attributes = GetFileAttributesA (file);
03404
03405 if (attributes != INVALID_FILE_ATTRIBUTES && GetLastError() != ERROR_PATH_NOT_FOUND)
03406 return TRUE;
03407 else
03408 return FALSE;
03409 }
03410
03418 const char*
03419 _dbus_strerror (int error_number)
03420 {
03421 #ifdef DBUS_WINCE
03422
03423 return "unknown";
03424 #else
03425 const char *msg;
03426
03427 switch (error_number)
03428 {
03429 case WSAEINTR:
03430 return "Interrupted function call";
03431 case WSAEACCES:
03432 return "Permission denied";
03433 case WSAEFAULT:
03434 return "Bad address";
03435 case WSAEINVAL:
03436 return "Invalid argument";
03437 case WSAEMFILE:
03438 return "Too many open files";
03439 case WSAEWOULDBLOCK:
03440 return "Resource temporarily unavailable";
03441 case WSAEINPROGRESS:
03442 return "Operation now in progress";
03443 case WSAEALREADY:
03444 return "Operation already in progress";
03445 case WSAENOTSOCK:
03446 return "Socket operation on nonsocket";
03447 case WSAEDESTADDRREQ:
03448 return "Destination address required";
03449 case WSAEMSGSIZE:
03450 return "Message too long";
03451 case WSAEPROTOTYPE:
03452 return "Protocol wrong type for socket";
03453 case WSAENOPROTOOPT:
03454 return "Bad protocol option";
03455 case WSAEPROTONOSUPPORT:
03456 return "Protocol not supported";
03457 case WSAESOCKTNOSUPPORT:
03458 return "Socket type not supported";
03459 case WSAEOPNOTSUPP:
03460 return "Operation not supported";
03461 case WSAEPFNOSUPPORT:
03462 return "Protocol family not supported";
03463 case WSAEAFNOSUPPORT:
03464 return "Address family not supported by protocol family";
03465 case WSAEADDRINUSE:
03466 return "Address already in use";
03467 case WSAEADDRNOTAVAIL:
03468 return "Cannot assign requested address";
03469 case WSAENETDOWN:
03470 return "Network is down";
03471 case WSAENETUNREACH:
03472 return "Network is unreachable";
03473 case WSAENETRESET:
03474 return "Network dropped connection on reset";
03475 case WSAECONNABORTED:
03476 return "Software caused connection abort";
03477 case WSAECONNRESET:
03478 return "Connection reset by peer";
03479 case WSAENOBUFS:
03480 return "No buffer space available";
03481 case WSAEISCONN:
03482 return "Socket is already connected";
03483 case WSAENOTCONN:
03484 return "Socket is not connected";
03485 case WSAESHUTDOWN:
03486 return "Cannot send after socket shutdown";
03487 case WSAETIMEDOUT:
03488 return "Connection timed out";
03489 case WSAECONNREFUSED:
03490 return "Connection refused";
03491 case WSAEHOSTDOWN:
03492 return "Host is down";
03493 case WSAEHOSTUNREACH:
03494 return "No route to host";
03495 case WSAEPROCLIM:
03496 return "Too many processes";
03497 case WSAEDISCON:
03498 return "Graceful shutdown in progress";
03499 case WSATYPE_NOT_FOUND:
03500 return "Class type not found";
03501 case WSAHOST_NOT_FOUND:
03502 return "Host not found";
03503 case WSATRY_AGAIN:
03504 return "Nonauthoritative host not found";
03505 case WSANO_RECOVERY:
03506 return "This is a nonrecoverable error";
03507 case WSANO_DATA:
03508 return "Valid name, no data record of requested type";
03509 case WSA_INVALID_HANDLE:
03510 return "Specified event object handle is invalid";
03511 case WSA_INVALID_PARAMETER:
03512 return "One or more parameters are invalid";
03513 case WSA_IO_INCOMPLETE:
03514 return "Overlapped I/O event object not in signaled state";
03515 case WSA_IO_PENDING:
03516 return "Overlapped operations will complete later";
03517 case WSA_NOT_ENOUGH_MEMORY:
03518 return "Insufficient memory available";
03519 case WSA_OPERATION_ABORTED:
03520 return "Overlapped operation aborted";
03521 #ifdef WSAINVALIDPROCTABLE
03522
03523 case WSAINVALIDPROCTABLE:
03524 return "Invalid procedure table from service provider";
03525 #endif
03526 #ifdef WSAINVALIDPROVIDER
03527
03528 case WSAINVALIDPROVIDER:
03529 return "Invalid service provider version number";
03530 #endif
03531 #ifdef WSAPROVIDERFAILEDINIT
03532
03533 case WSAPROVIDERFAILEDINIT:
03534 return "Unable to initialize a service provider";
03535 #endif
03536
03537 case WSASYSCALLFAILURE:
03538 return "System call failure";
03539 }
03540 msg = strerror (error_number);
03541 if (msg == NULL)
03542 msg = "unknown";
03543
03544 return msg;
03545 #endif //DBUS_WINCE
03546 }
03547
03555 void
03556 _dbus_win_set_error_from_win_error (DBusError *error,
03557 int code)
03558 {
03559 char *msg;
03560
03561
03562 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
03563 FORMAT_MESSAGE_IGNORE_INSERTS |
03564 FORMAT_MESSAGE_FROM_SYSTEM,
03565 NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
03566 (LPSTR) &msg, 0, NULL);
03567 if (msg)
03568 {
03569 char *msg_copy;
03570
03571 msg_copy = dbus_malloc (strlen (msg));
03572 strcpy (msg_copy, msg);
03573 LocalFree (msg);
03574
03575 dbus_set_error (error, "win32.error", "%s", msg_copy);
03576 }
03577 else
03578 dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code);
03579 }
03580
03581 void
03582 _dbus_win_warn_win_error (const char *message,
03583 int code)
03584 {
03585 DBusError error;
03586
03587 dbus_error_init (&error);
03588 _dbus_win_set_error_from_win_error (&error, code);
03589 _dbus_warn ("%s: %s\n", message, error.message);
03590 dbus_error_free (&error);
03591 }
03592
03600 dbus_bool_t
03601 _dbus_delete_directory (const DBusString *filename,
03602 DBusError *error)
03603 {
03604 const char *filename_c;
03605
03606 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03607
03608 filename_c = _dbus_string_get_const_data (filename);
03609
03610 if (RemoveDirectoryA (filename_c) == 0)
03611 {
03612 char *emsg = _dbus_win_error_string (GetLastError ());
03613 dbus_set_error (error, _dbus_win_error_from_last_error (),
03614 "Failed to remove directory %s: %s",
03615 filename_c, emsg);
03616 _dbus_win_free_error_string (emsg);
03617 return FALSE;
03618 }
03619
03620 return TRUE;
03621 }
03622
03629 dbus_bool_t
03630 _dbus_path_is_absolute (const DBusString *filename)
03631 {
03632 if (_dbus_string_get_length (filename) > 0)
03633 return _dbus_string_get_byte (filename, 1) == ':'
03634 || _dbus_string_get_byte (filename, 0) == '\\'
03635 || _dbus_string_get_byte (filename, 0) == '/';
03636 else
03637 return FALSE;
03638 }
03639
03640 dbus_bool_t
03641 _dbus_check_setuid (void)
03642 {
03643 return FALSE;
03644 }
03645
03647
03648