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
b06740ec
Commit
b06740ec
authored
Jun 22, 2019
by
Zebediah Figura
Committed by
Alexandre Julliard
Jun 25, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntoskrnl.exe: Load a driver's root PnP devices when the driver is started.
Signed-off-by:
Zebediah Figura
<
z.figura12@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
d4c91cc6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
103 additions
and
9 deletions
+103
-9
ntoskrnl.c
dlls/ntoskrnl.exe/ntoskrnl.c
+2
-0
ntoskrnl_private.h
dlls/ntoskrnl.exe/ntoskrnl_private.h
+1
-0
pnp.c
dlls/ntoskrnl.exe/pnp.c
+100
-9
No files found.
dlls/ntoskrnl.exe/ntoskrnl.c
View file @
b06740ec
...
...
@@ -3648,6 +3648,8 @@ NTSTATUS WINAPI ZwLoadDriver( const UNICODE_STRING *service_name )
driver
=
WINE_RB_ENTRY_VALUE
(
entry
,
struct
wine_driver
,
entry
);
driver
->
service_handle
=
service_handle
;
pnp_manager_enumerate_root_devices
(
service_name
->
Buffer
+
wcslen
(
servicesW
)
);
set_service_status
(
service_handle
,
SERVICE_RUNNING
,
SERVICE_ACCEPT_STOP
|
SERVICE_ACCEPT_SHUTDOWN
);
return
STATUS_SUCCESS
;
...
...
dlls/ntoskrnl.exe/ntoskrnl_private.h
View file @
b06740ec
...
...
@@ -76,6 +76,7 @@ extern POBJECT_TYPE SeTokenObjectType;
void
ObReferenceObject
(
void
*
obj
)
DECLSPEC_HIDDEN
;
void
pnp_manager_enumerate_root_devices
(
const
WCHAR
*
driver_name
)
DECLSPEC_HIDDEN
;
void
pnp_manager_start
(
void
)
DECLSPEC_HIDDEN
;
void
pnp_manager_stop
(
void
)
DECLSPEC_HIDDEN
;
...
...
dlls/ntoskrnl.exe/pnp.c
View file @
b06740ec
...
...
@@ -375,6 +375,18 @@ static BOOL install_device_driver( DEVICE_OBJECT *device, HDEVINFO set, SP_DEVIN
return
TRUE
;
}
/* Load the function driver for a newly created PDO, if one is present, and
* send IRPs to start the device. */
static
void
start_device
(
DEVICE_OBJECT
*
device
,
HDEVINFO
set
,
SP_DEVINFO_DATA
*
sp_device
)
{
load_function_driver
(
device
,
set
,
sp_device
);
if
(
device
->
DriverObject
)
{
send_pnp_irp
(
device
,
IRP_MN_START_DEVICE
);
send_power_irp
(
device
,
PowerDeviceD0
);
}
}
static
void
handle_bus_relations
(
DEVICE_OBJECT
*
device
)
{
static
const
WCHAR
infpathW
[]
=
{
'I'
,
'n'
,
'f'
,
'P'
,
'a'
,
't'
,
'h'
,
0
};
...
...
@@ -420,19 +432,14 @@ static void handle_bus_relations( DEVICE_OBJECT *device )
return
;
}
load_function_driver
(
device
,
set
,
&
sp_device
);
if
(
device
->
DriverObject
)
{
send_pnp_irp
(
device
,
IRP_MN_START_DEVICE
);
send_power_irp
(
device
,
PowerDeviceD0
);
}
start_device
(
device
,
set
,
&
sp_device
);
SetupDiDestroyDeviceInfoList
(
set
);
}
static
void
handle_removal_relations
(
DEVICE_OBJECT
*
device
)
static
void
remove_device
(
DEVICE_OBJECT
*
device
)
{
TRACE
(
"(%p)
\n
"
,
device
);
TRACE
(
"Removing device %p.
\n
"
,
device
);
send_power_irp
(
device
,
PowerDeviceD3
);
send_pnp_irp
(
device
,
IRP_MN_SURPRISE_REMOVAL
);
...
...
@@ -452,7 +459,7 @@ void WINAPI IoInvalidateDeviceRelations( DEVICE_OBJECT *device_object, DEVICE_RE
handle_bus_relations
(
device_object
);
break
;
case
RemovalRelations
:
handle_removal_relations
(
device_object
);
remove_device
(
device_object
);
break
;
default:
FIXME
(
"Unhandled relation %#x.
\n
"
,
type
);
...
...
@@ -755,6 +762,23 @@ POWER_STATE WINAPI PoSetPowerState( DEVICE_OBJECT *device, POWER_STATE_TYPE type
static
DRIVER_OBJECT
*
pnp_manager
;
struct
root_pnp_device
{
WCHAR
id
[
MAX_DEVICE_ID_LEN
];
struct
wine_rb_entry
entry
;
DEVICE_OBJECT
*
device
;
};
static
int
root_pnp_devices_rb_compare
(
const
void
*
key
,
const
struct
wine_rb_entry
*
entry
)
{
const
struct
root_pnp_device
*
device
=
WINE_RB_ENTRY_VALUE
(
entry
,
const
struct
root_pnp_device
,
entry
);
const
WCHAR
*
k
=
key
;
return
wcsicmp
(
k
,
device
->
id
);
}
static
struct
wine_rb_tree
root_pnp_devices
=
{
root_pnp_devices_rb_compare
};
static
NTSTATUS
WINAPI
pnp_manager_device_pnp
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
{
IO_STACK_LOCATION
*
stack
=
IoGetCurrentIrpStackLocation
(
irp
);
...
...
@@ -783,7 +807,74 @@ void pnp_manager_start(void)
ERR
(
"Failed to create PnP manager driver, status %#x.
\n
"
,
status
);
}
static
void
destroy_root_pnp_device
(
struct
wine_rb_entry
*
entry
,
void
*
context
)
{
struct
root_pnp_device
*
device
=
WINE_RB_ENTRY_VALUE
(
entry
,
struct
root_pnp_device
,
entry
);
remove_device
(
device
->
device
);
}
void
pnp_manager_stop
(
void
)
{
wine_rb_destroy
(
&
root_pnp_devices
,
destroy_root_pnp_device
,
NULL
);
IoDeleteDriver
(
pnp_manager
);
}
void
pnp_manager_enumerate_root_devices
(
const
WCHAR
*
driver_name
)
{
static
const
WCHAR
driverW
[]
=
{
'\\'
,
'D'
,
'r'
,
'i'
,
'v'
,
'e'
,
'r'
,
'\\'
,
0
};
static
const
WCHAR
rootW
[]
=
{
'R'
,
'O'
,
'O'
,
'T'
,
0
};
WCHAR
buffer
[
MAX_SERVICE_NAME
+
ARRAY_SIZE
(
driverW
)],
id
[
MAX_DEVICE_ID_LEN
];
SP_DEVINFO_DATA
sp_device
=
{
sizeof
(
sp_device
)};
struct
root_pnp_device
*
pnp_device
;
DEVICE_OBJECT
*
device
;
NTSTATUS
status
;
unsigned
int
i
;
HDEVINFO
set
;
TRACE
(
"Searching for new root-enumerated devices for driver %s.
\n
"
,
debugstr_w
(
driver_name
));
set
=
SetupDiGetClassDevsW
(
NULL
,
rootW
,
NULL
,
DIGCF_ALLCLASSES
);
if
(
set
==
INVALID_HANDLE_VALUE
)
{
ERR
(
"Failed to build device set, error %#x.
\n
"
,
GetLastError
());
return
;
}
for
(
i
=
0
;
SetupDiEnumDeviceInfo
(
set
,
i
,
&
sp_device
);
++
i
)
{
if
(
!
SetupDiGetDeviceRegistryPropertyW
(
set
,
&
sp_device
,
SPDRP_SERVICE
,
NULL
,
(
BYTE
*
)
buffer
,
sizeof
(
buffer
),
NULL
)
||
lstrcmpiW
(
buffer
,
driver_name
))
{
continue
;
}
SetupDiGetDeviceInstanceIdW
(
set
,
&
sp_device
,
id
,
ARRAY_SIZE
(
id
),
NULL
);
if
(
wine_rb_get
(
&
root_pnp_devices
,
id
))
continue
;
TRACE
(
"Adding new root-enumerated device %s.
\n
"
,
debugstr_w
(
id
));
if
((
status
=
IoCreateDevice
(
pnp_manager
,
sizeof
(
struct
root_pnp_device
),
NULL
,
FILE_DEVICE_CONTROLLER
,
FILE_AUTOGENERATED_DEVICE_NAME
,
FALSE
,
&
device
)))
{
ERR
(
"Failed to create root-enumerated PnP device %s, status %#x.
\n
"
,
debugstr_w
(
id
),
status
);
continue
;
}
pnp_device
=
device
->
DeviceExtension
;
wcscpy
(
pnp_device
->
id
,
id
);
pnp_device
->
device
=
device
;
if
(
wine_rb_put
(
&
root_pnp_devices
,
id
,
&
pnp_device
->
entry
))
{
ERR
(
"Failed to insert device %s into tree.
\n
"
,
debugstr_w
(
id
));
IoDeleteDevice
(
device
);
continue
;
}
start_device
(
device
,
set
,
&
sp_device
);
}
SetupDiDestroyDeviceInfoList
(
set
);
}
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