Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
18ba68ea
Commit
18ba68ea
authored
Sep 07, 2012
by
Hans Leidekker
Committed by
Alexandre Julliard
Sep 07, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
iphlpapi: Implement GetExtendedUdpTable.
parent
bde51568
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
316 additions
and
210 deletions
+316
-210
iphlpapi.spec
dlls/iphlpapi/iphlpapi.spec
+1
-1
iphlpapi_main.c
dlls/iphlpapi/iphlpapi_main.c
+26
-11
ipstats.c
dlls/iphlpapi/ipstats.c
+241
-197
ipstats.h
dlls/iphlpapi/ipstats.h
+1
-0
iphlpapi.c
dlls/iphlpapi/tests/iphlpapi.c
+36
-0
iphlpapi.h
include/iphlpapi.h
+3
-0
iprtrmib.h
include/iprtrmib.h
+7
-0
udpmib.h
include/udpmib.h
+1
-1
No files found.
dlls/iphlpapi/iphlpapi.spec
View file @
18ba68ea
...
...
@@ -81,7 +81,7 @@
@ stub GetBestRouteFromStack
#@ stub GetCurrentThreadCompartmentId
@ stdcall GetExtendedTcpTable( ptr ptr long long long long )
#@ stub GetExtendedUdpTable
@ stdcall GetExtendedUdpTable( ptr ptr long long long long )
@ stdcall GetFriendlyIfIndex( long )
#@ stub GetIcmpStatisticsEx
@ stdcall GetIcmpStatistics( ptr )
...
...
dlls/iphlpapi/iphlpapi_main.c
View file @
18ba68ea
...
...
@@ -1917,31 +1917,46 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder,
*/
DWORD
WINAPI
GetUdpTable
(
PMIB_UDPTABLE
pUdpTable
,
PDWORD
pdwSize
,
BOOL
bOrder
)
{
DWORD
ret
;
PMIB_UDPTABLE
table
;
return
GetExtendedUdpTable
(
pUdpTable
,
pdwSize
,
bOrder
,
AF_INET
,
UDP_TABLE_BASIC
,
0
);
}
/******************************************************************
* GetExtendedUdpTable (IPHLPAPI.@)
*/
DWORD
WINAPI
GetExtendedUdpTable
(
PVOID
pUdpTable
,
PDWORD
pdwSize
,
BOOL
bOrder
,
ULONG
ulAf
,
UDP_TABLE_CLASS
TableClass
,
ULONG
Reserved
)
{
DWORD
ret
,
size
;
void
*
table
;
TRACE
(
"pUdpTable %p, pdwSize %p, bOrder %d
\n
"
,
pUdpTable
,
pdwSize
,
bOrder
);
TRACE
(
"pUdpTable %p, pdwSize %p, bOrder %d, ulAf %u, TableClass %u, Reserved %u
\n
"
,
pUdpTable
,
pdwSize
,
bOrder
,
ulAf
,
TableClass
,
Reserved
);
if
(
!
pdwSize
)
return
ERROR_INVALID_PARAMETER
;
ret
=
AllocateAndGetUdpTableFromStack
(
&
table
,
bOrder
,
GetProcessHeap
(),
0
);
if
(
!
ret
)
{
DWORD
size
=
FIELD_OFFSET
(
MIB_UDPTABLE
,
table
[
table
->
dwNumEntries
]
);
if
(
!
pUdpTable
||
*
pdwSize
<
size
)
{
if
(
ulAf
!=
AF_INET
||
(
TableClass
!=
UDP_TABLE_BASIC
&&
TableClass
!=
UDP_TABLE_OWNER_PID
))
{
FIXME
(
"ulAf = %u, TableClass = %u not supported
\n
"
,
ulAf
,
TableClass
);
return
ERROR_NOT_SUPPORTED
;
}
if
((
ret
=
build_udp_table
(
TableClass
,
&
table
,
bOrder
,
GetProcessHeap
(),
0
,
&
size
)))
return
ret
;
if
(
!
pUdpTable
||
*
pdwSize
<
size
)
{
*
pdwSize
=
size
;
ret
=
ERROR_INSUFFICIENT_BUFFER
;
}
else
{
else
{
*
pdwSize
=
size
;
memcpy
(
pUdpTable
,
table
,
size
);
}
HeapFree
(
GetProcessHeap
(),
0
,
table
);
}
TRACE
(
"returning %d
\n
"
,
ret
);
return
ret
;
}
/******************************************************************
* GetUniDirectionalAdapterInfo (IPHLPAPI.@)
*
...
...
dlls/iphlpapi/ipstats.c
View file @
18ba68ea
...
...
@@ -1433,203 +1433,6 @@ done:
return
ret
;
}
static
MIB_UDPTABLE
*
append_udp_row
(
HANDLE
heap
,
DWORD
flags
,
MIB_UDPTABLE
*
table
,
DWORD
*
count
,
const
MIB_UDPROW
*
row
)
{
if
(
table
->
dwNumEntries
>=
*
count
)
{
MIB_UDPTABLE
*
new_table
;
DWORD
new_count
=
table
->
dwNumEntries
*
2
;
if
(
!
(
new_table
=
HeapReAlloc
(
heap
,
flags
,
table
,
FIELD_OFFSET
(
MIB_UDPTABLE
,
table
[
new_count
]
))))
{
HeapFree
(
heap
,
0
,
table
);
return
NULL
;
}
*
count
=
new_count
;
table
=
new_table
;
}
memcpy
(
&
table
->
table
[
table
->
dwNumEntries
++
],
row
,
sizeof
(
*
row
)
);
return
table
;
}
static
int
compare_udp_rows
(
const
void
*
a
,
const
void
*
b
)
{
const
MIB_UDPROW
*
rowA
=
a
;
const
MIB_UDPROW
*
rowB
=
b
;
int
ret
;
if
((
ret
=
rowA
->
dwLocalAddr
-
rowB
->
dwLocalAddr
)
!=
0
)
return
ret
;
return
rowA
->
dwLocalPort
-
rowB
->
dwLocalPort
;
}
/******************************************************************
* AllocateAndGetUdpTableFromStack (IPHLPAPI.@)
*
* Get the UDP listener table.
* Like GetUdpTable(), but allocate the returned table from heap.
*
* PARAMS
* ppUdpTable [Out] pointer into which the MIB_UDPTABLE is
* allocated and returned.
* bOrder [In] whether to sort the table
* heap [In] heap from which the table is allocated
* flags [In] flags to HeapAlloc
*
* RETURNS
* ERROR_INVALID_PARAMETER if ppUdpTable is NULL, whatever GetUdpTable()
* returns otherwise.
*/
DWORD
WINAPI
AllocateAndGetUdpTableFromStack
(
PMIB_UDPTABLE
*
ppUdpTable
,
BOOL
bOrder
,
HANDLE
heap
,
DWORD
flags
)
{
MIB_UDPTABLE
*
table
;
MIB_UDPROW
row
;
DWORD
ret
=
NO_ERROR
,
count
=
16
;
TRACE
(
"table %p, bOrder %d, heap %p, flags 0x%08x
\n
"
,
ppUdpTable
,
bOrder
,
heap
,
flags
);
if
(
!
ppUdpTable
)
return
ERROR_INVALID_PARAMETER
;
if
(
!
(
table
=
HeapAlloc
(
heap
,
flags
,
FIELD_OFFSET
(
MIB_UDPTABLE
,
table
[
count
]
))))
return
ERROR_OUTOFMEMORY
;
table
->
dwNumEntries
=
0
;
#ifdef __linux__
{
FILE
*
fp
;
if
((
fp
=
fopen
(
"/proc/net/udp"
,
"r"
)))
{
char
buf
[
512
],
*
ptr
;
DWORD
dummy
;
/* skip header line */
ptr
=
fgets
(
buf
,
sizeof
(
buf
),
fp
);
while
((
ptr
=
fgets
(
buf
,
sizeof
(
buf
),
fp
)))
{
if
(
sscanf
(
ptr
,
"%u: %x:%x"
,
&
dummy
,
&
row
.
dwLocalAddr
,
&
row
.
dwLocalPort
)
!=
3
)
continue
;
row
.
dwLocalPort
=
htons
(
row
.
dwLocalPort
);
if
(
!
(
table
=
append_udp_row
(
heap
,
flags
,
table
,
&
count
,
&
row
)))
break
;
}
fclose
(
fp
);
}
else
ret
=
ERROR_NOT_SUPPORTED
;
}
#elif defined(HAVE_SYS_TIHDR_H) && defined(T_OPTMGMT_ACK)
{
void
*
data
;
int
fd
,
len
;
mib2_udpEntry_t
*
entry
;
if
((
fd
=
open_streams_mib
(
"udp"
))
!=
-
1
)
{
if
((
data
=
read_mib_entry
(
fd
,
MIB2_UDP
,
MIB2_UDP_ENTRY
,
&
len
)))
{
for
(
entry
=
data
;
(
char
*
)(
entry
+
1
)
<=
(
char
*
)
data
+
len
;
entry
++
)
{
row
.
dwLocalAddr
=
entry
->
udpLocalAddress
;
row
.
dwLocalPort
=
htons
(
entry
->
udpLocalPort
);
if
(
!
(
table
=
append_udp_row
(
heap
,
flags
,
table
,
&
count
,
&
row
)))
break
;
}
HeapFree
(
GetProcessHeap
(),
0
,
data
);
}
close
(
fd
);
}
else
ret
=
ERROR_NOT_SUPPORTED
;
}
#elif defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_STRUCT_XINPGEN)
{
size_t
Len
=
0
;
char
*
Buf
=
NULL
;
struct
xinpgen
*
pXIG
,
*
pOrigXIG
;
if
(
sysctlbyname
(
"net.inet.udp.pcblist"
,
NULL
,
&
Len
,
NULL
,
0
)
<
0
)
{
ERR
(
"Failure to read net.inet.udp.pcblist via sysctlbyname!
\n
"
);
ret
=
ERROR_NOT_SUPPORTED
;
goto
done
;
}
Buf
=
HeapAlloc
(
GetProcessHeap
(),
0
,
Len
);
if
(
!
Buf
)
{
ret
=
ERROR_OUTOFMEMORY
;
goto
done
;
}
if
(
sysctlbyname
(
"net.inet.udp.pcblist"
,
Buf
,
&
Len
,
NULL
,
0
)
<
0
)
{
ERR
(
"Failure to read net.inet.udp.pcblist via sysctlbyname!
\n
"
);
ret
=
ERROR_NOT_SUPPORTED
;
goto
done
;
}
/* Might be nothing here; first entry is just a header it seems */
if
(
Len
<=
sizeof
(
struct
xinpgen
))
goto
done
;
pOrigXIG
=
(
struct
xinpgen
*
)
Buf
;
pXIG
=
pOrigXIG
;
for
(
pXIG
=
(
struct
xinpgen
*
)((
char
*
)
pXIG
+
pXIG
->
xig_len
);
pXIG
->
xig_len
>
sizeof
(
struct
xinpgen
);
pXIG
=
(
struct
xinpgen
*
)((
char
*
)
pXIG
+
pXIG
->
xig_len
))
{
struct
inpcb
*
pINData
;
struct
xsocket
*
pSockData
;
pINData
=
&
((
struct
xinpcb
*
)
pXIG
)
->
xi_inp
;
pSockData
=
&
((
struct
xinpcb
*
)
pXIG
)
->
xi_socket
;
/* Ignore sockets for other protocols */
if
(
pSockData
->
xso_protocol
!=
IPPROTO_UDP
)
continue
;
/* Ignore PCBs that were freed while generating the data */
if
(
pINData
->
inp_gencnt
>
pOrigXIG
->
xig_gen
)
continue
;
/* we're only interested in IPv4 addresses */
if
(
!
(
pINData
->
inp_vflag
&
INP_IPV4
)
||
(
pINData
->
inp_vflag
&
INP_IPV6
))
continue
;
/* If all 0's, skip it */
if
(
!
pINData
->
inp_laddr
.
s_addr
&&
!
pINData
->
inp_lport
)
continue
;
/* Fill in structure details */
row
.
dwLocalAddr
=
pINData
->
inp_laddr
.
s_addr
;
row
.
dwLocalPort
=
pINData
->
inp_lport
;
if
(
!
(
table
=
append_udp_row
(
heap
,
flags
,
table
,
&
count
,
&
row
)))
break
;
}
done:
HeapFree
(
GetProcessHeap
(),
0
,
Buf
);
}
#else
FIXME
(
"not implemented
\n
"
);
ret
=
ERROR_NOT_SUPPORTED
;
#endif
if
(
!
table
)
return
ERROR_OUTOFMEMORY
;
if
(
!
ret
)
{
if
(
bOrder
&&
table
->
dwNumEntries
)
qsort
(
table
->
table
,
table
->
dwNumEntries
,
sizeof
(
row
),
compare_udp_rows
);
*
ppUdpTable
=
table
;
}
else
HeapFree
(
heap
,
flags
,
table
);
TRACE
(
"returning ret %u table %p
\n
"
,
ret
,
table
);
return
ret
;
}
static
DWORD
get_tcp_table_sizes
(
TCP_TABLE_CLASS
class
,
DWORD
row_count
,
DWORD
*
row_size
)
{
DWORD
table_size
;
...
...
@@ -2015,3 +1818,244 @@ DWORD WINAPI AllocateAndGetTcpTableFromStack( PMIB_TCPTABLE *ppTcpTable, BOOL bO
if
(
!
ppTcpTable
)
return
ERROR_INVALID_PARAMETER
;
return
build_tcp_table
(
TCP_TABLE_BASIC_ALL
,
(
void
**
)
ppTcpTable
,
bOrder
,
heap
,
flags
,
NULL
);
}
static
DWORD
get_udp_table_sizes
(
UDP_TABLE_CLASS
class
,
DWORD
row_count
,
DWORD
*
row_size
)
{
DWORD
table_size
;
switch
(
class
)
{
case
UDP_TABLE_BASIC
:
{
table_size
=
FIELD_OFFSET
(
MIB_UDPTABLE
,
table
[
row_count
]);
if
(
row_size
)
*
row_size
=
sizeof
(
MIB_UDPROW
);
break
;
}
case
UDP_TABLE_OWNER_PID
:
{
table_size
=
FIELD_OFFSET
(
MIB_UDPTABLE_OWNER_PID
,
table
[
row_count
]);
if
(
row_size
)
*
row_size
=
sizeof
(
MIB_UDPROW_OWNER_PID
);
break
;
}
default:
ERR
(
"unhandled class %u
\n
"
,
class
);
return
0
;
}
return
table_size
;
}
static
MIB_UDPTABLE
*
append_udp_row
(
UDP_TABLE_CLASS
class
,
HANDLE
heap
,
DWORD
flags
,
MIB_UDPTABLE
*
table
,
DWORD
*
count
,
const
MIB_UDPROW_OWNER_PID
*
row
,
DWORD
row_size
)
{
if
(
table
->
dwNumEntries
>=
*
count
)
{
MIB_UDPTABLE
*
new_table
;
DWORD
new_count
=
table
->
dwNumEntries
*
2
,
new_table_size
;
new_table_size
=
get_udp_table_sizes
(
class
,
new_count
,
NULL
);
if
(
!
(
new_table
=
HeapReAlloc
(
heap
,
flags
,
table
,
new_table_size
)))
{
HeapFree
(
heap
,
0
,
table
);
return
NULL
;
}
*
count
=
new_count
;
table
=
new_table
;
}
memcpy
(
(
char
*
)
table
->
table
+
(
table
->
dwNumEntries
*
row_size
),
row
,
row_size
);
table
->
dwNumEntries
++
;
return
table
;
}
static
int
compare_udp_rows
(
const
void
*
a
,
const
void
*
b
)
{
const
MIB_UDPROW
*
rowA
=
a
;
const
MIB_UDPROW
*
rowB
=
b
;
int
ret
;
if
((
ret
=
rowA
->
dwLocalAddr
-
rowB
->
dwLocalAddr
)
!=
0
)
return
ret
;
return
rowA
->
dwLocalPort
-
rowB
->
dwLocalPort
;
}
DWORD
build_udp_table
(
UDP_TABLE_CLASS
class
,
void
**
tablep
,
BOOL
order
,
HANDLE
heap
,
DWORD
flags
,
DWORD
*
size
)
{
MIB_UDPTABLE
*
table
;
MIB_UDPROW_OWNER_PID
row
;
DWORD
ret
=
NO_ERROR
,
count
=
16
,
table_size
,
row_size
;
if
(
!
(
table_size
=
get_udp_table_sizes
(
class
,
count
,
&
row_size
)))
return
ERROR_INVALID_PARAMETER
;
if
(
!
(
table
=
HeapAlloc
(
heap
,
flags
,
table_size
)))
return
ERROR_OUTOFMEMORY
;
table
->
dwNumEntries
=
0
;
memset
(
&
row
,
0
,
sizeof
(
row
)
);
#ifdef __linux__
{
FILE
*
fp
;
if
((
fp
=
fopen
(
"/proc/net/udp"
,
"r"
)))
{
char
buf
[
512
],
*
ptr
;
struct
pid_map
*
map
=
NULL
;
unsigned
int
dummy
,
num_entries
=
0
;
int
inode
;
if
(
class
==
UDP_TABLE_OWNER_PID
)
map
=
get_pid_map
(
&
num_entries
);
/* skip header line */
ptr
=
fgets
(
buf
,
sizeof
(
buf
),
fp
);
while
((
ptr
=
fgets
(
buf
,
sizeof
(
buf
),
fp
)))
{
if
(
sscanf
(
ptr
,
"%u: %x:%x %*s %*s %*s %*s %*s %*s %*s %d"
,
&
dummy
,
&
row
.
dwLocalAddr
,
&
row
.
dwLocalPort
,
&
inode
)
!=
4
)
continue
;
row
.
dwLocalPort
=
htons
(
row
.
dwLocalPort
);
if
(
class
==
UDP_TABLE_OWNER_PID
)
row
.
dwOwningPid
=
find_owning_pid
(
map
,
num_entries
,
inode
);
if
(
!
(
table
=
append_udp_row
(
class
,
heap
,
flags
,
table
,
&
count
,
&
row
,
row_size
)))
break
;
}
HeapFree
(
GetProcessHeap
(),
0
,
map
);
fclose
(
fp
);
}
else
ret
=
ERROR_NOT_SUPPORTED
;
}
#elif defined(HAVE_SYS_TIHDR_H) && defined(T_OPTMGMT_ACK)
{
void
*
data
;
int
fd
,
len
;
mib2_udpEntry_t
*
entry
;
if
((
fd
=
open_streams_mib
(
"udp"
))
!=
-
1
)
{
if
((
data
=
read_mib_entry
(
fd
,
MIB2_UDP
,
MIB2_UDP_ENTRY
,
&
len
)))
{
for
(
entry
=
data
;
(
char
*
)(
entry
+
1
)
<=
(
char
*
)
data
+
len
;
entry
++
)
{
row
.
dwLocalAddr
=
entry
->
udpLocalAddress
;
row
.
dwLocalPort
=
htons
(
entry
->
udpLocalPort
);
if
(
!
(
table
=
append_udp_row
(
class
,
heap
,
flags
,
table
,
&
count
,
&
row
,
row_size
)))
break
;
}
HeapFree
(
GetProcessHeap
(),
0
,
data
);
}
close
(
fd
);
}
else
ret
=
ERROR_NOT_SUPPORTED
;
}
#elif defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_STRUCT_XINPGEN)
{
size_t
Len
=
0
;
char
*
Buf
=
NULL
;
struct
xinpgen
*
pXIG
,
*
pOrigXIG
;
if
(
sysctlbyname
(
"net.inet.udp.pcblist"
,
NULL
,
&
Len
,
NULL
,
0
)
<
0
)
{
ERR
(
"Failure to read net.inet.udp.pcblist via sysctlbyname!
\n
"
);
ret
=
ERROR_NOT_SUPPORTED
;
goto
done
;
}
Buf
=
HeapAlloc
(
GetProcessHeap
(),
0
,
Len
);
if
(
!
Buf
)
{
ret
=
ERROR_OUTOFMEMORY
;
goto
done
;
}
if
(
sysctlbyname
(
"net.inet.udp.pcblist"
,
Buf
,
&
Len
,
NULL
,
0
)
<
0
)
{
ERR
(
"Failure to read net.inet.udp.pcblist via sysctlbyname!
\n
"
);
ret
=
ERROR_NOT_SUPPORTED
;
goto
done
;
}
/* Might be nothing here; first entry is just a header it seems */
if
(
Len
<=
sizeof
(
struct
xinpgen
))
goto
done
;
pOrigXIG
=
(
struct
xinpgen
*
)
Buf
;
pXIG
=
pOrigXIG
;
for
(
pXIG
=
(
struct
xinpgen
*
)((
char
*
)
pXIG
+
pXIG
->
xig_len
);
pXIG
->
xig_len
>
sizeof
(
struct
xinpgen
);
pXIG
=
(
struct
xinpgen
*
)((
char
*
)
pXIG
+
pXIG
->
xig_len
))
{
struct
inpcb
*
pINData
;
struct
xsocket
*
pSockData
;
pINData
=
&
((
struct
xinpcb
*
)
pXIG
)
->
xi_inp
;
pSockData
=
&
((
struct
xinpcb
*
)
pXIG
)
->
xi_socket
;
/* Ignore sockets for other protocols */
if
(
pSockData
->
xso_protocol
!=
IPPROTO_UDP
)
continue
;
/* Ignore PCBs that were freed while generating the data */
if
(
pINData
->
inp_gencnt
>
pOrigXIG
->
xig_gen
)
continue
;
/* we're only interested in IPv4 addresses */
if
(
!
(
pINData
->
inp_vflag
&
INP_IPV4
)
||
(
pINData
->
inp_vflag
&
INP_IPV6
))
continue
;
/* If all 0's, skip it */
if
(
!
pINData
->
inp_laddr
.
s_addr
&&
!
pINData
->
inp_lport
)
continue
;
/* Fill in structure details */
row
.
dwLocalAddr
=
pINData
->
inp_laddr
.
s_addr
;
row
.
dwLocalPort
=
pINData
->
inp_lport
;
if
(
!
(
table
=
append_udp_row
(
class
,
heap
,
flags
,
table
,
&
count
,
&
row
,
row_size
)))
break
;
}
done:
HeapFree
(
GetProcessHeap
(),
0
,
Buf
);
}
#else
FIXME
(
"not implemented
\n
"
);
ret
=
ERROR_NOT_SUPPORTED
;
#endif
if
(
!
table
)
return
ERROR_OUTOFMEMORY
;
if
(
!
ret
)
{
if
(
order
&&
table
->
dwNumEntries
)
qsort
(
table
->
table
,
table
->
dwNumEntries
,
row_size
,
compare_udp_rows
);
*
tablep
=
table
;
}
else
HeapFree
(
heap
,
flags
,
table
);
if
(
size
)
*
size
=
get_udp_table_sizes
(
class
,
count
,
NULL
);
TRACE
(
"returning ret %u table %p
\n
"
,
ret
,
table
);
return
ret
;
}
/******************************************************************
* AllocateAndGetUdpTableFromStack (IPHLPAPI.@)
*
* Get the UDP listener table.
* Like GetUdpTable(), but allocate the returned table from heap.
*
* PARAMS
* ppUdpTable [Out] pointer into which the MIB_UDPTABLE is
* allocated and returned.
* bOrder [In] whether to sort the table
* heap [In] heap from which the table is allocated
* flags [In] flags to HeapAlloc
*
* RETURNS
* ERROR_INVALID_PARAMETER if ppUdpTable is NULL, whatever GetUdpTable()
* returns otherwise.
*/
DWORD
WINAPI
AllocateAndGetUdpTableFromStack
(
PMIB_UDPTABLE
*
ppUdpTable
,
BOOL
bOrder
,
HANDLE
heap
,
DWORD
flags
)
{
TRACE
(
"table %p, bOrder %d, heap %p, flags 0x%08x
\n
"
,
ppUdpTable
,
bOrder
,
heap
,
flags
);
if
(
!
ppUdpTable
)
return
ERROR_INVALID_PARAMETER
;
return
build_udp_table
(
UDP_TABLE_BASIC
,
(
void
**
)
ppUdpTable
,
bOrder
,
heap
,
flags
,
NULL
);
}
dlls/iphlpapi/ipstats.h
View file @
18ba68ea
...
...
@@ -38,5 +38,6 @@ DWORD WINAPI AllocateAndGetIpNetTableFromStack(PMIB_IPNETTABLE *ppIpNetTable, BO
DWORD
WINAPI
AllocateAndGetIpForwardTableFromStack
(
PMIB_IPFORWARDTABLE
*
ppIpForwardTable
,
BOOL
bOrder
,
HANDLE
heap
,
DWORD
flags
)
DECLSPEC_HIDDEN
;
DWORD
build_tcp_table
(
TCP_TABLE_CLASS
,
void
**
,
BOOL
,
HANDLE
,
DWORD
,
DWORD
*
)
DECLSPEC_HIDDEN
;
DWORD
build_udp_table
(
UDP_TABLE_CLASS
,
void
**
,
BOOL
,
HANDLE
,
DWORD
,
DWORD
*
)
DECLSPEC_HIDDEN
;
#endif
/* ndef WINE_IPSTATS_H_ */
dlls/iphlpapi/tests/iphlpapi.c
View file @
18ba68ea
...
...
@@ -71,6 +71,7 @@ static DWORD (WINAPI *pGetAdaptersAddresses)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRE
static
DWORD
(
WINAPI
*
pNotifyAddrChange
)(
PHANDLE
,
LPOVERLAPPED
);
static
BOOL
(
WINAPI
*
pCancelIPChangeNotify
)(
LPOVERLAPPED
);
static
DWORD
(
WINAPI
*
pGetExtendedTcpTable
)(
PVOID
,
PDWORD
,
BOOL
,
ULONG
,
TCP_TABLE_CLASS
,
ULONG
);
static
DWORD
(
WINAPI
*
pGetExtendedUdpTable
)(
PVOID
,
PDWORD
,
BOOL
,
ULONG
,
UDP_TABLE_CLASS
,
ULONG
);
static
DWORD
(
WINAPI
*
pSetTcpEntry
)(
PMIB_TCPROW
);
static
void
loadIPHlpApi
(
void
)
...
...
@@ -102,6 +103,7 @@ static void loadIPHlpApi(void)
pNotifyAddrChange
=
(
void
*
)
GetProcAddress
(
hLibrary
,
"NotifyAddrChange"
);
pCancelIPChangeNotify
=
(
void
*
)
GetProcAddress
(
hLibrary
,
"CancelIPChangeNotify"
);
pGetExtendedTcpTable
=
(
void
*
)
GetProcAddress
(
hLibrary
,
"GetExtendedTcpTable"
);
pGetExtendedUdpTable
=
(
void
*
)
GetProcAddress
(
hLibrary
,
"GetExtendedUdpTable"
);
pSetTcpEntry
=
(
void
*
)
GetProcAddress
(
hLibrary
,
"SetTcpEntry"
);
}
}
...
...
@@ -1203,6 +1205,39 @@ static void test_GetExtendedTcpTable(void)
HeapFree
(
GetProcessHeap
(),
0
,
table_pid
);
}
static
void
test_GetExtendedUdpTable
(
void
)
{
DWORD
ret
,
size
;
MIB_UDPTABLE
*
table
;
MIB_UDPTABLE_OWNER_PID
*
table_pid
;
if
(
!
pGetExtendedUdpTable
)
{
win_skip
(
"GetExtendedUdpTable not available
\n
"
);
return
;
}
ret
=
pGetExtendedUdpTable
(
NULL
,
NULL
,
TRUE
,
AF_INET
,
UDP_TABLE_BASIC
,
0
);
ok
(
ret
==
ERROR_INVALID_PARAMETER
,
"got %u
\n
"
,
ret
);
size
=
0
;
ret
=
pGetExtendedUdpTable
(
NULL
,
&
size
,
TRUE
,
AF_INET
,
UDP_TABLE_BASIC
,
0
);
ok
(
ret
==
ERROR_INSUFFICIENT_BUFFER
,
"got %u
\n
"
,
ret
);
table
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
ret
=
pGetExtendedUdpTable
(
table
,
&
size
,
TRUE
,
AF_INET
,
UDP_TABLE_BASIC
,
0
);
ok
(
ret
==
ERROR_SUCCESS
,
"got %u
\n
"
,
ret
);
HeapFree
(
GetProcessHeap
(),
0
,
table
);
size
=
0
;
ret
=
pGetExtendedUdpTable
(
NULL
,
&
size
,
TRUE
,
AF_INET
,
UDP_TABLE_OWNER_PID
,
0
);
ok
(
ret
==
ERROR_INSUFFICIENT_BUFFER
,
"got %u
\n
"
,
ret
);
table_pid
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
ret
=
pGetExtendedUdpTable
(
table_pid
,
&
size
,
TRUE
,
AF_INET
,
UDP_TABLE_OWNER_PID
,
0
);
ok
(
ret
==
ERROR_SUCCESS
,
"got %u
\n
"
,
ret
);
HeapFree
(
GetProcessHeap
(),
0
,
table_pid
);
}
START_TEST
(
iphlpapi
)
{
...
...
@@ -1221,6 +1256,7 @@ START_TEST(iphlpapi)
testWin2KFunctions
();
test_GetAdaptersAddresses
();
test_GetExtendedTcpTable
();
test_GetExtendedUdpTable
();
freeIPHlpApi
();
}
}
include/iphlpapi.h
View file @
18ba68ea
...
...
@@ -29,6 +29,9 @@ extern "C" {
DWORD
WINAPI
GetExtendedTcpTable
(
PVOID
pTcpTable
,
PDWORD
pdwSize
,
BOOL
bOrder
,
ULONG
ulAf
,
TCP_TABLE_CLASS
TableClass
,
ULONG
Reserved
);
DWORD
WINAPI
GetExtendedUdpTable
(
PVOID
pUdpTable
,
PDWORD
pdwSize
,
BOOL
bOrder
,
ULONG
ulAf
,
UDP_TABLE_CLASS
TableClass
,
ULONG
Reserved
);
DWORD
WINAPI
GetNumberOfInterfaces
(
PDWORD
pdwNumIf
);
DWORD
WINAPI
GetIfEntry
(
PMIB_IFROW
pIfRow
);
...
...
include/iprtrmib.h
View file @
18ba68ea
...
...
@@ -38,4 +38,11 @@ typedef enum _TCP_TABLE_CLASS
TCP_TABLE_OWNER_MODULE_ALL
}
TCP_TABLE_CLASS
,
*
PTCP_TABLE_CLASS
;
typedef
enum
_UDP_TABLE_CLASS
{
UDP_TABLE_BASIC
,
UDP_TABLE_OWNER_PID
,
UDP_TABLE_OWNER_MODULE
}
UDP_TABLE_CLASS
,
*
PUDP_TABLE_CLASS
;
#endif
/* WINE_IPRTRMIB_H__ */
include/udpmib.h
View file @
18ba68ea
...
...
@@ -39,6 +39,7 @@ typedef struct _MIB_UDPROW_OWNER_PID
{
DWORD
dwLocalAddr
;
DWORD
dwLocalPort
;
DWORD
dwOwningPid
;
}
MIB_UDPROW_OWNER_PID
,
*
PMIB_UDPROW_OWNER_PID
;
typedef
struct
_MIB_UDPTABLE_OWNER_PID
...
...
@@ -47,7 +48,6 @@ typedef struct _MIB_UDPTABLE_OWNER_PID
MIB_UDPROW_OWNER_PID
table
[
1
];
}
MIB_UDPTABLE_OWNER_PID
,
*
PMIB_UDPTABLE_OWNER_PID
;
/* UDP statistics */
typedef
struct
_MIB_UDPSTATS
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment