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
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 fd_set read_set, write_set;
00824 struct timeval tv;
00825 int res;
00826
00827 _dbus_win_startup_winsock ();
00828
00829 temp = socket (AF_INET, SOCK_STREAM, 0);
00830 if (temp == INVALID_SOCKET)
00831 {
00832 DBUS_SOCKET_SET_ERRNO ();
00833 goto out0;
00834 }
00835
00836 _DBUS_ZERO (saddr);
00837 saddr.sin_family = AF_INET;
00838 saddr.sin_port = 0;
00839 saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
00840
00841 if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr)) == SOCKET_ERROR)
00842 {
00843 DBUS_SOCKET_SET_ERRNO ();
00844 goto out0;
00845 }
00846
00847 if (listen (temp, 1) == SOCKET_ERROR)
00848 {
00849 DBUS_SOCKET_SET_ERRNO ();
00850 goto out0;
00851 }
00852
00853 len = sizeof (saddr);
00854 if (getsockname (temp, (struct sockaddr *)&saddr, &len) == SOCKET_ERROR)
00855 {
00856 DBUS_SOCKET_SET_ERRNO ();
00857 goto out0;
00858 }
00859
00860 socket1 = socket (AF_INET, SOCK_STREAM, 0);
00861 if (socket1 == INVALID_SOCKET)
00862 {
00863 DBUS_SOCKET_SET_ERRNO ();
00864 goto out0;
00865 }
00866
00867 if (connect (socket1, (struct sockaddr *)&saddr, len) == SOCKET_ERROR)
00868 {
00869 DBUS_SOCKET_SET_ERRNO ();
00870 goto out1;
00871 }
00872
00873 socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
00874 if (socket2 == INVALID_SOCKET)
00875 {
00876 DBUS_SOCKET_SET_ERRNO ();
00877 goto out1;
00878 }
00879
00880 if (!blocking)
00881 {
00882 arg = 1;
00883 if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
00884 {
00885 DBUS_SOCKET_SET_ERRNO ();
00886 goto out2;
00887 }
00888
00889 arg = 1;
00890 if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
00891 {
00892 DBUS_SOCKET_SET_ERRNO ();
00893 goto out2;
00894 }
00895 }
00896
00897 *fd1 = socket1;
00898 *fd2 = socket2;
00899
00900 _dbus_verbose ("full-duplex pipe %d:%d <-> %d:%d\n",
00901 *fd1, socket1, *fd2, socket2);
00902
00903 closesocket (temp);
00904
00905 return TRUE;
00906
00907 out2:
00908 closesocket (socket2);
00909 out1:
00910 closesocket (socket1);
00911 out0:
00912 closesocket (temp);
00913
00914 dbus_set_error (error, _dbus_error_from_errno (errno),
00915 "Could not setup socket pair: %s",
00916 _dbus_strerror_from_errno ());
00917
00918 return FALSE;
00919 }
00920
00929 int
00930 _dbus_poll (DBusPollFD *fds,
00931 int n_fds,
00932 int timeout_milliseconds)
00933 {
00934 #define USE_CHRIS_IMPL 0
00935
00936 #if USE_CHRIS_IMPL
00937
00938 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
00939 char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
00940 char *msgp;
00941
00942 int ret = 0;
00943 int i;
00944 struct timeval tv;
00945 int ready;
00946
00947 #define DBUS_STACK_WSAEVENTS 256
00948 WSAEVENT eventsOnStack[DBUS_STACK_WSAEVENTS];
00949 WSAEVENT *pEvents = NULL;
00950 if (n_fds > DBUS_STACK_WSAEVENTS)
00951 pEvents = calloc(sizeof(WSAEVENT), n_fds);
00952 else
00953 pEvents = eventsOnStack;
00954
00955
00956 #ifdef DBUS_ENABLE_VERBOSE_MODE
00957 msgp = msg;
00958 msgp += sprintf (msgp, "WSAEventSelect: to=%d\n\t", timeout_milliseconds);
00959 for (i = 0; i < n_fds; i++)
00960 {
00961 static dbus_bool_t warned = FALSE;
00962 DBusPollFD *fdp = &fds[i];
00963
00964
00965 if (fdp->events & _DBUS_POLLIN)
00966 msgp += sprintf (msgp, "R:%d ", fdp->fd);
00967
00968 if (fdp->events & _DBUS_POLLOUT)
00969 msgp += sprintf (msgp, "W:%d ", fdp->fd);
00970
00971 msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
00972
00973
00974
00975 if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
00976 {
00977 _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
00978 }
00979 }
00980
00981 msgp += sprintf (msgp, "\n");
00982 _dbus_verbose ("%s",msg);
00983 #endif
00984 for (i = 0; i < n_fds; i++)
00985 {
00986 DBusPollFD *fdp = &fds[i];
00987 WSAEVENT ev;
00988 long lNetworkEvents = FD_OOB;
00989
00990 ev = WSACreateEvent();
00991
00992 if (fdp->events & _DBUS_POLLIN)
00993 lNetworkEvents |= FD_READ | FD_ACCEPT | FD_CLOSE;
00994
00995 if (fdp->events & _DBUS_POLLOUT)
00996 lNetworkEvents |= FD_WRITE | FD_CONNECT;
00997
00998 WSAEventSelect(fdp->fd, ev, lNetworkEvents);
00999
01000 pEvents[i] = ev;
01001 }
01002
01003
01004 ready = WSAWaitForMultipleEvents (n_fds, pEvents, FALSE, timeout_milliseconds, FALSE);
01005
01006 if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
01007 {
01008 DBUS_SOCKET_SET_ERRNO ();
01009 if (errno != WSAEWOULDBLOCK)
01010 _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", _dbus_strerror_from_errno ());
01011 ret = -1;
01012 }
01013 else if (ready == WSA_WAIT_TIMEOUT)
01014 {
01015 _dbus_verbose ("WSAWaitForMultipleEvents: WSA_WAIT_TIMEOUT\n");
01016 ret = 0;
01017 }
01018 else if (ready >= WSA_WAIT_EVENT_0 && ready < (int)(WSA_WAIT_EVENT_0 + n_fds))
01019 {
01020 msgp = msg;
01021 msgp += sprintf (msgp, "WSAWaitForMultipleEvents: =%d\n\t", ready);
01022
01023 for (i = 0; i < n_fds; i++)
01024 {
01025 DBusPollFD *fdp = &fds[i];
01026 WSANETWORKEVENTS ne;
01027
01028 fdp->revents = 0;
01029
01030 WSAEnumNetworkEvents(fdp->fd, pEvents[i], &ne);
01031
01032 if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
01033 fdp->revents |= _DBUS_POLLIN;
01034
01035 if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
01036 fdp->revents |= _DBUS_POLLOUT;
01037
01038 if (ne.lNetworkEvents & (FD_OOB))
01039 fdp->revents |= _DBUS_POLLERR;
01040
01041 if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
01042 msgp += sprintf (msgp, "R:%d ", fdp->fd);
01043
01044 if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
01045 msgp += sprintf (msgp, "W:%d ", fdp->fd);
01046
01047 if (ne.lNetworkEvents & (FD_OOB))
01048 msgp += sprintf (msgp, "E:%d ", fdp->fd);
01049
01050 msgp += sprintf (msgp, "lNetworkEvents:%d ", ne.lNetworkEvents);
01051
01052 if(ne.lNetworkEvents)
01053 ret++;
01054
01055 WSAEventSelect(fdp->fd, pEvents[i], 0);
01056 }
01057
01058 msgp += sprintf (msgp, "\n");
01059 _dbus_verbose ("%s",msg);
01060 }
01061 else
01062 {
01063 _dbus_verbose ("WSAWaitForMultipleEvents: failed for unknown reason!");
01064 ret = -1;
01065 }
01066
01067 for(i = 0; i < n_fds; i++)
01068 {
01069 WSACloseEvent(pEvents[i]);
01070 }
01071
01072 if (n_fds > DBUS_STACK_WSAEVENTS)
01073 free(pEvents);
01074
01075 return ret;
01076
01077 #else
01078
01079 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
01080 char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
01081 char *msgp;
01082
01083 fd_set read_set, write_set, err_set;
01084 int max_fd = 0;
01085 int i;
01086 struct timeval tv;
01087 int ready;
01088
01089 FD_ZERO (&read_set);
01090 FD_ZERO (&write_set);
01091 FD_ZERO (&err_set);
01092
01093
01094 #ifdef DBUS_ENABLE_VERBOSE_MODE
01095 msgp = msg;
01096 msgp += sprintf (msgp, "select: to=%d\n\t", timeout_milliseconds);
01097 for (i = 0; i < n_fds; i++)
01098 {
01099 static dbus_bool_t warned = FALSE;
01100 DBusPollFD *fdp = &fds[i];
01101
01102
01103 if (fdp->events & _DBUS_POLLIN)
01104 msgp += sprintf (msgp, "R:%d ", fdp->fd);
01105
01106 if (fdp->events & _DBUS_POLLOUT)
01107 msgp += sprintf (msgp, "W:%d ", fdp->fd);
01108
01109 msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
01110
01111
01112
01113 if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
01114 {
01115 _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
01116 }
01117 }
01118
01119 msgp += sprintf (msgp, "\n");
01120 _dbus_verbose ("%s",msg);
01121 #endif
01122 for (i = 0; i < n_fds; i++)
01123 {
01124 DBusPollFD *fdp = &fds[i];
01125
01126 if (fdp->events & _DBUS_POLLIN)
01127 FD_SET (fdp->fd, &read_set);
01128
01129 if (fdp->events & _DBUS_POLLOUT)
01130 FD_SET (fdp->fd, &write_set);
01131
01132 FD_SET (fdp->fd, &err_set);
01133
01134 max_fd = MAX (max_fd, fdp->fd);
01135 }
01136
01137
01138 tv.tv_sec = timeout_milliseconds < 0 ? 1 : timeout_milliseconds / 1000;
01139 tv.tv_usec = timeout_milliseconds < 0 ? 0 : (timeout_milliseconds % 1000) * 1000;
01140
01141 ready = select (max_fd + 1, &read_set, &write_set, &err_set, &tv);
01142
01143 if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
01144 {
01145 DBUS_SOCKET_SET_ERRNO ();
01146 if (errno != WSAEWOULDBLOCK)
01147 _dbus_verbose ("select: failed: %s\n", _dbus_strerror_from_errno ());
01148 }
01149 else if (ready == 0)
01150 _dbus_verbose ("select: = 0\n");
01151 else
01152 if (ready > 0)
01153 {
01154 #ifdef DBUS_ENABLE_VERBOSE_MODE
01155 msgp = msg;
01156 msgp += sprintf (msgp, "select: = %d:\n\t", ready);
01157
01158 for (i = 0; i < n_fds; i++)
01159 {
01160 DBusPollFD *fdp = &fds[i];
01161
01162 if (FD_ISSET (fdp->fd, &read_set))
01163 msgp += sprintf (msgp, "R:%d ", fdp->fd);
01164
01165 if (FD_ISSET (fdp->fd, &write_set))
01166 msgp += sprintf (msgp, "W:%d ", fdp->fd);
01167
01168 if (FD_ISSET (fdp->fd, &err_set))
01169 msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
01170 }
01171 msgp += sprintf (msgp, "\n");
01172 _dbus_verbose ("%s",msg);
01173 #endif
01174
01175 for (i = 0; i < n_fds; i++)
01176 {
01177 DBusPollFD *fdp = &fds[i];
01178
01179 fdp->revents = 0;
01180
01181 if (FD_ISSET (fdp->fd, &read_set))
01182 fdp->revents |= _DBUS_POLLIN;
01183
01184 if (FD_ISSET (fdp->fd, &write_set))
01185 fdp->revents |= _DBUS_POLLOUT;
01186
01187 if (FD_ISSET (fdp->fd, &err_set))
01188 fdp->revents |= _DBUS_POLLERR;
01189 }
01190 }
01191 return ready;
01192 #endif
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
01224
01225
01226
01227
01228
01234 void
01235 _dbus_exit (int code)
01236 {
01237 _exit (code);
01238 }
01239
01251 int
01252 _dbus_connect_tcp_socket (const char *host,
01253 const char *port,
01254 const char *family,
01255 DBusError *error)
01256 {
01257 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01258 }
01259
01260 int
01261 _dbus_connect_tcp_socket_with_nonce (const char *host,
01262 const char *port,
01263 const char *family,
01264 const char *noncefile,
01265 DBusError *error)
01266 {
01267 int fd = -1, res;
01268 struct addrinfo hints;
01269 struct addrinfo *ai, *tmp;
01270
01271 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01272
01273 _dbus_win_startup_winsock ();
01274
01275 _DBUS_ZERO (hints);
01276
01277 if (!family)
01278 hints.ai_family = AF_UNSPEC;
01279 else if (!strcmp(family, "ipv4"))
01280 hints.ai_family = AF_INET;
01281 else if (!strcmp(family, "ipv6"))
01282 hints.ai_family = AF_INET6;
01283 else
01284 {
01285 dbus_set_error (error,
01286 DBUS_ERROR_INVALID_ARGS,
01287 "Unknown address family %s", family);
01288 return -1;
01289 }
01290 hints.ai_protocol = IPPROTO_TCP;
01291 hints.ai_socktype = SOCK_STREAM;
01292 #ifdef AI_ADDRCONFIG
01293 hints.ai_flags = AI_ADDRCONFIG;
01294 #else
01295 hints.ai_flags = 0;
01296 #endif
01297
01298 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01299 {
01300 dbus_set_error (error,
01301 _dbus_error_from_errno (res),
01302 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01303 host, port, _dbus_strerror(res), res);
01304 return -1;
01305 }
01306
01307 tmp = ai;
01308 while (tmp)
01309 {
01310 if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
01311 {
01312 DBUS_SOCKET_SET_ERRNO ();
01313 dbus_set_error (error,
01314 _dbus_error_from_errno (errno),
01315 "Failed to open socket: %s",
01316 _dbus_strerror_from_errno ());
01317 freeaddrinfo(ai);
01318 return -1;
01319 }
01320 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01321
01322 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
01323 {
01324 DBUS_SOCKET_SET_ERRNO ();
01325 closesocket(fd);
01326 fd = -1;
01327 tmp = tmp->ai_next;
01328 continue;
01329 }
01330
01331 break;
01332 }
01333 freeaddrinfo(ai);
01334
01335 if (fd == -1)
01336 {
01337 dbus_set_error (error,
01338 _dbus_error_from_errno (errno),
01339 "Failed to connect to socket \"%s:%s\" %s",
01340 host, port, _dbus_strerror_from_errno ());
01341 return -1;
01342 }
01343
01344 if (noncefile != NULL)
01345 {
01346 DBusString noncefileStr;
01347 dbus_bool_t ret;
01348 if (!_dbus_string_init (&noncefileStr) ||
01349 !_dbus_string_append(&noncefileStr, noncefile))
01350 {
01351 closesocket (fd);
01352 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01353 return -1;
01354 }
01355
01356 ret = _dbus_send_nonce (fd, &noncefileStr, error);
01357
01358 _dbus_string_free (&noncefileStr);
01359
01360 if (!ret)
01361 {
01362 closesocket (fd);
01363 return -1;
01364 }
01365 }
01366
01367 _dbus_fd_set_close_on_exec (fd);
01368
01369 if (!_dbus_set_fd_nonblocking (fd, error))
01370 {
01371 closesocket (fd);
01372 return -1;
01373 }
01374
01375 return fd;
01376 }
01377
01393 int
01394 _dbus_listen_tcp_socket (const char *host,
01395 const char *port,
01396 const char *family,
01397 DBusString *retport,
01398 int **fds_p,
01399 DBusError *error)
01400 {
01401 int nlisten_fd = 0, *listen_fd = NULL, res, i, port_num = -1;
01402 struct addrinfo hints;
01403 struct addrinfo *ai, *tmp;
01404
01405
01406
01407
01408
01409 typedef union {
01410 struct sockaddr Address;
01411 struct sockaddr_in AddressIn;
01412 struct sockaddr_in6 AddressIn6;
01413 } mysockaddr_gen;
01414
01415 *fds_p = NULL;
01416 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01417
01418 _dbus_win_startup_winsock ();
01419
01420 _DBUS_ZERO (hints);
01421
01422 if (!family)
01423 hints.ai_family = AF_UNSPEC;
01424 else if (!strcmp(family, "ipv4"))
01425 hints.ai_family = AF_INET;
01426 else if (!strcmp(family, "ipv6"))
01427 hints.ai_family = AF_INET6;
01428 else
01429 {
01430 dbus_set_error (error,
01431 DBUS_ERROR_INVALID_ARGS,
01432 "Unknown address family %s", family);
01433 return -1;
01434 }
01435
01436 hints.ai_protocol = IPPROTO_TCP;
01437 hints.ai_socktype = SOCK_STREAM;
01438 #ifdef AI_ADDRCONFIG
01439 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01440 #else
01441 hints.ai_flags = AI_PASSIVE;
01442 #endif
01443
01444 redo_lookup_with_port:
01445 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01446 {
01447 dbus_set_error (error,
01448 _dbus_error_from_errno (res),
01449 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01450 host ? host : "*", port, _dbus_strerror(res), res);
01451 return -1;
01452 }
01453
01454 tmp = ai;
01455 while (tmp)
01456 {
01457 int fd = -1, *newlisten_fd;
01458 if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
01459 {
01460 DBUS_SOCKET_SET_ERRNO ();
01461 dbus_set_error (error,
01462 _dbus_error_from_errno (errno),
01463 "Failed to open socket: %s",
01464 _dbus_strerror_from_errno ());
01465 goto failed;
01466 }
01467 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01468
01469 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
01470 {
01471 DBUS_SOCKET_SET_ERRNO ();
01472 dbus_set_error (error, _dbus_error_from_errno (errno),
01473 "Failed to bind socket \"%s:%s\": %s",
01474 host ? host : "*", port, _dbus_strerror_from_errno ());
01475 closesocket (fd);
01476 goto failed;
01477 }
01478
01479 if (listen (fd, 30 ) == SOCKET_ERROR)
01480 {
01481 DBUS_SOCKET_SET_ERRNO ();
01482 dbus_set_error (error, _dbus_error_from_errno (errno),
01483 "Failed to listen on socket \"%s:%s\": %s",
01484 host ? host : "*", port, _dbus_strerror_from_errno ());
01485 closesocket (fd);
01486 goto failed;
01487 }
01488
01489 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01490 if (!newlisten_fd)
01491 {
01492 closesocket (fd);
01493 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01494 "Failed to allocate file handle array");
01495 goto failed;
01496 }
01497 listen_fd = newlisten_fd;
01498 listen_fd[nlisten_fd] = fd;
01499 nlisten_fd++;
01500
01501 if (!_dbus_string_get_length(retport))
01502 {
01503
01504
01505
01506
01507 if (!port || !strcmp(port, "0"))
01508 {
01509 mysockaddr_gen addr;
01510 socklen_t addrlen = sizeof(addr);
01511 char portbuf[10];
01512
01513 if (getsockname(fd, &addr.Address, &addrlen) == SOCKET_ERROR)
01514 {
01515 DBUS_SOCKET_SET_ERRNO ();
01516 dbus_set_error (error, _dbus_error_from_errno (errno),
01517 "Failed to resolve port \"%s:%s\": %s",
01518 host ? host : "*", port, _dbus_strerror_from_errno());
01519 goto failed;
01520 }
01521 snprintf( portbuf, sizeof( portbuf ) - 1, "%d", addr.AddressIn.sin_port );
01522 if (!_dbus_string_append(retport, portbuf))
01523 {
01524 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01525 goto failed;
01526 }
01527
01528
01529 port = _dbus_string_get_const_data(retport);
01530 freeaddrinfo(ai);
01531 goto redo_lookup_with_port;
01532 }
01533 else
01534 {
01535 if (!_dbus_string_append(retport, port))
01536 {
01537 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01538 goto failed;
01539 }
01540 }
01541 }
01542
01543 tmp = tmp->ai_next;
01544 }
01545 freeaddrinfo(ai);
01546 ai = NULL;
01547
01548 if (!nlisten_fd)
01549 {
01550 _dbus_win_set_errno (WSAEADDRINUSE);
01551 dbus_set_error (error, _dbus_error_from_errno (errno),
01552 "Failed to bind socket \"%s:%s\": %s",
01553 host ? host : "*", port, _dbus_strerror_from_errno ());
01554 return -1;
01555 }
01556
01557 sscanf(_dbus_string_get_const_data(retport), "%d", &port_num);
01558
01559 for (i = 0 ; i < nlisten_fd ; i++)
01560 {
01561 _dbus_fd_set_close_on_exec (listen_fd[i]);
01562 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01563 {
01564 goto failed;
01565 }
01566 }
01567
01568 *fds_p = listen_fd;
01569
01570 return nlisten_fd;
01571
01572 failed:
01573 if (ai)
01574 freeaddrinfo(ai);
01575 for (i = 0 ; i < nlisten_fd ; i++)
01576 closesocket (listen_fd[i]);
01577 dbus_free(listen_fd);
01578 return -1;
01579 }
01580
01581
01589 int
01590 _dbus_accept (int listen_fd)
01591 {
01592 int client_fd;
01593
01594 retry:
01595 client_fd = accept (listen_fd, NULL, NULL);
01596
01597 if (DBUS_SOCKET_IS_INVALID (client_fd))
01598 {
01599 DBUS_SOCKET_SET_ERRNO ();
01600 if (errno == EINTR)
01601 goto retry;
01602 }
01603
01604 _dbus_verbose ("client fd %d accepted\n", client_fd);
01605
01606 return client_fd;
01607 }
01608
01609
01610
01611
01612 dbus_bool_t
01613 _dbus_send_credentials_socket (int handle,
01614 DBusError *error)
01615 {
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639 int bytes_written;
01640 DBusString buf;
01641
01642 _dbus_string_init_const_len (&buf, "\0", 1);
01643 again:
01644 bytes_written = _dbus_write_socket (handle, &buf, 0, 1 );
01645
01646 if (bytes_written < 0 && errno == EINTR)
01647 goto again;
01648
01649 if (bytes_written < 0)
01650 {
01651 dbus_set_error (error, _dbus_error_from_errno (errno),
01652 "Failed to write credentials byte: %s",
01653 _dbus_strerror_from_errno ());
01654 return FALSE;
01655 }
01656 else if (bytes_written == 0)
01657 {
01658 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01659 "wrote zero bytes writing credentials byte");
01660 return FALSE;
01661 }
01662 else
01663 {
01664 _dbus_assert (bytes_written == 1);
01665 _dbus_verbose ("wrote 1 zero byte, credential sending isn't implemented yet\n");
01666 return TRUE;
01667 }
01668 return TRUE;
01669 }
01670
01689 dbus_bool_t
01690 _dbus_read_credentials_socket (int handle,
01691 DBusCredentials *credentials,
01692 DBusError *error)
01693 {
01694 int bytes_read = 0;
01695 DBusString buf;
01696
01697
01698 if (_dbus_string_init(&buf))
01699 {
01700 bytes_read = _dbus_read_socket(handle, &buf, 1 );
01701
01702 if (bytes_read > 0)
01703 _dbus_verbose("got one zero byte from server");
01704
01705 _dbus_string_free(&buf);
01706 }
01707
01708 _dbus_credentials_add_from_current_process (credentials);
01709 _dbus_verbose("FIXME: get faked credentials from current process");
01710
01711 return TRUE;
01712 }
01713
01722 dbus_bool_t
01723 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01724 {
01725
01726 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01727 return TRUE;
01728 }
01729
01730
01741 dbus_bool_t
01742 _dbus_concat_dir_and_file (DBusString *dir,
01743 const DBusString *next_component)
01744 {
01745 dbus_bool_t dir_ends_in_slash;
01746 dbus_bool_t file_starts_with_slash;
01747
01748 if (_dbus_string_get_length (dir) == 0 ||
01749 _dbus_string_get_length (next_component) == 0)
01750 return TRUE;
01751
01752 dir_ends_in_slash =
01753 ('/' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1) ||
01754 '\\' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1));
01755
01756 file_starts_with_slash =
01757 ('/' == _dbus_string_get_byte (next_component, 0) ||
01758 '\\' == _dbus_string_get_byte (next_component, 0));
01759
01760 if (dir_ends_in_slash && file_starts_with_slash)
01761 {
01762 _dbus_string_shorten (dir, 1);
01763 }
01764 else if (!(dir_ends_in_slash || file_starts_with_slash))
01765 {
01766 if (!_dbus_string_append_byte (dir, '\\'))
01767 return FALSE;
01768 }
01769
01770 return _dbus_string_copy (next_component, 0, dir,
01771 _dbus_string_get_length (dir));
01772 }
01773
01774
01775
01783 dbus_bool_t
01784 _dbus_credentials_add_from_user (DBusCredentials *credentials,
01785 const DBusString *username)
01786 {
01787 return _dbus_credentials_add_windows_sid (credentials,
01788 _dbus_string_get_const_data(username));
01789 }
01790
01799 dbus_bool_t
01800 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
01801 {
01802 dbus_bool_t retval = FALSE;
01803 char *sid = NULL;
01804
01805 if (!_dbus_getsid(&sid))
01806 goto failed;
01807
01808 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
01809 goto failed;
01810
01811 if (!_dbus_credentials_add_windows_sid (credentials,sid))
01812 goto failed;
01813
01814 retval = TRUE;
01815 goto end;
01816 failed:
01817 retval = FALSE;
01818 end:
01819 if (sid)
01820 LocalFree(sid);
01821
01822 return retval;
01823 }
01824
01837 dbus_bool_t
01838 _dbus_append_user_from_current_process (DBusString *str)
01839 {
01840 dbus_bool_t retval = FALSE;
01841 char *sid = NULL;
01842
01843 if (!_dbus_getsid(&sid))
01844 return FALSE;
01845
01846 retval = _dbus_string_append (str,sid);
01847
01848 LocalFree(sid);
01849 return retval;
01850 }
01851
01856 dbus_pid_t
01857 _dbus_getpid (void)
01858 {
01859 return GetCurrentProcessId ();
01860 }
01861
01863 #define NANOSECONDS_PER_SECOND 1000000000
01864
01865 #define MICROSECONDS_PER_SECOND 1000000
01866
01867 #define MILLISECONDS_PER_SECOND 1000
01868
01869 #define NANOSECONDS_PER_MILLISECOND 1000000
01870
01871 #define MICROSECONDS_PER_MILLISECOND 1000
01872
01877 void
01878 _dbus_sleep_milliseconds (int milliseconds)
01879 {
01880 Sleep (milliseconds);
01881 }
01882
01883
01890 void
01891 _dbus_get_current_time (long *tv_sec,
01892 long *tv_usec)
01893 {
01894 FILETIME ft;
01895 dbus_uint64_t time64;
01896
01897 GetSystemTimeAsFileTime (&ft);
01898
01899 memcpy (&time64, &ft, sizeof (time64));
01900
01901
01902
01903
01904 time64 -= DBUS_INT64_CONSTANT (116444736000000000);
01905 time64 /= 10;
01906
01907 if (tv_sec)
01908 *tv_sec = time64 / 1000000;
01909
01910 if (tv_usec)
01911 *tv_usec = time64 % 1000000;
01912 }
01913
01914
01918 void
01919 _dbus_disable_sigpipe (void)
01920 {
01921 }
01922
01931 dbus_bool_t
01932 _dbus_create_directory (const DBusString *filename,
01933 DBusError *error)
01934 {
01935 const char *filename_c;
01936
01937 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01938
01939 filename_c = _dbus_string_get_const_data (filename);
01940
01941 if (!CreateDirectoryA (filename_c, NULL))
01942 {
01943 if (GetLastError () == ERROR_ALREADY_EXISTS)
01944 return TRUE;
01945
01946 dbus_set_error (error, DBUS_ERROR_FAILED,
01947 "Failed to create directory %s: %s\n",
01948 filename_c, _dbus_strerror_from_errno ());
01949 return FALSE;
01950 }
01951 else
01952 return TRUE;
01953 }
01954
01955
01964 dbus_bool_t
01965 _dbus_generate_random_bytes (DBusString *str,
01966 int n_bytes)
01967 {
01968 int old_len;
01969 char *p;
01970 HCRYPTPROV hprov;
01971
01972 old_len = _dbus_string_get_length (str);
01973
01974 if (!_dbus_string_lengthen (str, n_bytes))
01975 return FALSE;
01976
01977 p = _dbus_string_get_data_len (str, old_len, n_bytes);
01978
01979 if (!CryptAcquireContext (&hprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
01980 return FALSE;
01981
01982 if (!CryptGenRandom (hprov, n_bytes, p))
01983 {
01984 CryptReleaseContext (hprov, 0);
01985 return FALSE;
01986 }
01987
01988 CryptReleaseContext (hprov, 0);
01989
01990 return TRUE;
01991 }
01992
01999 const char*
02000 _dbus_get_tmpdir(void)
02001 {
02002 static const char* tmpdir = NULL;
02003 static char buf[1000];
02004
02005 if (tmpdir == NULL)
02006 {
02007 char *last_slash;
02008
02009 if (!GetTempPathA (sizeof (buf), buf))
02010 {
02011 _dbus_warn ("GetTempPath failed\n");
02012 _dbus_abort ();
02013 }
02014
02015
02016 last_slash = _mbsrchr (buf, '\\');
02017 if (last_slash > buf && last_slash[1] == '\0')
02018 last_slash[0] = '\0';
02019 last_slash = _mbsrchr (buf, '/');
02020 if (last_slash > buf && last_slash[1] == '\0')
02021 last_slash[0] = '\0';
02022
02023 tmpdir = buf;
02024 }
02025
02026 _dbus_assert(tmpdir != NULL);
02027
02028 return tmpdir;
02029 }
02030
02031
02040 dbus_bool_t
02041 _dbus_delete_file (const DBusString *filename,
02042 DBusError *error)
02043 {
02044 const char *filename_c;
02045
02046 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02047
02048 filename_c = _dbus_string_get_const_data (filename);
02049
02050 if (DeleteFileA (filename_c) == 0)
02051 {
02052 dbus_set_error (error, DBUS_ERROR_FAILED,
02053 "Failed to delete file %s: %s\n",
02054 filename_c, _dbus_strerror_from_errno ());
02055 return FALSE;
02056 }
02057 else
02058 return TRUE;
02059 }
02060
02061
02062
02063
02064
02065
02066
02067
02068 const char *
02069 _dbus_replace_install_prefix (const char *configure_time_path)
02070 {
02071 #ifndef DBUS_PREFIX
02072 return configure_time_path;
02073 #else
02074 static char retval[1000];
02075 static char runtime_prefix[1000];
02076 int len = 1000;
02077 int i;
02078
02079 if (!configure_time_path)
02080 return NULL;
02081
02082 if ((!_dbus_get_install_root(runtime_prefix, len) ||
02083 strncmp (configure_time_path, DBUS_PREFIX "/",
02084 strlen (DBUS_PREFIX) + 1))) {
02085 strcat (retval, configure_time_path);
02086 return retval;
02087 }
02088
02089 strcpy (retval, runtime_prefix);
02090 strcat (retval, configure_time_path + strlen (DBUS_PREFIX) + 1);
02091
02092
02093
02094
02095
02096
02097 for(i = 0; retval[i] != '\0'; i++) {
02098 if(retval[i] == '\\')
02099 retval[i] = '/';
02100 }
02101 return retval;
02102 #endif
02103 }
02104
02105 #if !defined (DBUS_DISABLE_ASSERTS) || defined(DBUS_BUILD_TESTS)
02106
02107 #if defined(_MSC_VER) || defined(DBUS_WINCE)
02108 # ifdef BACKTRACES
02109 # undef BACKTRACES
02110 # endif
02111 #else
02112 # define BACKTRACES
02113 #endif
02114
02115 #ifdef BACKTRACES
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137 #include <winver.h>
02138 #include <imagehlp.h>
02139 #include <stdio.h>
02140
02141 #define DPRINTF _dbus_warn
02142
02143 #ifdef _MSC_VER
02144 #define BOOL int
02145
02146 #define __i386__
02147 #endif
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157 static BOOL (WINAPI *pStackWalk)(
02158 DWORD MachineType,
02159 HANDLE hProcess,
02160 HANDLE hThread,
02161 LPSTACKFRAME StackFrame,
02162 PVOID ContextRecord,
02163 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
02164 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
02165 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
02166 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
02167 );
02168 #ifdef _WIN64
02169 static DWORD64 (WINAPI *pSymGetModuleBase)(
02170 HANDLE hProcess,
02171 DWORD64 dwAddr
02172 );
02173 static PVOID (WINAPI *pSymFunctionTableAccess)(
02174 HANDLE hProcess,
02175 DWORD64 AddrBase
02176 );
02177 #else
02178 static DWORD (WINAPI *pSymGetModuleBase)(
02179 HANDLE hProcess,
02180 DWORD dwAddr
02181 );
02182 static PVOID (WINAPI *pSymFunctionTableAccess)(
02183 HANDLE hProcess,
02184 DWORD AddrBase
02185 );
02186 #endif
02187 static BOOL (WINAPI *pSymInitialize)(
02188 HANDLE hProcess,
02189 PSTR UserSearchPath,
02190 BOOL fInvadeProcess
02191 );
02192 static BOOL (WINAPI *pSymGetSymFromAddr)(
02193 HANDLE hProcess,
02194 DWORD Address,
02195 PDWORD Displacement,
02196 PIMAGEHLP_SYMBOL Symbol
02197 );
02198 static BOOL (WINAPI *pSymGetModuleInfo)(
02199 HANDLE hProcess,
02200 DWORD dwAddr,
02201 PIMAGEHLP_MODULE ModuleInfo
02202 );
02203 static DWORD (WINAPI *pSymSetOptions)(
02204 DWORD SymOptions
02205 );
02206
02207
02208 static BOOL init_backtrace()
02209 {
02210 HMODULE hmodDbgHelp = LoadLibraryA("dbghelp");
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228 #define FUNC(x) #x
02229
02230 pStackWalk = (BOOL (WINAPI *)(
02231 DWORD MachineType,
02232 HANDLE hProcess,
02233 HANDLE hThread,
02234 LPSTACKFRAME StackFrame,
02235 PVOID ContextRecord,
02236 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
02237 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
02238 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
02239 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
02240 ))GetProcAddress (hmodDbgHelp, FUNC(StackWalk));
02241 #ifdef _WIN64
02242 pSymGetModuleBase=(DWORD64 (WINAPI *)(
02243 HANDLE hProcess,
02244 DWORD64 dwAddr
02245 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
02246 pSymFunctionTableAccess=(PVOID (WINAPI *)(
02247 HANDLE hProcess,
02248 DWORD64 AddrBase
02249 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
02250 #else
02251 pSymGetModuleBase=(DWORD (WINAPI *)(
02252 HANDLE hProcess,
02253 DWORD dwAddr
02254 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
02255 pSymFunctionTableAccess=(PVOID (WINAPI *)(
02256 HANDLE hProcess,
02257 DWORD AddrBase
02258 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
02259 #endif
02260 pSymInitialize = (BOOL (WINAPI *)(
02261 HANDLE hProcess,
02262 PSTR UserSearchPath,
02263 BOOL fInvadeProcess
02264 ))GetProcAddress (hmodDbgHelp, FUNC(SymInitialize));
02265 pSymGetSymFromAddr = (BOOL (WINAPI *)(
02266 HANDLE hProcess,
02267 DWORD Address,
02268 PDWORD Displacement,
02269 PIMAGEHLP_SYMBOL Symbol
02270 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetSymFromAddr));
02271 pSymGetModuleInfo = (BOOL (WINAPI *)(
02272 HANDLE hProcess,
02273 DWORD dwAddr,
02274 PIMAGEHLP_MODULE ModuleInfo
02275 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleInfo));
02276 pSymSetOptions = (DWORD (WINAPI *)(
02277 DWORD SymOptions
02278 ))GetProcAddress (hmodDbgHelp, FUNC(SymSetOptions));
02279
02280
02281 pSymSetOptions(SYMOPT_UNDNAME);
02282
02283 pSymInitialize(GetCurrentProcess(), NULL, TRUE);
02284
02285 return TRUE;
02286 }
02287
02288 static void dump_backtrace_for_thread(HANDLE hThread)
02289 {
02290 STACKFRAME sf;
02291 CONTEXT context;
02292 DWORD dwImageType;
02293
02294 if (!pStackWalk)
02295 if (!init_backtrace())
02296 return;
02297
02298
02299
02300 if (hThread == GetCurrentThread())
02301 return;
02302
02303 DPRINTF("Backtrace:\n");
02304
02305 _DBUS_ZERO(context);
02306 context.ContextFlags = CONTEXT_FULL;
02307
02308 SuspendThread(hThread);
02309
02310 if (!GetThreadContext(hThread, &context))
02311 {
02312 DPRINTF("Couldn't get thread context (error %ld)\n", GetLastError());
02313 ResumeThread(hThread);
02314 return;
02315 }
02316
02317 _DBUS_ZERO(sf);
02318
02319 #ifdef __i386__
02320 sf.AddrFrame.Offset = context.Ebp;
02321 sf.AddrFrame.Mode = AddrModeFlat;
02322 sf.AddrPC.Offset = context.Eip;
02323 sf.AddrPC.Mode = AddrModeFlat;
02324 dwImageType = IMAGE_FILE_MACHINE_I386;
02325 #elif _M_X64
02326 dwImageType = IMAGE_FILE_MACHINE_AMD64;
02327 sf.AddrPC.Offset = context.Rip;
02328 sf.AddrPC.Mode = AddrModeFlat;
02329 sf.AddrFrame.Offset = context.Rsp;
02330 sf.AddrFrame.Mode = AddrModeFlat;
02331 sf.AddrStack.Offset = context.Rsp;
02332 sf.AddrStack.Mode = AddrModeFlat;
02333 #elif _M_IA64
02334 dwImageType = IMAGE_FILE_MACHINE_IA64;
02335 sf.AddrPC.Offset = context.StIIP;
02336 sf.AddrPC.Mode = AddrModeFlat;
02337 sf.AddrFrame.Offset = context.IntSp;
02338 sf.AddrFrame.Mode = AddrModeFlat;
02339 sf.AddrBStore.Offset= context.RsBSP;
02340 sf.AddrBStore.Mode = AddrModeFlat;
02341 sf.AddrStack.Offset = context.IntSp;
02342 sf.AddrStack.Mode = AddrModeFlat;
02343 #else
02344 # error You need to fill in the STACKFRAME structure for your architecture
02345 #endif
02346
02347 while (pStackWalk(dwImageType, GetCurrentProcess(),
02348 hThread, &sf, &context, NULL, pSymFunctionTableAccess,
02349 pSymGetModuleBase, NULL))
02350 {
02351 BYTE buffer[256];
02352 IMAGEHLP_SYMBOL * pSymbol = (IMAGEHLP_SYMBOL *)buffer;
02353 DWORD dwDisplacement;
02354
02355 pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
02356 pSymbol->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1;
02357
02358 if (!pSymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset,
02359 &dwDisplacement, pSymbol))
02360 {
02361 IMAGEHLP_MODULE ModuleInfo;
02362 ModuleInfo.SizeOfStruct = sizeof(ModuleInfo);
02363
02364 if (!pSymGetModuleInfo(GetCurrentProcess(), sf.AddrPC.Offset,
02365 &ModuleInfo))
02366 DPRINTF("1\t%p\n", (void*)sf.AddrPC.Offset);
02367 else
02368 DPRINTF("2\t%s+0x%lx\n", ModuleInfo.ImageName,
02369 sf.AddrPC.Offset - ModuleInfo.BaseOfImage);
02370 }
02371 else if (dwDisplacement)
02372 DPRINTF("3\t%s+0x%lx\n", pSymbol->Name, dwDisplacement);
02373 else
02374 DPRINTF("4\t%s\n", pSymbol->Name);
02375 }
02376
02377 ResumeThread(hThread);
02378 }
02379
02380 static DWORD WINAPI dump_thread_proc(LPVOID lpParameter)
02381 {
02382 dump_backtrace_for_thread((HANDLE)lpParameter);
02383 return 0;
02384 }
02385
02386
02387
02388 static void dump_backtrace()
02389 {
02390 HANDLE hCurrentThread;
02391 HANDLE hThread;
02392 DWORD dwThreadId;
02393 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
02394 GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
02395 hThread = CreateThread(NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread,
02396 0, &dwThreadId);
02397 WaitForSingleObject(hThread, INFINITE);
02398 CloseHandle(hThread);
02399 CloseHandle(hCurrentThread);
02400 }
02401 #endif
02402 #endif
02403
02404 #ifdef BACKTRACES
02405 void _dbus_print_backtrace(void)
02406 {
02407 init_backtrace();
02408 dump_backtrace();
02409 }
02410 #else
02411 void _dbus_print_backtrace(void)
02412 {
02413 _dbus_verbose (" D-Bus not compiled with backtrace support\n");
02414 }
02415 #endif
02416
02417 static dbus_uint32_t fromAscii(char ascii)
02418 {
02419 if(ascii >= '0' && ascii <= '9')
02420 return ascii - '0';
02421 if(ascii >= 'A' && ascii <= 'F')
02422 return ascii - 'A' + 10;
02423 if(ascii >= 'a' && ascii <= 'f')
02424 return ascii - 'a' + 10;
02425 return 0;
02426 }
02427
02428 dbus_bool_t _dbus_read_local_machine_uuid (DBusGUID *machine_id,
02429 dbus_bool_t create_if_not_found,
02430 DBusError *error)
02431 {
02432 #ifdef DBUS_WINCE
02433 return TRUE;
02434
02435 #else
02436 HW_PROFILE_INFOA info;
02437 char *lpc = &info.szHwProfileGuid[0];
02438 dbus_uint32_t u;
02439
02440
02441 if(!GetCurrentHwProfileA(&info))
02442 {
02443 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02444 return FALSE;
02445 }
02446
02447
02448 lpc++;
02449
02450 u = ((fromAscii(lpc[0]) << 0) |
02451 (fromAscii(lpc[1]) << 4) |
02452 (fromAscii(lpc[2]) << 8) |
02453 (fromAscii(lpc[3]) << 12) |
02454 (fromAscii(lpc[4]) << 16) |
02455 (fromAscii(lpc[5]) << 20) |
02456 (fromAscii(lpc[6]) << 24) |
02457 (fromAscii(lpc[7]) << 28));
02458 machine_id->as_uint32s[0] = u;
02459
02460 lpc += 9;
02461
02462 u = ((fromAscii(lpc[0]) << 0) |
02463 (fromAscii(lpc[1]) << 4) |
02464 (fromAscii(lpc[2]) << 8) |
02465 (fromAscii(lpc[3]) << 12) |
02466 (fromAscii(lpc[5]) << 16) |
02467 (fromAscii(lpc[6]) << 20) |
02468 (fromAscii(lpc[7]) << 24) |
02469 (fromAscii(lpc[8]) << 28));
02470 machine_id->as_uint32s[1] = u;
02471
02472 lpc += 10;
02473
02474 u = ((fromAscii(lpc[0]) << 0) |
02475 (fromAscii(lpc[1]) << 4) |
02476 (fromAscii(lpc[2]) << 8) |
02477 (fromAscii(lpc[3]) << 12) |
02478 (fromAscii(lpc[5]) << 16) |
02479 (fromAscii(lpc[6]) << 20) |
02480 (fromAscii(lpc[7]) << 24) |
02481 (fromAscii(lpc[8]) << 28));
02482 machine_id->as_uint32s[2] = u;
02483
02484 lpc += 9;
02485
02486 u = ((fromAscii(lpc[0]) << 0) |
02487 (fromAscii(lpc[1]) << 4) |
02488 (fromAscii(lpc[2]) << 8) |
02489 (fromAscii(lpc[3]) << 12) |
02490 (fromAscii(lpc[4]) << 16) |
02491 (fromAscii(lpc[5]) << 20) |
02492 (fromAscii(lpc[6]) << 24) |
02493 (fromAscii(lpc[7]) << 28));
02494 machine_id->as_uint32s[3] = u;
02495 #endif
02496 return TRUE;
02497 }
02498
02499 static
02500 HANDLE _dbus_global_lock (const char *mutexname)
02501 {
02502 HANDLE mutex;
02503 DWORD gotMutex;
02504
02505 mutex = CreateMutexA( NULL, FALSE, mutexname );
02506 if( !mutex )
02507 {
02508 return FALSE;
02509 }
02510
02511 gotMutex = WaitForSingleObject( mutex, INFINITE );
02512 switch( gotMutex )
02513 {
02514 case WAIT_ABANDONED:
02515 ReleaseMutex (mutex);
02516 CloseHandle (mutex);
02517 return 0;
02518 case WAIT_FAILED:
02519 case WAIT_TIMEOUT:
02520 return 0;
02521 }
02522
02523 return mutex;
02524 }
02525
02526 static
02527 void _dbus_global_unlock (HANDLE mutex)
02528 {
02529 ReleaseMutex (mutex);
02530 CloseHandle (mutex);
02531 }
02532
02533
02534 static HANDLE hDBusDaemonMutex = NULL;
02535 static HANDLE hDBusSharedMem = NULL;
02536
02537 static const char *cUniqueDBusInitMutex = "UniqueDBusInitMutex";
02538
02539 static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex";
02540
02541 static const char *cDBusDaemonMutex = "DBusDaemonMutex";
02542
02543 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
02544
02545 static dbus_bool_t
02546 _dbus_get_install_root_as_hash(DBusString *out)
02547 {
02548 DBusString install_path;
02549
02550 char path[MAX_PATH*2];
02551 int path_size = sizeof(path);
02552
02553 if (!_dbus_get_install_root(path,path_size))
02554 return FALSE;
02555
02556 _dbus_string_init(&install_path);
02557 _dbus_string_append(&install_path,path);
02558
02559 _dbus_string_init(out);
02560 _dbus_string_tolower_ascii(&install_path,0,_dbus_string_get_length(&install_path));
02561
02562 if (!_dbus_sha_compute (&install_path, out))
02563 return FALSE;
02564
02565 return TRUE;
02566 }
02567
02568 static dbus_bool_t
02569 _dbus_get_address_string (DBusString *out, const char *basestring, const char *scope)
02570 {
02571 _dbus_string_init(out);
02572 _dbus_string_append(out,basestring);
02573
02574 if (!scope)
02575 {
02576 return TRUE;
02577 }
02578 else if (strcmp(scope,"*install-path") == 0
02579
02580 || strcmp(scope,"install-path") == 0)
02581 {
02582 DBusString temp;
02583 if (!_dbus_get_install_root_as_hash(&temp))
02584 {
02585 _dbus_string_free(out);
02586 return FALSE;
02587 }
02588 _dbus_string_append(out,"-");
02589 _dbus_string_append(out,_dbus_string_get_const_data(&temp));
02590 _dbus_string_free(&temp);
02591 }
02592 else if (strcmp(scope,"*user") == 0)
02593 {
02594 _dbus_string_append(out,"-");
02595 if (!_dbus_append_user_from_current_process(out))
02596 {
02597 _dbus_string_free(out);
02598 return FALSE;
02599 }
02600 }
02601 else if (strlen(scope) > 0)
02602 {
02603 _dbus_string_append(out,"-");
02604 _dbus_string_append(out,scope);
02605 return TRUE;
02606 }
02607 return TRUE;
02608 }
02609
02610 static dbus_bool_t
02611 _dbus_get_shm_name (DBusString *out,const char *scope)
02612 {
02613 return _dbus_get_address_string (out,cDBusDaemonAddressInfo,scope);
02614 }
02615
02616 static dbus_bool_t
02617 _dbus_get_mutex_name (DBusString *out,const char *scope)
02618 {
02619 return _dbus_get_address_string (out,cDBusDaemonMutex,scope);
02620 }
02621
02622 dbus_bool_t
02623 _dbus_daemon_is_session_bus_address_published (const char *scope)
02624 {
02625 HANDLE lock;
02626 HANDLE mutex;
02627 DBusString mutex_name;
02628 DWORD ret;
02629
02630 if (!_dbus_get_mutex_name(&mutex_name,scope))
02631 {
02632 _dbus_string_free( &mutex_name );
02633 return FALSE;
02634 }
02635
02636 if (hDBusDaemonMutex)
02637 return TRUE;
02638
02639
02640 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02641
02642
02643
02644 hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02645
02646
02647
02648
02649
02650 _dbus_global_unlock( lock );
02651
02652 _dbus_string_free( &mutex_name );
02653
02654 if (hDBusDaemonMutex == NULL)
02655 return FALSE;
02656 if (GetLastError() == ERROR_ALREADY_EXISTS)
02657 {
02658 CloseHandle(hDBusDaemonMutex);
02659 hDBusDaemonMutex = NULL;
02660 return TRUE;
02661 }
02662
02663
02664
02665 return FALSE;
02666 }
02667
02668 dbus_bool_t
02669 _dbus_daemon_publish_session_bus_address (const char* address, const char *scope)
02670 {
02671 HANDLE lock;
02672 char *shared_addr = NULL;
02673 DWORD ret;
02674 char addressInfo[1024];
02675 DBusString shm_name;
02676 DBusString mutex_name;
02677
02678 _dbus_assert (address);
02679
02680 if (!_dbus_get_mutex_name(&mutex_name,scope))
02681 {
02682 _dbus_string_free( &mutex_name );
02683 return FALSE;
02684 }
02685
02686
02687 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02688
02689 if (!hDBusDaemonMutex)
02690 {
02691 hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02692 }
02693 _dbus_string_free( &mutex_name );
02694
02695
02696 if (WaitForSingleObject( hDBusDaemonMutex, 10 ) != WAIT_OBJECT_0)
02697 {
02698 _dbus_global_unlock( lock );
02699 CloseHandle( hDBusDaemonMutex );
02700 return FALSE;
02701 }
02702
02703 if (!_dbus_get_shm_name(&shm_name,scope))
02704 {
02705 _dbus_string_free( &shm_name );
02706 _dbus_global_unlock( lock );
02707 return FALSE;
02708 }
02709
02710
02711 hDBusSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
02712 0, strlen( address ) + 1, _dbus_string_get_const_data(&shm_name) );
02713 _dbus_assert( hDBusSharedMem );
02714
02715 shared_addr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
02716
02717 _dbus_assert (shared_addr);
02718
02719 strcpy( shared_addr, address);
02720
02721
02722 UnmapViewOfFile( shared_addr );
02723
02724 _dbus_global_unlock( lock );
02725 _dbus_verbose( "published session bus address at %s\n",_dbus_string_get_const_data (&shm_name) );
02726
02727 _dbus_string_free( &shm_name );
02728 return TRUE;
02729 }
02730
02731 void
02732 _dbus_daemon_unpublish_session_bus_address (void)
02733 {
02734 HANDLE lock;
02735
02736
02737 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02738
02739 CloseHandle( hDBusSharedMem );
02740
02741 hDBusSharedMem = NULL;
02742
02743 ReleaseMutex( hDBusDaemonMutex );
02744
02745 CloseHandle( hDBusDaemonMutex );
02746
02747 hDBusDaemonMutex = NULL;
02748
02749 _dbus_global_unlock( lock );
02750 }
02751
02752 static dbus_bool_t
02753 _dbus_get_autolaunch_shm (DBusString *address, DBusString *shm_name)
02754 {
02755 HANDLE sharedMem;
02756 char *shared_addr;
02757 int i;
02758
02759
02760 for(i=0;i<20;++i) {
02761
02762 sharedMem = OpenFileMappingA( FILE_MAP_READ, FALSE, _dbus_string_get_const_data(shm_name));
02763 if( sharedMem == 0 )
02764 Sleep( 100 );
02765 if ( sharedMem != 0)
02766 break;
02767 }
02768
02769 if( sharedMem == 0 )
02770 return FALSE;
02771
02772 shared_addr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
02773
02774 if( !shared_addr )
02775 return FALSE;
02776
02777 _dbus_string_init( address );
02778
02779 _dbus_string_append( address, shared_addr );
02780
02781
02782 UnmapViewOfFile( shared_addr );
02783
02784 CloseHandle( sharedMem );
02785
02786 return TRUE;
02787 }
02788
02789 static dbus_bool_t
02790 _dbus_daemon_already_runs (DBusString *address, DBusString *shm_name, const char *scope)
02791 {
02792 HANDLE lock;
02793 HANDLE daemon;
02794 DBusString mutex_name;
02795 dbus_bool_t bRet = TRUE;
02796
02797 if (!_dbus_get_mutex_name(&mutex_name,scope))
02798 {
02799 _dbus_string_free( &mutex_name );
02800 return FALSE;
02801 }
02802
02803
02804 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02805
02806
02807 daemon = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02808 if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT)
02809 {
02810 ReleaseMutex (daemon);
02811 CloseHandle (daemon);
02812
02813 _dbus_global_unlock( lock );
02814 _dbus_string_free( &mutex_name );
02815 return FALSE;
02816 }
02817
02818
02819 bRet = _dbus_get_autolaunch_shm( address, shm_name );
02820
02821
02822 CloseHandle ( daemon );
02823
02824 _dbus_global_unlock( lock );
02825 _dbus_string_free( &mutex_name );
02826
02827 return bRet;
02828 }
02829
02830 dbus_bool_t
02831 _dbus_get_autolaunch_address (const char *scope, DBusString *address,
02832 DBusError *error)
02833 {
02834 HANDLE mutex;
02835 STARTUPINFOA si;
02836 PROCESS_INFORMATION pi;
02837 dbus_bool_t retval = FALSE;
02838 LPSTR lpFile;
02839 char dbus_exe_path[MAX_PATH];
02840 char dbus_args[MAX_PATH * 2];
02841 const char * daemon_name = DBUS_DAEMON_NAME ".exe";
02842 DBusString shm_name;
02843
02844 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02845
02846 if (!_dbus_get_shm_name(&shm_name,scope))
02847 {
02848 dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not determine shm name");
02849 return FALSE;
02850 }
02851
02852 mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
02853
02854 if (_dbus_daemon_already_runs(address,&shm_name,scope))
02855 {
02856 _dbus_verbose( "found running dbus daemon at %s\n",
02857 _dbus_string_get_const_data (&shm_name) );
02858 retval = TRUE;
02859 goto out;
02860 }
02861
02862 if (!SearchPathA(NULL, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
02863 {
02864 printf ("please add the path to %s to your PATH environment variable\n", daemon_name);
02865 printf ("or start the daemon manually\n\n");
02866 goto out;
02867 }
02868
02869
02870 ZeroMemory( &si, sizeof(si) );
02871 si.cb = sizeof(si);
02872 ZeroMemory( &pi, sizeof(pi) );
02873
02874 _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path, " --session");
02875
02876
02877
02878 if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
02879 {
02880 CloseHandle (pi.hThread);
02881 CloseHandle (pi.hProcess);
02882 retval = _dbus_get_autolaunch_shm( address, &shm_name );
02883 if (retval == FALSE)
02884 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to get autolaunch address from launched dbus-daemon");
02885 }
02886 else
02887 {
02888 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to launch dbus-daemon");
02889 retval = FALSE;
02890 }
02891
02892 out:
02893 if (retval)
02894 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02895 else
02896 _DBUS_ASSERT_ERROR_IS_SET (error);
02897
02898 _dbus_global_unlock (mutex);
02899
02900 return retval;
02901 }
02902
02903
02910 dbus_bool_t
02911 _dbus_make_file_world_readable(const DBusString *filename,
02912 DBusError *error)
02913 {
02914
02915 return TRUE;
02916 }
02917
02924 static const char *
02925 _dbus_windows_get_datadir (void)
02926 {
02927 return _dbus_replace_install_prefix(DBUS_DATADIR);
02928 }
02929
02930 #undef DBUS_DATADIR
02931 #define DBUS_DATADIR _dbus_windows_get_datadir ()
02932
02933
02934 #define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
02935 #define DBUS_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
02936
02953 dbus_bool_t
02954 _dbus_get_standard_session_servicedirs (DBusList **dirs)
02955 {
02956 const char *common_progs;
02957 DBusString servicedir_path;
02958
02959 if (!_dbus_string_init (&servicedir_path))
02960 return FALSE;
02961
02962 #ifdef DBUS_WINCE
02963 {
02964
02965 const char *data_dir = _dbus_getenv ("DBUS_DATADIR");
02966
02967 if (data_dir != NULL)
02968 {
02969 if (!_dbus_string_append (&servicedir_path, data_dir))
02970 goto oom;
02971
02972 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
02973 goto oom;
02974 }
02975 }
02976 #else
02977
02978
02979
02980
02981 #ifdef DBUS_WIN
02982 {
02983 DBusString p;
02984
02985 _dbus_string_init_const (&p, DBUS_DATADIR);
02986
02987 if (!_dbus_path_is_absolute (&p))
02988 {
02989 char install_root[1000];
02990 if (_dbus_get_install_root (install_root, sizeof(install_root)))
02991 if (!_dbus_string_append (&servicedir_path, install_root))
02992 goto oom;
02993 }
02994 }
02995 #endif
02996 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
02997 goto oom;
02998
02999 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
03000 goto oom;
03001 #endif
03002
03003 common_progs = _dbus_getenv ("CommonProgramFiles");
03004
03005 if (common_progs != NULL)
03006 {
03007 if (!_dbus_string_append (&servicedir_path, common_progs))
03008 goto oom;
03009
03010 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
03011 goto oom;
03012 }
03013
03014 if (!_dbus_split_paths_and_append (&servicedir_path,
03015 DBUS_STANDARD_SESSION_SERVICEDIR,
03016 dirs))
03017 goto oom;
03018
03019 _dbus_string_free (&servicedir_path);
03020 return TRUE;
03021
03022 oom:
03023 _dbus_string_free (&servicedir_path);
03024 return FALSE;
03025 }
03026
03045 dbus_bool_t
03046 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03047 {
03048 *dirs = NULL;
03049 return TRUE;
03050 }
03051
03052 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
03053
03061 dbus_int32_t
03062 _dbus_atomic_inc (DBusAtomic *atomic)
03063 {
03064
03065
03066 return InterlockedIncrement (&atomic->value) - 1;
03067 }
03068
03076 dbus_int32_t
03077 _dbus_atomic_dec (DBusAtomic *atomic)
03078 {
03079
03080
03081 return InterlockedDecrement (&atomic->value) + 1;
03082 }
03083
03091 dbus_int32_t
03092 _dbus_atomic_get (DBusAtomic *atomic)
03093 {
03094
03095 MemoryBarrier ();
03096 return atomic->value;
03097 }
03098
03106 void
03107 _dbus_flush_caches (void)
03108 {
03109 }
03110
03117 dbus_bool_t
03118 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03119 {
03120 return errno == WSAEWOULDBLOCK;
03121 }
03122
03130 dbus_bool_t
03131 _dbus_get_install_root(char *prefix, int len)
03132 {
03133
03134 char* p = 0;
03135 int i;
03136 DWORD pathLength;
03137 char *lastSlash;
03138 SetLastError( 0 );
03139 pathLength = GetModuleFileNameA(_dbus_win_get_dll_hmodule(), prefix, len);
03140 if ( pathLength == 0 || GetLastError() != 0 ) {
03141 *prefix = '\0';
03142 return FALSE;
03143 }
03144 lastSlash = _mbsrchr(prefix, '\\');
03145 if (lastSlash == NULL) {
03146 *prefix = '\0';
03147 return FALSE;
03148 }
03149
03150 lastSlash[1] = 0;
03151
03152
03153
03154
03155
03156
03157
03158 if (lastSlash - prefix >= 4 && strnicmp(lastSlash - 4, "\\bin", 4) == 0)
03159 lastSlash[-3] = 0;
03160 else if (lastSlash - prefix >= 10 && strnicmp(lastSlash - 10, "\\bin\\debug", 10) == 0)
03161 lastSlash[-9] = 0;
03162 else if (lastSlash - prefix >= 12 && strnicmp(lastSlash - 12, "\\bin\\release", 12) == 0)
03163 lastSlash[-11] = 0;
03164
03165 return TRUE;
03166 }
03167
03181 dbus_bool_t
03182 _dbus_get_config_file_name(DBusString *config_file, char *s)
03183 {
03184 char path[MAX_PATH*2];
03185 int path_size = sizeof(path);
03186
03187 if (!_dbus_get_install_root(path,path_size))
03188 return FALSE;
03189
03190 if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
03191 return FALSE;
03192 strcat(path,"etc\\");
03193 strcat(path,s);
03194 if (_dbus_file_exists(path))
03195 {
03196
03197 if (!_dbus_string_append (config_file, path))
03198 return FALSE;
03199 }
03200 else
03201 {
03202 if (!_dbus_get_install_root(path,path_size))
03203 return FALSE;
03204 if(strlen(s) + 11 + strlen(path) > sizeof(path)-2)
03205 return FALSE;
03206 strcat(path,"etc\\dbus-1\\");
03207 strcat(path,s);
03208
03209 if (_dbus_file_exists(path))
03210 {
03211 if (!_dbus_string_append (config_file, path))
03212 return FALSE;
03213 }
03214 else
03215 {
03216 if (!_dbus_get_install_root(path,path_size))
03217 return FALSE;
03218 if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
03219 return FALSE;
03220 strcat(path,"bus\\");
03221 strcat(path,s);
03222
03223 if (_dbus_file_exists(path))
03224 {
03225 if (!_dbus_string_append (config_file, path))
03226 return FALSE;
03227 }
03228 }
03229 }
03230 return TRUE;
03231 }
03232
03241 dbus_bool_t
03242 _dbus_append_system_config_file (DBusString *str)
03243 {
03244 return _dbus_get_config_file_name(str, "system.conf");
03245 }
03246
03253 dbus_bool_t
03254 _dbus_append_session_config_file (DBusString *str)
03255 {
03256 return _dbus_get_config_file_name(str, "session.conf");
03257 }
03258
03259
03260 dbus_bool_t
03261 _dbus_lookup_session_address (dbus_bool_t *supported,
03262 DBusString *address,
03263 DBusError *error)
03264 {
03265
03266 *supported = FALSE;
03267 return TRUE;
03268 }
03269
03283 dbus_bool_t
03284 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03285 DBusCredentials *credentials)
03286 {
03287 DBusString homedir;
03288 DBusString dotdir;
03289 dbus_uid_t uid;
03290 const char *homepath;
03291 const char *homedrive;
03292
03293 _dbus_assert (credentials != NULL);
03294 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03295
03296 if (!_dbus_string_init (&homedir))
03297 return FALSE;
03298
03299 homedrive = _dbus_getenv("HOMEDRIVE");
03300 if (homedrive != NULL && *homedrive != '\0')
03301 {
03302 _dbus_string_append(&homedir,homedrive);
03303 }
03304
03305 homepath = _dbus_getenv("HOMEPATH");
03306 if (homepath != NULL && *homepath != '\0')
03307 {
03308 _dbus_string_append(&homedir,homepath);
03309 }
03310
03311 #ifdef DBUS_BUILD_TESTS
03312 {
03313 const char *override;
03314
03315 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03316 if (override != NULL && *override != '\0')
03317 {
03318 _dbus_string_set_length (&homedir, 0);
03319 if (!_dbus_string_append (&homedir, override))
03320 goto failed;
03321
03322 _dbus_verbose ("Using fake homedir for testing: %s\n",
03323 _dbus_string_get_const_data (&homedir));
03324 }
03325 else
03326 {
03327 static dbus_bool_t already_warned = FALSE;
03328 if (!already_warned)
03329 {
03330 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03331 already_warned = TRUE;
03332 }
03333 }
03334 }
03335 #endif
03336
03337 #ifdef DBUS_WINCE
03338
03339
03340 #define KEYRING_DIR "dbus-keyrings"
03341 #else
03342 #define KEYRING_DIR ".dbus-keyrings"
03343 #endif
03344
03345 _dbus_string_init_const (&dotdir, KEYRING_DIR);
03346 if (!_dbus_concat_dir_and_file (&homedir,
03347 &dotdir))
03348 goto failed;
03349
03350 if (!_dbus_string_copy (&homedir, 0,
03351 directory, _dbus_string_get_length (directory))) {
03352 goto failed;
03353 }
03354
03355 _dbus_string_free (&homedir);
03356 return TRUE;
03357
03358 failed:
03359 _dbus_string_free (&homedir);
03360 return FALSE;
03361 }
03362
03368 dbus_bool_t
03369 _dbus_file_exists (const char *file)
03370 {
03371 DWORD attributes = GetFileAttributesA (file);
03372
03373 if (attributes != INVALID_FILE_ATTRIBUTES && GetLastError() != ERROR_PATH_NOT_FOUND)
03374 return TRUE;
03375 else
03376 return FALSE;
03377 }
03378
03386 const char*
03387 _dbus_strerror (int error_number)
03388 {
03389 #ifdef DBUS_WINCE
03390
03391 return "unknown";
03392 #else
03393 const char *msg;
03394
03395 switch (error_number)
03396 {
03397 case WSAEINTR:
03398 return "Interrupted function call";
03399 case WSAEACCES:
03400 return "Permission denied";
03401 case WSAEFAULT:
03402 return "Bad address";
03403 case WSAEINVAL:
03404 return "Invalid argument";
03405 case WSAEMFILE:
03406 return "Too many open files";
03407 case WSAEWOULDBLOCK:
03408 return "Resource temporarily unavailable";
03409 case WSAEINPROGRESS:
03410 return "Operation now in progress";
03411 case WSAEALREADY:
03412 return "Operation already in progress";
03413 case WSAENOTSOCK:
03414 return "Socket operation on nonsocket";
03415 case WSAEDESTADDRREQ:
03416 return "Destination address required";
03417 case WSAEMSGSIZE:
03418 return "Message too long";
03419 case WSAEPROTOTYPE:
03420 return "Protocol wrong type for socket";
03421 case WSAENOPROTOOPT:
03422 return "Bad protocol option";
03423 case WSAEPROTONOSUPPORT:
03424 return "Protocol not supported";
03425 case WSAESOCKTNOSUPPORT:
03426 return "Socket type not supported";
03427 case WSAEOPNOTSUPP:
03428 return "Operation not supported";
03429 case WSAEPFNOSUPPORT:
03430 return "Protocol family not supported";
03431 case WSAEAFNOSUPPORT:
03432 return "Address family not supported by protocol family";
03433 case WSAEADDRINUSE:
03434 return "Address already in use";
03435 case WSAEADDRNOTAVAIL:
03436 return "Cannot assign requested address";
03437 case WSAENETDOWN:
03438 return "Network is down";
03439 case WSAENETUNREACH:
03440 return "Network is unreachable";
03441 case WSAENETRESET:
03442 return "Network dropped connection on reset";
03443 case WSAECONNABORTED:
03444 return "Software caused connection abort";
03445 case WSAECONNRESET:
03446 return "Connection reset by peer";
03447 case WSAENOBUFS:
03448 return "No buffer space available";
03449 case WSAEISCONN:
03450 return "Socket is already connected";
03451 case WSAENOTCONN:
03452 return "Socket is not connected";
03453 case WSAESHUTDOWN:
03454 return "Cannot send after socket shutdown";
03455 case WSAETIMEDOUT:
03456 return "Connection timed out";
03457 case WSAECONNREFUSED:
03458 return "Connection refused";
03459 case WSAEHOSTDOWN:
03460 return "Host is down";
03461 case WSAEHOSTUNREACH:
03462 return "No route to host";
03463 case WSAEPROCLIM:
03464 return "Too many processes";
03465 case WSAEDISCON:
03466 return "Graceful shutdown in progress";
03467 case WSATYPE_NOT_FOUND:
03468 return "Class type not found";
03469 case WSAHOST_NOT_FOUND:
03470 return "Host not found";
03471 case WSATRY_AGAIN:
03472 return "Nonauthoritative host not found";
03473 case WSANO_RECOVERY:
03474 return "This is a nonrecoverable error";
03475 case WSANO_DATA:
03476 return "Valid name, no data record of requested type";
03477 case WSA_INVALID_HANDLE:
03478 return "Specified event object handle is invalid";
03479 case WSA_INVALID_PARAMETER:
03480 return "One or more parameters are invalid";
03481 case WSA_IO_INCOMPLETE:
03482 return "Overlapped I/O event object not in signaled state";
03483 case WSA_IO_PENDING:
03484 return "Overlapped operations will complete later";
03485 case WSA_NOT_ENOUGH_MEMORY:
03486 return "Insufficient memory available";
03487 case WSA_OPERATION_ABORTED:
03488 return "Overlapped operation aborted";
03489 #ifdef WSAINVALIDPROCTABLE
03490
03491 case WSAINVALIDPROCTABLE:
03492 return "Invalid procedure table from service provider";
03493 #endif
03494 #ifdef WSAINVALIDPROVIDER
03495
03496 case WSAINVALIDPROVIDER:
03497 return "Invalid service provider version number";
03498 #endif
03499 #ifdef WSAPROVIDERFAILEDINIT
03500
03501 case WSAPROVIDERFAILEDINIT:
03502 return "Unable to initialize a service provider";
03503 #endif
03504
03505 case WSASYSCALLFAILURE:
03506 return "System call failure";
03507 }
03508 msg = strerror (error_number);
03509 if (msg == NULL)
03510 msg = "unknown";
03511
03512 return msg;
03513 #endif //DBUS_WINCE
03514 }
03515
03523 void
03524 _dbus_win_set_error_from_win_error (DBusError *error,
03525 int code)
03526 {
03527 char *msg;
03528
03529
03530 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
03531 FORMAT_MESSAGE_IGNORE_INSERTS |
03532 FORMAT_MESSAGE_FROM_SYSTEM,
03533 NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
03534 (LPSTR) &msg, 0, NULL);
03535 if (msg)
03536 {
03537 char *msg_copy;
03538
03539 msg_copy = dbus_malloc (strlen (msg));
03540 strcpy (msg_copy, msg);
03541 LocalFree (msg);
03542
03543 dbus_set_error (error, "win32.error", "%s", msg_copy);
03544 }
03545 else
03546 dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code);
03547 }
03548
03549 void
03550 _dbus_win_warn_win_error (const char *message,
03551 int code)
03552 {
03553 DBusError error;
03554
03555 dbus_error_init (&error);
03556 _dbus_win_set_error_from_win_error (&error, code);
03557 _dbus_warn ("%s: %s\n", message, error.message);
03558 dbus_error_free (&error);
03559 }
03560
03568 dbus_bool_t
03569 _dbus_delete_directory (const DBusString *filename,
03570 DBusError *error)
03571 {
03572 const char *filename_c;
03573
03574 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03575
03576 filename_c = _dbus_string_get_const_data (filename);
03577
03578 if (RemoveDirectoryA (filename_c) == 0)
03579 {
03580 char *emsg = _dbus_win_error_string (GetLastError ());
03581 dbus_set_error (error, _dbus_win_error_from_last_error (),
03582 "Failed to remove directory %s: %s",
03583 filename_c, emsg);
03584 _dbus_win_free_error_string (emsg);
03585 return FALSE;
03586 }
03587
03588 return TRUE;
03589 }
03590
03597 dbus_bool_t
03598 _dbus_path_is_absolute (const DBusString *filename)
03599 {
03600 if (_dbus_string_get_length (filename) > 0)
03601 return _dbus_string_get_byte (filename, 1) == ':'
03602 || _dbus_string_get_byte (filename, 0) == '\\'
03603 || _dbus_string_get_byte (filename, 0) == '/';
03604 else
03605 return FALSE;
03606 }
03607
03609
03610