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 len = _vsnprintf (p, bufsize - 1, format, args);
00553 free (p);
00554 }
00555
00556 return len;
00557 }
00558
00559
00567 wchar_t *
00568 _dbus_win_utf8_to_utf16 (const char *str,
00569 DBusError *error)
00570 {
00571 DBusString s;
00572 int n;
00573 wchar_t *retval;
00574
00575 _dbus_string_init_const (&s, str);
00576
00577 if (!_dbus_string_validate_utf8 (&s, 0, _dbus_string_get_length (&s)))
00578 {
00579 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid UTF-8");
00580 return NULL;
00581 }
00582
00583 n = MultiByteToWideChar (CP_UTF8, 0, str, -1, NULL, 0);
00584
00585 if (n == 0)
00586 {
00587 _dbus_win_set_error_from_win_error (error, GetLastError ());
00588 return NULL;
00589 }
00590
00591 retval = dbus_new (wchar_t, n);
00592
00593 if (!retval)
00594 {
00595 _DBUS_SET_OOM (error);
00596 return NULL;
00597 }
00598
00599 if (MultiByteToWideChar (CP_UTF8, 0, str, -1, retval, n) != n)
00600 {
00601 dbus_free (retval);
00602 dbus_set_error_const (error, DBUS_ERROR_FAILED, "MultiByteToWideChar inconsistency");
00603 return NULL;
00604 }
00605
00606 return retval;
00607 }
00608
00616 char *
00617 _dbus_win_utf16_to_utf8 (const wchar_t *str,
00618 DBusError *error)
00619 {
00620 int n;
00621 char *retval;
00622
00623 n = WideCharToMultiByte (CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
00624
00625 if (n == 0)
00626 {
00627 _dbus_win_set_error_from_win_error (error, GetLastError ());
00628 return NULL;
00629 }
00630
00631 retval = dbus_malloc (n);
00632
00633 if (!retval)
00634 {
00635 _DBUS_SET_OOM (error);
00636 return NULL;
00637 }
00638
00639 if (WideCharToMultiByte (CP_UTF8, 0, str, -1, retval, n, NULL, NULL) != n)
00640 {
00641 dbus_free (retval);
00642 dbus_set_error_const (error, DBUS_ERROR_FAILED, "WideCharToMultiByte inconsistency");
00643 return NULL;
00644 }
00645
00646 return retval;
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 dbus_bool_t
00660 _dbus_win_account_to_sid (const wchar_t *waccount,
00661 void **ppsid,
00662 DBusError *error)
00663 {
00664 dbus_bool_t retval = FALSE;
00665 DWORD sid_length, wdomain_length;
00666 SID_NAME_USE use;
00667 wchar_t *wdomain;
00668
00669 *ppsid = NULL;
00670
00671 sid_length = 0;
00672 wdomain_length = 0;
00673 if (!LookupAccountNameW (NULL, waccount, NULL, &sid_length,
00674 NULL, &wdomain_length, &use) &&
00675 GetLastError () != ERROR_INSUFFICIENT_BUFFER)
00676 {
00677 _dbus_win_set_error_from_win_error (error, GetLastError ());
00678 return FALSE;
00679 }
00680
00681 *ppsid = dbus_malloc (sid_length);
00682 if (!*ppsid)
00683 {
00684 _DBUS_SET_OOM (error);
00685 return FALSE;
00686 }
00687
00688 wdomain = dbus_new (wchar_t, wdomain_length);
00689 if (!wdomain)
00690 {
00691 _DBUS_SET_OOM (error);
00692 goto out1;
00693 }
00694
00695 if (!LookupAccountNameW (NULL, waccount, (PSID) *ppsid, &sid_length,
00696 wdomain, &wdomain_length, &use))
00697 {
00698 _dbus_win_set_error_from_win_error (error, GetLastError ());
00699 goto out2;
00700 }
00701
00702 if (!IsValidSid ((PSID) *ppsid))
00703 {
00704 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID");
00705 goto out2;
00706 }
00707
00708 retval = TRUE;
00709
00710 out2:
00711 dbus_free (wdomain);
00712 out1:
00713 if (!retval)
00714 {
00715 dbus_free (*ppsid);
00716 *ppsid = NULL;
00717 }
00718
00719 return retval;
00720 }
00721
00731 unsigned long
00732 _dbus_pid_for_log (void)
00733 {
00734 return _dbus_getpid ();
00735 }
00736
00737
00738 #ifndef DBUS_WINCE
00739
00743 static dbus_bool_t
00744 _dbus_getsid(char **sid)
00745 {
00746 HANDLE process_token = INVALID_HANDLE_VALUE;
00747 TOKEN_USER *token_user = NULL;
00748 DWORD n;
00749 PSID psid;
00750 int retval = FALSE;
00751
00752 if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &process_token))
00753 {
00754 _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ());
00755 goto failed;
00756 }
00757 if ((!GetTokenInformation (process_token, TokenUser, NULL, 0, &n)
00758 && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
00759 || (token_user = alloca (n)) == NULL
00760 || !GetTokenInformation (process_token, TokenUser, token_user, n, &n))
00761 {
00762 _dbus_win_warn_win_error ("GetTokenInformation failed", GetLastError ());
00763 goto failed;
00764 }
00765 psid = token_user->User.Sid;
00766 if (!IsValidSid (psid))
00767 {
00768 _dbus_verbose("%s invalid sid\n",__FUNCTION__);
00769 goto failed;
00770 }
00771 if (!ConvertSidToStringSidA (psid, sid))
00772 {
00773 _dbus_verbose("%s invalid sid\n",__FUNCTION__);
00774 goto failed;
00775 }
00776
00777 retval = TRUE;
00778
00779 failed:
00780 if (process_token != INVALID_HANDLE_VALUE)
00781 CloseHandle (process_token);
00782
00783 _dbus_verbose("_dbus_getsid() returns %d\n",retval);
00784 return retval;
00785 }
00786 #endif
00787
00788
00789
00790
00791
00792
00793
00809 dbus_bool_t
00810 _dbus_full_duplex_pipe (int *fd1,
00811 int *fd2,
00812 dbus_bool_t blocking,
00813 DBusError *error)
00814 {
00815 SOCKET temp, socket1 = -1, socket2 = -1;
00816 struct sockaddr_in saddr;
00817 int len;
00818 u_long arg;
00819 fd_set read_set, write_set;
00820 struct timeval tv;
00821 int res;
00822
00823 _dbus_win_startup_winsock ();
00824
00825 temp = socket (AF_INET, SOCK_STREAM, 0);
00826 if (temp == INVALID_SOCKET)
00827 {
00828 DBUS_SOCKET_SET_ERRNO ();
00829 goto out0;
00830 }
00831
00832 _DBUS_ZERO (saddr);
00833 saddr.sin_family = AF_INET;
00834 saddr.sin_port = 0;
00835 saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
00836
00837 if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr)) == SOCKET_ERROR)
00838 {
00839 DBUS_SOCKET_SET_ERRNO ();
00840 goto out0;
00841 }
00842
00843 if (listen (temp, 1) == SOCKET_ERROR)
00844 {
00845 DBUS_SOCKET_SET_ERRNO ();
00846 goto out0;
00847 }
00848
00849 len = sizeof (saddr);
00850 if (getsockname (temp, (struct sockaddr *)&saddr, &len) == SOCKET_ERROR)
00851 {
00852 DBUS_SOCKET_SET_ERRNO ();
00853 goto out0;
00854 }
00855
00856 socket1 = socket (AF_INET, SOCK_STREAM, 0);
00857 if (socket1 == INVALID_SOCKET)
00858 {
00859 DBUS_SOCKET_SET_ERRNO ();
00860 goto out0;
00861 }
00862
00863 if (connect (socket1, (struct sockaddr *)&saddr, len) == SOCKET_ERROR)
00864 {
00865 DBUS_SOCKET_SET_ERRNO ();
00866 goto out1;
00867 }
00868
00869 socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
00870 if (socket2 == INVALID_SOCKET)
00871 {
00872 DBUS_SOCKET_SET_ERRNO ();
00873 goto out1;
00874 }
00875
00876 if (!blocking)
00877 {
00878 arg = 1;
00879 if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
00880 {
00881 DBUS_SOCKET_SET_ERRNO ();
00882 goto out2;
00883 }
00884
00885 arg = 1;
00886 if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
00887 {
00888 DBUS_SOCKET_SET_ERRNO ();
00889 goto out2;
00890 }
00891 }
00892
00893 *fd1 = socket1;
00894 *fd2 = socket2;
00895
00896 _dbus_verbose ("full-duplex pipe %d:%d <-> %d:%d\n",
00897 *fd1, socket1, *fd2, socket2);
00898
00899 closesocket (temp);
00900
00901 return TRUE;
00902
00903 out2:
00904 closesocket (socket2);
00905 out1:
00906 closesocket (socket1);
00907 out0:
00908 closesocket (temp);
00909
00910 dbus_set_error (error, _dbus_error_from_errno (errno),
00911 "Could not setup socket pair: %s",
00912 _dbus_strerror_from_errno ());
00913
00914 return FALSE;
00915 }
00916
00925 int
00926 _dbus_poll (DBusPollFD *fds,
00927 int n_fds,
00928 int timeout_milliseconds)
00929 {
00930 #define USE_CHRIS_IMPL 0
00931
00932 #if USE_CHRIS_IMPL
00933
00934 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
00935 char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
00936 char *msgp;
00937
00938 int ret = 0;
00939 int i;
00940 struct timeval tv;
00941 int ready;
00942
00943 #define DBUS_STACK_WSAEVENTS 256
00944 WSAEVENT eventsOnStack[DBUS_STACK_WSAEVENTS];
00945 WSAEVENT *pEvents = NULL;
00946 if (n_fds > DBUS_STACK_WSAEVENTS)
00947 pEvents = calloc(sizeof(WSAEVENT), n_fds);
00948 else
00949 pEvents = eventsOnStack;
00950
00951
00952 #ifdef DBUS_ENABLE_VERBOSE_MODE
00953 msgp = msg;
00954 msgp += sprintf (msgp, "WSAEventSelect: to=%d\n\t", timeout_milliseconds);
00955 for (i = 0; i < n_fds; i++)
00956 {
00957 static dbus_bool_t warned = FALSE;
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 static dbus_bool_t warned = FALSE;
01096 DBusPollFD *fdp = &fds[i];
01097
01098
01099 if (fdp->events & _DBUS_POLLIN)
01100 msgp += sprintf (msgp, "R:%d ", fdp->fd);
01101
01102 if (fdp->events & _DBUS_POLLOUT)
01103 msgp += sprintf (msgp, "W:%d ", fdp->fd);
01104
01105 msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
01106
01107
01108
01109 if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
01110 {
01111 _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
01112 }
01113 }
01114
01115 msgp += sprintf (msgp, "\n");
01116 _dbus_verbose ("%s",msg);
01117 #endif
01118 for (i = 0; i < n_fds; i++)
01119 {
01120 DBusPollFD *fdp = &fds[i];
01121
01122 if (fdp->events & _DBUS_POLLIN)
01123 FD_SET (fdp->fd, &read_set);
01124
01125 if (fdp->events & _DBUS_POLLOUT)
01126 FD_SET (fdp->fd, &write_set);
01127
01128 FD_SET (fdp->fd, &err_set);
01129
01130 max_fd = MAX (max_fd, fdp->fd);
01131 }
01132
01133
01134 tv.tv_sec = timeout_milliseconds < 0 ? 1 : timeout_milliseconds / 1000;
01135 tv.tv_usec = timeout_milliseconds < 0 ? 0 : (timeout_milliseconds % 1000) * 1000;
01136
01137 ready = select (max_fd + 1, &read_set, &write_set, &err_set, &tv);
01138
01139 if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
01140 {
01141 DBUS_SOCKET_SET_ERRNO ();
01142 if (errno != WSAEWOULDBLOCK)
01143 _dbus_verbose ("select: failed: %s\n", _dbus_strerror_from_errno ());
01144 }
01145 else if (ready == 0)
01146 _dbus_verbose ("select: = 0\n");
01147 else
01148 if (ready > 0)
01149 {
01150 #ifdef DBUS_ENABLE_VERBOSE_MODE
01151 msgp = msg;
01152 msgp += sprintf (msgp, "select: = %d:\n\t", ready);
01153
01154 for (i = 0; i < n_fds; i++)
01155 {
01156 DBusPollFD *fdp = &fds[i];
01157
01158 if (FD_ISSET (fdp->fd, &read_set))
01159 msgp += sprintf (msgp, "R:%d ", fdp->fd);
01160
01161 if (FD_ISSET (fdp->fd, &write_set))
01162 msgp += sprintf (msgp, "W:%d ", fdp->fd);
01163
01164 if (FD_ISSET (fdp->fd, &err_set))
01165 msgp += sprintf (msgp, "E:%d\n\t", fdp->fd);
01166 }
01167 msgp += sprintf (msgp, "\n");
01168 _dbus_verbose ("%s",msg);
01169 #endif
01170
01171 for (i = 0; i < n_fds; i++)
01172 {
01173 DBusPollFD *fdp = &fds[i];
01174
01175 fdp->revents = 0;
01176
01177 if (FD_ISSET (fdp->fd, &read_set))
01178 fdp->revents |= _DBUS_POLLIN;
01179
01180 if (FD_ISSET (fdp->fd, &write_set))
01181 fdp->revents |= _DBUS_POLLOUT;
01182
01183 if (FD_ISSET (fdp->fd, &err_set))
01184 fdp->revents |= _DBUS_POLLERR;
01185 }
01186 }
01187 return ready;
01188 #endif
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
01224
01230 void
01231 _dbus_exit (int code)
01232 {
01233 _exit (code);
01234 }
01235
01247 int
01248 _dbus_connect_tcp_socket (const char *host,
01249 const char *port,
01250 const char *family,
01251 DBusError *error)
01252 {
01253 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01254 }
01255
01256 int
01257 _dbus_connect_tcp_socket_with_nonce (const char *host,
01258 const char *port,
01259 const char *family,
01260 const char *noncefile,
01261 DBusError *error)
01262 {
01263 int fd = -1, res;
01264 struct addrinfo hints;
01265 struct addrinfo *ai, *tmp;
01266
01267 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01268
01269 _dbus_win_startup_winsock ();
01270
01271 _DBUS_ZERO (hints);
01272
01273 if (!family)
01274 hints.ai_family = AF_UNSPEC;
01275 else if (!strcmp(family, "ipv4"))
01276 hints.ai_family = AF_INET;
01277 else if (!strcmp(family, "ipv6"))
01278 hints.ai_family = AF_INET6;
01279 else
01280 {
01281 dbus_set_error (error,
01282 DBUS_ERROR_INVALID_ARGS,
01283 "Unknown address family %s", family);
01284 return -1;
01285 }
01286 hints.ai_protocol = IPPROTO_TCP;
01287 hints.ai_socktype = SOCK_STREAM;
01288 #ifdef AI_ADDRCONFIG
01289 hints.ai_flags = AI_ADDRCONFIG;
01290 #else
01291 hints.ai_flags = 0;
01292 #endif
01293
01294 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01295 {
01296 dbus_set_error (error,
01297 _dbus_error_from_errno (res),
01298 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01299 host, port, _dbus_strerror(res), res);
01300 return -1;
01301 }
01302
01303 tmp = ai;
01304 while (tmp)
01305 {
01306 if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
01307 {
01308 DBUS_SOCKET_SET_ERRNO ();
01309 dbus_set_error (error,
01310 _dbus_error_from_errno (errno),
01311 "Failed to open socket: %s",
01312 _dbus_strerror_from_errno ());
01313 freeaddrinfo(ai);
01314 return -1;
01315 }
01316 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01317
01318 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
01319 {
01320 DBUS_SOCKET_SET_ERRNO ();
01321 closesocket(fd);
01322 fd = -1;
01323 tmp = tmp->ai_next;
01324 continue;
01325 }
01326
01327 break;
01328 }
01329 freeaddrinfo(ai);
01330
01331 if (fd == -1)
01332 {
01333 dbus_set_error (error,
01334 _dbus_error_from_errno (errno),
01335 "Failed to connect to socket \"%s:%s\" %s",
01336 host, port, _dbus_strerror_from_errno ());
01337 return -1;
01338 }
01339
01340 if (noncefile != NULL)
01341 {
01342 DBusString noncefileStr;
01343 dbus_bool_t ret;
01344 if (!_dbus_string_init (&noncefileStr) ||
01345 !_dbus_string_append(&noncefileStr, noncefile))
01346 {
01347 closesocket (fd);
01348 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01349 return -1;
01350 }
01351
01352 ret = _dbus_send_nonce (fd, &noncefileStr, error);
01353
01354 _dbus_string_free (&noncefileStr);
01355
01356 if (!ret)
01357 {
01358 closesocket (fd);
01359 return -1;
01360 }
01361 }
01362
01363 _dbus_fd_set_close_on_exec (fd);
01364
01365 if (!_dbus_set_fd_nonblocking (fd, error))
01366 {
01367 closesocket (fd);
01368 return -1;
01369 }
01370
01371 return fd;
01372 }
01373
01389 int
01390 _dbus_listen_tcp_socket (const char *host,
01391 const char *port,
01392 const char *family,
01393 DBusString *retport,
01394 int **fds_p,
01395 DBusError *error)
01396 {
01397 int nlisten_fd = 0, *listen_fd = NULL, res, i, port_num = -1;
01398 struct addrinfo hints;
01399 struct addrinfo *ai, *tmp;
01400
01401
01402
01403
01404
01405 typedef union {
01406 struct sockaddr Address;
01407 struct sockaddr_in AddressIn;
01408 struct sockaddr_in6 AddressIn6;
01409 } mysockaddr_gen;
01410
01411 *fds_p = NULL;
01412 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01413
01414 _dbus_win_startup_winsock ();
01415
01416 _DBUS_ZERO (hints);
01417
01418 if (!family)
01419 hints.ai_family = AF_UNSPEC;
01420 else if (!strcmp(family, "ipv4"))
01421 hints.ai_family = AF_INET;
01422 else if (!strcmp(family, "ipv6"))
01423 hints.ai_family = AF_INET6;
01424 else
01425 {
01426 dbus_set_error (error,
01427 DBUS_ERROR_INVALID_ARGS,
01428 "Unknown address family %s", family);
01429 return -1;
01430 }
01431
01432 hints.ai_protocol = IPPROTO_TCP;
01433 hints.ai_socktype = SOCK_STREAM;
01434 #ifdef AI_ADDRCONFIG
01435 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01436 #else
01437 hints.ai_flags = AI_PASSIVE;
01438 #endif
01439
01440 redo_lookup_with_port:
01441 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01442 {
01443 dbus_set_error (error,
01444 _dbus_error_from_errno (res),
01445 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01446 host ? host : "*", port, _dbus_strerror(res), res);
01447 return -1;
01448 }
01449
01450 tmp = ai;
01451 while (tmp)
01452 {
01453 int fd = -1, *newlisten_fd;
01454 if ((fd = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
01455 {
01456 DBUS_SOCKET_SET_ERRNO ();
01457 dbus_set_error (error,
01458 _dbus_error_from_errno (errno),
01459 "Failed to open socket: %s",
01460 _dbus_strerror_from_errno ());
01461 goto failed;
01462 }
01463 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01464
01465 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
01466 {
01467 DBUS_SOCKET_SET_ERRNO ();
01468 dbus_set_error (error, _dbus_error_from_errno (errno),
01469 "Failed to bind socket \"%s:%s\": %s",
01470 host ? host : "*", port, _dbus_strerror_from_errno ());
01471 closesocket (fd);
01472 goto failed;
01473 }
01474
01475 if (listen (fd, 30 ) == SOCKET_ERROR)
01476 {
01477 DBUS_SOCKET_SET_ERRNO ();
01478 dbus_set_error (error, _dbus_error_from_errno (errno),
01479 "Failed to listen on socket \"%s:%s\": %s",
01480 host ? host : "*", port, _dbus_strerror_from_errno ());
01481 closesocket (fd);
01482 goto failed;
01483 }
01484
01485 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01486 if (!newlisten_fd)
01487 {
01488 closesocket (fd);
01489 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01490 "Failed to allocate file handle array");
01491 goto failed;
01492 }
01493 listen_fd = newlisten_fd;
01494 listen_fd[nlisten_fd] = fd;
01495 nlisten_fd++;
01496
01497 if (!_dbus_string_get_length(retport))
01498 {
01499
01500
01501
01502
01503 if (!port || !strcmp(port, "0"))
01504 {
01505 mysockaddr_gen addr;
01506 socklen_t addrlen = sizeof(addr);
01507 char portbuf[10];
01508
01509 if (getsockname(fd, &addr.Address, &addrlen) == SOCKET_ERROR)
01510 {
01511 DBUS_SOCKET_SET_ERRNO ();
01512 dbus_set_error (error, _dbus_error_from_errno (errno),
01513 "Failed to resolve port \"%s:%s\": %s",
01514 host ? host : "*", port, _dbus_strerror_from_errno());
01515 goto failed;
01516 }
01517 snprintf( portbuf, sizeof( portbuf ) - 1, "%d", addr.AddressIn.sin_port );
01518 if (!_dbus_string_append(retport, portbuf))
01519 {
01520 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01521 goto failed;
01522 }
01523
01524
01525 port = _dbus_string_get_const_data(retport);
01526 freeaddrinfo(ai);
01527 goto redo_lookup_with_port;
01528 }
01529 else
01530 {
01531 if (!_dbus_string_append(retport, port))
01532 {
01533 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01534 goto failed;
01535 }
01536 }
01537 }
01538
01539 tmp = tmp->ai_next;
01540 }
01541 freeaddrinfo(ai);
01542 ai = NULL;
01543
01544 if (!nlisten_fd)
01545 {
01546 _dbus_win_set_errno (WSAEADDRINUSE);
01547 dbus_set_error (error, _dbus_error_from_errno (errno),
01548 "Failed to bind socket \"%s:%s\": %s",
01549 host ? host : "*", port, _dbus_strerror_from_errno ());
01550 return -1;
01551 }
01552
01553 sscanf(_dbus_string_get_const_data(retport), "%d", &port_num);
01554
01555 for (i = 0 ; i < nlisten_fd ; i++)
01556 {
01557 _dbus_fd_set_close_on_exec (listen_fd[i]);
01558 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01559 {
01560 goto failed;
01561 }
01562 }
01563
01564 *fds_p = listen_fd;
01565
01566 return nlisten_fd;
01567
01568 failed:
01569 if (ai)
01570 freeaddrinfo(ai);
01571 for (i = 0 ; i < nlisten_fd ; i++)
01572 closesocket (listen_fd[i]);
01573 dbus_free(listen_fd);
01574 return -1;
01575 }
01576
01577
01585 int
01586 _dbus_accept (int listen_fd)
01587 {
01588 int client_fd;
01589
01590 retry:
01591 client_fd = accept (listen_fd, NULL, NULL);
01592
01593 if (DBUS_SOCKET_IS_INVALID (client_fd))
01594 {
01595 DBUS_SOCKET_SET_ERRNO ();
01596 if (errno == EINTR)
01597 goto retry;
01598 }
01599
01600 _dbus_verbose ("client fd %d accepted\n", client_fd);
01601
01602 return client_fd;
01603 }
01604
01605
01606
01607
01608 dbus_bool_t
01609 _dbus_send_credentials_socket (int handle,
01610 DBusError *error)
01611 {
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635 int bytes_written;
01636 DBusString buf;
01637
01638 _dbus_string_init_const_len (&buf, "\0", 1);
01639 again:
01640 bytes_written = _dbus_write_socket (handle, &buf, 0, 1 );
01641
01642 if (bytes_written < 0 && errno == EINTR)
01643 goto again;
01644
01645 if (bytes_written < 0)
01646 {
01647 dbus_set_error (error, _dbus_error_from_errno (errno),
01648 "Failed to write credentials byte: %s",
01649 _dbus_strerror_from_errno ());
01650 return FALSE;
01651 }
01652 else if (bytes_written == 0)
01653 {
01654 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01655 "wrote zero bytes writing credentials byte");
01656 return FALSE;
01657 }
01658 else
01659 {
01660 _dbus_assert (bytes_written == 1);
01661 _dbus_verbose ("wrote 1 zero byte, credential sending isn't implemented yet\n");
01662 return TRUE;
01663 }
01664 return TRUE;
01665 }
01666
01685 dbus_bool_t
01686 _dbus_read_credentials_socket (int handle,
01687 DBusCredentials *credentials,
01688 DBusError *error)
01689 {
01690 int bytes_read = 0;
01691 DBusString buf;
01692
01693
01694 if (_dbus_string_init(&buf))
01695 {
01696 bytes_read = _dbus_read_socket(handle, &buf, 1 );
01697
01698 if (bytes_read > 0)
01699 _dbus_verbose("got one zero byte from server");
01700
01701 _dbus_string_free(&buf);
01702 }
01703
01704 _dbus_credentials_add_from_current_process (credentials);
01705 _dbus_verbose("FIXME: get faked credentials from current process");
01706
01707 return TRUE;
01708 }
01709
01718 dbus_bool_t
01719 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01720 {
01721
01722 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01723 return TRUE;
01724 }
01725
01726
01737 dbus_bool_t
01738 _dbus_concat_dir_and_file (DBusString *dir,
01739 const DBusString *next_component)
01740 {
01741 dbus_bool_t dir_ends_in_slash;
01742 dbus_bool_t file_starts_with_slash;
01743
01744 if (_dbus_string_get_length (dir) == 0 ||
01745 _dbus_string_get_length (next_component) == 0)
01746 return TRUE;
01747
01748 dir_ends_in_slash =
01749 ('/' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1) ||
01750 '\\' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1));
01751
01752 file_starts_with_slash =
01753 ('/' == _dbus_string_get_byte (next_component, 0) ||
01754 '\\' == _dbus_string_get_byte (next_component, 0));
01755
01756 if (dir_ends_in_slash && file_starts_with_slash)
01757 {
01758 _dbus_string_shorten (dir, 1);
01759 }
01760 else if (!(dir_ends_in_slash || file_starts_with_slash))
01761 {
01762 if (!_dbus_string_append_byte (dir, '\\'))
01763 return FALSE;
01764 }
01765
01766 return _dbus_string_copy (next_component, 0, dir,
01767 _dbus_string_get_length (dir));
01768 }
01769
01770
01771
01779 dbus_bool_t
01780 _dbus_credentials_add_from_user (DBusCredentials *credentials,
01781 const DBusString *username)
01782 {
01783 return _dbus_credentials_add_windows_sid (credentials,
01784 _dbus_string_get_const_data(username));
01785 }
01786
01795 dbus_bool_t
01796 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
01797 {
01798 dbus_bool_t retval = FALSE;
01799 char *sid = NULL;
01800
01801 if (!_dbus_getsid(&sid))
01802 goto failed;
01803
01804 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
01805 goto failed;
01806
01807 if (!_dbus_credentials_add_windows_sid (credentials,sid))
01808 goto failed;
01809
01810 retval = TRUE;
01811 goto end;
01812 failed:
01813 retval = FALSE;
01814 end:
01815 if (sid)
01816 LocalFree(sid);
01817
01818 return retval;
01819 }
01820
01833 dbus_bool_t
01834 _dbus_append_user_from_current_process (DBusString *str)
01835 {
01836 dbus_bool_t retval = FALSE;
01837 char *sid = NULL;
01838
01839 if (!_dbus_getsid(&sid))
01840 return FALSE;
01841
01842 retval = _dbus_string_append (str,sid);
01843
01844 LocalFree(sid);
01845 return retval;
01846 }
01847
01852 dbus_pid_t
01853 _dbus_getpid (void)
01854 {
01855 return GetCurrentProcessId ();
01856 }
01857
01859 #define NANOSECONDS_PER_SECOND 1000000000
01860
01861 #define MICROSECONDS_PER_SECOND 1000000
01862
01863 #define MILLISECONDS_PER_SECOND 1000
01864
01865 #define NANOSECONDS_PER_MILLISECOND 1000000
01866
01867 #define MICROSECONDS_PER_MILLISECOND 1000
01868
01873 void
01874 _dbus_sleep_milliseconds (int milliseconds)
01875 {
01876 Sleep (milliseconds);
01877 }
01878
01879
01886 void
01887 _dbus_get_current_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
01910
01914 void
01915 _dbus_disable_sigpipe (void)
01916 {
01917 }
01918
01927 dbus_bool_t
01928 _dbus_create_directory (const DBusString *filename,
01929 DBusError *error)
01930 {
01931 const char *filename_c;
01932
01933 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01934
01935 filename_c = _dbus_string_get_const_data (filename);
01936
01937 if (!CreateDirectoryA (filename_c, NULL))
01938 {
01939 if (GetLastError () == ERROR_ALREADY_EXISTS)
01940 return TRUE;
01941
01942 dbus_set_error (error, DBUS_ERROR_FAILED,
01943 "Failed to create directory %s: %s\n",
01944 filename_c, _dbus_strerror_from_errno ());
01945 return FALSE;
01946 }
01947 else
01948 return TRUE;
01949 }
01950
01951
01960 dbus_bool_t
01961 _dbus_generate_random_bytes (DBusString *str,
01962 int n_bytes)
01963 {
01964 int old_len;
01965 char *p;
01966 HCRYPTPROV hprov;
01967
01968 old_len = _dbus_string_get_length (str);
01969
01970 if (!_dbus_string_lengthen (str, n_bytes))
01971 return FALSE;
01972
01973 p = _dbus_string_get_data_len (str, old_len, n_bytes);
01974
01975 if (!CryptAcquireContext (&hprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
01976 return FALSE;
01977
01978 if (!CryptGenRandom (hprov, n_bytes, p))
01979 {
01980 CryptReleaseContext (hprov, 0);
01981 return FALSE;
01982 }
01983
01984 CryptReleaseContext (hprov, 0);
01985
01986 return TRUE;
01987 }
01988
01995 const char*
01996 _dbus_get_tmpdir(void)
01997 {
01998 static const char* tmpdir = NULL;
01999 static char buf[1000];
02000
02001 if (tmpdir == NULL)
02002 {
02003 char *last_slash;
02004
02005 if (!GetTempPathA (sizeof (buf), buf))
02006 {
02007 _dbus_warn ("GetTempPath failed\n");
02008 _dbus_abort ();
02009 }
02010
02011
02012 last_slash = _mbsrchr (buf, '\\');
02013 if (last_slash > buf && last_slash[1] == '\0')
02014 last_slash[0] = '\0';
02015 last_slash = _mbsrchr (buf, '/');
02016 if (last_slash > buf && last_slash[1] == '\0')
02017 last_slash[0] = '\0';
02018
02019 tmpdir = buf;
02020 }
02021
02022 _dbus_assert(tmpdir != NULL);
02023
02024 return tmpdir;
02025 }
02026
02027
02036 dbus_bool_t
02037 _dbus_delete_file (const DBusString *filename,
02038 DBusError *error)
02039 {
02040 const char *filename_c;
02041
02042 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02043
02044 filename_c = _dbus_string_get_const_data (filename);
02045
02046 if (DeleteFileA (filename_c) == 0)
02047 {
02048 dbus_set_error (error, DBUS_ERROR_FAILED,
02049 "Failed to delete file %s: %s\n",
02050 filename_c, _dbus_strerror_from_errno ());
02051 return FALSE;
02052 }
02053 else
02054 return TRUE;
02055 }
02056
02057
02058
02059
02060
02061
02062
02063
02064 const char *
02065 _dbus_replace_install_prefix (const char *configure_time_path)
02066 {
02067 #ifndef DBUS_PREFIX
02068 return configure_time_path;
02069 #else
02070 static char retval[1000];
02071 static char runtime_prefix[1000];
02072 int len = 1000;
02073 int i;
02074
02075 if (!configure_time_path)
02076 return NULL;
02077
02078 if ((!_dbus_get_install_root(runtime_prefix, len) ||
02079 strncmp (configure_time_path, DBUS_PREFIX "/",
02080 strlen (DBUS_PREFIX) + 1))) {
02081 strcat (retval, configure_time_path);
02082 return retval;
02083 }
02084
02085 strcpy (retval, runtime_prefix);
02086 strcat (retval, configure_time_path + strlen (DBUS_PREFIX) + 1);
02087
02088
02089
02090
02091
02092
02093 for(i = 0; retval[i] != '\0'; i++) {
02094 if(retval[i] == '\\')
02095 retval[i] = '/';
02096 }
02097 return retval;
02098 #endif
02099 }
02100
02101 #if !defined (DBUS_DISABLE_ASSERTS) || defined(DBUS_BUILD_TESTS)
02102
02103 #if defined(_MSC_VER) || defined(DBUS_WINCE)
02104 # ifdef BACKTRACES
02105 # undef BACKTRACES
02106 # endif
02107 #else
02108 # define BACKTRACES
02109 #endif
02110
02111 #ifdef BACKTRACES
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133 #include <winver.h>
02134 #include <imagehlp.h>
02135 #include <stdio.h>
02136
02137 #define DPRINTF _dbus_warn
02138
02139 #ifdef _MSC_VER
02140 #define BOOL int
02141
02142 #define __i386__
02143 #endif
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153 static BOOL (WINAPI *pStackWalk)(
02154 DWORD MachineType,
02155 HANDLE hProcess,
02156 HANDLE hThread,
02157 LPSTACKFRAME StackFrame,
02158 PVOID ContextRecord,
02159 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
02160 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
02161 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
02162 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
02163 );
02164 #ifdef _WIN64
02165 static DWORD64 (WINAPI *pSymGetModuleBase)(
02166 HANDLE hProcess,
02167 DWORD64 dwAddr
02168 );
02169 static PVOID (WINAPI *pSymFunctionTableAccess)(
02170 HANDLE hProcess,
02171 DWORD64 AddrBase
02172 );
02173 #else
02174 static DWORD (WINAPI *pSymGetModuleBase)(
02175 HANDLE hProcess,
02176 DWORD dwAddr
02177 );
02178 static PVOID (WINAPI *pSymFunctionTableAccess)(
02179 HANDLE hProcess,
02180 DWORD AddrBase
02181 );
02182 #endif
02183 static BOOL (WINAPI *pSymInitialize)(
02184 HANDLE hProcess,
02185 PSTR UserSearchPath,
02186 BOOL fInvadeProcess
02187 );
02188 static BOOL (WINAPI *pSymGetSymFromAddr)(
02189 HANDLE hProcess,
02190 DWORD Address,
02191 PDWORD Displacement,
02192 PIMAGEHLP_SYMBOL Symbol
02193 );
02194 static BOOL (WINAPI *pSymGetModuleInfo)(
02195 HANDLE hProcess,
02196 DWORD dwAddr,
02197 PIMAGEHLP_MODULE ModuleInfo
02198 );
02199 static DWORD (WINAPI *pSymSetOptions)(
02200 DWORD SymOptions
02201 );
02202
02203
02204 static BOOL init_backtrace()
02205 {
02206 HMODULE hmodDbgHelp = LoadLibraryA("dbghelp");
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224 #define FUNC(x) #x
02225
02226 pStackWalk = (BOOL (WINAPI *)(
02227 DWORD MachineType,
02228 HANDLE hProcess,
02229 HANDLE hThread,
02230 LPSTACKFRAME StackFrame,
02231 PVOID ContextRecord,
02232 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
02233 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
02234 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
02235 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
02236 ))GetProcAddress (hmodDbgHelp, FUNC(StackWalk));
02237 #ifdef _WIN64
02238 pSymGetModuleBase=(DWORD64 (WINAPI *)(
02239 HANDLE hProcess,
02240 DWORD64 dwAddr
02241 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
02242 pSymFunctionTableAccess=(PVOID (WINAPI *)(
02243 HANDLE hProcess,
02244 DWORD64 AddrBase
02245 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
02246 #else
02247 pSymGetModuleBase=(DWORD (WINAPI *)(
02248 HANDLE hProcess,
02249 DWORD dwAddr
02250 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
02251 pSymFunctionTableAccess=(PVOID (WINAPI *)(
02252 HANDLE hProcess,
02253 DWORD AddrBase
02254 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
02255 #endif
02256 pSymInitialize = (BOOL (WINAPI *)(
02257 HANDLE hProcess,
02258 PSTR UserSearchPath,
02259 BOOL fInvadeProcess
02260 ))GetProcAddress (hmodDbgHelp, FUNC(SymInitialize));
02261 pSymGetSymFromAddr = (BOOL (WINAPI *)(
02262 HANDLE hProcess,
02263 DWORD Address,
02264 PDWORD Displacement,
02265 PIMAGEHLP_SYMBOL Symbol
02266 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetSymFromAddr));
02267 pSymGetModuleInfo = (BOOL (WINAPI *)(
02268 HANDLE hProcess,
02269 DWORD dwAddr,
02270 PIMAGEHLP_MODULE ModuleInfo
02271 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleInfo));
02272 pSymSetOptions = (DWORD (WINAPI *)(
02273 DWORD SymOptions
02274 ))GetProcAddress (hmodDbgHelp, FUNC(SymSetOptions));
02275
02276
02277 pSymSetOptions(SYMOPT_UNDNAME);
02278
02279 pSymInitialize(GetCurrentProcess(), NULL, TRUE);
02280
02281 return TRUE;
02282 }
02283
02284 static void dump_backtrace_for_thread(HANDLE hThread)
02285 {
02286 STACKFRAME sf;
02287 CONTEXT context;
02288 DWORD dwImageType;
02289
02290 if (!pStackWalk)
02291 if (!init_backtrace())
02292 return;
02293
02294
02295
02296 if (hThread == GetCurrentThread())
02297 return;
02298
02299 DPRINTF("Backtrace:\n");
02300
02301 _DBUS_ZERO(context);
02302 context.ContextFlags = CONTEXT_FULL;
02303
02304 SuspendThread(hThread);
02305
02306 if (!GetThreadContext(hThread, &context))
02307 {
02308 DPRINTF("Couldn't get thread context (error %ld)\n", GetLastError());
02309 ResumeThread(hThread);
02310 return;
02311 }
02312
02313 _DBUS_ZERO(sf);
02314
02315 #ifdef __i386__
02316 sf.AddrFrame.Offset = context.Ebp;
02317 sf.AddrFrame.Mode = AddrModeFlat;
02318 sf.AddrPC.Offset = context.Eip;
02319 sf.AddrPC.Mode = AddrModeFlat;
02320 dwImageType = IMAGE_FILE_MACHINE_I386;
02321 #elif _M_X64
02322 dwImageType = IMAGE_FILE_MACHINE_AMD64;
02323 sf.AddrPC.Offset = context.Rip;
02324 sf.AddrPC.Mode = AddrModeFlat;
02325 sf.AddrFrame.Offset = context.Rsp;
02326 sf.AddrFrame.Mode = AddrModeFlat;
02327 sf.AddrStack.Offset = context.Rsp;
02328 sf.AddrStack.Mode = AddrModeFlat;
02329 #elif _M_IA64
02330 dwImageType = IMAGE_FILE_MACHINE_IA64;
02331 sf.AddrPC.Offset = context.StIIP;
02332 sf.AddrPC.Mode = AddrModeFlat;
02333 sf.AddrFrame.Offset = context.IntSp;
02334 sf.AddrFrame.Mode = AddrModeFlat;
02335 sf.AddrBStore.Offset= context.RsBSP;
02336 sf.AddrBStore.Mode = AddrModeFlat;
02337 sf.AddrStack.Offset = context.IntSp;
02338 sf.AddrStack.Mode = AddrModeFlat;
02339 #else
02340 # error You need to fill in the STACKFRAME structure for your architecture
02341 #endif
02342
02343 while (pStackWalk(dwImageType, GetCurrentProcess(),
02344 hThread, &sf, &context, NULL, pSymFunctionTableAccess,
02345 pSymGetModuleBase, NULL))
02346 {
02347 BYTE buffer[256];
02348 IMAGEHLP_SYMBOL * pSymbol = (IMAGEHLP_SYMBOL *)buffer;
02349 DWORD dwDisplacement;
02350
02351 pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
02352 pSymbol->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1;
02353
02354 if (!pSymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset,
02355 &dwDisplacement, pSymbol))
02356 {
02357 IMAGEHLP_MODULE ModuleInfo;
02358 ModuleInfo.SizeOfStruct = sizeof(ModuleInfo);
02359
02360 if (!pSymGetModuleInfo(GetCurrentProcess(), sf.AddrPC.Offset,
02361 &ModuleInfo))
02362 DPRINTF("1\t%p\n", (void*)sf.AddrPC.Offset);
02363 else
02364 DPRINTF("2\t%s+0x%lx\n", ModuleInfo.ImageName,
02365 sf.AddrPC.Offset - ModuleInfo.BaseOfImage);
02366 }
02367 else if (dwDisplacement)
02368 DPRINTF("3\t%s+0x%lx\n", pSymbol->Name, dwDisplacement);
02369 else
02370 DPRINTF("4\t%s\n", pSymbol->Name);
02371 }
02372
02373 ResumeThread(hThread);
02374 }
02375
02376 static DWORD WINAPI dump_thread_proc(LPVOID lpParameter)
02377 {
02378 dump_backtrace_for_thread((HANDLE)lpParameter);
02379 return 0;
02380 }
02381
02382
02383
02384 static void dump_backtrace()
02385 {
02386 HANDLE hCurrentThread;
02387 HANDLE hThread;
02388 DWORD dwThreadId;
02389 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
02390 GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
02391 hThread = CreateThread(NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread,
02392 0, &dwThreadId);
02393 WaitForSingleObject(hThread, INFINITE);
02394 CloseHandle(hThread);
02395 CloseHandle(hCurrentThread);
02396 }
02397 #endif
02398 #endif
02399
02400 #ifdef BACKTRACES
02401 void _dbus_print_backtrace(void)
02402 {
02403 init_backtrace();
02404 dump_backtrace();
02405 }
02406 #else
02407 void _dbus_print_backtrace(void)
02408 {
02409 _dbus_verbose (" D-Bus not compiled with backtrace support\n");
02410 }
02411 #endif
02412
02413 static dbus_uint32_t fromAscii(char ascii)
02414 {
02415 if(ascii >= '0' && ascii <= '9')
02416 return ascii - '0';
02417 if(ascii >= 'A' && ascii <= 'F')
02418 return ascii - 'A' + 10;
02419 if(ascii >= 'a' && ascii <= 'f')
02420 return ascii - 'a' + 10;
02421 return 0;
02422 }
02423
02424 dbus_bool_t _dbus_read_local_machine_uuid (DBusGUID *machine_id,
02425 dbus_bool_t create_if_not_found,
02426 DBusError *error)
02427 {
02428 #ifdef DBUS_WINCE
02429 return TRUE;
02430
02431 #else
02432 HW_PROFILE_INFOA info;
02433 char *lpc = &info.szHwProfileGuid[0];
02434 dbus_uint32_t u;
02435
02436
02437 if(!GetCurrentHwProfileA(&info))
02438 {
02439 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02440 return FALSE;
02441 }
02442
02443
02444 lpc++;
02445
02446 u = ((fromAscii(lpc[0]) << 0) |
02447 (fromAscii(lpc[1]) << 4) |
02448 (fromAscii(lpc[2]) << 8) |
02449 (fromAscii(lpc[3]) << 12) |
02450 (fromAscii(lpc[4]) << 16) |
02451 (fromAscii(lpc[5]) << 20) |
02452 (fromAscii(lpc[6]) << 24) |
02453 (fromAscii(lpc[7]) << 28));
02454 machine_id->as_uint32s[0] = u;
02455
02456 lpc += 9;
02457
02458 u = ((fromAscii(lpc[0]) << 0) |
02459 (fromAscii(lpc[1]) << 4) |
02460 (fromAscii(lpc[2]) << 8) |
02461 (fromAscii(lpc[3]) << 12) |
02462 (fromAscii(lpc[5]) << 16) |
02463 (fromAscii(lpc[6]) << 20) |
02464 (fromAscii(lpc[7]) << 24) |
02465 (fromAscii(lpc[8]) << 28));
02466 machine_id->as_uint32s[1] = u;
02467
02468 lpc += 10;
02469
02470 u = ((fromAscii(lpc[0]) << 0) |
02471 (fromAscii(lpc[1]) << 4) |
02472 (fromAscii(lpc[2]) << 8) |
02473 (fromAscii(lpc[3]) << 12) |
02474 (fromAscii(lpc[5]) << 16) |
02475 (fromAscii(lpc[6]) << 20) |
02476 (fromAscii(lpc[7]) << 24) |
02477 (fromAscii(lpc[8]) << 28));
02478 machine_id->as_uint32s[2] = u;
02479
02480 lpc += 9;
02481
02482 u = ((fromAscii(lpc[0]) << 0) |
02483 (fromAscii(lpc[1]) << 4) |
02484 (fromAscii(lpc[2]) << 8) |
02485 (fromAscii(lpc[3]) << 12) |
02486 (fromAscii(lpc[4]) << 16) |
02487 (fromAscii(lpc[5]) << 20) |
02488 (fromAscii(lpc[6]) << 24) |
02489 (fromAscii(lpc[7]) << 28));
02490 machine_id->as_uint32s[3] = u;
02491 #endif
02492 return TRUE;
02493 }
02494
02495 static
02496 HANDLE _dbus_global_lock (const char *mutexname)
02497 {
02498 HANDLE mutex;
02499 DWORD gotMutex;
02500
02501 mutex = CreateMutexA( NULL, FALSE, mutexname );
02502 if( !mutex )
02503 {
02504 return FALSE;
02505 }
02506
02507 gotMutex = WaitForSingleObject( mutex, INFINITE );
02508 switch( gotMutex )
02509 {
02510 case WAIT_ABANDONED:
02511 ReleaseMutex (mutex);
02512 CloseHandle (mutex);
02513 return 0;
02514 case WAIT_FAILED:
02515 case WAIT_TIMEOUT:
02516 return 0;
02517 }
02518
02519 return mutex;
02520 }
02521
02522 static
02523 void _dbus_global_unlock (HANDLE mutex)
02524 {
02525 ReleaseMutex (mutex);
02526 CloseHandle (mutex);
02527 }
02528
02529
02530 static HANDLE hDBusDaemonMutex = NULL;
02531 static HANDLE hDBusSharedMem = NULL;
02532
02533 static const char *cUniqueDBusInitMutex = "UniqueDBusInitMutex";
02534
02535 static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex";
02536
02537 static const char *cDBusDaemonMutex = "DBusDaemonMutex";
02538
02539 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
02540
02541 static dbus_bool_t
02542 _dbus_get_install_root_as_hash(DBusString *out)
02543 {
02544 DBusString install_path;
02545
02546 char path[MAX_PATH*2];
02547 int path_size = sizeof(path);
02548
02549 if (!_dbus_get_install_root(path,path_size))
02550 return FALSE;
02551
02552 _dbus_string_init(&install_path);
02553 _dbus_string_append(&install_path,path);
02554
02555 _dbus_string_init(out);
02556 _dbus_string_tolower_ascii(&install_path,0,_dbus_string_get_length(&install_path));
02557
02558 if (!_dbus_sha_compute (&install_path, out))
02559 return FALSE;
02560
02561 return TRUE;
02562 }
02563
02564 static dbus_bool_t
02565 _dbus_get_address_string (DBusString *out, const char *basestring, const char *scope)
02566 {
02567 _dbus_string_init(out);
02568 _dbus_string_append(out,basestring);
02569
02570 if (!scope)
02571 {
02572 return TRUE;
02573 }
02574 else if (strcmp(scope,"*install-path") == 0
02575
02576 || strcmp(scope,"install-path") == 0)
02577 {
02578 DBusString temp;
02579 if (!_dbus_get_install_root_as_hash(&temp))
02580 {
02581 _dbus_string_free(out);
02582 return FALSE;
02583 }
02584 _dbus_string_append(out,"-");
02585 _dbus_string_append(out,_dbus_string_get_const_data(&temp));
02586 _dbus_string_free(&temp);
02587 }
02588 else if (strcmp(scope,"*user") == 0)
02589 {
02590 _dbus_string_append(out,"-");
02591 if (!_dbus_append_user_from_current_process(out))
02592 {
02593 _dbus_string_free(out);
02594 return FALSE;
02595 }
02596 }
02597 else if (strlen(scope) > 0)
02598 {
02599 _dbus_string_append(out,"-");
02600 _dbus_string_append(out,scope);
02601 return TRUE;
02602 }
02603 return TRUE;
02604 }
02605
02606 static dbus_bool_t
02607 _dbus_get_shm_name (DBusString *out,const char *scope)
02608 {
02609 return _dbus_get_address_string (out,cDBusDaemonAddressInfo,scope);
02610 }
02611
02612 static dbus_bool_t
02613 _dbus_get_mutex_name (DBusString *out,const char *scope)
02614 {
02615 return _dbus_get_address_string (out,cDBusDaemonMutex,scope);
02616 }
02617
02618 dbus_bool_t
02619 _dbus_daemon_is_session_bus_address_published (const char *scope)
02620 {
02621 HANDLE lock;
02622 HANDLE mutex;
02623 DBusString mutex_name;
02624 DWORD ret;
02625
02626 if (!_dbus_get_mutex_name(&mutex_name,scope))
02627 {
02628 _dbus_string_free( &mutex_name );
02629 return FALSE;
02630 }
02631
02632 if (hDBusDaemonMutex)
02633 return TRUE;
02634
02635
02636 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02637
02638
02639
02640 hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02641
02642 _dbus_global_unlock( lock );
02643
02644 _dbus_string_free( &mutex_name );
02645
02646 if (hDBusDaemonMutex == NULL)
02647 return FALSE;
02648 if (GetLastError() == ERROR_ALREADY_EXISTS)
02649 {
02650 CloseHandle(hDBusDaemonMutex);
02651 hDBusDaemonMutex = NULL;
02652 return TRUE;
02653 }
02654
02655
02656
02657 return FALSE;
02658 }
02659
02660 dbus_bool_t
02661 _dbus_daemon_publish_session_bus_address (const char* address, const char *scope)
02662 {
02663 HANDLE lock;
02664 char *shared_addr = NULL;
02665 DWORD ret;
02666 char addressInfo[1024];
02667 DBusString shm_name;
02668 DBusString mutex_name;
02669
02670 _dbus_assert (address);
02671
02672 if (!_dbus_get_mutex_name(&mutex_name,scope))
02673 {
02674 _dbus_string_free( &mutex_name );
02675 return FALSE;
02676 }
02677
02678
02679 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02680
02681 if (!hDBusDaemonMutex)
02682 {
02683 hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02684 }
02685 _dbus_string_free( &mutex_name );
02686
02687 if (!_dbus_get_shm_name(&shm_name,scope))
02688 {
02689 _dbus_string_free( &shm_name );
02690 _dbus_global_unlock( lock );
02691 return FALSE;
02692 }
02693
02694
02695 hDBusSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
02696 0, strlen( address ) + 1, _dbus_string_get_const_data(&shm_name) );
02697 _dbus_assert( hDBusSharedMem );
02698
02699 shared_addr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
02700
02701 _dbus_assert (shared_addr);
02702
02703 strcpy( shared_addr, address);
02704
02705
02706 UnmapViewOfFile( shared_addr );
02707
02708 _dbus_global_unlock( lock );
02709 _dbus_verbose( "published session bus address at %s\n",_dbus_string_get_const_data (&shm_name) );
02710
02711 _dbus_string_free( &shm_name );
02712 return TRUE;
02713 }
02714
02715 void
02716 _dbus_daemon_unpublish_session_bus_address (void)
02717 {
02718 HANDLE lock;
02719
02720
02721 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02722
02723 CloseHandle( hDBusSharedMem );
02724
02725 hDBusSharedMem = NULL;
02726
02727 ReleaseMutex( hDBusDaemonMutex );
02728
02729 CloseHandle( hDBusDaemonMutex );
02730
02731 hDBusDaemonMutex = NULL;
02732
02733 _dbus_global_unlock( lock );
02734 }
02735
02736 static dbus_bool_t
02737 _dbus_get_autolaunch_shm (DBusString *address, DBusString *shm_name)
02738 {
02739 HANDLE sharedMem;
02740 char *shared_addr;
02741 int i;
02742
02743
02744 for(i=0;i<20;++i) {
02745
02746 sharedMem = OpenFileMappingA( FILE_MAP_READ, FALSE, _dbus_string_get_const_data(shm_name));
02747 if( sharedMem == 0 )
02748 Sleep( 100 );
02749 if ( sharedMem != 0)
02750 break;
02751 }
02752
02753 if( sharedMem == 0 )
02754 return FALSE;
02755
02756 shared_addr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
02757
02758 if( !shared_addr )
02759 return FALSE;
02760
02761 _dbus_string_init( address );
02762
02763 _dbus_string_append( address, shared_addr );
02764
02765
02766 UnmapViewOfFile( shared_addr );
02767
02768 CloseHandle( sharedMem );
02769
02770 return TRUE;
02771 }
02772
02773 static dbus_bool_t
02774 _dbus_daemon_already_runs (DBusString *address, DBusString *shm_name, const char *scope)
02775 {
02776 HANDLE lock;
02777 HANDLE daemon;
02778 DBusString mutex_name;
02779 dbus_bool_t bRet = TRUE;
02780
02781 if (!_dbus_get_mutex_name(&mutex_name,scope))
02782 {
02783 _dbus_string_free( &mutex_name );
02784 return FALSE;
02785 }
02786
02787
02788 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02789
02790
02791 daemon = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02792 if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT)
02793 {
02794 ReleaseMutex (daemon);
02795 CloseHandle (daemon);
02796
02797 _dbus_global_unlock( lock );
02798 _dbus_string_free( &mutex_name );
02799 return FALSE;
02800 }
02801
02802
02803 bRet = _dbus_get_autolaunch_shm( address, shm_name );
02804
02805
02806 CloseHandle ( daemon );
02807
02808 _dbus_global_unlock( lock );
02809 _dbus_string_free( &mutex_name );
02810
02811 return bRet;
02812 }
02813
02814 dbus_bool_t
02815 _dbus_get_autolaunch_address (const char *scope, DBusString *address,
02816 DBusError *error)
02817 {
02818 HANDLE mutex;
02819 STARTUPINFOA si;
02820 PROCESS_INFORMATION pi;
02821 dbus_bool_t retval = FALSE;
02822 LPSTR lpFile;
02823 char dbus_exe_path[MAX_PATH];
02824 char dbus_args[MAX_PATH * 2];
02825 const char * daemon_name = DBUS_DAEMON_NAME ".exe";
02826 DBusString shm_name;
02827
02828 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02829
02830 if (!_dbus_get_shm_name(&shm_name,scope))
02831 {
02832 dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not determine shm name");
02833 return FALSE;
02834 }
02835
02836 mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
02837
02838 if (_dbus_daemon_already_runs(address,&shm_name,scope))
02839 {
02840 _dbus_verbose( "found running dbus daemon at %s\n",
02841 _dbus_string_get_const_data (&shm_name) );
02842 retval = TRUE;
02843 goto out;
02844 }
02845
02846 if (!SearchPathA(NULL, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
02847 {
02848 printf ("please add the path to %s to your PATH environment variable\n", daemon_name);
02849 printf ("or start the daemon manually\n\n");
02850 goto out;
02851 }
02852
02853
02854 ZeroMemory( &si, sizeof(si) );
02855 si.cb = sizeof(si);
02856 ZeroMemory( &pi, sizeof(pi) );
02857
02858 _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path, " --session");
02859
02860
02861
02862 if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
02863 {
02864 CloseHandle (pi.hThread);
02865 CloseHandle (pi.hProcess);
02866 retval = _dbus_get_autolaunch_shm( address, &shm_name );
02867 if (retval == FALSE)
02868 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to get autolaunch address from launched dbus-daemon");
02869 }
02870 else
02871 {
02872 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to launch dbus-daemon");
02873 retval = FALSE;
02874 }
02875
02876 out:
02877 if (retval)
02878 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02879 else
02880 _DBUS_ASSERT_ERROR_IS_SET (error);
02881
02882 _dbus_global_unlock (mutex);
02883
02884 return retval;
02885 }
02886
02887
02894 dbus_bool_t
02895 _dbus_make_file_world_readable(const DBusString *filename,
02896 DBusError *error)
02897 {
02898
02899 return TRUE;
02900 }
02901
02908 static const char *
02909 _dbus_windows_get_datadir (void)
02910 {
02911 return _dbus_replace_install_prefix(DBUS_DATADIR);
02912 }
02913
02914 #undef DBUS_DATADIR
02915 #define DBUS_DATADIR _dbus_windows_get_datadir ()
02916
02917
02918 #define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
02919 #define DBUS_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
02920
02937 dbus_bool_t
02938 _dbus_get_standard_session_servicedirs (DBusList **dirs)
02939 {
02940 const char *common_progs;
02941 DBusString servicedir_path;
02942
02943 if (!_dbus_string_init (&servicedir_path))
02944 return FALSE;
02945
02946 #ifdef DBUS_WINCE
02947 {
02948
02949 const char *data_dir = _dbus_getenv ("DBUS_DATADIR");
02950
02951 if (data_dir != NULL)
02952 {
02953 if (!_dbus_string_append (&servicedir_path, data_dir))
02954 goto oom;
02955
02956 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
02957 goto oom;
02958 }
02959 }
02960 #else
02961
02962
02963
02964
02965 #ifdef DBUS_WIN
02966 {
02967 DBusString p;
02968
02969 _dbus_string_init_const (&p, DBUS_DATADIR);
02970
02971 if (!_dbus_path_is_absolute (&p))
02972 {
02973 char install_root[1000];
02974 if (_dbus_get_install_root (install_root, sizeof(install_root)))
02975 if (!_dbus_string_append (&servicedir_path, install_root))
02976 goto oom;
02977 }
02978 }
02979 #endif
02980 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
02981 goto oom;
02982
02983 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
02984 goto oom;
02985 #endif
02986
02987 common_progs = _dbus_getenv ("CommonProgramFiles");
02988
02989 if (common_progs != NULL)
02990 {
02991 if (!_dbus_string_append (&servicedir_path, common_progs))
02992 goto oom;
02993
02994 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
02995 goto oom;
02996 }
02997
02998 if (!_dbus_split_paths_and_append (&servicedir_path,
02999 DBUS_STANDARD_SESSION_SERVICEDIR,
03000 dirs))
03001 goto oom;
03002
03003 _dbus_string_free (&servicedir_path);
03004 return TRUE;
03005
03006 oom:
03007 _dbus_string_free (&servicedir_path);
03008 return FALSE;
03009 }
03010
03029 dbus_bool_t
03030 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03031 {
03032 *dirs = NULL;
03033 return TRUE;
03034 }
03035
03036 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
03037
03045 dbus_int32_t
03046 _dbus_atomic_inc (DBusAtomic *atomic)
03047 {
03048
03049
03050 return InterlockedIncrement (&atomic->value) - 1;
03051 }
03052
03060 dbus_int32_t
03061 _dbus_atomic_dec (DBusAtomic *atomic)
03062 {
03063
03064
03065 return InterlockedDecrement (&atomic->value) + 1;
03066 }
03067
03075 dbus_int32_t
03076 _dbus_atomic_get (DBusAtomic *atomic)
03077 {
03078
03079 MemoryBarrier ();
03080 return atomic->value;
03081 }
03082
03090 void
03091 _dbus_flush_caches (void)
03092 {
03093 }
03094
03101 dbus_bool_t
03102 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03103 {
03104 return errno == WSAEWOULDBLOCK;
03105 }
03106
03114 dbus_bool_t
03115 _dbus_get_install_root(char *prefix, int len)
03116 {
03117
03118 char* p = 0;
03119 int i;
03120 DWORD pathLength;
03121 char *lastSlash;
03122 SetLastError( 0 );
03123 pathLength = GetModuleFileNameA(_dbus_win_get_dll_hmodule(), prefix, len);
03124 if ( pathLength == 0 || GetLastError() != 0 ) {
03125 *prefix = '\0';
03126 return FALSE;
03127 }
03128 lastSlash = _mbsrchr(prefix, '\\');
03129 if (lastSlash == NULL) {
03130 *prefix = '\0';
03131 return FALSE;
03132 }
03133
03134 lastSlash[1] = 0;
03135
03136
03137
03138
03139
03140
03141
03142 if (lastSlash - prefix >= 4 && strnicmp(lastSlash - 4, "\\bin", 4) == 0)
03143 lastSlash[-3] = 0;
03144 else if (lastSlash - prefix >= 10 && strnicmp(lastSlash - 10, "\\bin\\debug", 10) == 0)
03145 lastSlash[-9] = 0;
03146 else if (lastSlash - prefix >= 12 && strnicmp(lastSlash - 12, "\\bin\\release", 12) == 0)
03147 lastSlash[-11] = 0;
03148
03149 return TRUE;
03150 }
03151
03165 dbus_bool_t
03166 _dbus_get_config_file_name(DBusString *config_file, char *s)
03167 {
03168 char path[MAX_PATH*2];
03169 int path_size = sizeof(path);
03170
03171 if (!_dbus_get_install_root(path,path_size))
03172 return FALSE;
03173
03174 if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
03175 return FALSE;
03176 strcat(path,"etc\\");
03177 strcat(path,s);
03178 if (_dbus_file_exists(path))
03179 {
03180
03181 if (!_dbus_string_append (config_file, path))
03182 return FALSE;
03183 }
03184 else
03185 {
03186 if (!_dbus_get_install_root(path,path_size))
03187 return FALSE;
03188 if(strlen(s) + 11 + strlen(path) > sizeof(path)-2)
03189 return FALSE;
03190 strcat(path,"etc\\dbus-1\\");
03191 strcat(path,s);
03192
03193 if (_dbus_file_exists(path))
03194 {
03195 if (!_dbus_string_append (config_file, path))
03196 return FALSE;
03197 }
03198 else
03199 {
03200 if (!_dbus_get_install_root(path,path_size))
03201 return FALSE;
03202 if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
03203 return FALSE;
03204 strcat(path,"bus\\");
03205 strcat(path,s);
03206
03207 if (_dbus_file_exists(path))
03208 {
03209 if (!_dbus_string_append (config_file, path))
03210 return FALSE;
03211 }
03212 }
03213 }
03214 return TRUE;
03215 }
03216
03225 dbus_bool_t
03226 _dbus_append_system_config_file (DBusString *str)
03227 {
03228 return _dbus_get_config_file_name(str, "system.conf");
03229 }
03230
03237 dbus_bool_t
03238 _dbus_append_session_config_file (DBusString *str)
03239 {
03240 return _dbus_get_config_file_name(str, "session.conf");
03241 }
03242
03243
03244 dbus_bool_t
03245 _dbus_lookup_session_address (dbus_bool_t *supported,
03246 DBusString *address,
03247 DBusError *error)
03248 {
03249
03250 *supported = FALSE;
03251 return TRUE;
03252 }
03253
03267 dbus_bool_t
03268 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03269 DBusCredentials *credentials)
03270 {
03271 DBusString homedir;
03272 DBusString dotdir;
03273 dbus_uid_t uid;
03274 const char *homepath;
03275 const char *homedrive;
03276
03277 _dbus_assert (credentials != NULL);
03278 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03279
03280 if (!_dbus_string_init (&homedir))
03281 return FALSE;
03282
03283 homedrive = _dbus_getenv("HOMEDRIVE");
03284 if (homedrive != NULL && *homedrive != '\0')
03285 {
03286 _dbus_string_append(&homedir,homedrive);
03287 }
03288
03289 homepath = _dbus_getenv("HOMEPATH");
03290 if (homepath != NULL && *homepath != '\0')
03291 {
03292 _dbus_string_append(&homedir,homepath);
03293 }
03294
03295 #ifdef DBUS_BUILD_TESTS
03296 {
03297 const char *override;
03298
03299 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03300 if (override != NULL && *override != '\0')
03301 {
03302 _dbus_string_set_length (&homedir, 0);
03303 if (!_dbus_string_append (&homedir, override))
03304 goto failed;
03305
03306 _dbus_verbose ("Using fake homedir for testing: %s\n",
03307 _dbus_string_get_const_data (&homedir));
03308 }
03309 else
03310 {
03311 static dbus_bool_t already_warned = FALSE;
03312 if (!already_warned)
03313 {
03314 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03315 already_warned = TRUE;
03316 }
03317 }
03318 }
03319 #endif
03320
03321 #ifdef DBUS_WINCE
03322
03323
03324 #define KEYRING_DIR "dbus-keyrings"
03325 #else
03326 #define KEYRING_DIR ".dbus-keyrings"
03327 #endif
03328
03329 _dbus_string_init_const (&dotdir, KEYRING_DIR);
03330 if (!_dbus_concat_dir_and_file (&homedir,
03331 &dotdir))
03332 goto failed;
03333
03334 if (!_dbus_string_copy (&homedir, 0,
03335 directory, _dbus_string_get_length (directory))) {
03336 goto failed;
03337 }
03338
03339 _dbus_string_free (&homedir);
03340 return TRUE;
03341
03342 failed:
03343 _dbus_string_free (&homedir);
03344 return FALSE;
03345 }
03346
03352 dbus_bool_t
03353 _dbus_file_exists (const char *file)
03354 {
03355 DWORD attributes = GetFileAttributesA (file);
03356
03357 if (attributes != INVALID_FILE_ATTRIBUTES && GetLastError() != ERROR_PATH_NOT_FOUND)
03358 return TRUE;
03359 else
03360 return FALSE;
03361 }
03362
03370 const char*
03371 _dbus_strerror (int error_number)
03372 {
03373 #ifdef DBUS_WINCE
03374
03375 return "unknown";
03376 #else
03377 const char *msg;
03378
03379 switch (error_number)
03380 {
03381 case WSAEINTR:
03382 return "Interrupted function call";
03383 case WSAEACCES:
03384 return "Permission denied";
03385 case WSAEFAULT:
03386 return "Bad address";
03387 case WSAEINVAL:
03388 return "Invalid argument";
03389 case WSAEMFILE:
03390 return "Too many open files";
03391 case WSAEWOULDBLOCK:
03392 return "Resource temporarily unavailable";
03393 case WSAEINPROGRESS:
03394 return "Operation now in progress";
03395 case WSAEALREADY:
03396 return "Operation already in progress";
03397 case WSAENOTSOCK:
03398 return "Socket operation on nonsocket";
03399 case WSAEDESTADDRREQ:
03400 return "Destination address required";
03401 case WSAEMSGSIZE:
03402 return "Message too long";
03403 case WSAEPROTOTYPE:
03404 return "Protocol wrong type for socket";
03405 case WSAENOPROTOOPT:
03406 return "Bad protocol option";
03407 case WSAEPROTONOSUPPORT:
03408 return "Protocol not supported";
03409 case WSAESOCKTNOSUPPORT:
03410 return "Socket type not supported";
03411 case WSAEOPNOTSUPP:
03412 return "Operation not supported";
03413 case WSAEPFNOSUPPORT:
03414 return "Protocol family not supported";
03415 case WSAEAFNOSUPPORT:
03416 return "Address family not supported by protocol family";
03417 case WSAEADDRINUSE:
03418 return "Address already in use";
03419 case WSAEADDRNOTAVAIL:
03420 return "Cannot assign requested address";
03421 case WSAENETDOWN:
03422 return "Network is down";
03423 case WSAENETUNREACH:
03424 return "Network is unreachable";
03425 case WSAENETRESET:
03426 return "Network dropped connection on reset";
03427 case WSAECONNABORTED:
03428 return "Software caused connection abort";
03429 case WSAECONNRESET:
03430 return "Connection reset by peer";
03431 case WSAENOBUFS:
03432 return "No buffer space available";
03433 case WSAEISCONN:
03434 return "Socket is already connected";
03435 case WSAENOTCONN:
03436 return "Socket is not connected";
03437 case WSAESHUTDOWN:
03438 return "Cannot send after socket shutdown";
03439 case WSAETIMEDOUT:
03440 return "Connection timed out";
03441 case WSAECONNREFUSED:
03442 return "Connection refused";
03443 case WSAEHOSTDOWN:
03444 return "Host is down";
03445 case WSAEHOSTUNREACH:
03446 return "No route to host";
03447 case WSAEPROCLIM:
03448 return "Too many processes";
03449 case WSAEDISCON:
03450 return "Graceful shutdown in progress";
03451 case WSATYPE_NOT_FOUND:
03452 return "Class type not found";
03453 case WSAHOST_NOT_FOUND:
03454 return "Host not found";
03455 case WSATRY_AGAIN:
03456 return "Nonauthoritative host not found";
03457 case WSANO_RECOVERY:
03458 return "This is a nonrecoverable error";
03459 case WSANO_DATA:
03460 return "Valid name, no data record of requested type";
03461 case WSA_INVALID_HANDLE:
03462 return "Specified event object handle is invalid";
03463 case WSA_INVALID_PARAMETER:
03464 return "One or more parameters are invalid";
03465 case WSA_IO_INCOMPLETE:
03466 return "Overlapped I/O event object not in signaled state";
03467 case WSA_IO_PENDING:
03468 return "Overlapped operations will complete later";
03469 case WSA_NOT_ENOUGH_MEMORY:
03470 return "Insufficient memory available";
03471 case WSA_OPERATION_ABORTED:
03472 return "Overlapped operation aborted";
03473 #ifdef WSAINVALIDPROCTABLE
03474
03475 case WSAINVALIDPROCTABLE:
03476 return "Invalid procedure table from service provider";
03477 #endif
03478 #ifdef WSAINVALIDPROVIDER
03479
03480 case WSAINVALIDPROVIDER:
03481 return "Invalid service provider version number";
03482 #endif
03483 #ifdef WSAPROVIDERFAILEDINIT
03484
03485 case WSAPROVIDERFAILEDINIT:
03486 return "Unable to initialize a service provider";
03487 #endif
03488
03489 case WSASYSCALLFAILURE:
03490 return "System call failure";
03491 }
03492 msg = strerror (error_number);
03493 if (msg == NULL)
03494 msg = "unknown";
03495
03496 return msg;
03497 #endif //DBUS_WINCE
03498 }
03499
03507 void
03508 _dbus_win_set_error_from_win_error (DBusError *error,
03509 int code)
03510 {
03511 char *msg;
03512
03513
03514 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
03515 FORMAT_MESSAGE_IGNORE_INSERTS |
03516 FORMAT_MESSAGE_FROM_SYSTEM,
03517 NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
03518 (LPSTR) &msg, 0, NULL);
03519 if (msg)
03520 {
03521 char *msg_copy;
03522
03523 msg_copy = dbus_malloc (strlen (msg));
03524 strcpy (msg_copy, msg);
03525 LocalFree (msg);
03526
03527 dbus_set_error (error, "win32.error", "%s", msg_copy);
03528 }
03529 else
03530 dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code);
03531 }
03532
03533 void
03534 _dbus_win_warn_win_error (const char *message,
03535 int code)
03536 {
03537 DBusError error;
03538
03539 dbus_error_init (&error);
03540 _dbus_win_set_error_from_win_error (&error, code);
03541 _dbus_warn ("%s: %s\n", message, error.message);
03542 dbus_error_free (&error);
03543 }
03544
03552 dbus_bool_t
03553 _dbus_delete_directory (const DBusString *filename,
03554 DBusError *error)
03555 {
03556 const char *filename_c;
03557
03558 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03559
03560 filename_c = _dbus_string_get_const_data (filename);
03561
03562 if (RemoveDirectoryA (filename_c) == 0)
03563 {
03564 char *emsg = _dbus_win_error_string (GetLastError ());
03565 dbus_set_error (error, _dbus_win_error_from_last_error (),
03566 "Failed to remove directory %s: %s",
03567 filename_c, emsg);
03568 _dbus_win_free_error_string (emsg);
03569 return FALSE;
03570 }
03571
03572 return TRUE;
03573 }
03574
03576
03577