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 <wincrypt.h>
00056 #include <iphlpapi.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 #include <stdlib.h>
00064
00065 #include <string.h>
00066 #if HAVE_ERRNO_H
00067 #include <errno.h>
00068 #endif
00069 #ifndef DBUS_WINCE
00070 #include <mbstring.h>
00071 #include <sys/stat.h>
00072 #include <sys/types.h>
00073 #endif
00074
00075 #ifdef HAVE_WS2TCPIP_H
00076
00077 #include <ws2tcpip.h>
00078 #endif
00079
00080 #ifndef O_BINARY
00081 #define O_BINARY 0
00082 #endif
00083
00084 #ifndef PROCESS_QUERY_LIMITED_INFORMATION
00085
00086 #define PROCESS_QUERY_LIMITED_INFORMATION (0x1000)
00087 #endif
00088
00089 typedef int socklen_t;
00090
00091
00092 void
00093 _dbus_win_set_errno (int err)
00094 {
00095 #ifdef DBUS_WINCE
00096 SetLastError (err);
00097 #else
00098 errno = err;
00099 #endif
00100 }
00101
00102 static BOOL is_winxp_sp3_or_lower();
00103
00104
00105
00106
00107
00108 typedef MIB_TCPROW_OWNER_PID _MIB_TCPROW_EX;
00109 typedef MIB_TCPTABLE_OWNER_PID MIB_TCPTABLE_EX;
00110 typedef PMIB_TCPTABLE_OWNER_PID PMIB_TCPTABLE_EX;
00111 typedef DWORD (WINAPI *ProcAllocateAndGetTcpExtTableFromStack)(PMIB_TCPTABLE_EX*,BOOL,HANDLE,DWORD,DWORD);
00112 static ProcAllocateAndGetTcpExtTableFromStack lpfnAllocateAndGetTcpExTableFromStack = NULL;
00113
00119 static BOOL
00120 load_ex_ip_helper_procedures(void)
00121 {
00122 HMODULE hModule = LoadLibrary ("iphlpapi.dll");
00123 if (hModule == NULL)
00124 {
00125 _dbus_verbose ("could not load iphlpapi.dll\n");
00126 return FALSE;
00127 }
00128
00129 lpfnAllocateAndGetTcpExTableFromStack = (ProcAllocateAndGetTcpExtTableFromStack)GetProcAddress (hModule, "AllocateAndGetTcpExTableFromStack");
00130 if (lpfnAllocateAndGetTcpExTableFromStack == NULL)
00131 {
00132 _dbus_verbose ("could not find function AllocateAndGetTcpExTableFromStack in iphlpapi.dll\n");
00133 return FALSE;
00134 }
00135 return TRUE;
00136 }
00137
00144 static dbus_pid_t
00145 get_pid_from_extended_tcp_table(int peer_port)
00146 {
00147 dbus_pid_t result;
00148 DWORD errorCode, size = 0, i;
00149 MIB_TCPTABLE_OWNER_PID *tcp_table;
00150
00151 if ((errorCode =
00152 GetExtendedTcpTable (NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0)) == ERROR_INSUFFICIENT_BUFFER)
00153 {
00154 tcp_table = (MIB_TCPTABLE_OWNER_PID *) dbus_malloc (size);
00155 if (tcp_table == NULL)
00156 {
00157 _dbus_verbose ("Error allocating memory\n");
00158 return 0;
00159 }
00160 }
00161 else
00162 {
00163 _dbus_win_warn_win_error ("unexpected error returned from GetExtendedTcpTable", errorCode);
00164 return 0;
00165 }
00166
00167 if ((errorCode = GetExtendedTcpTable (tcp_table, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0)) != NO_ERROR)
00168 {
00169 _dbus_verbose ("Error fetching tcp table %d\n", (int)errorCode);
00170 dbus_free (tcp_table);
00171 return 0;
00172 }
00173
00174 result = 0;
00175 for (i = 0; i < tcp_table->dwNumEntries; i++)
00176 {
00177 MIB_TCPROW_OWNER_PID *p = &tcp_table->table[i];
00178 int local_address = ntohl (p->dwLocalAddr);
00179 int local_port = ntohs (p->dwLocalPort);
00180 if (p->dwState == MIB_TCP_STATE_ESTAB
00181 && local_address == INADDR_LOOPBACK && local_port == peer_port)
00182 result = p->dwOwningPid;
00183 }
00184
00185 dbus_free (tcp_table);
00186 _dbus_verbose ("got pid %lu\n", result);
00187 return result;
00188 }
00189
00197 static dbus_pid_t
00198 get_pid_from_tcp_ex_table(int peer_port)
00199 {
00200 dbus_pid_t result;
00201 DWORD errorCode, i;
00202 PMIB_TCPTABLE_EX tcp_table = NULL;
00203
00204 if (!load_ex_ip_helper_procedures ())
00205 {
00206 _dbus_verbose
00207 ("Error not been able to load iphelper procedures\n");
00208 return 0;
00209 }
00210
00211 errorCode = lpfnAllocateAndGetTcpExTableFromStack (&tcp_table, TRUE, GetProcessHeap(), 0, 2);
00212
00213 if (errorCode != NO_ERROR)
00214 {
00215 _dbus_verbose
00216 ("Error not been able to call AllocateAndGetTcpExTableFromStack()\n");
00217 return 0;
00218 }
00219
00220 result = 0;
00221 for (i = 0; i < tcp_table->dwNumEntries; i++)
00222 {
00223 _MIB_TCPROW_EX *p = &tcp_table->table[i];
00224 int local_port = ntohs (p->dwLocalPort);
00225 int local_address = ntohl (p->dwLocalAddr);
00226 if (local_address == INADDR_LOOPBACK && local_port == peer_port)
00227 {
00228 result = p->dwOwningPid;
00229 break;
00230 }
00231 }
00232
00233 HeapFree (GetProcessHeap(), 0, tcp_table);
00234 _dbus_verbose ("got pid %lu\n", result);
00235 return result;
00236 }
00237
00243 static dbus_pid_t
00244 _dbus_get_peer_pid_from_tcp_handle (int handle)
00245 {
00246 struct sockaddr_storage addr;
00247 socklen_t len = sizeof (addr);
00248 int peer_port;
00249
00250 dbus_pid_t result;
00251 dbus_bool_t is_localhost = FALSE;
00252
00253 getpeername (handle, (struct sockaddr *) &addr, &len);
00254
00255 if (addr.ss_family == AF_INET)
00256 {
00257 struct sockaddr_in *s = (struct sockaddr_in *) &addr;
00258 peer_port = ntohs (s->sin_port);
00259 is_localhost = (ntohl (s->sin_addr.s_addr) == INADDR_LOOPBACK);
00260 }
00261 else if (addr.ss_family == AF_INET6)
00262 {
00263 _dbus_verbose ("FIXME [61922]: IPV6 support not working on windows\n");
00264 return 0;
00265
00266
00267
00268
00269
00270
00271 }
00272 else
00273 {
00274 _dbus_verbose ("no idea what address family %d is\n", addr.ss_family);
00275 return 0;
00276 }
00277
00278 if (!is_localhost)
00279 {
00280 _dbus_verbose ("could not fetch process id from remote process\n");
00281 return 0;
00282 }
00283
00284 if (peer_port == 0)
00285 {
00286 _dbus_verbose
00287 ("Error not been able to fetch tcp peer port from connection\n");
00288 return 0;
00289 }
00290
00291 _dbus_verbose ("trying to get peer's pid\n");
00292
00293 result = get_pid_from_extended_tcp_table (peer_port);
00294 if (result > 0)
00295 return result;
00296 result = get_pid_from_tcp_ex_table (peer_port);
00297 return result;
00298 }
00299
00300
00301 const char*
00302 _dbus_win_error_from_last_error (void)
00303 {
00304 switch (GetLastError())
00305 {
00306 case 0:
00307 return DBUS_ERROR_FAILED;
00308
00309 case ERROR_NO_MORE_FILES:
00310 case ERROR_TOO_MANY_OPEN_FILES:
00311 return DBUS_ERROR_LIMITS_EXCEEDED;
00312
00313 case ERROR_ACCESS_DENIED:
00314 case ERROR_CANNOT_MAKE:
00315 return DBUS_ERROR_ACCESS_DENIED;
00316
00317 case ERROR_NOT_ENOUGH_MEMORY:
00318 return DBUS_ERROR_NO_MEMORY;
00319
00320 case ERROR_FILE_EXISTS:
00321 return DBUS_ERROR_FILE_EXISTS;
00322
00323 case ERROR_FILE_NOT_FOUND:
00324 case ERROR_PATH_NOT_FOUND:
00325 return DBUS_ERROR_FILE_NOT_FOUND;
00326 }
00327
00328 return DBUS_ERROR_FAILED;
00329 }
00330
00331
00332 char*
00333 _dbus_win_error_string (int error_number)
00334 {
00335 char *msg;
00336
00337 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
00338 FORMAT_MESSAGE_IGNORE_INSERTS |
00339 FORMAT_MESSAGE_FROM_SYSTEM,
00340 NULL, error_number, 0,
00341 (LPSTR) &msg, 0, NULL);
00342
00343 if (msg[strlen (msg) - 1] == '\n')
00344 msg[strlen (msg) - 1] = '\0';
00345 if (msg[strlen (msg) - 1] == '\r')
00346 msg[strlen (msg) - 1] = '\0';
00347
00348 return msg;
00349 }
00350
00351 void
00352 _dbus_win_free_error_string (char *string)
00353 {
00354 LocalFree (string);
00355 }
00356
00377 int
00378 _dbus_read_socket (DBusSocket fd,
00379 DBusString *buffer,
00380 int count)
00381 {
00382 int bytes_read;
00383 int start;
00384 char *data;
00385
00386 _dbus_assert (count >= 0);
00387
00388 start = _dbus_string_get_length (buffer);
00389
00390 if (!_dbus_string_lengthen (buffer, count))
00391 {
00392 _dbus_win_set_errno (ENOMEM);
00393 return -1;
00394 }
00395
00396 data = _dbus_string_get_data_len (buffer, start, count);
00397
00398 again:
00399
00400 _dbus_verbose ("recv: count=%d fd=%Iu\n", count, fd.sock);
00401 bytes_read = recv (fd.sock, data, count, 0);
00402
00403 if (bytes_read == SOCKET_ERROR)
00404 {
00405 DBUS_SOCKET_SET_ERRNO();
00406 _dbus_verbose ("recv: failed: %s (%d)\n", _dbus_strerror (errno), errno);
00407 bytes_read = -1;
00408 }
00409 else
00410 _dbus_verbose ("recv: = %d\n", bytes_read);
00411
00412 if (bytes_read < 0)
00413 {
00414 if (errno == EINTR)
00415 goto again;
00416 else
00417 {
00418
00419 _dbus_string_set_length (buffer, start);
00420 return -1;
00421 }
00422 }
00423 else
00424 {
00425
00426 _dbus_string_set_length (buffer, start + bytes_read);
00427
00428 #if 0
00429 if (bytes_read > 0)
00430 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00431 #endif
00432
00433 return bytes_read;
00434 }
00435 }
00436
00447 int
00448 _dbus_write_socket (DBusSocket fd,
00449 const DBusString *buffer,
00450 int start,
00451 int len)
00452 {
00453 const char *data;
00454 int bytes_written;
00455
00456 data = _dbus_string_get_const_data_len (buffer, start, len);
00457
00458 again:
00459
00460 _dbus_verbose ("send: len=%d fd=%Iu\n", len, fd.sock);
00461 bytes_written = send (fd.sock, data, len, 0);
00462
00463 if (bytes_written == SOCKET_ERROR)
00464 {
00465 DBUS_SOCKET_SET_ERRNO();
00466 _dbus_verbose ("send: failed: %s\n", _dbus_strerror_from_errno ());
00467 bytes_written = -1;
00468 }
00469 else
00470 _dbus_verbose ("send: = %d\n", bytes_written);
00471
00472 if (bytes_written < 0 && errno == EINTR)
00473 goto again;
00474
00475 #if 0
00476 if (bytes_written > 0)
00477 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00478 #endif
00479
00480 return bytes_written;
00481 }
00482
00483
00491 dbus_bool_t
00492 _dbus_close_socket (DBusSocket fd,
00493 DBusError *error)
00494 {
00495 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00496
00497 again:
00498 if (closesocket (fd.sock) == SOCKET_ERROR)
00499 {
00500 DBUS_SOCKET_SET_ERRNO ();
00501
00502 if (errno == EINTR)
00503 goto again;
00504
00505 dbus_set_error (error, _dbus_error_from_errno (errno),
00506 "Could not close socket: socket=%Iu, , %s",
00507 fd.sock, _dbus_strerror_from_errno ());
00508 return FALSE;
00509 }
00510 _dbus_verbose ("_dbus_close_socket: socket=%Iu, \n", fd.sock);
00511
00512 return TRUE;
00513 }
00514
00522 static void
00523 _dbus_win_handle_set_close_on_exec (HANDLE handle)
00524 {
00525 if ( !SetHandleInformation( (HANDLE) handle,
00526 HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE,
00527 0 ) )
00528 {
00529 _dbus_win_warn_win_error ("Disabling socket handle inheritance failed:", GetLastError());
00530 }
00531 }
00532
00540 dbus_bool_t
00541 _dbus_set_socket_nonblocking (DBusSocket handle,
00542 DBusError *error)
00543 {
00544 u_long one = 1;
00545
00546 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00547
00548 if (ioctlsocket (handle.sock, FIONBIO, &one) == SOCKET_ERROR)
00549 {
00550 DBUS_SOCKET_SET_ERRNO ();
00551 dbus_set_error (error, _dbus_error_from_errno (errno),
00552 "Failed to set socket %Iu to nonblocking: %s",
00553 handle.sock, _dbus_strerror_from_errno ());
00554 return FALSE;
00555 }
00556
00557 return TRUE;
00558 }
00559
00560
00581 int
00582 _dbus_write_socket_two (DBusSocket fd,
00583 const DBusString *buffer1,
00584 int start1,
00585 int len1,
00586 const DBusString *buffer2,
00587 int start2,
00588 int len2)
00589 {
00590 WSABUF vectors[2];
00591 const char *data1;
00592 const char *data2;
00593 int rc;
00594 DWORD bytes_written;
00595
00596 _dbus_assert (buffer1 != NULL);
00597 _dbus_assert (start1 >= 0);
00598 _dbus_assert (start2 >= 0);
00599 _dbus_assert (len1 >= 0);
00600 _dbus_assert (len2 >= 0);
00601
00602
00603 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00604
00605 if (buffer2 != NULL)
00606 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00607 else
00608 {
00609 data2 = NULL;
00610 start2 = 0;
00611 len2 = 0;
00612 }
00613
00614 vectors[0].buf = (char*) data1;
00615 vectors[0].len = len1;
00616 vectors[1].buf = (char*) data2;
00617 vectors[1].len = len2;
00618
00619 again:
00620
00621 _dbus_verbose ("WSASend: len1+2=%d+%d fd=%Iu\n", len1, len2, fd.sock);
00622 rc = WSASend (fd.sock,
00623 vectors,
00624 data2 ? 2 : 1,
00625 &bytes_written,
00626 0,
00627 NULL,
00628 NULL);
00629
00630 if (rc == SOCKET_ERROR)
00631 {
00632 DBUS_SOCKET_SET_ERRNO ();
00633 _dbus_verbose ("WSASend: failed: %s\n", _dbus_strerror_from_errno ());
00634 bytes_written = -1;
00635 }
00636 else
00637 _dbus_verbose ("WSASend: = %ld\n", bytes_written);
00638
00639 if (bytes_written < 0 && errno == EINTR)
00640 goto again;
00641
00642 return bytes_written;
00643 }
00644
00645 #if 0
00646
00655 int
00656 _dbus_connect_named_pipe (const char *path,
00657 DBusError *error)
00658 {
00659 _dbus_assert_not_reached ("not implemented");
00660 }
00661
00662 #endif
00663
00667 dbus_bool_t
00668 _dbus_win_startup_winsock (void)
00669 {
00670
00671
00672
00673 static dbus_bool_t beenhere = FALSE;
00674
00675 WORD wVersionRequested;
00676 WSADATA wsaData;
00677 int err;
00678
00679 if (!_DBUS_LOCK (sysdeps))
00680 return FALSE;
00681
00682 if (beenhere)
00683 goto out;
00684
00685 wVersionRequested = MAKEWORD (2, 0);
00686
00687 err = WSAStartup (wVersionRequested, &wsaData);
00688 if (err != 0)
00689 {
00690 _dbus_assert_not_reached ("Could not initialize WinSock");
00691 _dbus_abort ();
00692 }
00693
00694
00695
00696
00697
00698
00699 if (LOBYTE (wsaData.wVersion) != 2 ||
00700 HIBYTE (wsaData.wVersion) != 0)
00701 {
00702 _dbus_assert_not_reached ("No usable WinSock found");
00703 _dbus_abort ();
00704 }
00705
00706 beenhere = TRUE;
00707
00708 out:
00709 _DBUS_UNLOCK (sysdeps);
00710 return TRUE;
00711 }
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00730 int _dbus_printf_string_upper_bound (const char *format,
00731 va_list args)
00732 {
00733
00734 char buf[1024];
00735 int bufsize;
00736 int len;
00737 va_list args_copy;
00738
00739 bufsize = sizeof (buf);
00740 DBUS_VA_COPY (args_copy, args);
00741 len = _vsnprintf (buf, bufsize - 1, format, args_copy);
00742 va_end (args_copy);
00743
00744 while (len == -1)
00745 {
00746 char *p;
00747
00748 bufsize *= 2;
00749
00750 p = malloc (bufsize);
00751
00752 if (p == NULL)
00753 return -1;
00754
00755 DBUS_VA_COPY (args_copy, args);
00756 len = _vsnprintf (p, bufsize - 1, format, args_copy);
00757 va_end (args_copy);
00758 free (p);
00759 }
00760
00761 return len;
00762 }
00763
00764
00772 wchar_t *
00773 _dbus_win_utf8_to_utf16 (const char *str,
00774 DBusError *error)
00775 {
00776 DBusString s;
00777 int n;
00778 wchar_t *retval;
00779
00780 _dbus_string_init_const (&s, str);
00781
00782 if (!_dbus_string_validate_utf8 (&s, 0, _dbus_string_get_length (&s)))
00783 {
00784 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid UTF-8");
00785 return NULL;
00786 }
00787
00788 n = MultiByteToWideChar (CP_UTF8, 0, str, -1, NULL, 0);
00789
00790 if (n == 0)
00791 {
00792 _dbus_win_set_error_from_win_error (error, GetLastError ());
00793 return NULL;
00794 }
00795
00796 retval = dbus_new (wchar_t, n);
00797
00798 if (!retval)
00799 {
00800 _DBUS_SET_OOM (error);
00801 return NULL;
00802 }
00803
00804 if (MultiByteToWideChar (CP_UTF8, 0, str, -1, retval, n) != n)
00805 {
00806 dbus_free (retval);
00807 dbus_set_error_const (error, DBUS_ERROR_FAILED, "MultiByteToWideChar inconsistency");
00808 return NULL;
00809 }
00810
00811 return retval;
00812 }
00813
00821 char *
00822 _dbus_win_utf16_to_utf8 (const wchar_t *str,
00823 DBusError *error)
00824 {
00825 int n;
00826 char *retval;
00827
00828 n = WideCharToMultiByte (CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
00829
00830 if (n == 0)
00831 {
00832 _dbus_win_set_error_from_win_error (error, GetLastError ());
00833 return NULL;
00834 }
00835
00836 retval = dbus_malloc (n);
00837
00838 if (!retval)
00839 {
00840 _DBUS_SET_OOM (error);
00841 return NULL;
00842 }
00843
00844 if (WideCharToMultiByte (CP_UTF8, 0, str, -1, retval, n, NULL, NULL) != n)
00845 {
00846 dbus_free (retval);
00847 dbus_set_error_const (error, DBUS_ERROR_FAILED, "WideCharToMultiByte inconsistency");
00848 return NULL;
00849 }
00850
00851 return retval;
00852 }
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864 dbus_bool_t
00865 _dbus_win_account_to_sid (const wchar_t *waccount,
00866 void **ppsid,
00867 DBusError *error)
00868 {
00869 dbus_bool_t retval = FALSE;
00870 DWORD sid_length, wdomain_length;
00871 SID_NAME_USE use;
00872 wchar_t *wdomain;
00873
00874 *ppsid = NULL;
00875
00876 sid_length = 0;
00877 wdomain_length = 0;
00878 if (!LookupAccountNameW (NULL, waccount, NULL, &sid_length,
00879 NULL, &wdomain_length, &use) &&
00880 GetLastError () != ERROR_INSUFFICIENT_BUFFER)
00881 {
00882 _dbus_win_set_error_from_win_error (error, GetLastError ());
00883 return FALSE;
00884 }
00885
00886 *ppsid = dbus_malloc (sid_length);
00887 if (!*ppsid)
00888 {
00889 _DBUS_SET_OOM (error);
00890 return FALSE;
00891 }
00892
00893 wdomain = dbus_new (wchar_t, wdomain_length);
00894 if (!wdomain)
00895 {
00896 _DBUS_SET_OOM (error);
00897 goto out1;
00898 }
00899
00900 if (!LookupAccountNameW (NULL, waccount, (PSID) *ppsid, &sid_length,
00901 wdomain, &wdomain_length, &use))
00902 {
00903 _dbus_win_set_error_from_win_error (error, GetLastError ());
00904 goto out2;
00905 }
00906
00907 if (!IsValidSid ((PSID) *ppsid))
00908 {
00909 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Invalid SID");
00910 goto out2;
00911 }
00912
00913 retval = TRUE;
00914
00915 out2:
00916 dbus_free (wdomain);
00917 out1:
00918 if (!retval)
00919 {
00920 dbus_free (*ppsid);
00921 *ppsid = NULL;
00922 }
00923
00924 return retval;
00925 }
00926
00936 unsigned long
00937 _dbus_pid_for_log (void)
00938 {
00939 return _dbus_getpid ();
00940 }
00941
00942 #ifndef DBUS_WINCE
00943
00944 static BOOL is_winxp_sp3_or_lower()
00945 {
00946 OSVERSIONINFOEX osvi;
00947 DWORDLONG dwlConditionMask = 0;
00948 int op=VER_LESS_EQUAL;
00949
00950
00951
00952 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
00953 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
00954 osvi.dwMajorVersion = 5;
00955 osvi.dwMinorVersion = 1;
00956 osvi.wServicePackMajor = 3;
00957 osvi.wServicePackMinor = 0;
00958
00959
00960
00961 VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, op );
00962 VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION, op );
00963 VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMAJOR, op );
00964 VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMINOR, op );
00965
00966
00967
00968 return VerifyVersionInfo(
00969 &osvi,
00970 VER_MAJORVERSION | VER_MINORVERSION |
00971 VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
00972 dwlConditionMask);
00973 }
00974
00980 dbus_bool_t
00981 _dbus_getsid(char **sid, dbus_pid_t process_id)
00982 {
00983 HANDLE process_token = INVALID_HANDLE_VALUE;
00984 TOKEN_USER *token_user = NULL;
00985 DWORD n;
00986 PSID psid;
00987 int retval = FALSE;
00988
00989 HANDLE process_handle;
00990 if (process_id == 0)
00991 process_handle = GetCurrentProcess();
00992 else if (is_winxp_sp3_or_lower())
00993 process_handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, process_id);
00994 else
00995 process_handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id);
00996
00997 if (!OpenProcessToken (process_handle, TOKEN_QUERY, &process_token))
00998 {
00999 _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ());
01000 goto failed;
01001 }
01002 if ((!GetTokenInformation (process_token, TokenUser, NULL, 0, &n)
01003 && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
01004 || (token_user = alloca (n)) == NULL
01005 || !GetTokenInformation (process_token, TokenUser, token_user, n, &n))
01006 {
01007 _dbus_win_warn_win_error ("GetTokenInformation failed", GetLastError ());
01008 goto failed;
01009 }
01010 psid = token_user->User.Sid;
01011 if (!IsValidSid (psid))
01012 {
01013 _dbus_verbose("%s invalid sid\n",__FUNCTION__);
01014 goto failed;
01015 }
01016 if (!ConvertSidToStringSidA (psid, sid))
01017 {
01018 _dbus_verbose("%s invalid sid\n",__FUNCTION__);
01019 goto failed;
01020 }
01021
01022 retval = TRUE;
01023
01024 failed:
01025 CloseHandle (process_handle);
01026 if (process_token != INVALID_HANDLE_VALUE)
01027 CloseHandle (process_token);
01028
01029 _dbus_verbose("_dbus_getsid() got '%s' and returns %d\n", *sid, retval);
01030 return retval;
01031 }
01032 #endif
01033
01034
01035
01036
01037
01038
01039
01052 dbus_bool_t
01053 _dbus_socketpair (DBusSocket *fd1,
01054 DBusSocket *fd2,
01055 dbus_bool_t blocking,
01056 DBusError *error)
01057 {
01058 SOCKET temp, socket1 = -1, socket2 = -1;
01059 struct sockaddr_in saddr;
01060 int len;
01061 u_long arg;
01062
01063 if (!_dbus_win_startup_winsock ())
01064 {
01065 _DBUS_SET_OOM (error);
01066 return FALSE;
01067 }
01068
01069 temp = socket (AF_INET, SOCK_STREAM, 0);
01070 if (temp == INVALID_SOCKET)
01071 {
01072 DBUS_SOCKET_SET_ERRNO ();
01073 goto out0;
01074 }
01075
01076 _DBUS_ZERO (saddr);
01077 saddr.sin_family = AF_INET;
01078 saddr.sin_port = 0;
01079 saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
01080
01081 if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr)) == SOCKET_ERROR)
01082 {
01083 DBUS_SOCKET_SET_ERRNO ();
01084 goto out0;
01085 }
01086
01087 if (listen (temp, 1) == SOCKET_ERROR)
01088 {
01089 DBUS_SOCKET_SET_ERRNO ();
01090 goto out0;
01091 }
01092
01093 len = sizeof (saddr);
01094 if (getsockname (temp, (struct sockaddr *)&saddr, &len) == SOCKET_ERROR)
01095 {
01096 DBUS_SOCKET_SET_ERRNO ();
01097 goto out0;
01098 }
01099
01100 socket1 = socket (AF_INET, SOCK_STREAM, 0);
01101 if (socket1 == INVALID_SOCKET)
01102 {
01103 DBUS_SOCKET_SET_ERRNO ();
01104 goto out0;
01105 }
01106
01107 if (connect (socket1, (struct sockaddr *)&saddr, len) == SOCKET_ERROR)
01108 {
01109 DBUS_SOCKET_SET_ERRNO ();
01110 goto out1;
01111 }
01112
01113 socket2 = accept (temp, (struct sockaddr *) &saddr, &len);
01114 if (socket2 == INVALID_SOCKET)
01115 {
01116 DBUS_SOCKET_SET_ERRNO ();
01117 goto out1;
01118 }
01119
01120 if (!blocking)
01121 {
01122 arg = 1;
01123 if (ioctlsocket (socket1, FIONBIO, &arg) == SOCKET_ERROR)
01124 {
01125 DBUS_SOCKET_SET_ERRNO ();
01126 goto out2;
01127 }
01128
01129 arg = 1;
01130 if (ioctlsocket (socket2, FIONBIO, &arg) == SOCKET_ERROR)
01131 {
01132 DBUS_SOCKET_SET_ERRNO ();
01133 goto out2;
01134 }
01135 }
01136
01137 fd1->sock = socket1;
01138 fd2->sock = socket2;
01139
01140 _dbus_verbose ("full-duplex pipe %Iu:%Iu <-> %Iu:%Iu\n",
01141 fd1->sock, socket1, fd2->sock, socket2);
01142
01143 closesocket (temp);
01144
01145 return TRUE;
01146
01147 out2:
01148 closesocket (socket2);
01149 out1:
01150 closesocket (socket1);
01151 out0:
01152 closesocket (temp);
01153
01154 dbus_set_error (error, _dbus_error_from_errno (errno),
01155 "Could not setup socket pair: %s",
01156 _dbus_strerror_from_errno ());
01157
01158 return FALSE;
01159 }
01160
01169 int
01170 _dbus_poll (DBusPollFD *fds,
01171 int n_fds,
01172 int timeout_milliseconds)
01173 {
01174 #define USE_CHRIS_IMPL 0
01175
01176 #if USE_CHRIS_IMPL
01177
01178 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
01179 char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
01180 char *msgp;
01181
01182 int ret = 0;
01183 int i;
01184 struct timeval tv;
01185 int ready;
01186
01187 #define DBUS_STACK_WSAEVENTS 256
01188 WSAEVENT eventsOnStack[DBUS_STACK_WSAEVENTS];
01189 WSAEVENT *pEvents = NULL;
01190 if (n_fds > DBUS_STACK_WSAEVENTS)
01191 pEvents = calloc(sizeof(WSAEVENT), n_fds);
01192 else
01193 pEvents = eventsOnStack;
01194
01195
01196 #ifdef DBUS_ENABLE_VERBOSE_MODE
01197 msgp = msg;
01198 msgp += sprintf (msgp, "WSAEventSelect: to=%d\n\t", timeout_milliseconds);
01199 for (i = 0; i < n_fds; i++)
01200 {
01201 DBusPollFD *fdp = &fds[i];
01202
01203
01204 if (fdp->events & _DBUS_POLLIN)
01205 msgp += sprintf (msgp, "R:%Iu ", fdp->fd.sock);
01206
01207 if (fdp->events & _DBUS_POLLOUT)
01208 msgp += sprintf (msgp, "W:%Iu ", fdp->fd.sock);
01209
01210 msgp += sprintf (msgp, "E:%Iu\n\t", fdp->fd.sock);
01211
01212
01213
01214 if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
01215 {
01216 _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
01217 }
01218 }
01219
01220 msgp += sprintf (msgp, "\n");
01221 _dbus_verbose ("%s",msg);
01222 #endif
01223 for (i = 0; i < n_fds; i++)
01224 {
01225 DBusPollFD *fdp = &fds[i];
01226 WSAEVENT ev;
01227 long lNetworkEvents = FD_OOB;
01228
01229 ev = WSACreateEvent();
01230
01231 if (fdp->events & _DBUS_POLLIN)
01232 lNetworkEvents |= FD_READ | FD_ACCEPT | FD_CLOSE;
01233
01234 if (fdp->events & _DBUS_POLLOUT)
01235 lNetworkEvents |= FD_WRITE | FD_CONNECT;
01236
01237 WSAEventSelect(fdp->fd.sock, ev, lNetworkEvents);
01238
01239 pEvents[i] = ev;
01240 }
01241
01242
01243 ready = WSAWaitForMultipleEvents (n_fds, pEvents, FALSE, timeout_milliseconds, FALSE);
01244
01245 if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
01246 {
01247 DBUS_SOCKET_SET_ERRNO ();
01248 if (errno != WSAEWOULDBLOCK)
01249 _dbus_verbose ("WSAWaitForMultipleEvents: failed: %s\n", _dbus_strerror_from_errno ());
01250 ret = -1;
01251 }
01252 else if (ready == WSA_WAIT_TIMEOUT)
01253 {
01254 _dbus_verbose ("WSAWaitForMultipleEvents: WSA_WAIT_TIMEOUT\n");
01255 ret = 0;
01256 }
01257 else if (ready >= WSA_WAIT_EVENT_0 && ready < (int)(WSA_WAIT_EVENT_0 + n_fds))
01258 {
01259 msgp = msg;
01260 msgp += sprintf (msgp, "WSAWaitForMultipleEvents: =%d\n\t", ready);
01261
01262 for (i = 0; i < n_fds; i++)
01263 {
01264 DBusPollFD *fdp = &fds[i];
01265 WSANETWORKEVENTS ne;
01266
01267 fdp->revents = 0;
01268
01269 WSAEnumNetworkEvents(fdp->fd.sock, pEvents[i], &ne);
01270
01271 if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
01272 fdp->revents |= _DBUS_POLLIN;
01273
01274 if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
01275 fdp->revents |= _DBUS_POLLOUT;
01276
01277 if (ne.lNetworkEvents & (FD_OOB))
01278 fdp->revents |= _DBUS_POLLERR;
01279
01280 if (ne.lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
01281 msgp += sprintf (msgp, "R:%Iu ", fdp->fd.sock);
01282
01283 if (ne.lNetworkEvents & (FD_WRITE | FD_CONNECT))
01284 msgp += sprintf (msgp, "W:%Iu ", fdp->fd.sock);
01285
01286 if (ne.lNetworkEvents & (FD_OOB))
01287 msgp += sprintf (msgp, "E:%Iu ", fdp->fd.sock);
01288
01289 msgp += sprintf (msgp, "lNetworkEvents:%d ", ne.lNetworkEvents);
01290
01291 if(ne.lNetworkEvents)
01292 ret++;
01293
01294 WSAEventSelect(fdp->fd.sock, pEvents[i], 0);
01295 }
01296
01297 msgp += sprintf (msgp, "\n");
01298 _dbus_verbose ("%s",msg);
01299 }
01300 else
01301 {
01302 _dbus_verbose ("WSAWaitForMultipleEvents: failed for unknown reason!");
01303 ret = -1;
01304 }
01305
01306 for(i = 0; i < n_fds; i++)
01307 {
01308 WSACloseEvent(pEvents[i]);
01309 }
01310
01311 if (n_fds > DBUS_STACK_WSAEVENTS)
01312 free(pEvents);
01313
01314 return ret;
01315
01316 #else
01317
01318 #define DBUS_POLL_CHAR_BUFFER_SIZE 2000
01319 char msg[DBUS_POLL_CHAR_BUFFER_SIZE];
01320 char *msgp;
01321
01322 fd_set read_set, write_set, err_set;
01323 SOCKET max_fd = 0;
01324 int i;
01325 struct timeval tv;
01326 int ready;
01327
01328 FD_ZERO (&read_set);
01329 FD_ZERO (&write_set);
01330 FD_ZERO (&err_set);
01331
01332
01333 #ifdef DBUS_ENABLE_VERBOSE_MODE
01334 msgp = msg;
01335 msgp += sprintf (msgp, "select: to=%d\n\t", timeout_milliseconds);
01336 for (i = 0; i < n_fds; i++)
01337 {
01338 DBusPollFD *fdp = &fds[i];
01339
01340
01341 if (fdp->events & _DBUS_POLLIN)
01342 msgp += sprintf (msgp, "R:%Iu ", fdp->fd.sock);
01343
01344 if (fdp->events & _DBUS_POLLOUT)
01345 msgp += sprintf (msgp, "W:%Iu ", fdp->fd.sock);
01346
01347 msgp += sprintf (msgp, "E:%Iu\n\t", fdp->fd.sock);
01348
01349
01350
01351 if (msgp >= msg + DBUS_POLL_CHAR_BUFFER_SIZE)
01352 {
01353 _dbus_assert_not_reached ("buffer overflow in _dbus_poll");
01354 }
01355 }
01356
01357 msgp += sprintf (msgp, "\n");
01358 _dbus_verbose ("%s",msg);
01359 #endif
01360 for (i = 0; i < n_fds; i++)
01361 {
01362 DBusPollFD *fdp = &fds[i];
01363
01364 if (fdp->events & _DBUS_POLLIN)
01365 FD_SET (fdp->fd.sock, &read_set);
01366
01367 if (fdp->events & _DBUS_POLLOUT)
01368 FD_SET (fdp->fd.sock, &write_set);
01369
01370 FD_SET (fdp->fd.sock, &err_set);
01371
01372 max_fd = MAX (max_fd, fdp->fd.sock);
01373 }
01374
01375
01376 tv.tv_sec = timeout_milliseconds < 0 ? 1 : timeout_milliseconds / 1000;
01377 tv.tv_usec = timeout_milliseconds < 0 ? 0 : (timeout_milliseconds % 1000) * 1000;
01378
01379 ready = select (max_fd + 1, &read_set, &write_set, &err_set, &tv);
01380
01381 if (DBUS_SOCKET_API_RETURNS_ERROR (ready))
01382 {
01383 DBUS_SOCKET_SET_ERRNO ();
01384 if (errno != WSAEWOULDBLOCK)
01385 _dbus_verbose ("select: failed: %s\n", _dbus_strerror_from_errno ());
01386 }
01387 else if (ready == 0)
01388 _dbus_verbose ("select: = 0\n");
01389 else
01390 if (ready > 0)
01391 {
01392 #ifdef DBUS_ENABLE_VERBOSE_MODE
01393 msgp = msg;
01394 msgp += sprintf (msgp, "select: = %d:\n\t", ready);
01395
01396 for (i = 0; i < n_fds; i++)
01397 {
01398 DBusPollFD *fdp = &fds[i];
01399
01400 if (FD_ISSET (fdp->fd.sock, &read_set))
01401 msgp += sprintf (msgp, "R:%Iu ", fdp->fd.sock);
01402
01403 if (FD_ISSET (fdp->fd.sock, &write_set))
01404 msgp += sprintf (msgp, "W:%Iu ", fdp->fd.sock);
01405
01406 if (FD_ISSET (fdp->fd.sock, &err_set))
01407 msgp += sprintf (msgp, "E:%Iu\n\t", fdp->fd.sock);
01408 }
01409 msgp += sprintf (msgp, "\n");
01410 _dbus_verbose ("%s",msg);
01411 #endif
01412
01413 for (i = 0; i < n_fds; i++)
01414 {
01415 DBusPollFD *fdp = &fds[i];
01416
01417 fdp->revents = 0;
01418
01419 if (FD_ISSET (fdp->fd.sock, &read_set))
01420 fdp->revents |= _DBUS_POLLIN;
01421
01422 if (FD_ISSET (fdp->fd.sock, &write_set))
01423 fdp->revents |= _DBUS_POLLOUT;
01424
01425 if (FD_ISSET (fdp->fd.sock, &err_set))
01426 fdp->revents |= _DBUS_POLLERR;
01427 }
01428 }
01429 return ready;
01430 #endif
01431 }
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01472 void
01473 _dbus_exit (int code)
01474 {
01475 _exit (code);
01476 }
01477
01489 DBusSocket
01490 _dbus_connect_tcp_socket (const char *host,
01491 const char *port,
01492 const char *family,
01493 DBusError *error)
01494 {
01495 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01496 }
01497
01498 DBusSocket
01499 _dbus_connect_tcp_socket_with_nonce (const char *host,
01500 const char *port,
01501 const char *family,
01502 const char *noncefile,
01503 DBusError *error)
01504 {
01505 DBusSocket fd = DBUS_SOCKET_INIT;
01506 int res;
01507 struct addrinfo hints;
01508 struct addrinfo *ai, *tmp;
01509
01510 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01511
01512 if (!_dbus_win_startup_winsock ())
01513 {
01514 _DBUS_SET_OOM (error);
01515 return _dbus_socket_get_invalid ();
01516 }
01517
01518 _DBUS_ZERO (hints);
01519
01520 if (!family)
01521 hints.ai_family = AF_UNSPEC;
01522 else if (!strcmp(family, "ipv4"))
01523 hints.ai_family = AF_INET;
01524 else if (!strcmp(family, "ipv6"))
01525 hints.ai_family = AF_INET6;
01526 else
01527 {
01528 dbus_set_error (error,
01529 DBUS_ERROR_INVALID_ARGS,
01530 "Unknown address family %s", family);
01531 return _dbus_socket_get_invalid ();
01532 }
01533 hints.ai_protocol = IPPROTO_TCP;
01534 hints.ai_socktype = SOCK_STREAM;
01535 #ifdef AI_ADDRCONFIG
01536 hints.ai_flags = AI_ADDRCONFIG;
01537 #else
01538 hints.ai_flags = 0;
01539 #endif
01540
01541 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01542 {
01543 dbus_set_error (error,
01544 _dbus_error_from_errno (res),
01545 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01546 host, port, _dbus_strerror(res), res);
01547 return _dbus_socket_get_invalid ();
01548 }
01549
01550 tmp = ai;
01551 while (tmp)
01552 {
01553 if ((fd.sock = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
01554 {
01555 DBUS_SOCKET_SET_ERRNO ();
01556 dbus_set_error (error,
01557 _dbus_error_from_errno (errno),
01558 "Failed to open socket: %s",
01559 _dbus_strerror_from_errno ());
01560 freeaddrinfo(ai);
01561 return _dbus_socket_get_invalid ();
01562 }
01563 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01564
01565 if (connect (fd.sock, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
01566 {
01567 DBUS_SOCKET_SET_ERRNO ();
01568 closesocket(fd.sock);
01569 fd.sock = INVALID_SOCKET;
01570 tmp = tmp->ai_next;
01571 continue;
01572 }
01573
01574 break;
01575 }
01576 freeaddrinfo(ai);
01577
01578 if (!_dbus_socket_is_valid (fd))
01579 {
01580 dbus_set_error (error,
01581 _dbus_error_from_errno (errno),
01582 "Failed to connect to socket \"%s:%s\" %s",
01583 host, port, _dbus_strerror_from_errno ());
01584 return _dbus_socket_get_invalid ();
01585 }
01586
01587 if (noncefile != NULL)
01588 {
01589 DBusString noncefileStr;
01590 dbus_bool_t ret;
01591 if (!_dbus_string_init (&noncefileStr) ||
01592 !_dbus_string_append(&noncefileStr, noncefile))
01593 {
01594 closesocket (fd.sock);
01595 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01596 return _dbus_socket_get_invalid ();
01597 }
01598
01599 ret = _dbus_send_nonce (fd, &noncefileStr, error);
01600
01601 _dbus_string_free (&noncefileStr);
01602
01603 if (!ret)
01604 {
01605 closesocket (fd.sock);
01606 return _dbus_socket_get_invalid ();
01607 }
01608 }
01609
01610
01611 _dbus_win_handle_set_close_on_exec ((HANDLE) fd.sock);
01612
01613 if (!_dbus_set_socket_nonblocking (fd, error))
01614 {
01615 closesocket (fd.sock);
01616 return _dbus_socket_get_invalid ();
01617 }
01618
01619 return fd;
01620 }
01621
01637 int
01638 _dbus_listen_tcp_socket (const char *host,
01639 const char *port,
01640 const char *family,
01641 DBusString *retport,
01642 DBusSocket **fds_p,
01643 DBusError *error)
01644 {
01645 DBusSocket *listen_fd = NULL;
01646 int nlisten_fd = 0, res, i, port_num = -1;
01647 struct addrinfo hints;
01648 struct addrinfo *ai, *tmp;
01649
01650
01651
01652
01653
01654 typedef union {
01655 struct sockaddr Address;
01656 struct sockaddr_in AddressIn;
01657 struct sockaddr_in6 AddressIn6;
01658 } mysockaddr_gen;
01659
01660 *fds_p = NULL;
01661 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01662
01663 if (!_dbus_win_startup_winsock ())
01664 {
01665 _DBUS_SET_OOM (error);
01666 return -1;
01667 }
01668
01669 _DBUS_ZERO (hints);
01670
01671 if (!family)
01672 hints.ai_family = AF_INET;
01673 else if (!strcmp(family, "ipv4"))
01674 hints.ai_family = AF_INET;
01675 else if (!strcmp(family, "ipv6"))
01676 hints.ai_family = AF_INET6;
01677 else
01678 {
01679 dbus_set_error (error,
01680 DBUS_ERROR_INVALID_ARGS,
01681 "Unknown address family %s", family);
01682 return -1;
01683 }
01684
01685 hints.ai_protocol = IPPROTO_TCP;
01686 hints.ai_socktype = SOCK_STREAM;
01687 #ifdef AI_ADDRCONFIG
01688 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01689 #else
01690 hints.ai_flags = AI_PASSIVE;
01691 #endif
01692
01693 redo_lookup_with_port:
01694 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01695 {
01696 dbus_set_error (error,
01697 _dbus_error_from_errno (res),
01698 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01699 host ? host : "*", port, _dbus_strerror(res), res);
01700 return -1;
01701 }
01702
01703 tmp = ai;
01704 while (tmp)
01705 {
01706 DBusSocket fd = DBUS_SOCKET_INIT, *newlisten_fd;
01707 if ((fd.sock = socket (tmp->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
01708 {
01709 DBUS_SOCKET_SET_ERRNO ();
01710 dbus_set_error (error,
01711 _dbus_error_from_errno (errno),
01712 "Failed to open socket: %s",
01713 _dbus_strerror_from_errno ());
01714 goto failed;
01715 }
01716 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01717
01718 if (bind (fd.sock, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) == SOCKET_ERROR)
01719 {
01720 DBUS_SOCKET_SET_ERRNO ();
01721 closesocket (fd.sock);
01722 if (errno == WSAEADDRINUSE)
01723 {
01724
01725
01726
01727
01728 tmp = tmp->ai_next;
01729 continue;
01730 }
01731 dbus_set_error (error, _dbus_error_from_errno (errno),
01732 "Failed to bind socket \"%s:%s\": %s",
01733 host ? host : "*", port, _dbus_strerror_from_errno ());
01734 goto failed;
01735 }
01736
01737 if (listen (fd.sock, 30 ) == SOCKET_ERROR)
01738 {
01739 DBUS_SOCKET_SET_ERRNO ();
01740 dbus_set_error (error, _dbus_error_from_errno (errno),
01741 "Failed to listen on socket \"%s:%s\": %s",
01742 host ? host : "*", port, _dbus_strerror_from_errno ());
01743 closesocket (fd.sock);
01744 goto failed;
01745 }
01746
01747 newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
01748 if (!newlisten_fd)
01749 {
01750 closesocket (fd.sock);
01751 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01752 "Failed to allocate file handle array");
01753 goto failed;
01754 }
01755 listen_fd = newlisten_fd;
01756 listen_fd[nlisten_fd] = fd;
01757 nlisten_fd++;
01758
01759 if (!_dbus_string_get_length(retport))
01760 {
01761
01762
01763
01764
01765 if (!port || !strcmp(port, "0"))
01766 {
01767 mysockaddr_gen addr;
01768 socklen_t addrlen = sizeof(addr);
01769 char portbuf[NI_MAXSERV];
01770
01771 if (getsockname(fd.sock, &addr.Address, &addrlen) == SOCKET_ERROR ||
01772 (res = getnameinfo (&addr.Address, addrlen, NULL, 0,
01773 portbuf, sizeof(portbuf),
01774 NI_NUMERICSERV)) != 0)
01775 {
01776 DBUS_SOCKET_SET_ERRNO ();
01777 dbus_set_error (error, _dbus_error_from_errno (errno),
01778 "Failed to resolve port \"%s:%s\": %s",
01779 host ? host : "*", port, _dbus_strerror_from_errno());
01780 goto failed;
01781 }
01782 if (!_dbus_string_append(retport, portbuf))
01783 {
01784 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01785 goto failed;
01786 }
01787
01788
01789 port = _dbus_string_get_const_data(retport);
01790 freeaddrinfo(ai);
01791 goto redo_lookup_with_port;
01792 }
01793 else
01794 {
01795 if (!_dbus_string_append(retport, port))
01796 {
01797 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01798 goto failed;
01799 }
01800 }
01801 }
01802
01803 tmp = tmp->ai_next;
01804 }
01805 freeaddrinfo(ai);
01806 ai = NULL;
01807
01808 if (!nlisten_fd)
01809 {
01810 _dbus_win_set_errno (WSAEADDRINUSE);
01811 dbus_set_error (error, _dbus_error_from_errno (errno),
01812 "Failed to bind socket \"%s:%s\": %s",
01813 host ? host : "*", port, _dbus_strerror_from_errno ());
01814 return -1;
01815 }
01816
01817 sscanf(_dbus_string_get_const_data(retport), "%d", &port_num);
01818
01819 for (i = 0 ; i < nlisten_fd ; i++)
01820 {
01821 _dbus_win_handle_set_close_on_exec ((HANDLE) listen_fd[i].sock);
01822 if (!_dbus_set_socket_nonblocking (listen_fd[i], error))
01823 {
01824 goto failed;
01825 }
01826 }
01827
01828 *fds_p = listen_fd;
01829
01830 return nlisten_fd;
01831
01832 failed:
01833 if (ai)
01834 freeaddrinfo(ai);
01835 for (i = 0 ; i < nlisten_fd ; i++)
01836 closesocket (listen_fd[i].sock);
01837 dbus_free(listen_fd);
01838 return -1;
01839 }
01840
01841
01849 DBusSocket
01850 _dbus_accept (DBusSocket listen_fd)
01851 {
01852 DBusSocket client_fd;
01853
01854 retry:
01855 client_fd.sock = accept (listen_fd.sock, NULL, NULL);
01856
01857 if (!_dbus_socket_is_valid (client_fd))
01858 {
01859 DBUS_SOCKET_SET_ERRNO ();
01860 if (errno == EINTR)
01861 goto retry;
01862 }
01863
01864 _dbus_verbose ("client fd %Iu accepted\n", client_fd.sock);
01865
01866 return client_fd;
01867 }
01868
01869
01870
01871
01872 dbus_bool_t
01873 _dbus_send_credentials_socket (DBusSocket handle,
01874 DBusError *error)
01875 {
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899 int bytes_written;
01900 DBusString buf;
01901
01902 _dbus_string_init_const_len (&buf, "\0", 1);
01903 again:
01904 bytes_written = _dbus_write_socket (handle, &buf, 0, 1 );
01905
01906 if (bytes_written < 0 && errno == EINTR)
01907 goto again;
01908
01909 if (bytes_written < 0)
01910 {
01911 dbus_set_error (error, _dbus_error_from_errno (errno),
01912 "Failed to write credentials byte: %s",
01913 _dbus_strerror_from_errno ());
01914 return FALSE;
01915 }
01916 else if (bytes_written == 0)
01917 {
01918 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01919 "wrote zero bytes writing credentials byte");
01920 return FALSE;
01921 }
01922 else
01923 {
01924 _dbus_assert (bytes_written == 1);
01925 _dbus_verbose ("wrote 1 zero byte, credential sending isn't implemented yet\n");
01926 return TRUE;
01927 }
01928 return TRUE;
01929 }
01930
01949 dbus_bool_t
01950 _dbus_read_credentials_socket (DBusSocket handle,
01951 DBusCredentials *credentials,
01952 DBusError *error)
01953 {
01954 int bytes_read = 0;
01955 DBusString buf;
01956
01957 char *sid = NULL;
01958 dbus_pid_t pid;
01959 int retval = FALSE;
01960
01961
01962 if (_dbus_string_init (&buf))
01963 {
01964 bytes_read = _dbus_read_socket (handle, &buf, 1 );
01965
01966 if (bytes_read > 0)
01967 _dbus_verbose ("got one zero byte from server\n");
01968
01969 _dbus_string_free (&buf);
01970 }
01971
01972 pid = _dbus_get_peer_pid_from_tcp_handle (handle.sock);
01973 if (pid == 0)
01974 return TRUE;
01975
01976 _dbus_credentials_add_pid (credentials, pid);
01977
01978 if (_dbus_getsid (&sid, pid))
01979 {
01980 if (!_dbus_credentials_add_windows_sid (credentials, sid))
01981 goto out;
01982 }
01983
01984 retval = TRUE;
01985
01986 out:
01987 if (sid)
01988 LocalFree (sid);
01989
01990 return retval;
01991 }
01992
02001 dbus_bool_t
02002 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
02003 {
02004
02005 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02006 return TRUE;
02007 }
02008
02009
02020 dbus_bool_t
02021 _dbus_concat_dir_and_file (DBusString *dir,
02022 const DBusString *next_component)
02023 {
02024 dbus_bool_t dir_ends_in_slash;
02025 dbus_bool_t file_starts_with_slash;
02026
02027 if (_dbus_string_get_length (dir) == 0 ||
02028 _dbus_string_get_length (next_component) == 0)
02029 return TRUE;
02030
02031 dir_ends_in_slash =
02032 ('/' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1) ||
02033 '\\' == _dbus_string_get_byte (dir, _dbus_string_get_length (dir) - 1));
02034
02035 file_starts_with_slash =
02036 ('/' == _dbus_string_get_byte (next_component, 0) ||
02037 '\\' == _dbus_string_get_byte (next_component, 0));
02038
02039 if (dir_ends_in_slash && file_starts_with_slash)
02040 {
02041 _dbus_string_shorten (dir, 1);
02042 }
02043 else if (!(dir_ends_in_slash || file_starts_with_slash))
02044 {
02045 if (!_dbus_string_append_byte (dir, '\\'))
02046 return FALSE;
02047 }
02048
02049 return _dbus_string_copy (next_component, 0, dir,
02050 _dbus_string_get_length (dir));
02051 }
02052
02053
02054
02062 dbus_bool_t
02063 _dbus_credentials_add_from_user (DBusCredentials *credentials,
02064 const DBusString *username)
02065 {
02066 return _dbus_credentials_add_windows_sid (credentials,
02067 _dbus_string_get_const_data(username));
02068 }
02069
02078 dbus_bool_t
02079 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02080 {
02081 dbus_bool_t retval = FALSE;
02082 char *sid = NULL;
02083
02084 if (!_dbus_getsid(&sid, _dbus_getpid()))
02085 goto failed;
02086
02087 if (!_dbus_credentials_add_pid (credentials, _dbus_getpid()))
02088 goto failed;
02089
02090 if (!_dbus_credentials_add_windows_sid (credentials,sid))
02091 goto failed;
02092
02093 retval = TRUE;
02094 goto end;
02095 failed:
02096 retval = FALSE;
02097 end:
02098 if (sid)
02099 LocalFree(sid);
02100
02101 return retval;
02102 }
02103
02116 dbus_bool_t
02117 _dbus_append_user_from_current_process (DBusString *str)
02118 {
02119 dbus_bool_t retval = FALSE;
02120 char *sid = NULL;
02121
02122 if (!_dbus_getsid(&sid, _dbus_getpid()))
02123 return FALSE;
02124
02125 retval = _dbus_string_append (str,sid);
02126
02127 LocalFree(sid);
02128 return retval;
02129 }
02130
02135 dbus_pid_t
02136 _dbus_getpid (void)
02137 {
02138 return GetCurrentProcessId ();
02139 }
02140
02144 dbus_uid_t
02145 _dbus_getuid (void)
02146 {
02147 return DBUS_UID_UNSET;
02148 }
02149
02151 #define NANOSECONDS_PER_SECOND 1000000000
02152
02153 #define MICROSECONDS_PER_SECOND 1000000
02154
02155 #define MILLISECONDS_PER_SECOND 1000
02156
02157 #define NANOSECONDS_PER_MILLISECOND 1000000
02158
02159 #define MICROSECONDS_PER_MILLISECOND 1000
02160
02165 void
02166 _dbus_sleep_milliseconds (int milliseconds)
02167 {
02168 Sleep (milliseconds);
02169 }
02170
02171
02179 void
02180 _dbus_get_real_time (long *tv_sec,
02181 long *tv_usec)
02182 {
02183 FILETIME ft;
02184 dbus_uint64_t time64;
02185
02186 GetSystemTimeAsFileTime (&ft);
02187
02188 memcpy (&time64, &ft, sizeof (time64));
02189
02190
02191
02192
02193 time64 -= DBUS_INT64_CONSTANT (116444736000000000);
02194 time64 /= 10;
02195
02196 if (tv_sec)
02197 *tv_sec = time64 / 1000000;
02198
02199 if (tv_usec)
02200 *tv_usec = time64 % 1000000;
02201 }
02202
02210 void
02211 _dbus_get_monotonic_time (long *tv_sec,
02212 long *tv_usec)
02213 {
02214
02215 _dbus_get_real_time (tv_sec, tv_usec);
02216 }
02217
02221 void
02222 _dbus_disable_sigpipe (void)
02223 {
02224 }
02225
02234 dbus_bool_t
02235 _dbus_create_directory (const DBusString *filename,
02236 DBusError *error)
02237 {
02238 const char *filename_c;
02239
02240 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02241
02242 filename_c = _dbus_string_get_const_data (filename);
02243
02244 if (!CreateDirectoryA (filename_c, NULL))
02245 {
02246 dbus_set_error (error, DBUS_ERROR_FAILED,
02247 "Failed to create directory %s: %s\n",
02248 filename_c, _dbus_strerror_from_errno ());
02249 return FALSE;
02250 }
02251 else
02252 return TRUE;
02253 }
02254
02263 dbus_bool_t
02264 _dbus_ensure_directory (const DBusString *filename,
02265 DBusError *error)
02266 {
02267 const char *filename_c;
02268
02269 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02270
02271 filename_c = _dbus_string_get_const_data (filename);
02272
02273 if (!CreateDirectoryA (filename_c, NULL))
02274 {
02275 if (GetLastError () == ERROR_ALREADY_EXISTS)
02276 return TRUE;
02277
02278 dbus_set_error (error, DBUS_ERROR_FAILED,
02279 "Failed to create directory %s: %s\n",
02280 filename_c, _dbus_strerror_from_errno ());
02281 return FALSE;
02282 }
02283 else
02284 return TRUE;
02285 }
02286
02287
02297 dbus_bool_t
02298 _dbus_generate_random_bytes (DBusString *str,
02299 int n_bytes,
02300 DBusError *error)
02301 {
02302 int old_len;
02303 char *p;
02304 HCRYPTPROV hprov;
02305
02306 old_len = _dbus_string_get_length (str);
02307
02308 if (!_dbus_string_lengthen (str, n_bytes))
02309 {
02310 _DBUS_SET_OOM (error);
02311 return FALSE;
02312 }
02313
02314 p = _dbus_string_get_data_len (str, old_len, n_bytes);
02315
02316 if (!CryptAcquireContext (&hprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
02317 {
02318 _DBUS_SET_OOM (error);
02319 return FALSE;
02320 }
02321
02322 if (!CryptGenRandom (hprov, n_bytes, p))
02323 {
02324 _DBUS_SET_OOM (error);
02325 CryptReleaseContext (hprov, 0);
02326 return FALSE;
02327 }
02328
02329 CryptReleaseContext (hprov, 0);
02330
02331 return TRUE;
02332 }
02333
02340 const char*
02341 _dbus_get_tmpdir(void)
02342 {
02343
02344 static const char* tmpdir = NULL;
02345 static char buf[1000];
02346
02347 if (!_DBUS_LOCK (sysdeps))
02348 return NULL;
02349
02350 if (tmpdir == NULL)
02351 {
02352 char *last_slash;
02353
02354 if (!GetTempPathA (sizeof (buf), buf))
02355 {
02356 _dbus_warn ("GetTempPath failed\n");
02357 _dbus_abort ();
02358 }
02359
02360
02361 last_slash = _mbsrchr (buf, '\\');
02362 if (last_slash > buf && last_slash[1] == '\0')
02363 last_slash[0] = '\0';
02364 last_slash = _mbsrchr (buf, '/');
02365 if (last_slash > buf && last_slash[1] == '\0')
02366 last_slash[0] = '\0';
02367
02368 tmpdir = buf;
02369 }
02370
02371 _DBUS_UNLOCK (sysdeps);
02372
02373 _dbus_assert(tmpdir != NULL);
02374
02375 return tmpdir;
02376 }
02377
02378
02387 dbus_bool_t
02388 _dbus_delete_file (const DBusString *filename,
02389 DBusError *error)
02390 {
02391 const char *filename_c;
02392
02393 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02394
02395 filename_c = _dbus_string_get_const_data (filename);
02396
02397 if (DeleteFileA (filename_c) == 0)
02398 {
02399 dbus_set_error (error, DBUS_ERROR_FAILED,
02400 "Failed to delete file %s: %s\n",
02401 filename_c, _dbus_strerror_from_errno ());
02402 return FALSE;
02403 }
02404 else
02405 return TRUE;
02406 }
02407
02408 #if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_ENABLE_EMBEDDED_TESTS)
02409
02410 #if defined(_MSC_VER) || defined(DBUS_WINCE)
02411 # ifdef BACKTRACES
02412 # undef BACKTRACES
02413 # endif
02414 #else
02415 # define BACKTRACES
02416 #endif
02417
02418 #ifdef BACKTRACES
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440 #include <winver.h>
02441 #include <imagehlp.h>
02442 #include <stdio.h>
02443
02444 #define DPRINTF(fmt, ...) fprintf (stderr, fmt, ##__VA_ARGS__)
02445
02446 #ifdef _MSC_VER
02447 #define BOOL int
02448
02449 #define __i386__
02450 #endif
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460 static BOOL (WINAPI *pStackWalk)(
02461 DWORD MachineType,
02462 HANDLE hProcess,
02463 HANDLE hThread,
02464 LPSTACKFRAME StackFrame,
02465 PVOID ContextRecord,
02466 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
02467 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
02468 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
02469 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
02470 );
02471 #ifdef _WIN64
02472 static DWORD64 (WINAPI *pSymGetModuleBase)(
02473 HANDLE hProcess,
02474 DWORD64 dwAddr
02475 );
02476 static PVOID (WINAPI *pSymFunctionTableAccess)(
02477 HANDLE hProcess,
02478 DWORD64 AddrBase
02479 );
02480 #else
02481 static DWORD (WINAPI *pSymGetModuleBase)(
02482 HANDLE hProcess,
02483 DWORD dwAddr
02484 );
02485 static PVOID (WINAPI *pSymFunctionTableAccess)(
02486 HANDLE hProcess,
02487 DWORD AddrBase
02488 );
02489 #endif
02490 static BOOL (WINAPI *pSymInitialize)(
02491 HANDLE hProcess,
02492 PSTR UserSearchPath,
02493 BOOL fInvadeProcess
02494 );
02495 static BOOL (WINAPI *pSymGetSymFromAddr)(
02496 HANDLE hProcess,
02497 DWORD Address,
02498 PDWORD Displacement,
02499 PIMAGEHLP_SYMBOL Symbol
02500 );
02501 static BOOL (WINAPI *pSymGetModuleInfo)(
02502 HANDLE hProcess,
02503 DWORD dwAddr,
02504 PIMAGEHLP_MODULE ModuleInfo
02505 );
02506 static DWORD (WINAPI *pSymSetOptions)(
02507 DWORD SymOptions
02508 );
02509
02510
02511 static BOOL init_backtrace()
02512 {
02513 HMODULE hmodDbgHelp = LoadLibraryA("dbghelp");
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531 #define FUNC(x) #x
02532
02533 pStackWalk = (BOOL (WINAPI *)(
02534 DWORD MachineType,
02535 HANDLE hProcess,
02536 HANDLE hThread,
02537 LPSTACKFRAME StackFrame,
02538 PVOID ContextRecord,
02539 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
02540 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
02541 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
02542 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
02543 ))GetProcAddress (hmodDbgHelp, FUNC(StackWalk));
02544 #ifdef _WIN64
02545 pSymGetModuleBase=(DWORD64 (WINAPI *)(
02546 HANDLE hProcess,
02547 DWORD64 dwAddr
02548 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
02549 pSymFunctionTableAccess=(PVOID (WINAPI *)(
02550 HANDLE hProcess,
02551 DWORD64 AddrBase
02552 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
02553 #else
02554 pSymGetModuleBase=(DWORD (WINAPI *)(
02555 HANDLE hProcess,
02556 DWORD dwAddr
02557 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
02558 pSymFunctionTableAccess=(PVOID (WINAPI *)(
02559 HANDLE hProcess,
02560 DWORD AddrBase
02561 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
02562 #endif
02563 pSymInitialize = (BOOL (WINAPI *)(
02564 HANDLE hProcess,
02565 PSTR UserSearchPath,
02566 BOOL fInvadeProcess
02567 ))GetProcAddress (hmodDbgHelp, FUNC(SymInitialize));
02568 pSymGetSymFromAddr = (BOOL (WINAPI *)(
02569 HANDLE hProcess,
02570 DWORD Address,
02571 PDWORD Displacement,
02572 PIMAGEHLP_SYMBOL Symbol
02573 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetSymFromAddr));
02574 pSymGetModuleInfo = (BOOL (WINAPI *)(
02575 HANDLE hProcess,
02576 DWORD dwAddr,
02577 PIMAGEHLP_MODULE ModuleInfo
02578 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleInfo));
02579 pSymSetOptions = (DWORD (WINAPI *)(
02580 DWORD SymOptions
02581 ))GetProcAddress (hmodDbgHelp, FUNC(SymSetOptions));
02582
02583
02584 pSymSetOptions(SYMOPT_UNDNAME);
02585
02586 pSymInitialize(GetCurrentProcess(), NULL, TRUE);
02587
02588 return TRUE;
02589 }
02590
02591 static void dump_backtrace_for_thread(HANDLE hThread)
02592 {
02593 STACKFRAME sf;
02594 CONTEXT context;
02595 DWORD dwImageType;
02596
02597 if (!pStackWalk)
02598 if (!init_backtrace())
02599 return;
02600
02601
02602
02603 if (hThread == GetCurrentThread())
02604 return;
02605
02606 DPRINTF("Backtrace:\n");
02607
02608 _DBUS_ZERO(context);
02609 context.ContextFlags = CONTEXT_FULL;
02610
02611 SuspendThread(hThread);
02612
02613 if (!GetThreadContext(hThread, &context))
02614 {
02615 DPRINTF("Couldn't get thread context (error %ld)\n", GetLastError());
02616 ResumeThread(hThread);
02617 return;
02618 }
02619
02620 _DBUS_ZERO(sf);
02621
02622 #ifdef __i386__
02623 sf.AddrFrame.Offset = context.Ebp;
02624 sf.AddrFrame.Mode = AddrModeFlat;
02625 sf.AddrPC.Offset = context.Eip;
02626 sf.AddrPC.Mode = AddrModeFlat;
02627 dwImageType = IMAGE_FILE_MACHINE_I386;
02628 #elif _M_X64
02629 dwImageType = IMAGE_FILE_MACHINE_AMD64;
02630 sf.AddrPC.Offset = context.Rip;
02631 sf.AddrPC.Mode = AddrModeFlat;
02632 sf.AddrFrame.Offset = context.Rsp;
02633 sf.AddrFrame.Mode = AddrModeFlat;
02634 sf.AddrStack.Offset = context.Rsp;
02635 sf.AddrStack.Mode = AddrModeFlat;
02636 #elif _M_IA64
02637 dwImageType = IMAGE_FILE_MACHINE_IA64;
02638 sf.AddrPC.Offset = context.StIIP;
02639 sf.AddrPC.Mode = AddrModeFlat;
02640 sf.AddrFrame.Offset = context.IntSp;
02641 sf.AddrFrame.Mode = AddrModeFlat;
02642 sf.AddrBStore.Offset= context.RsBSP;
02643 sf.AddrBStore.Mode = AddrModeFlat;
02644 sf.AddrStack.Offset = context.IntSp;
02645 sf.AddrStack.Mode = AddrModeFlat;
02646 #else
02647 # error You need to fill in the STACKFRAME structure for your architecture
02648 #endif
02649
02650 while (pStackWalk(dwImageType, GetCurrentProcess(),
02651 hThread, &sf, &context, NULL, pSymFunctionTableAccess,
02652 pSymGetModuleBase, NULL))
02653 {
02654 BYTE buffer[256];
02655 IMAGEHLP_SYMBOL * pSymbol = (IMAGEHLP_SYMBOL *)buffer;
02656 DWORD dwDisplacement;
02657
02658 pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
02659 pSymbol->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1;
02660
02661 if (!pSymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset,
02662 &dwDisplacement, pSymbol))
02663 {
02664 IMAGEHLP_MODULE ModuleInfo;
02665 ModuleInfo.SizeOfStruct = sizeof(ModuleInfo);
02666
02667 if (!pSymGetModuleInfo(GetCurrentProcess(), sf.AddrPC.Offset,
02668 &ModuleInfo))
02669 DPRINTF("1\t%p\n", (void*)sf.AddrPC.Offset);
02670 else
02671 DPRINTF("2\t%s+0x%lx\n", ModuleInfo.ImageName,
02672 sf.AddrPC.Offset - ModuleInfo.BaseOfImage);
02673 }
02674 else if (dwDisplacement)
02675 DPRINTF("3\t%s+0x%lx\n", pSymbol->Name, dwDisplacement);
02676 else
02677 DPRINTF("4\t%s\n", pSymbol->Name);
02678 }
02679
02680 ResumeThread(hThread);
02681 }
02682
02683 static DWORD WINAPI dump_thread_proc(LPVOID lpParameter)
02684 {
02685 dump_backtrace_for_thread((HANDLE)lpParameter);
02686 return 0;
02687 }
02688
02689
02690
02691 static void dump_backtrace()
02692 {
02693 HANDLE hCurrentThread;
02694 HANDLE hThread;
02695 DWORD dwThreadId;
02696 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
02697 GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
02698 hThread = CreateThread(NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread,
02699 0, &dwThreadId);
02700 WaitForSingleObject(hThread, INFINITE);
02701 CloseHandle(hThread);
02702 CloseHandle(hCurrentThread);
02703 }
02704 #endif
02705 #endif
02706
02707 #ifdef BACKTRACES
02708 void _dbus_print_backtrace(void)
02709 {
02710 init_backtrace();
02711 dump_backtrace();
02712 }
02713 #else
02714 void _dbus_print_backtrace(void)
02715 {
02716 _dbus_verbose (" D-Bus not compiled with backtrace support\n");
02717 }
02718 #endif
02719
02720 static dbus_uint32_t fromAscii(char ascii)
02721 {
02722 if(ascii >= '0' && ascii <= '9')
02723 return ascii - '0';
02724 if(ascii >= 'A' && ascii <= 'F')
02725 return ascii - 'A' + 10;
02726 if(ascii >= 'a' && ascii <= 'f')
02727 return ascii - 'a' + 10;
02728 return 0;
02729 }
02730
02731 dbus_bool_t _dbus_read_local_machine_uuid (DBusGUID *machine_id,
02732 dbus_bool_t create_if_not_found,
02733 DBusError *error)
02734 {
02735 #ifdef DBUS_WINCE
02736 return TRUE;
02737
02738 #else
02739 HW_PROFILE_INFOA info;
02740 char *lpc = &info.szHwProfileGuid[0];
02741 dbus_uint32_t u;
02742
02743
02744 if(!GetCurrentHwProfileA(&info))
02745 {
02746 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02747 return FALSE;
02748 }
02749
02750
02751 lpc++;
02752
02753 u = ((fromAscii(lpc[0]) << 0) |
02754 (fromAscii(lpc[1]) << 4) |
02755 (fromAscii(lpc[2]) << 8) |
02756 (fromAscii(lpc[3]) << 12) |
02757 (fromAscii(lpc[4]) << 16) |
02758 (fromAscii(lpc[5]) << 20) |
02759 (fromAscii(lpc[6]) << 24) |
02760 (fromAscii(lpc[7]) << 28));
02761 machine_id->as_uint32s[0] = u;
02762
02763 lpc += 9;
02764
02765 u = ((fromAscii(lpc[0]) << 0) |
02766 (fromAscii(lpc[1]) << 4) |
02767 (fromAscii(lpc[2]) << 8) |
02768 (fromAscii(lpc[3]) << 12) |
02769 (fromAscii(lpc[5]) << 16) |
02770 (fromAscii(lpc[6]) << 20) |
02771 (fromAscii(lpc[7]) << 24) |
02772 (fromAscii(lpc[8]) << 28));
02773 machine_id->as_uint32s[1] = u;
02774
02775 lpc += 10;
02776
02777 u = ((fromAscii(lpc[0]) << 0) |
02778 (fromAscii(lpc[1]) << 4) |
02779 (fromAscii(lpc[2]) << 8) |
02780 (fromAscii(lpc[3]) << 12) |
02781 (fromAscii(lpc[5]) << 16) |
02782 (fromAscii(lpc[6]) << 20) |
02783 (fromAscii(lpc[7]) << 24) |
02784 (fromAscii(lpc[8]) << 28));
02785 machine_id->as_uint32s[2] = u;
02786
02787 lpc += 9;
02788
02789 u = ((fromAscii(lpc[0]) << 0) |
02790 (fromAscii(lpc[1]) << 4) |
02791 (fromAscii(lpc[2]) << 8) |
02792 (fromAscii(lpc[3]) << 12) |
02793 (fromAscii(lpc[4]) << 16) |
02794 (fromAscii(lpc[5]) << 20) |
02795 (fromAscii(lpc[6]) << 24) |
02796 (fromAscii(lpc[7]) << 28));
02797 machine_id->as_uint32s[3] = u;
02798 #endif
02799 return TRUE;
02800 }
02801
02802 static
02803 HANDLE _dbus_global_lock (const char *mutexname)
02804 {
02805 HANDLE mutex;
02806 DWORD gotMutex;
02807
02808 mutex = CreateMutexA( NULL, FALSE, mutexname );
02809 if( !mutex )
02810 {
02811 return FALSE;
02812 }
02813
02814 gotMutex = WaitForSingleObject( mutex, INFINITE );
02815 switch( gotMutex )
02816 {
02817 case WAIT_ABANDONED:
02818 ReleaseMutex (mutex);
02819 CloseHandle (mutex);
02820 return 0;
02821 case WAIT_FAILED:
02822 case WAIT_TIMEOUT:
02823 return 0;
02824 }
02825
02826 return mutex;
02827 }
02828
02829 static
02830 void _dbus_global_unlock (HANDLE mutex)
02831 {
02832 ReleaseMutex (mutex);
02833 CloseHandle (mutex);
02834 }
02835
02836
02837 static HANDLE hDBusDaemonMutex = NULL;
02838 static HANDLE hDBusSharedMem = NULL;
02839
02840 static const char *cUniqueDBusInitMutex = "UniqueDBusInitMutex";
02841
02842 static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex";
02843
02844 static const char *cDBusDaemonMutex = "DBusDaemonMutex";
02845
02846 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
02847
02848 static dbus_bool_t
02849 _dbus_get_install_root_as_hash(DBusString *out)
02850 {
02851 DBusString install_path;
02852
02853 char path[MAX_PATH*2];
02854 int path_size = sizeof(path);
02855
02856 if (!_dbus_get_install_root(path,path_size))
02857 return FALSE;
02858
02859 _dbus_string_init(&install_path);
02860 _dbus_string_append(&install_path,path);
02861
02862 _dbus_string_init(out);
02863 _dbus_string_tolower_ascii(&install_path,0,_dbus_string_get_length(&install_path));
02864
02865 if (!_dbus_sha_compute (&install_path, out))
02866 return FALSE;
02867
02868 return TRUE;
02869 }
02870
02871 static dbus_bool_t
02872 _dbus_get_address_string (DBusString *out, const char *basestring, const char *scope)
02873 {
02874 _dbus_string_init(out);
02875 _dbus_string_append(out,basestring);
02876
02877 if (!scope)
02878 {
02879 return TRUE;
02880 }
02881 else if (strcmp(scope,"*install-path") == 0
02882
02883 || strcmp(scope,"install-path") == 0)
02884 {
02885 DBusString temp;
02886 if (!_dbus_get_install_root_as_hash(&temp))
02887 {
02888 _dbus_string_free(out);
02889 return FALSE;
02890 }
02891 _dbus_string_append(out,"-");
02892 _dbus_string_append(out,_dbus_string_get_const_data(&temp));
02893 _dbus_string_free(&temp);
02894 }
02895 else if (strcmp(scope,"*user") == 0)
02896 {
02897 _dbus_string_append(out,"-");
02898 if (!_dbus_append_user_from_current_process(out))
02899 {
02900 _dbus_string_free(out);
02901 return FALSE;
02902 }
02903 }
02904 else if (strlen(scope) > 0)
02905 {
02906 _dbus_string_append(out,"-");
02907 _dbus_string_append(out,scope);
02908 return TRUE;
02909 }
02910 return TRUE;
02911 }
02912
02913 static dbus_bool_t
02914 _dbus_get_shm_name (DBusString *out,const char *scope)
02915 {
02916 return _dbus_get_address_string (out,cDBusDaemonAddressInfo,scope);
02917 }
02918
02919 static dbus_bool_t
02920 _dbus_get_mutex_name (DBusString *out,const char *scope)
02921 {
02922 return _dbus_get_address_string (out,cDBusDaemonMutex,scope);
02923 }
02924
02925 dbus_bool_t
02926 _dbus_daemon_is_session_bus_address_published (const char *scope)
02927 {
02928 HANDLE lock;
02929 DBusString mutex_name;
02930
02931 if (!_dbus_get_mutex_name(&mutex_name,scope))
02932 {
02933 _dbus_string_free( &mutex_name );
02934 return FALSE;
02935 }
02936
02937 if (hDBusDaemonMutex)
02938 return TRUE;
02939
02940
02941 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02942
02943
02944
02945 hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02946
02947
02948
02949
02950
02951 _dbus_global_unlock( lock );
02952
02953 _dbus_string_free( &mutex_name );
02954
02955 if (hDBusDaemonMutex == NULL)
02956 return FALSE;
02957 if (GetLastError() == ERROR_ALREADY_EXISTS)
02958 {
02959 CloseHandle(hDBusDaemonMutex);
02960 hDBusDaemonMutex = NULL;
02961 return TRUE;
02962 }
02963
02964
02965
02966 return FALSE;
02967 }
02968
02969 dbus_bool_t
02970 _dbus_daemon_publish_session_bus_address (const char* address, const char *scope)
02971 {
02972 HANDLE lock;
02973 char *shared_addr = NULL;
02974 DBusString shm_name;
02975 DBusString mutex_name;
02976 dbus_uint64_t len;
02977
02978 _dbus_assert (address);
02979
02980 if (!_dbus_get_mutex_name(&mutex_name,scope))
02981 {
02982 _dbus_string_free( &mutex_name );
02983 return FALSE;
02984 }
02985
02986
02987 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02988
02989 if (!hDBusDaemonMutex)
02990 {
02991 hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02992 }
02993 _dbus_string_free( &mutex_name );
02994
02995
02996 if (WaitForSingleObject( hDBusDaemonMutex, 10 ) != WAIT_OBJECT_0)
02997 {
02998 _dbus_global_unlock( lock );
02999 CloseHandle( hDBusDaemonMutex );
03000 return FALSE;
03001 }
03002
03003 if (!_dbus_get_shm_name(&shm_name,scope))
03004 {
03005 _dbus_string_free( &shm_name );
03006 _dbus_global_unlock( lock );
03007 return FALSE;
03008 }
03009
03010
03011 len = strlen (address) + 1;
03012
03013 hDBusSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
03014 len >> 32, len & 0xffffffffu,
03015 _dbus_string_get_const_data(&shm_name) );
03016 _dbus_assert( hDBusSharedMem );
03017
03018 shared_addr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
03019
03020 _dbus_assert (shared_addr);
03021
03022 strcpy( shared_addr, address);
03023
03024
03025 UnmapViewOfFile( shared_addr );
03026
03027 _dbus_global_unlock( lock );
03028 _dbus_verbose( "published session bus address at %s\n",_dbus_string_get_const_data (&shm_name) );
03029
03030 _dbus_string_free( &shm_name );
03031 return TRUE;
03032 }
03033
03034 void
03035 _dbus_daemon_unpublish_session_bus_address (void)
03036 {
03037 HANDLE lock;
03038
03039
03040 lock = _dbus_global_lock( cUniqueDBusInitMutex );
03041
03042 CloseHandle( hDBusSharedMem );
03043
03044 hDBusSharedMem = NULL;
03045
03046 ReleaseMutex( hDBusDaemonMutex );
03047
03048 CloseHandle( hDBusDaemonMutex );
03049
03050 hDBusDaemonMutex = NULL;
03051
03052 _dbus_global_unlock( lock );
03053 }
03054
03055 static dbus_bool_t
03056 _dbus_get_autolaunch_shm (DBusString *address, DBusString *shm_name)
03057 {
03058 HANDLE sharedMem;
03059 char *shared_addr;
03060 int i;
03061
03062
03063 for(i=0;i<20;++i) {
03064
03065 sharedMem = OpenFileMappingA( FILE_MAP_READ, FALSE, _dbus_string_get_const_data(shm_name));
03066 if( sharedMem == 0 )
03067 Sleep( 100 );
03068 if ( sharedMem != 0)
03069 break;
03070 }
03071
03072 if( sharedMem == 0 )
03073 return FALSE;
03074
03075 shared_addr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
03076
03077 if( !shared_addr )
03078 return FALSE;
03079
03080 _dbus_string_init( address );
03081
03082 _dbus_string_append( address, shared_addr );
03083
03084
03085 UnmapViewOfFile( shared_addr );
03086
03087 CloseHandle( sharedMem );
03088
03089 return TRUE;
03090 }
03091
03092 static dbus_bool_t
03093 _dbus_daemon_already_runs (DBusString *address, DBusString *shm_name, const char *scope)
03094 {
03095 HANDLE lock;
03096 HANDLE daemon;
03097 DBusString mutex_name;
03098 dbus_bool_t bRet = TRUE;
03099
03100 if (!_dbus_get_mutex_name(&mutex_name,scope))
03101 {
03102 _dbus_string_free( &mutex_name );
03103 return FALSE;
03104 }
03105
03106
03107 lock = _dbus_global_lock( cUniqueDBusInitMutex );
03108
03109
03110 daemon = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
03111 if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT)
03112 {
03113 ReleaseMutex (daemon);
03114 CloseHandle (daemon);
03115
03116 _dbus_global_unlock( lock );
03117 _dbus_string_free( &mutex_name );
03118 return FALSE;
03119 }
03120
03121
03122 bRet = _dbus_get_autolaunch_shm( address, shm_name );
03123
03124
03125 CloseHandle ( daemon );
03126
03127 _dbus_global_unlock( lock );
03128 _dbus_string_free( &mutex_name );
03129
03130 return bRet;
03131 }
03132
03133 dbus_bool_t
03134 _dbus_get_autolaunch_address (const char *scope, DBusString *address,
03135 DBusError *error)
03136 {
03137 HANDLE mutex;
03138 STARTUPINFOA si;
03139 PROCESS_INFORMATION pi;
03140 dbus_bool_t retval = FALSE;
03141 LPSTR lpFile;
03142 char dbus_exe_path[MAX_PATH];
03143 char dbus_args[MAX_PATH * 2];
03144 const char * daemon_name = DBUS_DAEMON_NAME ".exe";
03145 DBusString shm_name;
03146
03147 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03148
03149 if (!_dbus_get_shm_name(&shm_name,scope))
03150 {
03151 dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not determine shm name");
03152 return FALSE;
03153 }
03154
03155 mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
03156
03157 if (_dbus_daemon_already_runs(address,&shm_name,scope))
03158 {
03159 _dbus_verbose( "found running dbus daemon for scope '%s' at %s\n",
03160 scope ? scope : "", _dbus_string_get_const_data (&shm_name) );
03161 retval = TRUE;
03162 goto out;
03163 }
03164
03165 if (!SearchPathA(NULL, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
03166 {
03167
03168 HMODULE hmod;
03169 char dbus_module_path[MAX_PATH];
03170 DWORD rc;
03171
03172 _dbus_verbose( "did not found dbus daemon executable on default search path, "
03173 "trying path where dbus shared library is located");
03174
03175 hmod = _dbus_win_get_dll_hmodule();
03176 rc = GetModuleFileNameA(hmod, dbus_module_path, sizeof(dbus_module_path));
03177 if (rc <= 0)
03178 {
03179 dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not retrieve dbus shared library file name");
03180 retval = FALSE;
03181 goto out;
03182 }
03183 else
03184 {
03185 char *ext_idx = strrchr(dbus_module_path, '\\');
03186 if (ext_idx)
03187 *ext_idx = '\0';
03188 if (!SearchPathA(dbus_module_path, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
03189 {
03190 dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not find dbus-daemon executable");
03191 retval = FALSE;
03192 printf ("please add the path to %s to your PATH environment variable\n", daemon_name);
03193 printf ("or start the daemon manually\n\n");
03194 goto out;
03195 }
03196 _dbus_verbose( "found dbus daemon executable at %s",dbus_module_path);
03197 }
03198 }
03199
03200
03201
03202 ZeroMemory( &si, sizeof(si) );
03203 si.cb = sizeof(si);
03204 ZeroMemory( &pi, sizeof(pi) );
03205
03206 _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path, " --session");
03207
03208
03209
03210 if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
03211 {
03212 CloseHandle (pi.hThread);
03213 CloseHandle (pi.hProcess);
03214 retval = _dbus_get_autolaunch_shm( address, &shm_name );
03215 if (retval == FALSE)
03216 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to get autolaunch address from launched dbus-daemon");
03217 }
03218 else
03219 {
03220 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to launch dbus-daemon");
03221 retval = FALSE;
03222 }
03223
03224 out:
03225 if (retval)
03226 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03227 else
03228 _DBUS_ASSERT_ERROR_IS_SET (error);
03229
03230 _dbus_global_unlock (mutex);
03231 _dbus_string_free (&shm_name);
03232
03233 return retval;
03234 }
03235
03236
03243 dbus_bool_t
03244 _dbus_make_file_world_readable(const DBusString *filename,
03245 DBusError *error)
03246 {
03247
03248 return TRUE;
03249 }
03250
03258 dbus_int32_t
03259 _dbus_atomic_inc (DBusAtomic *atomic)
03260 {
03261
03262
03263 return InterlockedIncrement (&atomic->value) - 1;
03264 }
03265
03273 dbus_int32_t
03274 _dbus_atomic_dec (DBusAtomic *atomic)
03275 {
03276
03277
03278 return InterlockedDecrement (&atomic->value) + 1;
03279 }
03280
03288 dbus_int32_t
03289 _dbus_atomic_get (DBusAtomic *atomic)
03290 {
03291
03292
03293
03294
03295
03296
03297
03298
03299 long dummy = 0;
03300
03301 InterlockedExchange (&dummy, 1);
03302
03303 return atomic->value;
03304 }
03305
03313 void
03314 _dbus_flush_caches (void)
03315 {
03316 }
03317
03324 dbus_bool_t
03325 _dbus_get_is_errno_eagain_or_ewouldblock (int e)
03326 {
03327 return e == WSAEWOULDBLOCK;
03328 }
03329
03337 dbus_bool_t
03338 _dbus_get_install_root(char *prefix, int len)
03339 {
03340
03341 DWORD pathLength;
03342 char *lastSlash;
03343 SetLastError( 0 );
03344 pathLength = GetModuleFileNameA(_dbus_win_get_dll_hmodule(), prefix, len);
03345 if ( pathLength == 0 || GetLastError() != 0 ) {
03346 *prefix = '\0';
03347 return FALSE;
03348 }
03349 lastSlash = _mbsrchr(prefix, '\\');
03350 if (lastSlash == NULL) {
03351 *prefix = '\0';
03352 return FALSE;
03353 }
03354
03355 lastSlash[1] = 0;
03356
03357
03358
03359
03360
03361
03362
03363 if (lastSlash - prefix >= 4 && strnicmp(lastSlash - 4, "\\bin", 4) == 0)
03364 lastSlash[-3] = 0;
03365 else if (lastSlash - prefix >= 10 && strnicmp(lastSlash - 10, "\\bin\\debug", 10) == 0)
03366 lastSlash[-9] = 0;
03367 else if (lastSlash - prefix >= 12 && strnicmp(lastSlash - 12, "\\bin\\release", 12) == 0)
03368 lastSlash[-11] = 0;
03369
03370 return TRUE;
03371 }
03372
03373
03374 dbus_bool_t
03375 _dbus_lookup_session_address (dbus_bool_t *supported,
03376 DBusString *address,
03377 DBusError *error)
03378 {
03379
03380 *supported = FALSE;
03381 return TRUE;
03382 }
03383
03397 dbus_bool_t
03398 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03399 DBusCredentials *credentials)
03400 {
03401 DBusString homedir;
03402 DBusString dotdir;
03403 const char *homepath;
03404 const char *homedrive;
03405
03406 _dbus_assert (credentials != NULL);
03407 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03408
03409 if (!_dbus_string_init (&homedir))
03410 return FALSE;
03411
03412 homedrive = _dbus_getenv("HOMEDRIVE");
03413 if (homedrive != NULL && *homedrive != '\0')
03414 {
03415 _dbus_string_append(&homedir,homedrive);
03416 }
03417
03418 homepath = _dbus_getenv("HOMEPATH");
03419 if (homepath != NULL && *homepath != '\0')
03420 {
03421 _dbus_string_append(&homedir,homepath);
03422 }
03423
03424 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
03425 {
03426 const char *override;
03427
03428 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03429 if (override != NULL && *override != '\0')
03430 {
03431 _dbus_string_set_length (&homedir, 0);
03432 if (!_dbus_string_append (&homedir, override))
03433 goto failed;
03434
03435 _dbus_verbose ("Using fake homedir for testing: %s\n",
03436 _dbus_string_get_const_data (&homedir));
03437 }
03438 else
03439 {
03440
03441
03442 static dbus_bool_t already_warned = FALSE;
03443 if (!already_warned)
03444 {
03445 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03446 already_warned = TRUE;
03447 }
03448 }
03449 }
03450 #endif
03451
03452 #ifdef DBUS_WINCE
03453
03454
03455 #define KEYRING_DIR "dbus-keyrings"
03456 #else
03457 #define KEYRING_DIR ".dbus-keyrings"
03458 #endif
03459
03460 _dbus_string_init_const (&dotdir, KEYRING_DIR);
03461 if (!_dbus_concat_dir_and_file (&homedir,
03462 &dotdir))
03463 goto failed;
03464
03465 if (!_dbus_string_copy (&homedir, 0,
03466 directory, _dbus_string_get_length (directory))) {
03467 goto failed;
03468 }
03469
03470 _dbus_string_free (&homedir);
03471 return TRUE;
03472
03473 failed:
03474 _dbus_string_free (&homedir);
03475 return FALSE;
03476 }
03477
03483 dbus_bool_t
03484 _dbus_file_exists (const char *file)
03485 {
03486 DWORD attributes = GetFileAttributesA (file);
03487
03488 if (attributes != INVALID_FILE_ATTRIBUTES && GetLastError() != ERROR_PATH_NOT_FOUND)
03489 return TRUE;
03490 else
03491 return FALSE;
03492 }
03493
03501 const char*
03502 _dbus_strerror (int error_number)
03503 {
03504 #ifdef DBUS_WINCE
03505
03506 return "unknown";
03507 #else
03508 const char *msg;
03509
03510 switch (error_number)
03511 {
03512 case WSAEINTR:
03513 return "Interrupted function call";
03514 case WSAEACCES:
03515 return "Permission denied";
03516 case WSAEFAULT:
03517 return "Bad address";
03518 case WSAEINVAL:
03519 return "Invalid argument";
03520 case WSAEMFILE:
03521 return "Too many open files";
03522 case WSAEWOULDBLOCK:
03523 return "Resource temporarily unavailable";
03524 case WSAEINPROGRESS:
03525 return "Operation now in progress";
03526 case WSAEALREADY:
03527 return "Operation already in progress";
03528 case WSAENOTSOCK:
03529 return "Socket operation on nonsocket";
03530 case WSAEDESTADDRREQ:
03531 return "Destination address required";
03532 case WSAEMSGSIZE:
03533 return "Message too long";
03534 case WSAEPROTOTYPE:
03535 return "Protocol wrong type for socket";
03536 case WSAENOPROTOOPT:
03537 return "Bad protocol option";
03538 case WSAEPROTONOSUPPORT:
03539 return "Protocol not supported";
03540 case WSAESOCKTNOSUPPORT:
03541 return "Socket type not supported";
03542 case WSAEOPNOTSUPP:
03543 return "Operation not supported";
03544 case WSAEPFNOSUPPORT:
03545 return "Protocol family not supported";
03546 case WSAEAFNOSUPPORT:
03547 return "Address family not supported by protocol family";
03548 case WSAEADDRINUSE:
03549 return "Address already in use";
03550 case WSAEADDRNOTAVAIL:
03551 return "Cannot assign requested address";
03552 case WSAENETDOWN:
03553 return "Network is down";
03554 case WSAENETUNREACH:
03555 return "Network is unreachable";
03556 case WSAENETRESET:
03557 return "Network dropped connection on reset";
03558 case WSAECONNABORTED:
03559 return "Software caused connection abort";
03560 case WSAECONNRESET:
03561 return "Connection reset by peer";
03562 case WSAENOBUFS:
03563 return "No buffer space available";
03564 case WSAEISCONN:
03565 return "Socket is already connected";
03566 case WSAENOTCONN:
03567 return "Socket is not connected";
03568 case WSAESHUTDOWN:
03569 return "Cannot send after socket shutdown";
03570 case WSAETIMEDOUT:
03571 return "Connection timed out";
03572 case WSAECONNREFUSED:
03573 return "Connection refused";
03574 case WSAEHOSTDOWN:
03575 return "Host is down";
03576 case WSAEHOSTUNREACH:
03577 return "No route to host";
03578 case WSAEPROCLIM:
03579 return "Too many processes";
03580 case WSAEDISCON:
03581 return "Graceful shutdown in progress";
03582 case WSATYPE_NOT_FOUND:
03583 return "Class type not found";
03584 case WSAHOST_NOT_FOUND:
03585 return "Host not found";
03586 case WSATRY_AGAIN:
03587 return "Nonauthoritative host not found";
03588 case WSANO_RECOVERY:
03589 return "This is a nonrecoverable error";
03590 case WSANO_DATA:
03591 return "Valid name, no data record of requested type";
03592 case WSA_INVALID_HANDLE:
03593 return "Specified event object handle is invalid";
03594 case WSA_INVALID_PARAMETER:
03595 return "One or more parameters are invalid";
03596 case WSA_IO_INCOMPLETE:
03597 return "Overlapped I/O event object not in signaled state";
03598 case WSA_IO_PENDING:
03599 return "Overlapped operations will complete later";
03600 case WSA_NOT_ENOUGH_MEMORY:
03601 return "Insufficient memory available";
03602 case WSA_OPERATION_ABORTED:
03603 return "Overlapped operation aborted";
03604 #ifdef WSAINVALIDPROCTABLE
03605
03606 case WSAINVALIDPROCTABLE:
03607 return "Invalid procedure table from service provider";
03608 #endif
03609 #ifdef WSAINVALIDPROVIDER
03610
03611 case WSAINVALIDPROVIDER:
03612 return "Invalid service provider version number";
03613 #endif
03614 #ifdef WSAPROVIDERFAILEDINIT
03615
03616 case WSAPROVIDERFAILEDINIT:
03617 return "Unable to initialize a service provider";
03618 #endif
03619
03620 case WSASYSCALLFAILURE:
03621 return "System call failure";
03622 }
03623 msg = strerror (error_number);
03624 if (msg == NULL)
03625 msg = "unknown";
03626
03627 return msg;
03628 #endif //DBUS_WINCE
03629 }
03630
03638 void
03639 _dbus_win_set_error_from_win_error (DBusError *error,
03640 int code)
03641 {
03642 char *msg;
03643
03644
03645 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
03646 FORMAT_MESSAGE_IGNORE_INSERTS |
03647 FORMAT_MESSAGE_FROM_SYSTEM,
03648 NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
03649 (LPSTR) &msg, 0, NULL);
03650 if (msg)
03651 {
03652 dbus_set_error (error, "win32.error", "%s", msg);
03653 LocalFree (msg);
03654 }
03655 else
03656 dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code);
03657 }
03658
03659 void
03660 _dbus_win_warn_win_error (const char *message,
03661 unsigned long code)
03662 {
03663 DBusError error;
03664
03665 dbus_error_init (&error);
03666 _dbus_win_set_error_from_win_error (&error, code);
03667 _dbus_warn ("%s: %s\n", message, error.message);
03668 dbus_error_free (&error);
03669 }
03670
03678 dbus_bool_t
03679 _dbus_delete_directory (const DBusString *filename,
03680 DBusError *error)
03681 {
03682 const char *filename_c;
03683
03684 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03685
03686 filename_c = _dbus_string_get_const_data (filename);
03687
03688 if (RemoveDirectoryA (filename_c) == 0)
03689 {
03690 char *emsg = _dbus_win_error_string (GetLastError ());
03691 dbus_set_error (error, _dbus_win_error_from_last_error (),
03692 "Failed to remove directory %s: %s",
03693 filename_c, emsg);
03694 _dbus_win_free_error_string (emsg);
03695 return FALSE;
03696 }
03697
03698 return TRUE;
03699 }
03700
03707 dbus_bool_t
03708 _dbus_path_is_absolute (const DBusString *filename)
03709 {
03710 if (_dbus_string_get_length (filename) > 0)
03711 return _dbus_string_get_byte (filename, 1) == ':'
03712 || _dbus_string_get_byte (filename, 0) == '\\'
03713 || _dbus_string_get_byte (filename, 0) == '/';
03714 else
03715 return FALSE;
03716 }
03717
03718 dbus_bool_t
03719 _dbus_check_setuid (void)
03720 {
03721 return FALSE;
03722 }
03723
03724 int
03725 _dbus_save_socket_errno (void)
03726 {
03727 return errno;
03728 }
03729
03730 void
03731 _dbus_restore_socket_errno (int saved_errno)
03732 {
03733 _dbus_win_set_errno (saved_errno);
03734 }
03735
03737
03738