Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
a1c159e0
Commit
a1c159e0
authored
Nov 19, 2019
by
Hans Leidekker
Committed by
Alexandre Julliard
Nov 19, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mountmgr.sys: Add support for querying DHCP parameters on Linux.
Signed-off-by:
Hans Leidekker
<
hans@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
5106885f
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
338 additions
and
2 deletions
+338
-2
Makefile.in
dlls/mountmgr.sys/Makefile.in
+1
-1
dbus.c
dlls/mountmgr.sys/dbus.c
+273
-1
mountmgr.c
dlls/mountmgr.sys/mountmgr.c
+40
-0
mountmgr.h
dlls/mountmgr.sys/mountmgr.h
+3
-0
mountmgr.h
include/ddk/mountmgr.h
+21
-0
No files found.
dlls/mountmgr.sys/Makefile.in
View file @
a1c159e0
MODULE
=
mountmgr.sys
IMPORTS
=
uuid advapi32 ntoskrnl
DELAYIMPORTS
=
user32
DELAYIMPORTS
=
user32
iphlpapi
EXTRADLLFLAGS
=
-Wl
,--subsystem,native
EXTRAINCL
=
$(DBUS_CFLAGS)
$(HAL_CFLAGS)
EXTRALIBS
=
$(DISKARBITRATION_LIBS)
...
...
dlls/mountmgr.sys/dbus.c
View file @
a1c159e0
...
...
@@ -36,6 +36,14 @@
#include "mountmgr.h"
#include "winnls.h"
#include "excpt.h"
#define USE_WS_PREFIX
#include "winsock2.h"
#include "ws2ipdef.h"
#include "nldef.h"
#include "netioapi.h"
#include "inaddr.h"
#include "ip2string.h"
#include "dhcpcsdk.h"
#include "wine/library.h"
#include "wine/exception.h"
...
...
@@ -45,9 +53,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(mountmgr);
#ifdef SONAME_LIBDBUS_1
#define DBUS_FUNCS \
#define DBUS_FUNCS
\
DO_FUNC(dbus_bus_add_match); \
DO_FUNC(dbus_bus_get); \
DO_FUNC(dbus_bus_get_private); \
DO_FUNC(dbus_bus_remove_match); \
DO_FUNC(dbus_connection_add_filter); \
DO_FUNC(dbus_connection_read_write_dispatch); \
...
...
@@ -762,6 +771,269 @@ void initialize_dbus(void)
CloseHandle
(
handle
);
}
/* The udisks dispatch loop will block all threads using the same connection, so we'll
use a private connection. Multiple threads can make methods calls at the same time
on the same connection, according to the documentation.
*/
static
DBusConnection
*
dhcp_connection
;
static
DBusConnection
*
get_dhcp_connection
(
void
)
{
if
(
!
dhcp_connection
)
{
DBusError
error
;
p_dbus_error_init
(
&
error
);
if
(
!
(
dhcp_connection
=
p_dbus_bus_get_private
(
DBUS_BUS_SYSTEM
,
&
error
)))
{
WARN
(
"failed to get system dbus connection: %s
\n
"
,
error
.
message
);
p_dbus_error_free
(
&
error
);
}
}
return
dhcp_connection
;
}
static
DBusMessage
*
device_by_iface_request
(
const
char
*
iface
)
{
DBusMessage
*
request
,
*
reply
;
DBusMessageIter
iter
;
DBusError
error
;
request
=
p_dbus_message_new_method_call
(
"org.freedesktop.NetworkManager"
,
"/org/freedesktop/NetworkManager"
,
"org.freedesktop.NetworkManager"
,
"GetDeviceByIpIface"
);
if
(
!
request
)
return
NULL
;
p_dbus_message_iter_init_append
(
request
,
&
iter
);
p_dbus_message_iter_append_basic
(
&
iter
,
DBUS_TYPE_STRING
,
&
iface
);
p_dbus_error_init
(
&
error
);
reply
=
p_dbus_connection_send_with_reply_and_block
(
get_dhcp_connection
(),
request
,
-
1
,
&
error
);
p_dbus_message_unref
(
request
);
if
(
!
reply
)
{
WARN
(
"failed: %s
\n
"
,
error
.
message
);
p_dbus_error_free
(
&
error
);
return
NULL
;
}
p_dbus_error_free
(
&
error
);
return
reply
;
}
#define IF_NAMESIZE 16
static
BOOL
map_adapter_name
(
const
WCHAR
*
name
,
char
*
unix_name
,
DWORD
len
)
{
WCHAR
unix_nameW
[
IF_NAMESIZE
];
UNICODE_STRING
str
;
GUID
guid
;
RtlInitUnicodeString
(
&
str
,
name
);
if
(
!
RtlGUIDFromString
(
&
str
,
&
guid
))
{
NET_LUID
luid
;
if
(
ConvertInterfaceGuidToLuid
(
&
guid
,
&
luid
)
||
ConvertInterfaceLuidToNameW
(
&
luid
,
unix_nameW
,
ARRAY_SIZE
(
unix_nameW
)
))
return
FALSE
;
name
=
unix_nameW
;
}
return
WideCharToMultiByte
(
CP_UNIXCP
,
0
,
name
,
-
1
,
unix_name
,
len
,
NULL
,
NULL
)
!=
0
;
}
static
DBusMessage
*
dhcp4_config_request
(
const
WCHAR
*
adapter
)
{
static
const
char
*
device
=
"org.freedesktop.NetworkManager.Device"
;
static
const
char
*
dhcp4_config
=
"Dhcp4Config"
;
char
iface
[
IF_NAMESIZE
];
DBusMessage
*
request
,
*
reply
;
DBusMessageIter
iter
;
DBusError
error
;
const
char
*
path
=
NULL
;
if
(
!
map_adapter_name
(
adapter
,
iface
,
sizeof
(
iface
)
))
return
NULL
;
if
(
!
(
reply
=
device_by_iface_request
(
iface
)))
return
NULL
;
p_dbus_message_iter_init
(
reply
,
&
iter
);
if
(
p_dbus_message_iter_get_arg_type
(
&
iter
)
==
DBUS_TYPE_OBJECT_PATH
)
p_dbus_message_iter_get_basic
(
&
iter
,
&
path
);
p_dbus_message_unref
(
reply
);
if
(
!
path
)
return
NULL
;
request
=
p_dbus_message_new_method_call
(
"org.freedesktop.NetworkManager"
,
path
,
"org.freedesktop.DBus.Properties"
,
"Get"
);
if
(
!
request
)
return
NULL
;
p_dbus_message_iter_init_append
(
request
,
&
iter
);
p_dbus_message_iter_append_basic
(
&
iter
,
DBUS_TYPE_STRING
,
&
device
);
p_dbus_message_iter_append_basic
(
&
iter
,
DBUS_TYPE_STRING
,
&
dhcp4_config
);
p_dbus_error_init
(
&
error
);
reply
=
p_dbus_connection_send_with_reply_and_block
(
get_dhcp_connection
(),
request
,
-
1
,
&
error
);
p_dbus_message_unref
(
request
);
if
(
!
reply
)
{
WARN
(
"failed: %s
\n
"
,
error
.
message
);
p_dbus_error_free
(
&
error
);
return
NULL
;
}
p_dbus_error_free
(
&
error
);
return
reply
;
}
static
DBusMessage
*
dhcp4_config_options_request
(
const
WCHAR
*
adapter
)
{
static
const
char
*
dhcp4_config
=
"org.freedesktop.NetworkManager.DHCP4Config"
;
static
const
char
*
options
=
"Options"
;
DBusMessage
*
request
,
*
reply
;
DBusMessageIter
iter
,
sub
;
DBusError
error
;
const
char
*
path
=
NULL
;
if
(
!
(
reply
=
dhcp4_config_request
(
adapter
)))
return
NULL
;
p_dbus_message_iter_init
(
reply
,
&
iter
);
if
(
p_dbus_message_iter_get_arg_type
(
&
iter
)
==
DBUS_TYPE_VARIANT
)
{
p_dbus_message_iter_recurse
(
&
iter
,
&
sub
);
p_dbus_message_iter_get_basic
(
&
sub
,
&
path
);
}
if
(
!
path
)
{
p_dbus_message_unref
(
reply
);
return
NULL
;
}
request
=
p_dbus_message_new_method_call
(
"org.freedesktop.NetworkManager"
,
path
,
"org.freedesktop.DBus.Properties"
,
"Get"
);
p_dbus_message_unref
(
reply
);
if
(
!
request
)
return
NULL
;
p_dbus_message_iter_init_append
(
request
,
&
iter
);
p_dbus_message_iter_append_basic
(
&
iter
,
DBUS_TYPE_STRING
,
&
dhcp4_config
);
p_dbus_message_iter_append_basic
(
&
iter
,
DBUS_TYPE_STRING
,
&
options
);
p_dbus_error_init
(
&
error
);
reply
=
p_dbus_connection_send_with_reply_and_block
(
get_dhcp_connection
(),
request
,
-
1
,
&
error
);
p_dbus_message_unref
(
request
);
if
(
!
reply
)
{
p_dbus_error_free
(
&
error
);
return
NULL
;
}
p_dbus_error_free
(
&
error
);
return
reply
;
}
static
const
char
*
dhcp4_config_option_next_dict_entry
(
DBusMessageIter
*
iter
,
DBusMessageIter
*
variant
)
{
DBusMessageIter
sub
;
const
char
*
name
;
if
(
p_dbus_message_iter_get_arg_type
(
iter
)
!=
DBUS_TYPE_DICT_ENTRY
)
return
NULL
;
p_dbus_message_iter_recurse
(
iter
,
&
sub
);
p_dbus_message_iter_next
(
iter
);
p_dbus_message_iter_get_basic
(
&
sub
,
&
name
);
p_dbus_message_iter_next
(
&
sub
);
p_dbus_message_iter_recurse
(
&
sub
,
variant
);
return
name
;
}
static
DBusMessage
*
dhcp4_config_option_request
(
const
WCHAR
*
adapter
,
const
char
*
option
,
const
char
**
value
)
{
DBusMessage
*
reply
;
DBusMessageIter
iter
,
variant
;
const
char
*
name
;
if
(
!
(
reply
=
dhcp4_config_options_request
(
adapter
)))
return
NULL
;
*
value
=
NULL
;
p_dbus_message_iter_init
(
reply
,
&
iter
);
if
(
p_dbus_message_iter_get_arg_type
(
&
iter
)
==
DBUS_TYPE_VARIANT
)
{
p_dbus_message_iter_recurse
(
&
iter
,
&
iter
);
if
(
p_dbus_message_iter_get_arg_type
(
&
iter
)
==
DBUS_TYPE_ARRAY
)
{
p_dbus_message_iter_recurse
(
&
iter
,
&
iter
);
while
((
name
=
dhcp4_config_option_next_dict_entry
(
&
iter
,
&
variant
)))
{
if
(
!
strcmp
(
name
,
option
))
{
p_dbus_message_iter_get_basic
(
&
variant
,
value
);
break
;
}
}
}
}
return
reply
;
}
static
const
char
*
map_option
(
ULONG
option
)
{
switch
(
option
)
{
case
OPTION_SUBNET_MASK
:
return
"subnet_mask"
;
case
OPTION_ROUTER_ADDRESS
:
return
"next_server"
;
case
OPTION_HOST_NAME
:
return
"host_name"
;
case
OPTION_DOMAIN_NAME
:
return
"domain_name"
;
case
OPTION_BROADCAST_ADDRESS
:
return
"broadcast_address"
;
case
OPTION_MSFT_IE_PROXY
:
return
"wpad"
;
default:
FIXME
(
"unhandled option %u
\n
"
,
option
);
return
""
;
}
}
ULONG
get_dhcp_request_param
(
const
WCHAR
*
adapter
,
struct
mountmgr_dhcp_request_param
*
param
,
char
*
buf
,
ULONG
offset
,
ULONG
size
)
{
DBusMessage
*
reply
;
const
char
*
value
;
ULONG
ret
=
0
;
param
->
offset
=
param
->
size
=
0
;
if
(
!
(
reply
=
dhcp4_config_option_request
(
adapter
,
map_option
(
param
->
id
),
&
value
)))
return
0
;
switch
(
param
->
id
)
{
case
OPTION_SUBNET_MASK
:
case
OPTION_ROUTER_ADDRESS
:
case
OPTION_BROADCAST_ADDRESS
:
{
IN_ADDR
*
ptr
=
(
IN_ADDR
*
)(
buf
+
offset
);
if
(
value
&&
size
>=
sizeof
(
IN_ADDR
)
&&
!
RtlIpv4StringToAddressA
(
value
,
TRUE
,
NULL
,
ptr
))
{
param
->
offset
=
offset
;
param
->
size
=
sizeof
(
*
ptr
);
TRACE
(
"returning %08x
\n
"
,
*
(
DWORD
*
)
ptr
);
}
ret
=
sizeof
(
*
ptr
);
break
;
}
case
OPTION_HOST_NAME
:
case
OPTION_DOMAIN_NAME
:
case
OPTION_MSFT_IE_PROXY
:
{
char
*
ptr
=
buf
+
offset
;
int
len
=
value
?
strlen
(
value
)
:
0
;
if
(
len
&&
size
>=
len
)
{
memcpy
(
ptr
,
value
,
len
);
param
->
offset
=
offset
;
param
->
size
=
len
;
TRACE
(
"returning %s
\n
"
,
debugstr_an
(
ptr
,
len
)
);
}
ret
=
len
;
break
;
}
default:
FIXME
(
"option %u not supported
\n
"
,
param
->
id
);
break
;
}
p_dbus_message_unref
(
reply
);
return
ret
;
}
#else
/* SONAME_LIBDBUS_1 */
void
initialize_dbus
(
void
)
...
...
dlls/mountmgr.sys/mountmgr.c
View file @
a1c159e0
...
...
@@ -359,6 +359,35 @@ done:
return
status
;
}
/* implementation of IOCTL_MOUNTMGR_QUERY_DHCP_REQUEST_PARAMS */
static
NTSTATUS
query_dhcp_request_params
(
void
*
buff
,
SIZE_T
insize
,
SIZE_T
outsize
,
IO_STATUS_BLOCK
*
iosb
)
{
struct
mountmgr_dhcp_request_params
*
query
=
buff
;
ULONG
i
,
offset
;
/* sanity checks */
if
(
FIELD_OFFSET
(
struct
mountmgr_dhcp_request_params
,
params
[
query
->
count
])
>
insize
||
!
memchrW
(
query
->
adapter
,
0
,
ARRAY_SIZE
(
query
->
adapter
)
))
return
STATUS_INVALID_PARAMETER
;
for
(
i
=
0
;
i
<
query
->
count
;
i
++
)
if
(
query
->
params
[
i
].
offset
+
query
->
params
[
i
].
size
>
insize
)
return
STATUS_INVALID_PARAMETER
;
offset
=
FIELD_OFFSET
(
struct
mountmgr_dhcp_request_params
,
params
[
query
->
count
]);
for
(
i
=
0
;
i
<
query
->
count
;
i
++
)
{
offset
+=
get_dhcp_request_param
(
query
->
adapter
,
&
query
->
params
[
i
],
buff
,
offset
,
outsize
-
offset
);
if
(
offset
>
outsize
)
{
if
(
offset
>=
sizeof
(
query
->
size
))
query
->
size
=
offset
;
iosb
->
Information
=
sizeof
(
query
->
size
);
return
STATUS_MORE_ENTRIES
;
}
}
iosb
->
Information
=
offset
;
return
STATUS_SUCCESS
;
}
/* handler for ioctls on the mount manager device */
static
NTSTATUS
WINAPI
mountmgr_ioctl
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
{
...
...
@@ -403,6 +432,17 @@ static NTSTATUS WINAPI mountmgr_ioctl( DEVICE_OBJECT *device, IRP *irp )
irpsp
->
Parameters
.
DeviceIoControl
.
OutputBufferLength
,
&
irp
->
IoStatus
);
break
;
case
IOCTL_MOUNTMGR_QUERY_DHCP_REQUEST_PARAMS
:
if
(
irpsp
->
Parameters
.
DeviceIoControl
.
InputBufferLength
<
sizeof
(
struct
mountmgr_dhcp_request_params
))
{
irp
->
IoStatus
.
u
.
Status
=
STATUS_INVALID_PARAMETER
;
break
;
}
irp
->
IoStatus
.
u
.
Status
=
query_dhcp_request_params
(
irp
->
AssociatedIrp
.
SystemBuffer
,
irpsp
->
Parameters
.
DeviceIoControl
.
InputBufferLength
,
irpsp
->
Parameters
.
DeviceIoControl
.
OutputBufferLength
,
&
irp
->
IoStatus
);
break
;
default:
FIXME
(
"ioctl %x not supported
\n
"
,
irpsp
->
Parameters
.
DeviceIoControl
.
IoControlCode
);
irp
->
IoStatus
.
u
.
Status
=
STATUS_NOT_SUPPORTED
;
...
...
dlls/mountmgr.sys/mountmgr.h
View file @
a1c159e0
...
...
@@ -70,3 +70,6 @@ extern struct mount_point *add_volume_mount_point( DEVICE_OBJECT *device, UNICOD
const
GUID
*
guid
)
DECLSPEC_HIDDEN
;
extern
void
delete_mount_point
(
struct
mount_point
*
mount
)
DECLSPEC_HIDDEN
;
extern
void
set_mount_point_id
(
struct
mount_point
*
mount
,
const
void
*
id
,
unsigned
int
id_len
)
DECLSPEC_HIDDEN
;
extern
ULONG
get_dhcp_request_param
(
const
WCHAR
*
adapter
,
struct
mountmgr_dhcp_request_param
*
param
,
char
*
buf
,
ULONG
offset
,
ULONG
size
)
DECLSPEC_HIDDEN
;
include/ddk/mountmgr.h
View file @
a1c159e0
...
...
@@ -61,6 +61,27 @@ struct mountmgr_unix_drive
USHORT
device_offset
;
};
#define IOCTL_MOUNTMGR_QUERY_DHCP_REQUEST_PARAMS CTL_CODE(MOUNTMGRCONTROLTYPE, 64, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
struct
mountmgr_dhcp_request_param
{
ULONG
id
;
ULONG
offset
;
ULONG
size
;
};
#ifndef IF_MAX_STRING_SIZE
#define IF_MAX_STRING_SIZE 256
#endif
struct
mountmgr_dhcp_request_params
{
ULONG
size
;
ULONG
count
;
WCHAR
adapter
[
IF_MAX_STRING_SIZE
+
1
];
struct
mountmgr_dhcp_request_param
params
[
1
];
};
#endif
typedef
struct
_MOUNTMGR_CREATE_POINT_INPUT
...
...
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