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 if (GetLastError () == ERROR_ALREADY_EXISTS)
02247 return TRUE;
02248
02249 dbus_set_error (error, DBUS_ERROR_FAILED,
02250 "Failed to create directory %s: %s\n",
02251 filename_c, _dbus_strerror_from_errno ());
02252 return FALSE;
02253 }
02254 else
02255 return TRUE;
02256 }
02257
02258
02268 dbus_bool_t
02269 _dbus_generate_random_bytes (DBusString *str,
02270 int n_bytes,
02271 DBusError *error)
02272 {
02273 int old_len;
02274 char *p;
02275 HCRYPTPROV hprov;
02276
02277 old_len = _dbus_string_get_length (str);
02278
02279 if (!_dbus_string_lengthen (str, n_bytes))
02280 {
02281 _DBUS_SET_OOM (error);
02282 return FALSE;
02283 }
02284
02285 p = _dbus_string_get_data_len (str, old_len, n_bytes);
02286
02287 if (!CryptAcquireContext (&hprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
02288 {
02289 _DBUS_SET_OOM (error);
02290 return FALSE;
02291 }
02292
02293 if (!CryptGenRandom (hprov, n_bytes, p))
02294 {
02295 _DBUS_SET_OOM (error);
02296 CryptReleaseContext (hprov, 0);
02297 return FALSE;
02298 }
02299
02300 CryptReleaseContext (hprov, 0);
02301
02302 return TRUE;
02303 }
02304
02311 const char*
02312 _dbus_get_tmpdir(void)
02313 {
02314
02315 static const char* tmpdir = NULL;
02316 static char buf[1000];
02317
02318 if (!_DBUS_LOCK (sysdeps))
02319 return NULL;
02320
02321 if (tmpdir == NULL)
02322 {
02323 char *last_slash;
02324
02325 if (!GetTempPathA (sizeof (buf), buf))
02326 {
02327 _dbus_warn ("GetTempPath failed\n");
02328 _dbus_abort ();
02329 }
02330
02331
02332 last_slash = _mbsrchr (buf, '\\');
02333 if (last_slash > buf && last_slash[1] == '\0')
02334 last_slash[0] = '\0';
02335 last_slash = _mbsrchr (buf, '/');
02336 if (last_slash > buf && last_slash[1] == '\0')
02337 last_slash[0] = '\0';
02338
02339 tmpdir = buf;
02340 }
02341
02342 _DBUS_UNLOCK (sysdeps);
02343
02344 _dbus_assert(tmpdir != NULL);
02345
02346 return tmpdir;
02347 }
02348
02349
02358 dbus_bool_t
02359 _dbus_delete_file (const DBusString *filename,
02360 DBusError *error)
02361 {
02362 const char *filename_c;
02363
02364 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02365
02366 filename_c = _dbus_string_get_const_data (filename);
02367
02368 if (DeleteFileA (filename_c) == 0)
02369 {
02370 dbus_set_error (error, DBUS_ERROR_FAILED,
02371 "Failed to delete file %s: %s\n",
02372 filename_c, _dbus_strerror_from_errno ());
02373 return FALSE;
02374 }
02375 else
02376 return TRUE;
02377 }
02378
02379 #if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_ENABLE_EMBEDDED_TESTS)
02380
02381 #if defined(_MSC_VER) || defined(DBUS_WINCE)
02382 # ifdef BACKTRACES
02383 # undef BACKTRACES
02384 # endif
02385 #else
02386 # define BACKTRACES
02387 #endif
02388
02389 #ifdef BACKTRACES
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411 #include <winver.h>
02412 #include <imagehlp.h>
02413 #include <stdio.h>
02414
02415 #define DPRINTF(fmt, ...) fprintf (stderr, fmt, ##__VA_ARGS__)
02416
02417 #ifdef _MSC_VER
02418 #define BOOL int
02419
02420 #define __i386__
02421 #endif
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431 static BOOL (WINAPI *pStackWalk)(
02432 DWORD MachineType,
02433 HANDLE hProcess,
02434 HANDLE hThread,
02435 LPSTACKFRAME StackFrame,
02436 PVOID ContextRecord,
02437 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
02438 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
02439 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
02440 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
02441 );
02442 #ifdef _WIN64
02443 static DWORD64 (WINAPI *pSymGetModuleBase)(
02444 HANDLE hProcess,
02445 DWORD64 dwAddr
02446 );
02447 static PVOID (WINAPI *pSymFunctionTableAccess)(
02448 HANDLE hProcess,
02449 DWORD64 AddrBase
02450 );
02451 #else
02452 static DWORD (WINAPI *pSymGetModuleBase)(
02453 HANDLE hProcess,
02454 DWORD dwAddr
02455 );
02456 static PVOID (WINAPI *pSymFunctionTableAccess)(
02457 HANDLE hProcess,
02458 DWORD AddrBase
02459 );
02460 #endif
02461 static BOOL (WINAPI *pSymInitialize)(
02462 HANDLE hProcess,
02463 PSTR UserSearchPath,
02464 BOOL fInvadeProcess
02465 );
02466 static BOOL (WINAPI *pSymGetSymFromAddr)(
02467 HANDLE hProcess,
02468 DWORD Address,
02469 PDWORD Displacement,
02470 PIMAGEHLP_SYMBOL Symbol
02471 );
02472 static BOOL (WINAPI *pSymGetModuleInfo)(
02473 HANDLE hProcess,
02474 DWORD dwAddr,
02475 PIMAGEHLP_MODULE ModuleInfo
02476 );
02477 static DWORD (WINAPI *pSymSetOptions)(
02478 DWORD SymOptions
02479 );
02480
02481
02482 static BOOL init_backtrace()
02483 {
02484 HMODULE hmodDbgHelp = LoadLibraryA("dbghelp");
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502 #define FUNC(x) #x
02503
02504 pStackWalk = (BOOL (WINAPI *)(
02505 DWORD MachineType,
02506 HANDLE hProcess,
02507 HANDLE hThread,
02508 LPSTACKFRAME StackFrame,
02509 PVOID ContextRecord,
02510 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
02511 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
02512 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
02513 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
02514 ))GetProcAddress (hmodDbgHelp, FUNC(StackWalk));
02515 #ifdef _WIN64
02516 pSymGetModuleBase=(DWORD64 (WINAPI *)(
02517 HANDLE hProcess,
02518 DWORD64 dwAddr
02519 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
02520 pSymFunctionTableAccess=(PVOID (WINAPI *)(
02521 HANDLE hProcess,
02522 DWORD64 AddrBase
02523 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
02524 #else
02525 pSymGetModuleBase=(DWORD (WINAPI *)(
02526 HANDLE hProcess,
02527 DWORD dwAddr
02528 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase));
02529 pSymFunctionTableAccess=(PVOID (WINAPI *)(
02530 HANDLE hProcess,
02531 DWORD AddrBase
02532 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess));
02533 #endif
02534 pSymInitialize = (BOOL (WINAPI *)(
02535 HANDLE hProcess,
02536 PSTR UserSearchPath,
02537 BOOL fInvadeProcess
02538 ))GetProcAddress (hmodDbgHelp, FUNC(SymInitialize));
02539 pSymGetSymFromAddr = (BOOL (WINAPI *)(
02540 HANDLE hProcess,
02541 DWORD Address,
02542 PDWORD Displacement,
02543 PIMAGEHLP_SYMBOL Symbol
02544 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetSymFromAddr));
02545 pSymGetModuleInfo = (BOOL (WINAPI *)(
02546 HANDLE hProcess,
02547 DWORD dwAddr,
02548 PIMAGEHLP_MODULE ModuleInfo
02549 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleInfo));
02550 pSymSetOptions = (DWORD (WINAPI *)(
02551 DWORD SymOptions
02552 ))GetProcAddress (hmodDbgHelp, FUNC(SymSetOptions));
02553
02554
02555 pSymSetOptions(SYMOPT_UNDNAME);
02556
02557 pSymInitialize(GetCurrentProcess(), NULL, TRUE);
02558
02559 return TRUE;
02560 }
02561
02562 static void dump_backtrace_for_thread(HANDLE hThread)
02563 {
02564 STACKFRAME sf;
02565 CONTEXT context;
02566 DWORD dwImageType;
02567
02568 if (!pStackWalk)
02569 if (!init_backtrace())
02570 return;
02571
02572
02573
02574 if (hThread == GetCurrentThread())
02575 return;
02576
02577 DPRINTF("Backtrace:\n");
02578
02579 _DBUS_ZERO(context);
02580 context.ContextFlags = CONTEXT_FULL;
02581
02582 SuspendThread(hThread);
02583
02584 if (!GetThreadContext(hThread, &context))
02585 {
02586 DPRINTF("Couldn't get thread context (error %ld)\n", GetLastError());
02587 ResumeThread(hThread);
02588 return;
02589 }
02590
02591 _DBUS_ZERO(sf);
02592
02593 #ifdef __i386__
02594 sf.AddrFrame.Offset = context.Ebp;
02595 sf.AddrFrame.Mode = AddrModeFlat;
02596 sf.AddrPC.Offset = context.Eip;
02597 sf.AddrPC.Mode = AddrModeFlat;
02598 dwImageType = IMAGE_FILE_MACHINE_I386;
02599 #elif _M_X64
02600 dwImageType = IMAGE_FILE_MACHINE_AMD64;
02601 sf.AddrPC.Offset = context.Rip;
02602 sf.AddrPC.Mode = AddrModeFlat;
02603 sf.AddrFrame.Offset = context.Rsp;
02604 sf.AddrFrame.Mode = AddrModeFlat;
02605 sf.AddrStack.Offset = context.Rsp;
02606 sf.AddrStack.Mode = AddrModeFlat;
02607 #elif _M_IA64
02608 dwImageType = IMAGE_FILE_MACHINE_IA64;
02609 sf.AddrPC.Offset = context.StIIP;
02610 sf.AddrPC.Mode = AddrModeFlat;
02611 sf.AddrFrame.Offset = context.IntSp;
02612 sf.AddrFrame.Mode = AddrModeFlat;
02613 sf.AddrBStore.Offset= context.RsBSP;
02614 sf.AddrBStore.Mode = AddrModeFlat;
02615 sf.AddrStack.Offset = context.IntSp;
02616 sf.AddrStack.Mode = AddrModeFlat;
02617 #else
02618 # error You need to fill in the STACKFRAME structure for your architecture
02619 #endif
02620
02621 while (pStackWalk(dwImageType, GetCurrentProcess(),
02622 hThread, &sf, &context, NULL, pSymFunctionTableAccess,
02623 pSymGetModuleBase, NULL))
02624 {
02625 BYTE buffer[256];
02626 IMAGEHLP_SYMBOL * pSymbol = (IMAGEHLP_SYMBOL *)buffer;
02627 DWORD dwDisplacement;
02628
02629 pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
02630 pSymbol->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1;
02631
02632 if (!pSymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset,
02633 &dwDisplacement, pSymbol))
02634 {
02635 IMAGEHLP_MODULE ModuleInfo;
02636 ModuleInfo.SizeOfStruct = sizeof(ModuleInfo);
02637
02638 if (!pSymGetModuleInfo(GetCurrentProcess(), sf.AddrPC.Offset,
02639 &ModuleInfo))
02640 DPRINTF("1\t%p\n", (void*)sf.AddrPC.Offset);
02641 else
02642 DPRINTF("2\t%s+0x%lx\n", ModuleInfo.ImageName,
02643 sf.AddrPC.Offset - ModuleInfo.BaseOfImage);
02644 }
02645 else if (dwDisplacement)
02646 DPRINTF("3\t%s+0x%lx\n", pSymbol->Name, dwDisplacement);
02647 else
02648 DPRINTF("4\t%s\n", pSymbol->Name);
02649 }
02650
02651 ResumeThread(hThread);
02652 }
02653
02654 static DWORD WINAPI dump_thread_proc(LPVOID lpParameter)
02655 {
02656 dump_backtrace_for_thread((HANDLE)lpParameter);
02657 return 0;
02658 }
02659
02660
02661
02662 static void dump_backtrace()
02663 {
02664 HANDLE hCurrentThread;
02665 HANDLE hThread;
02666 DWORD dwThreadId;
02667 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
02668 GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
02669 hThread = CreateThread(NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread,
02670 0, &dwThreadId);
02671 WaitForSingleObject(hThread, INFINITE);
02672 CloseHandle(hThread);
02673 CloseHandle(hCurrentThread);
02674 }
02675 #endif
02676 #endif
02677
02678 #ifdef BACKTRACES
02679 void _dbus_print_backtrace(void)
02680 {
02681 init_backtrace();
02682 dump_backtrace();
02683 }
02684 #else
02685 void _dbus_print_backtrace(void)
02686 {
02687 _dbus_verbose (" D-Bus not compiled with backtrace support\n");
02688 }
02689 #endif
02690
02691 static dbus_uint32_t fromAscii(char ascii)
02692 {
02693 if(ascii >= '0' && ascii <= '9')
02694 return ascii - '0';
02695 if(ascii >= 'A' && ascii <= 'F')
02696 return ascii - 'A' + 10;
02697 if(ascii >= 'a' && ascii <= 'f')
02698 return ascii - 'a' + 10;
02699 return 0;
02700 }
02701
02702 dbus_bool_t _dbus_read_local_machine_uuid (DBusGUID *machine_id,
02703 dbus_bool_t create_if_not_found,
02704 DBusError *error)
02705 {
02706 #ifdef DBUS_WINCE
02707 return TRUE;
02708
02709 #else
02710 HW_PROFILE_INFOA info;
02711 char *lpc = &info.szHwProfileGuid[0];
02712 dbus_uint32_t u;
02713
02714
02715 if(!GetCurrentHwProfileA(&info))
02716 {
02717 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02718 return FALSE;
02719 }
02720
02721
02722 lpc++;
02723
02724 u = ((fromAscii(lpc[0]) << 0) |
02725 (fromAscii(lpc[1]) << 4) |
02726 (fromAscii(lpc[2]) << 8) |
02727 (fromAscii(lpc[3]) << 12) |
02728 (fromAscii(lpc[4]) << 16) |
02729 (fromAscii(lpc[5]) << 20) |
02730 (fromAscii(lpc[6]) << 24) |
02731 (fromAscii(lpc[7]) << 28));
02732 machine_id->as_uint32s[0] = u;
02733
02734 lpc += 9;
02735
02736 u = ((fromAscii(lpc[0]) << 0) |
02737 (fromAscii(lpc[1]) << 4) |
02738 (fromAscii(lpc[2]) << 8) |
02739 (fromAscii(lpc[3]) << 12) |
02740 (fromAscii(lpc[5]) << 16) |
02741 (fromAscii(lpc[6]) << 20) |
02742 (fromAscii(lpc[7]) << 24) |
02743 (fromAscii(lpc[8]) << 28));
02744 machine_id->as_uint32s[1] = u;
02745
02746 lpc += 10;
02747
02748 u = ((fromAscii(lpc[0]) << 0) |
02749 (fromAscii(lpc[1]) << 4) |
02750 (fromAscii(lpc[2]) << 8) |
02751 (fromAscii(lpc[3]) << 12) |
02752 (fromAscii(lpc[5]) << 16) |
02753 (fromAscii(lpc[6]) << 20) |
02754 (fromAscii(lpc[7]) << 24) |
02755 (fromAscii(lpc[8]) << 28));
02756 machine_id->as_uint32s[2] = u;
02757
02758 lpc += 9;
02759
02760 u = ((fromAscii(lpc[0]) << 0) |
02761 (fromAscii(lpc[1]) << 4) |
02762 (fromAscii(lpc[2]) << 8) |
02763 (fromAscii(lpc[3]) << 12) |
02764 (fromAscii(lpc[4]) << 16) |
02765 (fromAscii(lpc[5]) << 20) |
02766 (fromAscii(lpc[6]) << 24) |
02767 (fromAscii(lpc[7]) << 28));
02768 machine_id->as_uint32s[3] = u;
02769 #endif
02770 return TRUE;
02771 }
02772
02773 static
02774 HANDLE _dbus_global_lock (const char *mutexname)
02775 {
02776 HANDLE mutex;
02777 DWORD gotMutex;
02778
02779 mutex = CreateMutexA( NULL, FALSE, mutexname );
02780 if( !mutex )
02781 {
02782 return FALSE;
02783 }
02784
02785 gotMutex = WaitForSingleObject( mutex, INFINITE );
02786 switch( gotMutex )
02787 {
02788 case WAIT_ABANDONED:
02789 ReleaseMutex (mutex);
02790 CloseHandle (mutex);
02791 return 0;
02792 case WAIT_FAILED:
02793 case WAIT_TIMEOUT:
02794 return 0;
02795 }
02796
02797 return mutex;
02798 }
02799
02800 static
02801 void _dbus_global_unlock (HANDLE mutex)
02802 {
02803 ReleaseMutex (mutex);
02804 CloseHandle (mutex);
02805 }
02806
02807
02808 static HANDLE hDBusDaemonMutex = NULL;
02809 static HANDLE hDBusSharedMem = NULL;
02810
02811 static const char *cUniqueDBusInitMutex = "UniqueDBusInitMutex";
02812
02813 static const char *cDBusAutolaunchMutex = "DBusAutolaunchMutex";
02814
02815 static const char *cDBusDaemonMutex = "DBusDaemonMutex";
02816
02817 static const char *cDBusDaemonAddressInfo = "DBusDaemonAddressInfo";
02818
02819 static dbus_bool_t
02820 _dbus_get_install_root_as_hash(DBusString *out)
02821 {
02822 DBusString install_path;
02823
02824 char path[MAX_PATH*2];
02825 int path_size = sizeof(path);
02826
02827 if (!_dbus_get_install_root(path,path_size))
02828 return FALSE;
02829
02830 _dbus_string_init(&install_path);
02831 _dbus_string_append(&install_path,path);
02832
02833 _dbus_string_init(out);
02834 _dbus_string_tolower_ascii(&install_path,0,_dbus_string_get_length(&install_path));
02835
02836 if (!_dbus_sha_compute (&install_path, out))
02837 return FALSE;
02838
02839 return TRUE;
02840 }
02841
02842 static dbus_bool_t
02843 _dbus_get_address_string (DBusString *out, const char *basestring, const char *scope)
02844 {
02845 _dbus_string_init(out);
02846 _dbus_string_append(out,basestring);
02847
02848 if (!scope)
02849 {
02850 return TRUE;
02851 }
02852 else if (strcmp(scope,"*install-path") == 0
02853
02854 || strcmp(scope,"install-path") == 0)
02855 {
02856 DBusString temp;
02857 if (!_dbus_get_install_root_as_hash(&temp))
02858 {
02859 _dbus_string_free(out);
02860 return FALSE;
02861 }
02862 _dbus_string_append(out,"-");
02863 _dbus_string_append(out,_dbus_string_get_const_data(&temp));
02864 _dbus_string_free(&temp);
02865 }
02866 else if (strcmp(scope,"*user") == 0)
02867 {
02868 _dbus_string_append(out,"-");
02869 if (!_dbus_append_user_from_current_process(out))
02870 {
02871 _dbus_string_free(out);
02872 return FALSE;
02873 }
02874 }
02875 else if (strlen(scope) > 0)
02876 {
02877 _dbus_string_append(out,"-");
02878 _dbus_string_append(out,scope);
02879 return TRUE;
02880 }
02881 return TRUE;
02882 }
02883
02884 static dbus_bool_t
02885 _dbus_get_shm_name (DBusString *out,const char *scope)
02886 {
02887 return _dbus_get_address_string (out,cDBusDaemonAddressInfo,scope);
02888 }
02889
02890 static dbus_bool_t
02891 _dbus_get_mutex_name (DBusString *out,const char *scope)
02892 {
02893 return _dbus_get_address_string (out,cDBusDaemonMutex,scope);
02894 }
02895
02896 dbus_bool_t
02897 _dbus_daemon_is_session_bus_address_published (const char *scope)
02898 {
02899 HANDLE lock;
02900 DBusString mutex_name;
02901
02902 if (!_dbus_get_mutex_name(&mutex_name,scope))
02903 {
02904 _dbus_string_free( &mutex_name );
02905 return FALSE;
02906 }
02907
02908 if (hDBusDaemonMutex)
02909 return TRUE;
02910
02911
02912 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02913
02914
02915
02916 hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02917
02918
02919
02920
02921
02922 _dbus_global_unlock( lock );
02923
02924 _dbus_string_free( &mutex_name );
02925
02926 if (hDBusDaemonMutex == NULL)
02927 return FALSE;
02928 if (GetLastError() == ERROR_ALREADY_EXISTS)
02929 {
02930 CloseHandle(hDBusDaemonMutex);
02931 hDBusDaemonMutex = NULL;
02932 return TRUE;
02933 }
02934
02935
02936
02937 return FALSE;
02938 }
02939
02940 dbus_bool_t
02941 _dbus_daemon_publish_session_bus_address (const char* address, const char *scope)
02942 {
02943 HANDLE lock;
02944 char *shared_addr = NULL;
02945 DBusString shm_name;
02946 DBusString mutex_name;
02947 dbus_uint64_t len;
02948
02949 _dbus_assert (address);
02950
02951 if (!_dbus_get_mutex_name(&mutex_name,scope))
02952 {
02953 _dbus_string_free( &mutex_name );
02954 return FALSE;
02955 }
02956
02957
02958 lock = _dbus_global_lock( cUniqueDBusInitMutex );
02959
02960 if (!hDBusDaemonMutex)
02961 {
02962 hDBusDaemonMutex = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
02963 }
02964 _dbus_string_free( &mutex_name );
02965
02966
02967 if (WaitForSingleObject( hDBusDaemonMutex, 10 ) != WAIT_OBJECT_0)
02968 {
02969 _dbus_global_unlock( lock );
02970 CloseHandle( hDBusDaemonMutex );
02971 return FALSE;
02972 }
02973
02974 if (!_dbus_get_shm_name(&shm_name,scope))
02975 {
02976 _dbus_string_free( &shm_name );
02977 _dbus_global_unlock( lock );
02978 return FALSE;
02979 }
02980
02981
02982 len = strlen (address) + 1;
02983
02984 hDBusSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
02985 len >> 32, len & 0xffffffffu,
02986 _dbus_string_get_const_data(&shm_name) );
02987 _dbus_assert( hDBusSharedMem );
02988
02989 shared_addr = MapViewOfFile( hDBusSharedMem, FILE_MAP_WRITE, 0, 0, 0 );
02990
02991 _dbus_assert (shared_addr);
02992
02993 strcpy( shared_addr, address);
02994
02995
02996 UnmapViewOfFile( shared_addr );
02997
02998 _dbus_global_unlock( lock );
02999 _dbus_verbose( "published session bus address at %s\n",_dbus_string_get_const_data (&shm_name) );
03000
03001 _dbus_string_free( &shm_name );
03002 return TRUE;
03003 }
03004
03005 void
03006 _dbus_daemon_unpublish_session_bus_address (void)
03007 {
03008 HANDLE lock;
03009
03010
03011 lock = _dbus_global_lock( cUniqueDBusInitMutex );
03012
03013 CloseHandle( hDBusSharedMem );
03014
03015 hDBusSharedMem = NULL;
03016
03017 ReleaseMutex( hDBusDaemonMutex );
03018
03019 CloseHandle( hDBusDaemonMutex );
03020
03021 hDBusDaemonMutex = NULL;
03022
03023 _dbus_global_unlock( lock );
03024 }
03025
03026 static dbus_bool_t
03027 _dbus_get_autolaunch_shm (DBusString *address, DBusString *shm_name)
03028 {
03029 HANDLE sharedMem;
03030 char *shared_addr;
03031 int i;
03032
03033
03034 for(i=0;i<20;++i) {
03035
03036 sharedMem = OpenFileMappingA( FILE_MAP_READ, FALSE, _dbus_string_get_const_data(shm_name));
03037 if( sharedMem == 0 )
03038 Sleep( 100 );
03039 if ( sharedMem != 0)
03040 break;
03041 }
03042
03043 if( sharedMem == 0 )
03044 return FALSE;
03045
03046 shared_addr = MapViewOfFile( sharedMem, FILE_MAP_READ, 0, 0, 0 );
03047
03048 if( !shared_addr )
03049 return FALSE;
03050
03051 _dbus_string_init( address );
03052
03053 _dbus_string_append( address, shared_addr );
03054
03055
03056 UnmapViewOfFile( shared_addr );
03057
03058 CloseHandle( sharedMem );
03059
03060 return TRUE;
03061 }
03062
03063 static dbus_bool_t
03064 _dbus_daemon_already_runs (DBusString *address, DBusString *shm_name, const char *scope)
03065 {
03066 HANDLE lock;
03067 HANDLE daemon;
03068 DBusString mutex_name;
03069 dbus_bool_t bRet = TRUE;
03070
03071 if (!_dbus_get_mutex_name(&mutex_name,scope))
03072 {
03073 _dbus_string_free( &mutex_name );
03074 return FALSE;
03075 }
03076
03077
03078 lock = _dbus_global_lock( cUniqueDBusInitMutex );
03079
03080
03081 daemon = CreateMutexA( NULL, FALSE, _dbus_string_get_const_data(&mutex_name) );
03082 if(WaitForSingleObject( daemon, 10 ) != WAIT_TIMEOUT)
03083 {
03084 ReleaseMutex (daemon);
03085 CloseHandle (daemon);
03086
03087 _dbus_global_unlock( lock );
03088 _dbus_string_free( &mutex_name );
03089 return FALSE;
03090 }
03091
03092
03093 bRet = _dbus_get_autolaunch_shm( address, shm_name );
03094
03095
03096 CloseHandle ( daemon );
03097
03098 _dbus_global_unlock( lock );
03099 _dbus_string_free( &mutex_name );
03100
03101 return bRet;
03102 }
03103
03104 dbus_bool_t
03105 _dbus_get_autolaunch_address (const char *scope, DBusString *address,
03106 DBusError *error)
03107 {
03108 HANDLE mutex;
03109 STARTUPINFOA si;
03110 PROCESS_INFORMATION pi;
03111 dbus_bool_t retval = FALSE;
03112 LPSTR lpFile;
03113 char dbus_exe_path[MAX_PATH];
03114 char dbus_args[MAX_PATH * 2];
03115 const char * daemon_name = DBUS_DAEMON_NAME ".exe";
03116 DBusString shm_name;
03117
03118 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03119
03120 if (!_dbus_get_shm_name(&shm_name,scope))
03121 {
03122 dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not determine shm name");
03123 return FALSE;
03124 }
03125
03126 mutex = _dbus_global_lock ( cDBusAutolaunchMutex );
03127
03128 if (_dbus_daemon_already_runs(address,&shm_name,scope))
03129 {
03130 _dbus_verbose( "found running dbus daemon for scope '%s' at %s\n",
03131 scope ? scope : "", _dbus_string_get_const_data (&shm_name) );
03132 retval = TRUE;
03133 goto out;
03134 }
03135
03136 if (!SearchPathA(NULL, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
03137 {
03138
03139 HMODULE hmod;
03140 char dbus_module_path[MAX_PATH];
03141 DWORD rc;
03142
03143 _dbus_verbose( "did not found dbus daemon executable on default search path, "
03144 "trying path where dbus shared library is located");
03145
03146 hmod = _dbus_win_get_dll_hmodule();
03147 rc = GetModuleFileNameA(hmod, dbus_module_path, sizeof(dbus_module_path));
03148 if (rc <= 0)
03149 {
03150 dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not retrieve dbus shared library file name");
03151 retval = FALSE;
03152 goto out;
03153 }
03154 else
03155 {
03156 char *ext_idx = strrchr(dbus_module_path, '\\');
03157 if (ext_idx)
03158 *ext_idx = '\0';
03159 if (!SearchPathA(dbus_module_path, daemon_name, NULL, sizeof(dbus_exe_path), dbus_exe_path, &lpFile))
03160 {
03161 dbus_set_error_const (error, DBUS_ERROR_FAILED, "could not find dbus-daemon executable");
03162 retval = FALSE;
03163 printf ("please add the path to %s to your PATH environment variable\n", daemon_name);
03164 printf ("or start the daemon manually\n\n");
03165 goto out;
03166 }
03167 _dbus_verbose( "found dbus daemon executable at %s",dbus_module_path);
03168 }
03169 }
03170
03171
03172
03173 ZeroMemory( &si, sizeof(si) );
03174 si.cb = sizeof(si);
03175 ZeroMemory( &pi, sizeof(pi) );
03176
03177 _snprintf(dbus_args, sizeof(dbus_args) - 1, "\"%s\" %s", dbus_exe_path, " --session");
03178
03179
03180
03181 if(CreateProcessA(dbus_exe_path, dbus_args, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
03182 {
03183 CloseHandle (pi.hThread);
03184 CloseHandle (pi.hProcess);
03185 retval = _dbus_get_autolaunch_shm( address, &shm_name );
03186 if (retval == FALSE)
03187 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to get autolaunch address from launched dbus-daemon");
03188 }
03189 else
03190 {
03191 dbus_set_error_const (error, DBUS_ERROR_FAILED, "Failed to launch dbus-daemon");
03192 retval = FALSE;
03193 }
03194
03195 out:
03196 if (retval)
03197 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03198 else
03199 _DBUS_ASSERT_ERROR_IS_SET (error);
03200
03201 _dbus_global_unlock (mutex);
03202 _dbus_string_free (&shm_name);
03203
03204 return retval;
03205 }
03206
03207
03214 dbus_bool_t
03215 _dbus_make_file_world_readable(const DBusString *filename,
03216 DBusError *error)
03217 {
03218
03219 return TRUE;
03220 }
03221
03229 dbus_int32_t
03230 _dbus_atomic_inc (DBusAtomic *atomic)
03231 {
03232
03233
03234 return InterlockedIncrement (&atomic->value) - 1;
03235 }
03236
03244 dbus_int32_t
03245 _dbus_atomic_dec (DBusAtomic *atomic)
03246 {
03247
03248
03249 return InterlockedDecrement (&atomic->value) + 1;
03250 }
03251
03259 dbus_int32_t
03260 _dbus_atomic_get (DBusAtomic *atomic)
03261 {
03262
03263
03264
03265
03266
03267
03268
03269
03270 long dummy = 0;
03271
03272 InterlockedExchange (&dummy, 1);
03273
03274 return atomic->value;
03275 }
03276
03284 void
03285 _dbus_flush_caches (void)
03286 {
03287 }
03288
03295 dbus_bool_t
03296 _dbus_get_is_errno_eagain_or_ewouldblock (int e)
03297 {
03298 return e == WSAEWOULDBLOCK;
03299 }
03300
03308 dbus_bool_t
03309 _dbus_get_install_root(char *prefix, int len)
03310 {
03311
03312 DWORD pathLength;
03313 char *lastSlash;
03314 SetLastError( 0 );
03315 pathLength = GetModuleFileNameA(_dbus_win_get_dll_hmodule(), prefix, len);
03316 if ( pathLength == 0 || GetLastError() != 0 ) {
03317 *prefix = '\0';
03318 return FALSE;
03319 }
03320 lastSlash = _mbsrchr(prefix, '\\');
03321 if (lastSlash == NULL) {
03322 *prefix = '\0';
03323 return FALSE;
03324 }
03325
03326 lastSlash[1] = 0;
03327
03328
03329
03330
03331
03332
03333
03334 if (lastSlash - prefix >= 4 && strnicmp(lastSlash - 4, "\\bin", 4) == 0)
03335 lastSlash[-3] = 0;
03336 else if (lastSlash - prefix >= 10 && strnicmp(lastSlash - 10, "\\bin\\debug", 10) == 0)
03337 lastSlash[-9] = 0;
03338 else if (lastSlash - prefix >= 12 && strnicmp(lastSlash - 12, "\\bin\\release", 12) == 0)
03339 lastSlash[-11] = 0;
03340
03341 return TRUE;
03342 }
03343
03344
03345 dbus_bool_t
03346 _dbus_lookup_session_address (dbus_bool_t *supported,
03347 DBusString *address,
03348 DBusError *error)
03349 {
03350
03351 *supported = FALSE;
03352 return TRUE;
03353 }
03354
03368 dbus_bool_t
03369 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03370 DBusCredentials *credentials)
03371 {
03372 DBusString homedir;
03373 DBusString dotdir;
03374 const char *homepath;
03375 const char *homedrive;
03376
03377 _dbus_assert (credentials != NULL);
03378 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03379
03380 if (!_dbus_string_init (&homedir))
03381 return FALSE;
03382
03383 homedrive = _dbus_getenv("HOMEDRIVE");
03384 if (homedrive != NULL && *homedrive != '\0')
03385 {
03386 _dbus_string_append(&homedir,homedrive);
03387 }
03388
03389 homepath = _dbus_getenv("HOMEPATH");
03390 if (homepath != NULL && *homepath != '\0')
03391 {
03392 _dbus_string_append(&homedir,homepath);
03393 }
03394
03395 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
03396 {
03397 const char *override;
03398
03399 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03400 if (override != NULL && *override != '\0')
03401 {
03402 _dbus_string_set_length (&homedir, 0);
03403 if (!_dbus_string_append (&homedir, override))
03404 goto failed;
03405
03406 _dbus_verbose ("Using fake homedir for testing: %s\n",
03407 _dbus_string_get_const_data (&homedir));
03408 }
03409 else
03410 {
03411
03412
03413 static dbus_bool_t already_warned = FALSE;
03414 if (!already_warned)
03415 {
03416 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03417 already_warned = TRUE;
03418 }
03419 }
03420 }
03421 #endif
03422
03423 #ifdef DBUS_WINCE
03424
03425
03426 #define KEYRING_DIR "dbus-keyrings"
03427 #else
03428 #define KEYRING_DIR ".dbus-keyrings"
03429 #endif
03430
03431 _dbus_string_init_const (&dotdir, KEYRING_DIR);
03432 if (!_dbus_concat_dir_and_file (&homedir,
03433 &dotdir))
03434 goto failed;
03435
03436 if (!_dbus_string_copy (&homedir, 0,
03437 directory, _dbus_string_get_length (directory))) {
03438 goto failed;
03439 }
03440
03441 _dbus_string_free (&homedir);
03442 return TRUE;
03443
03444 failed:
03445 _dbus_string_free (&homedir);
03446 return FALSE;
03447 }
03448
03454 dbus_bool_t
03455 _dbus_file_exists (const char *file)
03456 {
03457 DWORD attributes = GetFileAttributesA (file);
03458
03459 if (attributes != INVALID_FILE_ATTRIBUTES && GetLastError() != ERROR_PATH_NOT_FOUND)
03460 return TRUE;
03461 else
03462 return FALSE;
03463 }
03464
03472 const char*
03473 _dbus_strerror (int error_number)
03474 {
03475 #ifdef DBUS_WINCE
03476
03477 return "unknown";
03478 #else
03479 const char *msg;
03480
03481 switch (error_number)
03482 {
03483 case WSAEINTR:
03484 return "Interrupted function call";
03485 case WSAEACCES:
03486 return "Permission denied";
03487 case WSAEFAULT:
03488 return "Bad address";
03489 case WSAEINVAL:
03490 return "Invalid argument";
03491 case WSAEMFILE:
03492 return "Too many open files";
03493 case WSAEWOULDBLOCK:
03494 return "Resource temporarily unavailable";
03495 case WSAEINPROGRESS:
03496 return "Operation now in progress";
03497 case WSAEALREADY:
03498 return "Operation already in progress";
03499 case WSAENOTSOCK:
03500 return "Socket operation on nonsocket";
03501 case WSAEDESTADDRREQ:
03502 return "Destination address required";
03503 case WSAEMSGSIZE:
03504 return "Message too long";
03505 case WSAEPROTOTYPE:
03506 return "Protocol wrong type for socket";
03507 case WSAENOPROTOOPT:
03508 return "Bad protocol option";
03509 case WSAEPROTONOSUPPORT:
03510 return "Protocol not supported";
03511 case WSAESOCKTNOSUPPORT:
03512 return "Socket type not supported";
03513 case WSAEOPNOTSUPP:
03514 return "Operation not supported";
03515 case WSAEPFNOSUPPORT:
03516 return "Protocol family not supported";
03517 case WSAEAFNOSUPPORT:
03518 return "Address family not supported by protocol family";
03519 case WSAEADDRINUSE:
03520 return "Address already in use";
03521 case WSAEADDRNOTAVAIL:
03522 return "Cannot assign requested address";
03523 case WSAENETDOWN:
03524 return "Network is down";
03525 case WSAENETUNREACH:
03526 return "Network is unreachable";
03527 case WSAENETRESET:
03528 return "Network dropped connection on reset";
03529 case WSAECONNABORTED:
03530 return "Software caused connection abort";
03531 case WSAECONNRESET:
03532 return "Connection reset by peer";
03533 case WSAENOBUFS:
03534 return "No buffer space available";
03535 case WSAEISCONN:
03536 return "Socket is already connected";
03537 case WSAENOTCONN:
03538 return "Socket is not connected";
03539 case WSAESHUTDOWN:
03540 return "Cannot send after socket shutdown";
03541 case WSAETIMEDOUT:
03542 return "Connection timed out";
03543 case WSAECONNREFUSED:
03544 return "Connection refused";
03545 case WSAEHOSTDOWN:
03546 return "Host is down";
03547 case WSAEHOSTUNREACH:
03548 return "No route to host";
03549 case WSAEPROCLIM:
03550 return "Too many processes";
03551 case WSAEDISCON:
03552 return "Graceful shutdown in progress";
03553 case WSATYPE_NOT_FOUND:
03554 return "Class type not found";
03555 case WSAHOST_NOT_FOUND:
03556 return "Host not found";
03557 case WSATRY_AGAIN:
03558 return "Nonauthoritative host not found";
03559 case WSANO_RECOVERY:
03560 return "This is a nonrecoverable error";
03561 case WSANO_DATA:
03562 return "Valid name, no data record of requested type";
03563 case WSA_INVALID_HANDLE:
03564 return "Specified event object handle is invalid";
03565 case WSA_INVALID_PARAMETER:
03566 return "One or more parameters are invalid";
03567 case WSA_IO_INCOMPLETE:
03568 return "Overlapped I/O event object not in signaled state";
03569 case WSA_IO_PENDING:
03570 return "Overlapped operations will complete later";
03571 case WSA_NOT_ENOUGH_MEMORY:
03572 return "Insufficient memory available";
03573 case WSA_OPERATION_ABORTED:
03574 return "Overlapped operation aborted";
03575 #ifdef WSAINVALIDPROCTABLE
03576
03577 case WSAINVALIDPROCTABLE:
03578 return "Invalid procedure table from service provider";
03579 #endif
03580 #ifdef WSAINVALIDPROVIDER
03581
03582 case WSAINVALIDPROVIDER:
03583 return "Invalid service provider version number";
03584 #endif
03585 #ifdef WSAPROVIDERFAILEDINIT
03586
03587 case WSAPROVIDERFAILEDINIT:
03588 return "Unable to initialize a service provider";
03589 #endif
03590
03591 case WSASYSCALLFAILURE:
03592 return "System call failure";
03593 }
03594 msg = strerror (error_number);
03595 if (msg == NULL)
03596 msg = "unknown";
03597
03598 return msg;
03599 #endif //DBUS_WINCE
03600 }
03601
03609 void
03610 _dbus_win_set_error_from_win_error (DBusError *error,
03611 int code)
03612 {
03613 char *msg;
03614
03615
03616 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
03617 FORMAT_MESSAGE_IGNORE_INSERTS |
03618 FORMAT_MESSAGE_FROM_SYSTEM,
03619 NULL, code, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
03620 (LPSTR) &msg, 0, NULL);
03621 if (msg)
03622 {
03623 dbus_set_error (error, "win32.error", "%s", msg);
03624 LocalFree (msg);
03625 }
03626 else
03627 dbus_set_error (error, "win32.error", "Unknown error code %d or FormatMessage failed", code);
03628 }
03629
03630 void
03631 _dbus_win_warn_win_error (const char *message,
03632 unsigned long code)
03633 {
03634 DBusError error;
03635
03636 dbus_error_init (&error);
03637 _dbus_win_set_error_from_win_error (&error, code);
03638 _dbus_warn ("%s: %s\n", message, error.message);
03639 dbus_error_free (&error);
03640 }
03641
03649 dbus_bool_t
03650 _dbus_delete_directory (const DBusString *filename,
03651 DBusError *error)
03652 {
03653 const char *filename_c;
03654
03655 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03656
03657 filename_c = _dbus_string_get_const_data (filename);
03658
03659 if (RemoveDirectoryA (filename_c) == 0)
03660 {
03661 char *emsg = _dbus_win_error_string (GetLastError ());
03662 dbus_set_error (error, _dbus_win_error_from_last_error (),
03663 "Failed to remove directory %s: %s",
03664 filename_c, emsg);
03665 _dbus_win_free_error_string (emsg);
03666 return FALSE;
03667 }
03668
03669 return TRUE;
03670 }
03671
03678 dbus_bool_t
03679 _dbus_path_is_absolute (const DBusString *filename)
03680 {
03681 if (_dbus_string_get_length (filename) > 0)
03682 return _dbus_string_get_byte (filename, 1) == ':'
03683 || _dbus_string_get_byte (filename, 0) == '\\'
03684 || _dbus_string_get_byte (filename, 0) == '/';
03685 else
03686 return FALSE;
03687 }
03688
03689 dbus_bool_t
03690 _dbus_check_setuid (void)
03691 {
03692 return FALSE;
03693 }
03694
03695 int
03696 _dbus_save_socket_errno (void)
03697 {
03698 return errno;
03699 }
03700
03701 void
03702 _dbus_restore_socket_errno (int saved_errno)
03703 {
03704 _dbus_win_set_errno (saved_errno);
03705 }
03706
03708
03709