X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-sysdeps-win.c;h=38758bd480f0d87dc39eab519393650b6cb3cc7e;hb=64e50dd167993fb2344d2d3be18bb0d5820b5b26;hp=66d6b76759ed2fd4e9fe9bcbf16f232d5c528834;hpb=3b1ad7f7c583fbb80c5a084c78b926ecaaca0aa9;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index 66d6b76..38758bd 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -104,6 +104,142 @@ _dbus_win_set_errno (int err) #endif } +static BOOL is_winxp_sp3_or_lower(); + +/* + * _MIB_TCPROW_EX and friends are not available in system headers + * and are mapped to attribute identical ...OWNER_PID typedefs. + */ +typedef MIB_TCPROW_OWNER_PID _MIB_TCPROW_EX; +typedef MIB_TCPTABLE_OWNER_PID MIB_TCPTABLE_EX; +typedef PMIB_TCPTABLE_OWNER_PID PMIB_TCPTABLE_EX; +typedef DWORD (WINAPI *ProcAllocateAndGetTcpExtTableFromStack)(PMIB_TCPTABLE_EX*,BOOL,HANDLE,DWORD,DWORD); +static ProcAllocateAndGetTcpExtTableFromStack lpfnAllocateAndGetTcpExTableFromStack = NULL; + +/** + * AllocateAndGetTcpExTableFromStack() is undocumented and not exported, + * but is the only way to do this in older XP versions. + * @return true if the procedures could be loaded + */ +static BOOL +load_ex_ip_helper_procedures(void) +{ + HMODULE hModule = LoadLibrary ("iphlpapi.dll"); + if (hModule == NULL) + { + _dbus_verbose ("could not load iphlpapi.dll\n"); + return FALSE; + } + + lpfnAllocateAndGetTcpExTableFromStack = (ProcAllocateAndGetTcpExtTableFromStack)GetProcAddress (hModule, "AllocateAndGetTcpExTableFromStack"); + if (lpfnAllocateAndGetTcpExTableFromStack == NULL) + { + _dbus_verbose ("could not find function AllocateAndGetTcpExTableFromStack in iphlpapi.dll\n"); + return FALSE; + } + return TRUE; +} + +/** + * get pid from localhost tcp connection using peer_port + * This function is available on WinXP >= SP3 + * @param peer_port peers tcp port + * @return process id or 0 if connection has not been found + */ +static dbus_pid_t +get_pid_from_extended_tcp_table(int peer_port) +{ + dbus_pid_t result; + DWORD errorCode, size, i; + MIB_TCPTABLE_OWNER_PID *tcp_table; + + if ((errorCode = + GetExtendedTcpTable (NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0)) == ERROR_INSUFFICIENT_BUFFER) + { + tcp_table = (MIB_TCPTABLE_OWNER_PID *) dbus_malloc (size); + if (tcp_table == NULL) + { + _dbus_verbose ("Error allocating memory\n"); + return 0; + } + } + else + { + _dbus_verbose ("unexpected error returned from GetExtendedTcpTable %d\n", errorCode); + return 0; + } + + if ((errorCode = GetExtendedTcpTable (tcp_table, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0)) != NO_ERROR) + { + _dbus_verbose ("Error fetching tcp table %d\n", (int)errorCode); + dbus_free (tcp_table); + return 0; + } + + result = 0; + for (i = 0; i < tcp_table->dwNumEntries; i++) + { + MIB_TCPROW_OWNER_PID *p = &tcp_table->table[i]; + int local_address = ntohl (p->dwLocalAddr); + int local_port = ntohs (p->dwLocalPort); + if (p->dwState == MIB_TCP_STATE_ESTAB + && local_address == INADDR_LOOPBACK && local_port == peer_port) + result = p->dwOwningPid; + } + + dbus_free (tcp_table); + _dbus_verbose ("got pid %d\n", (int)result); + return result; +} + +/** + * get pid from localhost tcp connection using peer_port + * This function is available on all WinXP versions, but + * not in wine (at least version <= 1.6.0) + * @param peer_port peers tcp port + * @return process id or 0 if connection has not been found + */ +static dbus_pid_t +get_pid_from_tcp_ex_table(int peer_port) +{ + dbus_pid_t result; + DWORD errorCode, i; + PMIB_TCPTABLE_EX tcp_table = NULL; + + if (!load_ex_ip_helper_procedures ()) + { + _dbus_verbose + ("Error not been able to load iphelper procedures\n"); + return 0; + } + + errorCode = lpfnAllocateAndGetTcpExTableFromStack (&tcp_table, TRUE, GetProcessHeap(), 0, 2); + + if (errorCode != NO_ERROR) + { + _dbus_verbose + ("Error not been able to call AllocateAndGetTcpExTableFromStack()\n"); + return 0; + } + + result = 0; + for (i = 0; i < tcp_table->dwNumEntries; i++) + { + _MIB_TCPROW_EX *p = &tcp_table->table[i]; + int local_port = ntohs (p->dwLocalPort); + int local_address = ntohl (p->dwLocalAddr); + if (local_address == INADDR_LOOPBACK && local_port == peer_port) + { + result = p->dwOwningPid; + break; + } + } + + HeapFree (GetProcessHeap(), 0, tcp_table); + _dbus_verbose ("got pid %d\n", (int)result); + return result; +} + /** * @brief return peer process id from tcp handle for localhost connections * @param handle tcp socket descriptor @@ -117,9 +253,6 @@ _dbus_get_peer_pid_from_tcp_handle (int handle) int peer_port; dbus_pid_t result; - DWORD size; - MIB_TCPTABLE_OWNER_PID *tcp_table; - DWORD i; dbus_bool_t is_localhost = FALSE; getpeername (handle, (struct sockaddr *) &addr, &len); @@ -128,7 +261,7 @@ _dbus_get_peer_pid_from_tcp_handle (int handle) { struct sockaddr_in *s = (struct sockaddr_in *) &addr; peer_port = ntohs (s->sin_port); - is_localhost = (htonl (s->sin_addr.s_addr) == INADDR_LOOPBACK); + is_localhost = (ntohl (s->sin_addr.s_addr) == INADDR_LOOPBACK); } else if (addr.ss_family == AF_INET6) { @@ -160,35 +293,12 @@ _dbus_get_peer_pid_from_tcp_handle (int handle) return 0; } - if ((result = - GetExtendedTcpTable (NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0)) == ERROR_INSUFFICIENT_BUFFER) - { - tcp_table = (MIB_TCPTABLE_OWNER_PID *) dbus_malloc (size); - if (tcp_table == NULL) - { - _dbus_verbose ("Error allocating memory\n"); - return 0; - } - } - - if ((result = GetExtendedTcpTable (tcp_table, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0)) != NO_ERROR) - { - _dbus_verbose ("Error fetching tcp table %d\n", result); - dbus_free (tcp_table); - return 0; - } - - result = 0; - for (i = 0; i < tcp_table->dwNumEntries; i++) - { - MIB_TCPROW_OWNER_PID *p = &tcp_table->table[i]; - int local_port = ntohs (p->dwLocalPort); - if (p->dwState == MIB_TCP_STATE_ESTAB && local_port == peer_port) - result = p->dwOwningPid; - } + _dbus_verbose ("trying to get peers pid"); - _dbus_verbose ("got pid %d\n", result); - dbus_free (tcp_table); + result = get_pid_from_extended_tcp_table (peer_port); + if (result > 0) + return result; + result = get_pid_from_tcp_ex_table (peer_port); return result; } @@ -412,7 +522,7 @@ _dbus_close_socket (int fd, * on exec. Should be called for all file * descriptors in D-Bus code. * - * @param fd the file descriptor + * @param handle the Windows HANDLE */ void _dbus_fd_set_close_on_exec (intptr_t handle) @@ -428,7 +538,7 @@ _dbus_fd_set_close_on_exec (intptr_t handle) /** * Sets a file descriptor to be nonblocking. * - * @param fd the file descriptor. + * @param handle the file descriptor. * @param error address of error location. * @returns #TRUE on success. */ @@ -626,9 +736,12 @@ int _dbus_printf_string_upper_bound (const char *format, char buf[1024]; int bufsize; int len; + va_list args_copy; bufsize = sizeof (buf); - len = _vsnprintf (buf, bufsize - 1, format, args); + DBUS_VA_COPY (args_copy, args); + len = _vsnprintf (buf, bufsize - 1, format, args_copy); + va_end (args_copy); while (len == -1) /* try again */ { @@ -641,7 +754,9 @@ int _dbus_printf_string_upper_bound (const char *format, if (p == NULL) return -1; - len = _vsnprintf (p, bufsize - 1, format, args); + DBUS_VA_COPY (args_copy, args); + len = _vsnprintf (p, bufsize - 1, format, args_copy); + va_end (args_copy); free (p); } @@ -827,6 +942,38 @@ _dbus_pid_for_log (void) } #ifndef DBUS_WINCE + +static BOOL is_winxp_sp3_or_lower() +{ + OSVERSIONINFOEX osvi; + DWORDLONG dwlConditionMask = 0; + int op=VER_LESS_EQUAL; + + // Initialize the OSVERSIONINFOEX structure. + + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + osvi.dwMajorVersion = 5; + osvi.dwMinorVersion = 1; + osvi.wServicePackMajor = 3; + osvi.wServicePackMinor = 0; + + // Initialize the condition mask. + + VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, op ); + VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION, op ); + VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMAJOR, op ); + VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMINOR, op ); + + // Perform the test. + + return VerifyVersionInfo( + &osvi, + VER_MAJORVERSION | VER_MINORVERSION | + VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + dwlConditionMask); +} + /** Gets our SID * @param sid points to sid buffer, need to be freed with LocalFree() * @param process_id the process id for which the sid should be returned @@ -840,7 +987,8 @@ _dbus_getsid(char **sid, dbus_pid_t process_id) DWORD n; PSID psid; int retval = FALSE; - HANDLE process_handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id); + + HANDLE process_handle = OpenProcess(is_winxp_sp3_or_lower() ? PROCESS_QUERY_INFORMATION : PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id); if (!OpenProcessToken (process_handle, TOKEN_QUERY, &process_token)) { @@ -874,7 +1022,7 @@ failed: if (process_token != INVALID_HANDLE_VALUE) CloseHandle (process_token); - _dbus_verbose("_dbus_getsid() returns %d\n",retval); + _dbus_verbose("_dbus_getsid() got '%s' and returns %d\n", *sid, retval); return retval; } #endif @@ -1761,7 +1909,7 @@ again: * The point of the byte is that on some systems we have to * use sendmsg()/recvmsg() to transmit credentials. * - * @param client_fd the client file descriptor + * @param handle the client file descriptor * @param credentials struct to fill with credentials of client * @param error location to store error code * @returns #TRUE on success @@ -2216,7 +2364,7 @@ _dbus_replace_install_prefix (const char *configure_time_path) #endif } -#if !defined (DBUS_DISABLE_ASSERTS) || defined(DBUS_BUILD_TESTS) +#if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_ENABLE_EMBEDDED_TESTS) #if defined(_MSC_VER) || defined(DBUS_WINCE) # ifdef BACKTRACES @@ -3188,8 +3336,6 @@ _dbus_get_standard_system_servicedirs (DBusList **dirs) return TRUE; } -_DBUS_DEFINE_GLOBAL_LOCK (atomic); - /** * Atomically increments an integer * @@ -3272,7 +3418,7 @@ _dbus_get_is_errno_eagain_or_ewouldblock (void) /** * return the absolute path of the dbus installation * - * @param s buffer for installation path + * @param prefix buffer for installation path * @param len length of buffer * @returns #FALSE on failure */ @@ -3454,7 +3600,7 @@ _dbus_append_keyring_directory_for_credentials (DBusString *directory, _dbus_string_append(&homedir,homepath); } -#ifdef DBUS_BUILD_TESTS +#ifdef DBUS_ENABLE_EMBEDDED_TESTS { const char *override;