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
e93053c3
Commit
e93053c3
authored
Jul 09, 2021
by
Huw Davies
Committed by
Alexandre Julliard
Jul 09, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
iphlpapi: Implement GetIfTable() on top of nsi.
Signed-off-by:
Huw Davies
<
huw@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
bdc48738
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
87 additions
and
60 deletions
+87
-60
iphlpapi_main.c
dlls/iphlpapi/iphlpapi_main.c
+71
-60
iphlpapi.c
dlls/iphlpapi/tests/iphlpapi.c
+16
-0
No files found.
dlls/iphlpapi/iphlpapi_main.c
View file @
e93053c3
...
...
@@ -1775,6 +1775,38 @@ DWORD WINAPI GetFriendlyIfIndex(DWORD IfIndex)
return
IfIndex
;
}
static
void
if_counted_string_copy
(
WCHAR
*
dst
,
unsigned
int
len
,
IF_COUNTED_STRING
*
src
);
static
void
if_row_fill
(
MIB_IFROW
*
row
,
struct
nsi_ndis_ifinfo_rw
*
rw
,
struct
nsi_ndis_ifinfo_dynamic
*
dyn
,
struct
nsi_ndis_ifinfo_static
*
stat
)
{
if_counted_string_copy
(
row
->
wszName
,
ARRAY_SIZE
(
row
->
wszName
),
&
rw
->
alias
);
row
->
dwIndex
=
stat
->
if_index
;
row
->
dwType
=
stat
->
type
;
row
->
dwMtu
=
dyn
->
mtu
;
row
->
dwSpeed
=
dyn
->
rcv_speed
;
row
->
dwPhysAddrLen
=
rw
->
phys_addr
.
Length
;
if
(
row
->
dwPhysAddrLen
>
sizeof
(
row
->
bPhysAddr
))
row
->
dwPhysAddrLen
=
0
;
memcpy
(
row
->
bPhysAddr
,
rw
->
phys_addr
.
Address
,
row
->
dwPhysAddrLen
);
row
->
dwAdminStatus
=
rw
->
admin_status
;
row
->
dwOperStatus
=
(
dyn
->
oper_status
==
IfOperStatusUp
)
?
MIB_IF_OPER_STATUS_OPERATIONAL
:
MIB_IF_OPER_STATUS_NON_OPERATIONAL
;
row
->
dwLastChange
=
0
;
row
->
dwInOctets
=
dyn
->
in_octets
;
row
->
dwInUcastPkts
=
dyn
->
in_ucast_pkts
;
row
->
dwInNUcastPkts
=
dyn
->
in_bcast_pkts
+
dyn
->
in_mcast_pkts
;
row
->
dwInDiscards
=
dyn
->
in_discards
;
row
->
dwInErrors
=
dyn
->
in_errors
;
row
->
dwInUnknownProtos
=
0
;
row
->
dwOutOctets
=
dyn
->
out_octets
;
row
->
dwOutUcastPkts
=
dyn
->
out_ucast_pkts
;
row
->
dwOutNUcastPkts
=
dyn
->
out_bcast_pkts
+
dyn
->
out_mcast_pkts
;
row
->
dwOutDiscards
=
dyn
->
out_discards
;
row
->
dwOutErrors
=
dyn
->
out_errors
;
row
->
dwOutQLen
=
0
;
row
->
dwDescrLen
=
WideCharToMultiByte
(
CP_ACP
,
0
,
stat
->
descr
.
String
,
stat
->
descr
.
Length
/
sizeof
(
WCHAR
),
(
char
*
)
row
->
bDescr
,
sizeof
(
row
->
bDescr
)
-
1
,
NULL
,
NULL
);
row
->
bDescr
[
row
->
dwDescrLen
]
=
'\0'
;
}
/******************************************************************
* GetIfEntry (IPHLPAPI.@)
...
...
@@ -1811,91 +1843,70 @@ DWORD WINAPI GetIfEntry(PMIB_IFROW pIfRow)
return
ret
;
}
static
int
IfTableSorter
(
const
void
*
a
,
const
void
*
b
)
static
int
ifrow_cmp
(
const
void
*
a
,
const
void
*
b
)
{
int
ret
;
if
(
a
&&
b
)
ret
=
((
const
MIB_IFROW
*
)
a
)
->
dwIndex
-
((
const
MIB_IFROW
*
)
b
)
->
dwIndex
;
else
ret
=
0
;
return
ret
;
return
((
const
MIB_IFROW
*
)
a
)
->
dwIndex
-
((
const
MIB_IFROW
*
)
b
)
->
dwIndex
;
}
/******************************************************************
* GetIfTable (IPHLPAPI.@)
*
* Get a table of local interfaces.
*
* PARAMS
*
pIfT
able [Out] buffer for local interfaces table
*
pdwS
ize [In/Out] length of output buffer
*
bOrder
[In] whether to sort the table
*
t
able [Out] buffer for local interfaces table
*
s
ize [In/Out] length of output buffer
*
sort
[In] whether to sort the table
*
* RETURNS
* Success: NO_ERROR
* Failure: error code from winerror.h
*
* NOTES
* If
pdwS
ize is less than required, the function will return
* If
s
ize is less than required, the function will return
* ERROR_INSUFFICIENT_BUFFER, and *pdwSize will be set to the required byte
* size.
* If
bOrder
is true, the returned table will be sorted by interface index.
* If
sort
is true, the returned table will be sorted by interface index.
*/
DWORD
WINAPI
GetIfTable
(
PMIB_IFTABLE
pIfTable
,
PULONG
pdwSize
,
BOOL
bOrder
)
DWORD
WINAPI
GetIfTable
(
MIB_IFTABLE
*
table
,
ULONG
*
size
,
BOOL
sort
)
{
DWORD
ret
;
DWORD
i
,
count
,
needed
,
err
;
NET_LUID
*
keys
;
struct
nsi_ndis_ifinfo_rw
*
rw
;
struct
nsi_ndis_ifinfo_dynamic
*
dyn
;
struct
nsi_ndis_ifinfo_static
*
stat
;
TRACE
(
"pIfTable %p, pdwSize %p, bOrder %d
\n
"
,
pIfTable
,
pdwSize
,
bOrder
)
;
if
(
!
size
)
return
ERROR_INVALID_PARAMETER
;
if
(
!
pdwSize
)
ret
=
ERROR_INVALID_PARAMETER
;
else
{
DWORD
numInterfaces
=
get_interface_indices
(
FALSE
,
NULL
);
ULONG
size
=
sizeof
(
MIB_IFTABLE
);
/* While this could be implemented on top of GetIfTable2(), it would require
an additional copy of the data */
err
=
NsiAllocateAndGetTable
(
1
,
&
NPI_MS_NDIS_MODULEID
,
NSI_NDIS_IFINFO_TABLE
,
(
void
**
)
&
keys
,
sizeof
(
*
keys
),
(
void
**
)
&
rw
,
sizeof
(
*
rw
),
(
void
**
)
&
dyn
,
sizeof
(
*
dyn
),
(
void
**
)
&
stat
,
sizeof
(
*
stat
),
&
count
,
0
);
if
(
err
)
return
err
;
needed
=
FIELD_OFFSET
(
MIB_IFTABLE
,
table
[
count
]
);
if
(
numInterfaces
>
1
)
size
+=
(
numInterfaces
-
1
)
*
sizeof
(
MIB_IFROW
);
if
(
!
pIfTable
||
*
pdwSize
<
size
)
{
*
pdwSize
=
size
;
ret
=
ERROR_INSUFFICIENT_BUFFER
;
if
(
!
table
||
*
size
<
needed
)
{
*
size
=
needed
;
err
=
ERROR_INSUFFICIENT_BUFFER
;
goto
err
;
}
else
{
InterfaceIndexTable
*
table
;
get_interface_indices
(
FALSE
,
&
table
);
if
(
table
)
{
size
=
sizeof
(
MIB_IFTABLE
);
if
(
table
->
numIndexes
>
1
)
size
+=
(
table
->
numIndexes
-
1
)
*
sizeof
(
MIB_IFROW
);
if
(
*
pdwSize
<
size
)
{
*
pdwSize
=
size
;
ret
=
ERROR_INSUFFICIENT_BUFFER
;
}
else
{
DWORD
ndx
;
*
pdwSize
=
size
;
pIfTable
->
dwNumEntries
=
0
;
for
(
ndx
=
0
;
ndx
<
table
->
numIndexes
;
ndx
++
)
{
pIfTable
->
table
[
ndx
].
dwIndex
=
table
->
indexes
[
ndx
];
GetIfEntry
(
&
pIfTable
->
table
[
ndx
]);
pIfTable
->
dwNumEntries
++
;
}
if
(
bOrder
)
qsort
(
pIfTable
->
table
,
pIfTable
->
dwNumEntries
,
sizeof
(
MIB_IFROW
),
IfTableSorter
);
ret
=
NO_ERROR
;
}
HeapFree
(
GetProcessHeap
(),
0
,
table
);
}
else
ret
=
ERROR_OUTOFMEMORY
;
table
->
dwNumEntries
=
count
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
MIB_IFROW
*
row
=
table
->
table
+
i
;
if_row_fill
(
row
,
rw
+
i
,
dyn
+
i
,
stat
+
i
);
}
}
TRACE
(
"returning %d
\n
"
,
ret
);
return
ret
;
if
(
sort
)
qsort
(
table
->
table
,
count
,
sizeof
(
MIB_IFROW
),
ifrow_cmp
);
err:
NsiFreeTable
(
keys
,
rw
,
dyn
,
stat
);
return
err
;
}
static
void
if_counted_string_copy
(
WCHAR
*
dst
,
unsigned
int
len
,
IF_COUNTED_STRING
*
src
)
...
...
dlls/iphlpapi/tests/iphlpapi.c
View file @
e93053c3
...
...
@@ -238,12 +238,16 @@ static void testGetIfTable(void)
if
(
apiReturn
==
NO_ERROR
)
{
char
descr
[
MAX_INTERFACE_NAME_LEN
];
WCHAR
name
[
MAX_INTERFACE_NAME_LEN
];
DWORD
i
,
index
;
if
(
winetest_debug
>
1
)
trace
(
"interface table: %u entries
\n
"
,
buf
->
dwNumEntries
);
for
(
i
=
0
;
i
<
buf
->
dwNumEntries
;
i
++
)
{
MIB_IFROW
*
row
=
&
buf
->
table
[
i
];
MIB_IF_ROW2
row2
;
GUID
*
guid
;
if
(
winetest_debug
>
1
)
{
...
...
@@ -261,6 +265,18 @@ static void testGetIfTable(void)
ok
(
index
==
row
->
dwIndex
||
broken
(
index
!=
row
->
dwIndex
&&
index
),
/* Win8 can have identical guids for two different ifaces */
"got %d vs %d
\n
"
,
index
,
row
->
dwIndex
);
memset
(
&
row2
,
0
,
sizeof
(
row2
)
);
row2
.
InterfaceIndex
=
row
->
dwIndex
;
GetIfEntry2
(
&
row2
);
WideCharToMultiByte
(
CP_ACP
,
0
,
row2
.
Description
,
-
1
,
descr
,
sizeof
(
descr
),
NULL
,
NULL
);
ok
(
!
strcmp
(
(
char
*
)
row
->
bDescr
,
descr
),
"got %s vs %s
\n
"
,
row
->
bDescr
,
descr
);
guid
=
&
row2
.
InterfaceGuid
;
swprintf
(
name
,
ARRAY_SIZE
(
name
),
L"
\\
DEVICE
\\
TCPIP_{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"
,
guid
->
Data1
,
guid
->
Data2
,
guid
->
Data3
,
guid
->
Data4
[
0
],
guid
->
Data4
[
1
],
guid
->
Data4
[
2
],
guid
->
Data4
[
3
],
guid
->
Data4
[
4
],
guid
->
Data4
[
5
],
guid
->
Data4
[
6
],
guid
->
Data4
[
7
]);
todo_wine
ok
(
!
wcscmp
(
row
->
wszName
,
name
),
"got %s vs %s
\n
"
,
debugstr_w
(
row
->
wszName
),
debugstr_w
(
name
)
);
}
}
HeapFree
(
GetProcessHeap
(),
0
,
buf
);
...
...
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