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
c81d0995
Commit
c81d0995
authored
May 17, 2007
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winedevice: Add a service process that loads and runs a kernel driver.
parent
29700766
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
260 additions
and
0 deletions
+260
-0
.gitignore
.gitignore
+1
-0
Makefile.in
Makefile.in
+2
-0
configure
configure
+3
-0
configure.ac
configure.ac
+1
-0
Makefile.in
programs/Makefile.in
+2
-0
Makefile.in
programs/winedevice/Makefile.in
+14
-0
device.c
programs/winedevice/device.c
+237
-0
No files found.
.gitignore
View file @
c81d0995
...
...
@@ -809,6 +809,7 @@ programs/winedbg/dbg.tab.h
programs/winedbg/debug.yy.c
programs/winedbg/winedbg
programs/winedbg/winedbg.man
programs/winedevice/winedevice
programs/winefile/drivebar.bmp
programs/winefile/images.bmp
programs/winefile/rsrc.res
...
...
Makefile.in
View file @
c81d0995
...
...
@@ -469,6 +469,7 @@ ALL_MAKEFILES = \
programs/winecfg/Makefile
\
programs/wineconsole/Makefile
\
programs/winedbg/Makefile
\
programs/winedevice/Makefile
\
programs/winefile/Makefile
\
programs/winemenubuilder/Makefile
\
programs/winemine/Makefile
\
...
...
@@ -817,6 +818,7 @@ programs/winebrowser/Makefile: programs/winebrowser/Makefile.in programs/Makepro
programs/winecfg/Makefile
:
programs/winecfg/Makefile.in programs/Makeprog.rules
programs/wineconsole/Makefile
:
programs/wineconsole/Makefile.in programs/Makeprog.rules
programs/winedbg/Makefile
:
programs/winedbg/Makefile.in programs/Makeprog.rules
programs/winedevice/Makefile
:
programs/winedevice/Makefile.in programs/Makeprog.rules
programs/winefile/Makefile
:
programs/winefile/Makefile.in programs/Makeprog.rules
programs/winemenubuilder/Makefile
:
programs/winemenubuilder/Makefile.in programs/Makeprog.rules
programs/winemine/Makefile
:
programs/winemine/Makefile.in programs/Makeprog.rules
...
...
configure
View file @
c81d0995
...
...
@@ -21007,6 +21007,8 @@ ac_config_files="$ac_config_files programs/wineconsole/Makefile"
ac_config_files
=
"
$ac_config_files
programs/winedbg/Makefile"
ac_config_files
=
"
$ac_config_files
programs/winedevice/Makefile"
ac_config_files
=
"
$ac_config_files
programs/winefile/Makefile"
ac_config_files
=
"
$ac_config_files
programs/winemenubuilder/Makefile"
...
...
@@ -21928,6 +21930,7 @@ do
"programs/winecfg/Makefile") CONFIG_FILES="
$CONFIG_FILES
programs/winecfg/Makefile" ;;
"programs/wineconsole/Makefile") CONFIG_FILES="
$CONFIG_FILES
programs/wineconsole/Makefile" ;;
"programs/winedbg/Makefile") CONFIG_FILES="
$CONFIG_FILES
programs/winedbg/Makefile" ;;
"programs/winedevice/Makefile") CONFIG_FILES="
$CONFIG_FILES
programs/winedevice/Makefile" ;;
"programs/winefile/Makefile") CONFIG_FILES="
$CONFIG_FILES
programs/winefile/Makefile" ;;
"programs/winemenubuilder/Makefile") CONFIG_FILES="
$CONFIG_FILES
programs/winemenubuilder/Makefile" ;;
"programs/winemine/Makefile") CONFIG_FILES="
$CONFIG_FILES
programs/winemine/Makefile" ;;
...
...
configure.ac
View file @
c81d0995
...
...
@@ -1799,6 +1799,7 @@ AC_CONFIG_FILES([programs/winebrowser/Makefile])
AC_CONFIG_FILES([programs/winecfg/Makefile])
AC_CONFIG_FILES([programs/wineconsole/Makefile])
AC_CONFIG_FILES([programs/winedbg/Makefile])
AC_CONFIG_FILES([programs/winedevice/Makefile])
AC_CONFIG_FILES([programs/winefile/Makefile])
AC_CONFIG_FILES([programs/winemenubuilder/Makefile])
AC_CONFIG_FILES([programs/winemine/Makefile])
...
...
programs/Makefile.in
View file @
c81d0995
...
...
@@ -35,6 +35,7 @@ SUBDIRS = \
winecfg
\
wineconsole
\
winedbg
\
winedevice
\
winefile
\
winemenubuilder
\
winemine
\
...
...
@@ -75,6 +76,7 @@ INSTALLSUBDIRS = \
winecfg
\
wineconsole
\
winedbg
\
winedevice
\
winefile
\
winemenubuilder
\
winemine
\
...
...
programs/winedevice/Makefile.in
0 → 100644
View file @
c81d0995
TOPSRCDIR
=
@top_srcdir@
TOPOBJDIR
=
../..
SRCDIR
=
@srcdir@
VPATH
=
@srcdir@
MODULE
=
winedevice.exe
APPMODE
=
-mwindows
-municode
IMPORTS
=
advapi32 ntoskrnl.exe kernel32 ntdll
C_SRCS
=
\
device.c
@MAKE_PROG_RULES@
@DEPENDENCIES@
# everything below this line is overwritten by make depend
programs/winedevice/device.c
0 → 100644
View file @
c81d0995
/*
* Service process to load a kernel driver
*
* Copyright 2007 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "winreg.h"
#include "winnls.h"
#include "winsvc.h"
#include "ddk/wdm.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
winedevice
);
WINE_DECLARE_DEBUG_CHANNEL
(
relay
);
extern
NTSTATUS
wine_ntoskrnl_main_loop
(
HANDLE
stop_event
);
static
WCHAR
*
driver_name
;
static
SERVICE_STATUS_HANDLE
service_handle
;
static
HKEY
driver_hkey
;
static
HANDLE
stop_event
;
static
DRIVER_OBJECT
driver_obj
;
static
DRIVER_EXTENSION
driver_extension
;
/* find the LDR_MODULE corresponding to the driver module */
static
LDR_MODULE
*
find_ldr_module
(
HMODULE
module
)
{
LIST_ENTRY
*
entry
,
*
list
=
&
NtCurrentTeb
()
->
Peb
->
LdrData
->
InMemoryOrderModuleList
;
for
(
entry
=
list
->
Flink
;
entry
!=
list
;
entry
=
entry
->
Flink
)
{
LDR_MODULE
*
ldr
=
CONTAINING_RECORD
(
entry
,
LDR_MODULE
,
InMemoryOrderModuleList
);
if
(
ldr
->
BaseAddress
==
module
)
return
ldr
;
if
(
ldr
->
BaseAddress
>
(
void
*
)
module
)
break
;
}
return
NULL
;
}
/* call the driver init entry point */
static
NTSTATUS
init_driver
(
HMODULE
module
,
UNICODE_STRING
*
keyname
)
{
unsigned
int
i
;
NTSTATUS
status
;
const
IMAGE_NT_HEADERS
*
nt
=
RtlImageNtHeader
(
module
);
if
(
!
nt
->
OptionalHeader
.
AddressOfEntryPoint
)
return
STATUS_SUCCESS
;
driver_obj
.
Size
=
sizeof
(
driver_obj
);
driver_obj
.
DriverSection
=
find_ldr_module
(
module
);
driver_obj
.
DriverInit
=
(
PDRIVER_INITIALIZE
)((
char
*
)
module
+
nt
->
OptionalHeader
.
AddressOfEntryPoint
);
driver_obj
.
DriverExtension
=
&
driver_extension
;
driver_extension
.
DriverObject
=
&
driver_obj
;
driver_extension
.
ServiceKeyName
=
*
keyname
;
if
(
WINE_TRACE_ON
(
relay
))
WINE_DPRINTF
(
"%04x:Call driver init %p (obj=%p,str=%s)
\n
"
,
GetCurrentThreadId
(),
driver_obj
.
DriverInit
,
&
driver_obj
,
wine_dbgstr_w
(
keyname
->
Buffer
)
);
status
=
driver_obj
.
DriverInit
(
&
driver_obj
,
keyname
);
if
(
WINE_TRACE_ON
(
relay
))
WINE_DPRINTF
(
"%04x:Ret driver init %p (obj=%p,str=%s) retval=%08x
\n
"
,
GetCurrentThreadId
(),
driver_obj
.
DriverInit
,
&
driver_obj
,
wine_dbgstr_w
(
keyname
->
Buffer
),
status
);
WINE_TRACE
(
"init done for %s obj %p
\n
"
,
wine_dbgstr_w
(
driver_name
),
&
driver_obj
);
WINE_TRACE
(
"- DriverInit = %p
\n
"
,
driver_obj
.
DriverInit
);
WINE_TRACE
(
"- DriverStartIo = %p
\n
"
,
driver_obj
.
DriverStartIo
);
WINE_TRACE
(
"- DriverUnload = %p
\n
"
,
driver_obj
.
DriverUnload
);
for
(
i
=
0
;
i
<=
IRP_MJ_MAXIMUM_FUNCTION
;
i
++
)
WINE_TRACE
(
"- MajorFunction[%d] = %p
\n
"
,
i
,
driver_obj
.
MajorFunction
[
i
]
);
return
status
;
}
/* load the .sys module for a device driver */
static
BOOL
load_driver
(
void
)
{
static
const
WCHAR
ntprefixW
[]
=
{
'\\'
,
'?'
,
'?'
,
'\\'
,
0
};
static
const
WCHAR
ImagePathW
[]
=
{
'I'
,
'm'
,
'a'
,
'g'
,
'e'
,
'P'
,
'a'
,
't'
,
'h'
,
0
};
static
const
WCHAR
servicesW
[]
=
{
'\\'
,
'R'
,
'e'
,
'g'
,
'i'
,
's'
,
't'
,
'r'
,
'y'
,
'\\'
,
'M'
,
'a'
,
'c'
,
'h'
,
'i'
,
'n'
,
'e'
,
'\\'
,
'S'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
'\\'
,
'C'
,
'u'
,
'r'
,
'r'
,
'e'
,
'n'
,
't'
,
'C'
,
'o'
,
'n'
,
't'
,
'r'
,
'o'
,
'l'
,
'S'
,
'e'
,
't'
,
'\\'
,
'S'
,
'e'
,
'r'
,
'v'
,
'i'
,
'c'
,
'e'
,
's'
,
'\\'
,
0
};
UNICODE_STRING
keypath
;
HMODULE
module
;
LPWSTR
path
=
NULL
,
str
;
DWORD
type
,
size
;
str
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
servicesW
)
+
strlenW
(
driver_name
)
*
sizeof
(
WCHAR
)
);
lstrcpyW
(
str
,
servicesW
);
lstrcatW
(
str
,
driver_name
);
if
(
RegOpenKeyW
(
HKEY_LOCAL_MACHINE
,
str
+
18
/* skip \registry\machine */
,
&
driver_hkey
))
{
WINE_ERR
(
"cannot open key %s, err=%u
\n
"
,
wine_dbgstr_w
(
str
),
GetLastError
()
);
return
FALSE
;
}
RtlInitUnicodeString
(
&
keypath
,
str
);
/* read the executable path from memory */
size
=
0
;
if
(
RegQueryValueExW
(
driver_hkey
,
ImagePathW
,
NULL
,
&
type
,
NULL
,
&
size
))
return
FALSE
;
str
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
if
(
!
RegQueryValueExW
(
driver_hkey
,
ImagePathW
,
NULL
,
&
type
,
(
LPBYTE
)
str
,
&
size
))
{
size
=
ExpandEnvironmentStringsW
(
str
,
NULL
,
0
);
path
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
*
sizeof
(
WCHAR
));
ExpandEnvironmentStringsW
(
str
,
path
,
size
);
}
HeapFree
(
GetProcessHeap
(),
0
,
str
);
if
(
!
path
)
return
FALSE
;
/* make sure msvcrt is loaded to resolve the ntoskrnl.exe forwards */
LoadLibraryA
(
"msvcrt.dll"
);
/* GameGuard uses an NT-style path name */
str
=
path
;
if
(
!
strncmpW
(
path
,
ntprefixW
,
4
))
str
+=
4
;
WINE_TRACE
(
"loading driver %s
\n
"
,
wine_dbgstr_w
(
str
)
);
module
=
LoadLibraryW
(
str
);
HeapFree
(
GetProcessHeap
(),
0
,
path
);
if
(
!
module
)
return
FALSE
;
init_driver
(
module
,
&
keypath
);
return
TRUE
;
}
static
DWORD
WINAPI
service_handler
(
DWORD
ctrl
,
DWORD
event_type
,
LPVOID
event_data
,
LPVOID
context
)
{
SERVICE_STATUS
status
;
status
.
dwServiceType
=
SERVICE_WIN32
;
status
.
dwControlsAccepted
=
SERVICE_ACCEPT_STOP
;
status
.
dwWin32ExitCode
=
0
;
status
.
dwServiceSpecificExitCode
=
0
;
status
.
dwCheckPoint
=
0
;
status
.
dwWaitHint
=
0
;
switch
(
ctrl
)
{
case
SERVICE_CONTROL_STOP
:
case
SERVICE_CONTROL_SHUTDOWN
:
WINE_TRACE
(
"shutting down %s
\n
"
,
wine_dbgstr_w
(
driver_name
)
);
status
.
dwCurrentState
=
SERVICE_STOP_PENDING
;
status
.
dwControlsAccepted
=
0
;
SetServiceStatus
(
service_handle
,
&
status
);
SetEvent
(
stop_event
);
return
NO_ERROR
;
default:
WINE_FIXME
(
"got service ctrl %x for %s
\n
"
,
ctrl
,
wine_dbgstr_w
(
driver_name
)
);
status
.
dwCurrentState
=
SERVICE_RUNNING
;
SetServiceStatus
(
service_handle
,
&
status
);
return
NO_ERROR
;
}
}
static
void
WINAPI
ServiceMain
(
DWORD
argc
,
LPWSTR
*
argv
)
{
SERVICE_STATUS
status
;
WINE_TRACE
(
"starting service %s
\n
"
,
wine_dbgstr_w
(
driver_name
)
);
stop_event
=
CreateEventW
(
NULL
,
TRUE
,
FALSE
,
NULL
);
service_handle
=
RegisterServiceCtrlHandlerExW
(
driver_name
,
service_handler
,
NULL
);
status
.
dwServiceType
=
SERVICE_WIN32
;
status
.
dwCurrentState
=
SERVICE_START_PENDING
;
status
.
dwControlsAccepted
=
0
;
status
.
dwWin32ExitCode
=
0
;
status
.
dwServiceSpecificExitCode
=
0
;
status
.
dwCheckPoint
=
0
;
status
.
dwWaitHint
=
10000
;
SetServiceStatus
(
service_handle
,
&
status
);
if
(
load_driver
())
{
status
.
dwCurrentState
=
SERVICE_RUNNING
;
status
.
dwControlsAccepted
=
SERVICE_ACCEPT_STOP
;
SetServiceStatus
(
service_handle
,
&
status
);
wine_ntoskrnl_main_loop
(
stop_event
);
}
else
WINE_ERR
(
"driver %s failed to load
\n
"
,
wine_dbgstr_w
(
driver_name
)
);
status
.
dwCurrentState
=
SERVICE_STOPPED
;
status
.
dwControlsAccepted
=
0
;
SetServiceStatus
(
service_handle
,
&
status
);
WINE_TRACE
(
"service %s stopped
\n
"
,
wine_dbgstr_w
(
driver_name
)
);
}
int
wmain
(
int
argc
,
WCHAR
*
argv
[]
)
{
SERVICE_TABLE_ENTRYW
service_table
[
2
];
if
(
!
(
driver_name
=
argv
[
1
]))
{
WINE_ERR
(
"missing device name, winedevice isn't supposed to be run manually
\n
"
);
return
1
;
}
service_table
[
0
].
lpServiceName
=
argv
[
1
];
service_table
[
0
].
lpServiceProc
=
ServiceMain
;
service_table
[
1
].
lpServiceName
=
NULL
;
service_table
[
1
].
lpServiceProc
=
NULL
;
StartServiceCtrlDispatcherW
(
service_table
);
return
0
;
}
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