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 static dbus_bool_t
02059 _dbus_get_install_root(char *prefix, int len);
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 dbus_bool_t
02546 _dbus_get_install_root(char *prefix, int len);
02547
02548 static dbus_bool_t
02549 _dbus_get_install_root_as_hash(DBusString *out)
02550 {
02551 DBusString install_path;
02552
02553 char path[MAX_PATH*2];
02554 int path_size = sizeof(path);
02555
02556 if (!_dbus_get_install_root(path,path_size))
02557 return FALSE;
02558
02559 _dbus_string_init(&install_path);
02560 _dbus_string_append(&install_path,path);
02561
02562 _dbus_string_init(out);
02563 _dbus_string_tolower_ascii(&install_path,0,_dbus_string_get_length(&install_path));
02564
02565 if (!_dbus_sha_compute (&install_path, out))
02566 return FALSE;
02567
02568 return TRUE;
02569 }
02570
02571 static dbus_bool_t
02572 _dbus_get_address_string (DBusString *out, const char *basestring, const char *scope)
02573 {
02574 _dbus_string_init(out);
02575 _dbus_string_append(out,basestring);
02576
02577 if (!scope)
02578 {
02579 return TRUE;
02580 }
02581 else if (strcmp(scope,"*install-path") == 0
02582
02583 || strcmp(scope,"install-path") == 0)
02584 {
02585 DBusString temp;
02586 if (!_dbus_get_install_root_as_hash(&temp))
02587 {
02588 _dbus_string_free(out);
02589 return FALSE;
02590 }
02591 _dbus_string_append(out,"-");
02592 _dbus_string_append(out,_dbus_string_get_const_data(&temp));
02593 _dbus_string_free(&temp);
02594 }
02595 else if (strcmp(scope,"*user") == 0)
02596 {
02597 _dbus_string_append(out,"-");
02598 if (!_dbus_append_user_from_current_process(out))
02599 {
02600 _dbus_string_free(out);
02601 return FALSE;
02602 }
02603 }
02604 else if (strlen(scope) > 0)
02605 {
02606 _dbus_string_append(out,"-");
02607 _dbus_string_append(out,scope);
02608 return TRUE;
02609 }
02610 return TRUE;
02611 }
02612
02613 static dbus_bool_t
02614 _dbus_get_shm_name (DBusString *out,const char *scope)
02615 {
02616 return _dbus_get_address_string (out,cDBusDaemonAddressInfo,scope);
02617 }
02618
02619 static dbus_bool_t
02620 _dbus_get_mutex_name (DBusString *out,const char *scope)
02621 {
02622 return _dbus_get_address_string (out,cDBusDaemonMutex,scope);
02623 }
02624
02625 dbus_bool_t
02626 _dbus_daemon_is_session_bus_address_published (const char *scope)
02627 {
02628 HANDLE lock;
02629 HANDLE mutex;
02630 DBusString mutex_name;
02631 DWORD ret;
02632
02633 if (!_dbus_get_mutex_name(&mutex_name,scope))
02634 {
02635 _dbus_string_free( &mutex_name );
02636 return FALSE;
02637 }
02638
02639 if (hDBusDaemonMutex)
02640 return TRUE;
02641
02642
02643 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02644
02645
02646
02647 hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02648
02649 _dbus_global_unlock( lock );
02650
02651 _dbus_string_free( &mutex_name );
02652
02653 if (hDBusDaemonMutex == NULL)
02654 return FALSE;
02655 if (GetLastError() == ERROR_ALREADY_EXISTS)
02656 {
02657 CloseHandle(hDBusDaemonMutex);
02658 hDBusDaemonMutex = NULL;
02659 return TRUE;
02660 }
02661
02662
02663
02664 return FALSE;
02665 }
02666
02667 dbus_bool_t
02668 _dbus_daemon_publish_session_bus_address (const char* address, const char *scope)
02669 {
02670 HANDLE lock;
02671 char *shared_addr = NULL;
02672 DWORD ret;
02673 char addressInfo[1024];
02674 DBusString shm_name;
02675 DBusString mutex_name;
02676
02677 _dbus_assert (address);
02678
02679 if (!_dbus_get_mutex_name(&mutex_name,scope))
02680 {
02681 _dbus_string_free( &mutex_name );
02682 return FALSE;
02683 }
02684
02685
02686 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02687
02688 if (!hDBusDaemonMutex)
02689 {
02690 hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02691 }
02692 _dbus_string_free( &mutex_name );
02693
02694 if (!_dbus_get_shm_name(&shm_name,scope))
02695 {
02696 _dbus_string_free( &shm_name );
02697 _dbus_global_unlock( lock );
02698 return FALSE;
02699 }
02700
02701
02702 hDBusSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
02703 0, strlen( address ) + 1, _dbus_string_get_const_data(&shm_name) );
02704 _dbus_assert( hDBusSharedMem );
02705
02706 shared_addr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
02707
02708 _dbus_assert (shared_addr);
02709
02710 strcpy( shared_addr, address);
02711
02712
02713 UnmapViewOfFile( shared_addr );
02714
02715 _dbus_global_unlock( lock );
02716 _dbus_verbose( "published session bus address at %s\n",_dbus_string_get_const_data (&shm_name) );
02717
02718 _dbus_string_free( &shm_name );
02719 return TRUE;
02720 }
02721
02722 void
02723 _dbus_daemon_unpublish_session_bus_address (void)
02724 {
02725 HANDLE lock;
02726
02727
02728 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02729
02730 CloseHandle( hDBusSharedMem );
02731
02732 hDBusSharedMem = NULL;
02733
02734 ReleaseMutex( hDBusDaemonMutex );
02735
02736 CloseHandle( hDBusDaemonMutex );
02737
02738 hDBusDaemonMutex = NULL;
02739
02740 _dbus_global_unlock( lock );
02741 }
02742
02743 static dbus_bool_t
02744 _dbus_get_autolaunch_shm (DBusString *address, DBusString *shm_name)
02745 {
02746 HANDLE sharedMem;
02747 char *shared_addr;
02748 int i;
02749
02750
02751 for(i=0;i<20;++i) {
02752
02753 sharedMem = OpenFileMappingA( FILE_MAP_READ, FALSE, _dbus_string_get_const_data(shm_name));
02754 if( sharedMem == 0 )
02755 Sleep( 100 );
02756 if ( sharedMem != 0)
02757 break;
02758 }
02759
02760 if( sharedMem == 0 )
02761 return FALSE;
02762
02763 shared_addr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
02764
02765 if( !shared_addr )
02766 return FALSE;
02767
02768 _dbus_string_init( address );
02769
02770 _dbus_string_append( address, shared_addr );
02771
02772
02773 UnmapViewOfFile( shared_addr );
02774
02775 CloseHandle( sharedMem );
02776
02777 return TRUE;
02778 }
02779
02780 static dbus_bool_t
02781 _dbus_daemon_already_runs (DBusString *address, DBusString *shm_name, const char *scope)
02782 {
02783 HANDLE lock;
02784 HANDLE daemon;
02785 DBusString mutex_name;
02786 dbus_bool_t bRet = TRUE;
02787
02788 if (!_dbus_get_mutex_name(&mutex_name,scope))
02789 {
02790 _dbus_string_free( &mutex_name );
02791 return FALSE;
02792 }
02793
02794
02795 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02796
02797
02798 daemon = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02799 if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT)
02800 {
02801 ReleaseMutex (daemon);
02802 CloseHandle (daemon);
02803
02804 _dbus_global_unlock( lock );
02805 _dbus_string_free( &mutex_name );
02806 return FALSE;
02807 }
02808
02809
02810 bRet = _dbus_get_autolaunch_shm( address, shm_name );
02811
02812
02813 CloseHandle ( daemon );
02814
02815 _dbus_global_unlock( lock );
02816 _dbus_string_free( &mutex_name );
02817
02818 return bRet;
02819 }
02820
02821 dbus_bool_t
02822 _dbus_get_autolaunch_address (const char *scope, DBusString *address,
02823 DBusError *error)
02824 {
02825 HANDLE mutex;
02826 STARTUPINFOA si;
02827 PROCESS_INFORMATION pi;
02828 dbus_bool_t retval = FALSE;
02829 LPSTR lpFile;
02830 char dbus_exe_path[MAX_PATH];
02831 char dbus_args[MAX_PATH * 2];
02832 const char * daemon_name = DBUS_DAEMON_NAME ".exe";
02833 DBusString shm_name;
02834
02835 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02836
02837 if (!_dbus_get_shm_name(&shm_name,scope))
02838 {
02839 dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not determine shm name");
02840 return FALSE;
02841 }
02842
02843 mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
02844
02845 if (_dbus_daemon_already_runs(address,&shm_name,scope))
02846 {
02847 _dbus_verbose( "found running dbus daemon at %s\n",
02848 _dbus_string_get_const_data (&shm_name) );
02849 retval = TRUE;
02850 goto out;
02851 }
02852
02853 if (!SearchPathA(NULL, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
02854 {
02855 printf ("please add the path to %s to your PATH environment variable\n", daemon_name);
02856 printf ("or start the daemon manually\n\n");
02857 goto out;
02858 }
02859
02860
02861 ZeroMemory( &si, sizeof(si) );
02862 si.cb = sizeof(si);
02863 ZeroMemory( &pi, sizeof(pi) );
02864
02865 _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path, " --session");
02866
02867
02868
02869 if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
02870 {
02871 CloseHandle (pi.hThread);
02872 CloseHandle (pi.hProcess);
02873 retval = _dbus_get_autolaunch_shm( address, &shm_name );
02874 if (retval == FALSE)
02875 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to get autolaunch address from launched dbus-daemon");
02876 }
02877 else
02878 {
02879 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to launch dbus-daemon");
02880 retval = FALSE;
02881 }
02882
02883 out:
02884 if (retval)
02885 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02886 else
02887 _DBUS_ASSERT_ERROR_IS_SET (error);
02888
02889 _dbus_global_unlock (mutex);
02890
02891 return retval;
02892 }
02893
02894
02901 dbus_bool_t
02902 _dbus_make_file_world_readable(const DBusString *filename,
02903 DBusError *error)
02904 {
02905
02906 return TRUE;
02907 }
02908
02915 static const char *
02916 _dbus_windows_get_datadir (void)
02917 {
02918 return _dbus_replace_install_prefix(DBUS_DATADIR);
02919 }
02920
02921 #undef DBUS_DATADIR
02922 #define DBUS_DATADIR _dbus_windows_get_datadir ()
02923
02924
02925 #define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
02926 #define DBUS_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
02927
02944 dbus_bool_t
02945 _dbus_get_standard_session_servicedirs (DBusList **dirs)
02946 {
02947 const char *common_progs;
02948 DBusString servicedir_path;
02949
02950 if (!_dbus_string_init (&servicedir_path))
02951 return FALSE;
02952
02953 #ifdef DBUS_WINCE
02954 {
02955
02956 const char *data_dir = _dbus_getenv ("DBUS_DATADIR");
02957
02958 if (data_dir != NULL)
02959 {
02960 if (!_dbus_string_append (&servicedir_path, data_dir))
02961 goto oom;
02962
02963 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
02964 goto oom;
02965 }
02966 }
02967 #else
02968
02969
02970
02971
02972 #ifdef DBUS_WIN
02973 {
02974 DBusString p;
02975
02976 _dbus_string_init_const (&p, DBUS_DATADIR);
02977
02978 if (!_dbus_path_is_absolute (&p))
02979 {
02980 char install_root[1000];
02981 if (_dbus_get_install_root (install_root, sizeof(install_root)))
02982 if (!_dbus_string_append (&servicedir_path, install_root))
02983 goto oom;
02984 }
02985 }
02986 #endif
02987 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
02988 goto oom;
02989
02990 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
02991 goto oom;
02992 #endif
02993
02994 common_progs = _dbus_getenv ("CommonProgramFiles");
02995
02996 if (common_progs != NULL)
02997 {
02998 if (!_dbus_string_append (&servicedir_path, common_progs))
02999 goto oom;
03000
03001 if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
03002 goto oom;
03003 }
03004
03005 if (!_dbus_split_paths_and_append (&servicedir_path,
03006 DBUS_STANDARD_SESSION_SERVICEDIR,
03007 dirs))
03008 goto oom;
03009
03010 _dbus_string_free (&servicedir_path);
03011 return TRUE;
03012
03013 oom:
03014 _dbus_string_free (&servicedir_path);
03015 return FALSE;
03016 }
03017
03036 dbus_bool_t
03037 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03038 {
03039 *dirs = NULL;
03040 return TRUE;
03041 }
03042
03043 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
03044
03052 dbus_int32_t
03053 _dbus_atomic_inc (DBusAtomic *atomic)
03054 {
03055
03056
03057 return InterlockedIncrement (&atomic->value) - 1;
03058 }
03059
03067 dbus_int32_t
03068 _dbus_atomic_dec (DBusAtomic *atomic)
03069 {
03070
03071
03072 return InterlockedDecrement (&atomic->value) + 1;
03073 }
03074
03082 void
03083 _dbus_flush_caches (void)
03084 {
03085 }
03086
03093 dbus_bool_t
03094 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03095 {
03096 return errno == WSAEWOULDBLOCK;
03097 }
03098
03106 static dbus_bool_t
03107 _dbus_get_install_root(char *prefix, int len)
03108 {
03109
03110 char* p = 0;
03111 int i;
03112 DWORD pathLength;
03113 char *lastSlash;
03114 SetLastError( 0 );
03115 pathLength = GetModuleFileNameA(_dbus_win_get_dll_hmodule(), prefix, len);
03116 if ( pathLength == 0 || GetLastError() != 0 ) {
03117 *prefix = '\0';
03118 return FALSE;
03119 }
03120 lastSlash = _mbsrchr(prefix, '\\');
03121 if (lastSlash == NULL) {
03122 *prefix = '\0';
03123 return FALSE;
03124 }
03125
03126 lastSlash[1] = 0;
03127
03128
03129
03130
03131
03132
03133
03134 if (lastSlash - prefix >= 4 && strnicmp(lastSlash - 4, "\\bin", 4) == 0)
03135 lastSlash[-3] = 0;
03136 else if (lastSlash - prefix >= 10 && strnicmp(lastSlash - 10, "\\bin\\debug", 10) == 0)
03137 lastSlash[-9] = 0;
03138 else if (lastSlash - prefix >= 12 && strnicmp(lastSlash - 12, "\\bin\\release", 12) == 0)
03139 lastSlash[-11] = 0;
03140
03141 return TRUE;
03142 }
03143
03157 dbus_bool_t
03158 _dbus_get_config_file_name(DBusString *config_file, char *s)
03159 {
03160 char path[MAX_PATH*2];
03161 int path_size = sizeof(path);
03162
03163 if (!_dbus_get_install_root(path,path_size))
03164 return FALSE;
03165
03166 if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
03167 return FALSE;
03168 strcat(path,"etc\\");
03169 strcat(path,s);
03170 if (_dbus_file_exists(path))
03171 {
03172
03173 if (!_dbus_string_append (config_file, path))
03174 return FALSE;
03175 }
03176 else
03177 {
03178 if (!_dbus_get_install_root(path,path_size))
03179 return FALSE;
03180 if(strlen(s) + 11 + strlen(path) > sizeof(path)-2)
03181 return FALSE;
03182 strcat(path,"etc\\dbus-1\\");
03183 strcat(path,s);
03184
03185 if (_dbus_file_exists(path))
03186 {
03187 if (!_dbus_string_append (config_file, path))
03188 return FALSE;
03189 }
03190 else
03191 {
03192 if (!_dbus_get_install_root(path,path_size))
03193 return FALSE;
03194 if(strlen(s) + 4 + strlen(path) > sizeof(path)-2)
03195 return FALSE;
03196 strcat(path,"bus\\");
03197 strcat(path,s);
03198
03199 if (_dbus_file_exists(path))
03200 {
03201 if (!_dbus_string_append (config_file, path))
03202 return FALSE;
03203 }
03204 }
03205 }
03206 return TRUE;
03207 }
03208
03217 dbus_bool_t
03218 _dbus_append_system_config_file (DBusString *str)
03219 {
03220 return _dbus_get_config_file_name(str, "system.conf");
03221 }
03222
03229 dbus_bool_t
03230 _dbus_append_session_config_file (DBusString *str)
03231 {
03232 return _dbus_get_config_file_name(str, "session.conf");
03233 }
03234
03235
03236 dbus_bool_t
03237 _dbus_lookup_session_address (dbus_bool_t *supported,
03238 DBusString *address,
03239 DBusError *error)
03240 {
03241
03242 *supported = FALSE;
03243 return TRUE;
03244 }
03245
03259 dbus_bool_t
03260 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03261 DBusCredentials *credentials)
03262 {
03263 DBusString homedir;
03264 DBusString dotdir;
03265 dbus_uid_t uid;
03266 const char *homepath;
03267 const char *homedrive;
03268
03269 _dbus_assert (credentials != NULL);
03270 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03271
03272 if (!_dbus_string_init (&homedir))
03273 return FALSE;
03274
03275 homedrive = _dbus_getenv("HOMEDRIVE");
03276 if (homedrive != NULL && *homedrive != '\0')
03277 {
03278 _dbus_string_append(&homedir,homedrive);
03279 }
03280
03281 homepath = _dbus_getenv("HOMEPATH");
03282 if (homepath != NULL && *homepath != '\0')
03283 {
03284 _dbus_string_append(&homedir,homepath);
03285 }
03286
03287 #ifdef DBUS_BUILD_TESTS
03288 {
03289 const char *override;
03290
03291 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03292 if (override != NULL && *override != '\0')
03293 {
03294 _dbus_string_set_length (&homedir, 0);
03295 if (!_dbus_string_append (&homedir, override))
03296 goto failed;
03297
03298 _dbus_verbose ("Using fake homedir for testing: %s\n",
03299 _dbus_string_get_const_data (&homedir));
03300 }
03301 else
03302 {
03303 static dbus_bool_t already_warned = FALSE;
03304 if (!already_warned)
03305 {
03306 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03307 already_warned = TRUE;
03308 }
03309 }
03310 }
03311 #endif
03312
03313 #ifdef DBUS_WINCE
03314
03315
03316 #define KEYRING_DIR "dbus-keyrings"
03317 #else
03318 #define KEYRING_DIR ".dbus-keyrings"
03319 #endif
03320
03321 _dbus_string_init_const (&dotdir, KEYRING_DIR);
03322 if (!_dbus_concat_dir_and_file (&homedir,
03323 &dotdir))
03324 goto failed;
03325
03326 if (!_dbus_string_copy (&homedir, 0,
03327 directory, _dbus_string_get_length (directory))) {
03328 goto failed;
03329 }
03330
03331 _dbus_string_free (&homedir);
03332 return TRUE;
03333
03334 failed:
03335 _dbus_string_free (&homedir);
03336 return FALSE;
03337 }
03338
03344 dbus_bool_t
03345 _dbus_file_exists (const char *file)
03346 {
03347 DWORD attributes = GetFileAttributesA (file);
03348
03349 if (attributes != INVALID_FILE_ATTRIBUTES && GetLastError() != ERROR_PATH_NOT_FOUND)
03350 return TRUE;
03351 else
03352 return FALSE;
03353 }
03354
03362 const char*
03363 _dbus_strerror (int error_number)
03364 {
03365 #ifdef DBUS_WINCE
03366
03367 return "unknown";
03368 #else
03369 const char *msg;
03370
03371 switch (error_number)
03372 {
03373 case WSAEINTR:
03374 return "Interrupted function call";
03375 case WSAEACCES:
03376 return "Permission denied";
03377 case WSAEFAULT:
03378 return "Bad address";
03379 case WSAEINVAL:
03380 return "Invalid argument";
03381 case WSAEMFILE:
03382 return "Too many open files";
03383 case WSAEWOULDBLOCK:
03384 return "Resource temporarily unavailable";
03385 case WSAEINPROGRESS:
03386 return "Operation now in progress";
03387 case WSAEALREADY:
03388 return "Operation already in progress";
03389 case WSAENOTSOCK:
03390 return "Socket operation on nonsocket";
03391 case WSAEDESTADDRREQ:
03392 return "Destination address required";
03393 case WSAEMSGSIZE:
03394 return "Message too long";
03395 case WSAEPROTOTYPE:
03396 return "Protocol wrong type for socket";
03397 case WSAENOPROTOOPT:
03398 return "Bad protocol option";
03399 case WSAEPROTONOSUPPORT:
03400 return "Protocol not supported";
03401 case WSAESOCKTNOSUPPORT:
03402 return "Socket type not supported";
03403 case WSAEOPNOTSUPP:
03404 return "Operation not supported";
03405 case WSAEPFNOSUPPORT:
03406 return "Protocol family not supported";
03407 case WSAEAFNOSUPPORT:
03408 return "Address family not supported by protocol family";
03409 case WSAEADDRINUSE:
03410 return "Address already in use";
03411 case WSAEADDRNOTAVAIL:
03412 return "Cannot assign requested address";
03413 case WSAENETDOWN:
03414 return "Network is down";
03415 case WSAENETUNREACH:
03416 return "Network is unreachable";
03417 case WSAENETRESET:
03418 return "Network dropped connection on reset";
03419 case WSAECONNABORTED:
03420 return "Software caused connection abort";
03421 case WSAECONNRESET:
03422 return "Connection reset by peer";
03423 case WSAENOBUFS:
03424 return "No buffer space available";
03425 case WSAEISCONN:
03426 return "Socket is already connected";
03427 case WSAENOTCONN:
03428 return "Socket is not connected";
03429 case WSAESHUTDOWN:
03430 return "Cannot send after socket shutdown";
03431 case WSAETIMEDOUT:
03432 return "Connection timed out";
03433 case WSAECONNREFUSED:
03434 return "Connection refused";
03435 case WSAEHOSTDOWN:
03436 return "Host is down";
03437 case WSAEHOSTUNREACH:
03438 return "No route to host";
03439 case WSAEPROCLIM:
03440 return "Too many processes";
03441 case WSAEDISCON:
03442 return "Graceful shutdown in progress";
03443 case WSATYPE_NOT_FOUND:
03444 return "Class type not found";
03445 case WSAHOST_NOT_FOUND:
03446 return "Host not found";
03447 case WSATRY_AGAIN:
03448 return "Nonauthoritative host not found";
03449 case WSANO_RECOVERY:
03450 return "This is a nonrecoverable error";
03451 case WSANO_DATA:
03452 return "Valid name, no data record of requested type";
03453 case WSA_INVALID_HANDLE:
03454 return "Specified event object handle is invalid";
03455 case WSA_INVALID_PARAMETER:
03456 return "One or more parameters are invalid";
03457 case WSA_IO_INCOMPLETE:
03458 return "Overlapped I/O event object not in signaled state";
03459 case WSA_IO_PENDING:
03460 return "Overlapped operations will complete later";
03461 case WSA_NOT_ENOUGH_MEMORY:
03462 return "Insufficient memory available";
03463 case WSA_OPERATION_ABORTED:
03464 return "Overlapped operation aborted";
03465 #ifdef WSAINVALIDPROCTABLE
03466
03467 case WSAINVALIDPROCTABLE:
03468 return "Invalid procedure table from service provider";
03469 #endif
03470 #ifdef WSAINVALIDPROVIDER
03471
03472 case WSAINVALIDPROVIDER:
03473 return "Invalid service provider version number";
03474 #endif
03475 #ifdef WSAPROVIDERFAILEDINIT
03476
03477 case WSAPROVIDERFAILEDINIT:
03478 return "Unable to initialize a service provider";
03479 #endif
03480
03481 case WSASYSCALLFAILURE:
03482 return "System call failure";
03483 }
03484 msg = strerror (error_number);
03485 if (msg == NULL)
03486 msg = "unknown";
03487
03488 return msg;
03489 #endif //DBUS_WINCE
03490 }
03491
03499 void
03500 _dbus_win_set_error_from_win_error (DBusError *error,
03501 int code)
03502 {
03503 char *msg;
03504
03505
03506 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
03507 FORMAT_MESSAGE_IGNORE_INSERTS |
03508 FORMAT_MESSAGE_FROM_SYSTEM,
03509 NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
03510 (LPSTR) &msg, 0, NULL);
03511 if (msg)
03512 {
03513 char *msg_copy;
03514
03515 msg_copy = dbus_malloc (strlen (msg));
03516 strcpy (msg_copy, msg);
03517 LocalFree (msg);
03518
03519 dbus_set_error (error, "win32.error", "%s", msg_copy);
03520 }
03521 else
03522 dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code);
03523 }
03524
03525 void
03526 _dbus_win_warn_win_error (const char *message,
03527 int code)
03528 {
03529 DBusError error;
03530
03531 dbus_error_init (&error);
03532 _dbus_win_set_error_from_win_error (&error, code);
03533 _dbus_warn ("%s: %s\n", message, error.message);
03534 dbus_error_free (&error);
03535 }
03536
03544 dbus_bool_t
03545 _dbus_delete_directory (const DBusString *filename,
03546 DBusError *error)
03547 {
03548 const char *filename_c;
03549
03550 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03551
03552 filename_c = _dbus_string_get_const_data (filename);
03553
03554 if (RemoveDirectoryA (filename_c) == 0)
03555 {
03556 char *emsg = _dbus_win_error_string (GetLastError ());
03557 dbus_set_error (error, _dbus_win_error_from_last_error (),
03558 "Failed to remove directory %s: %s",
03559 filename_c, emsg);
03560 _dbus_win_free_error_string (emsg);
03561 return FALSE;
03562 }
03563
03564 return TRUE;
03565 }
03566
03568
03569