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
c4986ee2
Commit
c4986ee2
authored
Apr 02, 2021
by
Zebediah Figura
Committed by
Alexandre Julliard
Apr 02, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntoskrnl/tests: Add a basic PnP test driver.
Signed-off-by:
Zebediah Figura
<
z.figura12@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
eb5ff502
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
375 additions
and
1 deletion
+375
-1
Makefile.in
dlls/ntoskrnl.exe/tests/Makefile.in
+5
-1
driver_pnp.c
dlls/ntoskrnl.exe/tests/driver_pnp.c
+143
-0
driver_pnp.spec
dlls/ntoskrnl.exe/tests/driver_pnp.spec
+1
-0
ntoskrnl.c
dlls/ntoskrnl.exe/tests/ntoskrnl.c
+226
-0
No files found.
dlls/ntoskrnl.exe/tests/Makefile.in
View file @
c4986ee2
TESTDLL
=
ntoskrnl.exe
IMPORTS
=
advapi32 crypt32 wintrust ws2_32
IMPORTS
=
advapi32 crypt32
newdev setupapi
wintrust ws2_32
driver_IMPORTS
=
winecrt0 ntoskrnl
driver_EXTRADLLFLAGS
=
-nodefaultlibs
-nostartfiles
-Wl
,--subsystem,native
...
...
@@ -9,6 +9,8 @@ driver3_IMPORTS = winecrt0 ntoskrnl
driver3_EXTRADLLFLAGS
=
-nodefaultlibs
-nostartfiles
-Wl
,--subsystem,native
driver4_IMPORTS
=
winecrt0 ntoskrnl netio
driver4_EXTRADLLFLAGS
=
-nodefaultlibs
-nostartfiles
-Wl
,--subsystem,native
driver_pnp_IMPORTS
=
winecrt0 ntoskrnl
driver_pnp_EXTRADLLFLAGS
=
-nodefaultlibs
-nostartfiles
-Wl
,--subsystem,native
SOURCES
=
\
driver.c
\
...
...
@@ -19,4 +21,6 @@ SOURCES = \
driver3.spec
\
driver4.c
\
driver4.spec
\
driver_pnp.c
\
driver_pnp.spec
\
ntoskrnl.c
dlls/ntoskrnl.exe/tests/driver_pnp.c
0 → 100644
View file @
c4986ee2
/*
* ntoskrnl.exe testing framework
*
* Copyright 2020 Zebediah Figura
*
* 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 "winioctl.h"
#include "ddk/wdm.h"
#include "driver.h"
static
const
GUID
control_class
=
{
0xdeadbeef
,
0x29ef
,
0x4538
,
{
0xa5
,
0xfd
,
0xb6
,
0x95
,
0x73
,
0xa3
,
0x62
,
0xc0
}};
static
UNICODE_STRING
control_symlink
;
static
DEVICE_OBJECT
*
bus_fdo
,
*
bus_pdo
;
static
NTSTATUS
fdo_pnp
(
IRP
*
irp
)
{
IO_STACK_LOCATION
*
stack
=
IoGetCurrentIrpStackLocation
(
irp
);
NTSTATUS
ret
;
switch
(
stack
->
MinorFunction
)
{
case
IRP_MN_START_DEVICE
:
irp
->
IoStatus
.
Status
=
IoSetDeviceInterfaceState
(
&
control_symlink
,
TRUE
);
break
;
case
IRP_MN_SURPRISE_REMOVAL
:
irp
->
IoStatus
.
Status
=
STATUS_SUCCESS
;
break
;
case
IRP_MN_REMOVE_DEVICE
:
IoSetDeviceInterfaceState
(
&
control_symlink
,
FALSE
);
irp
->
IoStatus
.
Status
=
STATUS_SUCCESS
;
IoSkipCurrentIrpStackLocation
(
irp
);
ret
=
IoCallDriver
(
bus_pdo
,
irp
);
IoDetachDevice
(
bus_pdo
);
IoDeleteDevice
(
bus_fdo
);
RtlFreeUnicodeString
(
&
control_symlink
);
return
ret
;
}
IoSkipCurrentIrpStackLocation
(
irp
);
return
IoCallDriver
(
bus_pdo
,
irp
);
}
static
NTSTATUS
pdo_pnp
(
DEVICE_OBJECT
*
device_obj
,
IRP
*
irp
)
{
IO_STACK_LOCATION
*
stack
=
IoGetCurrentIrpStackLocation
(
irp
);
NTSTATUS
ret
=
irp
->
IoStatus
.
Status
;
switch
(
stack
->
MinorFunction
)
{
case
IRP_MN_START_DEVICE
:
ret
=
STATUS_SUCCESS
;
break
;
case
IRP_MN_QUERY_CAPABILITIES
:
case
IRP_MN_SURPRISE_REMOVAL
:
ret
=
STATUS_SUCCESS
;
break
;
}
irp
->
IoStatus
.
Status
=
ret
;
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
return
ret
;
}
static
NTSTATUS
WINAPI
driver_pnp
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
{
if
(
device
==
bus_fdo
)
return
fdo_pnp
(
irp
);
return
pdo_pnp
(
device
,
irp
);
}
static
NTSTATUS
WINAPI
driver_add_device
(
DRIVER_OBJECT
*
driver
,
DEVICE_OBJECT
*
pdo
)
{
NTSTATUS
ret
;
if
((
ret
=
IoCreateDevice
(
driver
,
0
,
NULL
,
FILE_DEVICE_BUS_EXTENDER
,
0
,
FALSE
,
&
bus_fdo
)))
return
ret
;
if
((
ret
=
IoRegisterDeviceInterface
(
pdo
,
&
control_class
,
NULL
,
&
control_symlink
)))
{
IoDeleteDevice
(
bus_fdo
);
return
ret
;
}
IoAttachDeviceToDeviceStack
(
bus_fdo
,
pdo
);
bus_pdo
=
pdo
;
bus_fdo
->
Flags
&=
~
DO_DEVICE_INITIALIZING
;
return
STATUS_SUCCESS
;
}
static
NTSTATUS
WINAPI
driver_create
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
{
irp
->
IoStatus
.
Status
=
STATUS_SUCCESS
;
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
return
STATUS_SUCCESS
;
}
static
NTSTATUS
WINAPI
driver_close
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
{
irp
->
IoStatus
.
Status
=
STATUS_SUCCESS
;
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
return
STATUS_SUCCESS
;
}
static
void
WINAPI
driver_unload
(
DRIVER_OBJECT
*
driver
)
{
}
NTSTATUS
WINAPI
DriverEntry
(
DRIVER_OBJECT
*
driver
,
UNICODE_STRING
*
registry
)
{
driver
->
DriverExtension
->
AddDevice
=
driver_add_device
;
driver
->
DriverUnload
=
driver_unload
;
driver
->
MajorFunction
[
IRP_MJ_PNP
]
=
driver_pnp
;
driver
->
MajorFunction
[
IRP_MJ_CREATE
]
=
driver_create
;
driver
->
MajorFunction
[
IRP_MJ_CLOSE
]
=
driver_close
;
return
STATUS_SUCCESS
;
}
dlls/ntoskrnl.exe/tests/driver_pnp.spec
0 → 100644
View file @
c4986ee2
# nothing here yet
dlls/ntoskrnl.exe/tests/ntoskrnl.c
View file @
c4986ee2
...
...
@@ -32,12 +32,16 @@
#include "ntsecapi.h"
#include "mscat.h"
#include "mssip.h"
#include "setupapi.h"
#include "newdev.h"
#include "wine/test.h"
#include "wine/heap.h"
#include "wine/mssign.h"
#include "driver.h"
static
const
GUID
GUID_NULL
;
static
HANDLE
device
;
static
BOOL
(
WINAPI
*
pRtlDosPathNameToNtPathName_U
)(
const
WCHAR
*
,
UNICODE_STRING
*
,
WCHAR
**
,
CURDIR
*
);
...
...
@@ -935,6 +939,226 @@ static void test_driver4(struct testsign_context *ctx)
ok
(
ret
,
"DeleteFile failed: %u
\n
"
,
GetLastError
());
}
static
void
add_file_to_catalog
(
HANDLE
catalog
,
const
WCHAR
*
file
)
{
SIP_SUBJECTINFO
subject_info
=
{
sizeof
(
SIP_SUBJECTINFO
)};
SIP_INDIRECT_DATA
*
indirect_data
;
const
WCHAR
*
filepart
=
file
;
CRYPTCATMEMBER
*
member
;
WCHAR
hash_buffer
[
100
];
GUID
subject_guid
;
unsigned
int
i
;
DWORD
size
;
BOOL
ret
;
ret
=
CryptSIPRetrieveSubjectGuidForCatalogFile
(
file
,
NULL
,
&
subject_guid
);
todo_wine
ok
(
ret
,
"Failed to get subject guid, error %u
\n
"
,
GetLastError
());
size
=
0
;
subject_info
.
pgSubjectType
=
&
subject_guid
;
subject_info
.
pwsFileName
=
file
;
subject_info
.
DigestAlgorithm
.
pszObjId
=
(
char
*
)
szOID_OIWSEC_sha1
;
subject_info
.
dwFlags
=
SPC_INC_PE_RESOURCES_FLAG
|
SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG
|
SPC_EXC_PE_PAGE_HASHES_FLAG
|
0x10000
;
ret
=
CryptSIPCreateIndirectData
(
&
subject_info
,
&
size
,
NULL
);
todo_wine
ok
(
ret
,
"Failed to get indirect data size, error %u
\n
"
,
GetLastError
());
indirect_data
=
malloc
(
size
);
ret
=
CryptSIPCreateIndirectData
(
&
subject_info
,
&
size
,
indirect_data
);
todo_wine
ok
(
ret
,
"Failed to get indirect data, error %u
\n
"
,
GetLastError
());
if
(
ret
)
{
memset
(
hash_buffer
,
0
,
sizeof
(
hash_buffer
));
for
(
i
=
0
;
i
<
indirect_data
->
Digest
.
cbData
;
++
i
)
swprintf
(
&
hash_buffer
[
i
*
2
],
2
,
L"%02X"
,
indirect_data
->
Digest
.
pbData
[
i
]);
member
=
CryptCATPutMemberInfo
(
catalog
,
(
WCHAR
*
)
file
,
hash_buffer
,
&
subject_guid
,
0
,
size
,
(
BYTE
*
)
indirect_data
);
ok
(
!!
member
,
"Failed to write member, error %u
\n
"
,
GetLastError
());
if
(
wcsrchr
(
file
,
'\\'
))
filepart
=
wcsrchr
(
file
,
'\\'
)
+
1
;
ret
=
!!
CryptCATPutAttrInfo
(
catalog
,
member
,
(
WCHAR
*
)
L"File"
,
CRYPTCAT_ATTR_NAMEASCII
|
CRYPTCAT_ATTR_DATAASCII
|
CRYPTCAT_ATTR_AUTHENTICATED
,
(
wcslen
(
filepart
)
+
1
)
*
2
,
(
BYTE
*
)
filepart
);
ok
(
ret
,
"Failed to write attr, error %u
\n
"
,
GetLastError
());
ret
=
!!
CryptCATPutAttrInfo
(
catalog
,
member
,
(
WCHAR
*
)
L"OSAttr"
,
CRYPTCAT_ATTR_NAMEASCII
|
CRYPTCAT_ATTR_DATAASCII
|
CRYPTCAT_ATTR_AUTHENTICATED
,
sizeof
(
L"2:6.0"
),
(
BYTE
*
)
L"2:6.0"
);
ok
(
ret
,
"Failed to write attr, error %u
\n
"
,
GetLastError
());
}
}
static
void
test_pnp_driver
(
struct
testsign_context
*
ctx
)
{
static
const
char
hardware_id
[]
=
"test_hardware_id
\0
"
;
char
path
[
MAX_PATH
],
dest
[
MAX_PATH
],
*
filepart
;
SP_DEVINFO_DATA
device
=
{
sizeof
(
device
)};
char
cwd
[
MAX_PATH
],
tempdir
[
MAX_PATH
];
WCHAR
driver_filename
[
MAX_PATH
];
SC_HANDLE
manager
,
service
;
BOOL
ret
,
need_reboot
;
HANDLE
catalog
,
file
;
HDEVINFO
set
;
FILE
*
f
;
#ifdef __i386__
#define EXT "x86"
#elif defined(__x86_64__)
#define EXT "amd64"
#elif defined(__arm__)
#define EXT "arm"
#elif defined(__aarch64__)
#define EXT "arm64"
#else
#define EXT
#endif
static
const
char
inf_text
[]
=
"[Version]
\n
"
"Signature=$Chicago$
\n
"
"ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}
\n
"
"CatalogFile=winetest.cat
\n
"
"DriverVer=09/21/2006,6.0.5736.1
\n
"
"[Manufacturer]
\n
"
"Wine=mfg_section,NT"
EXT
"
\n
"
"[mfg_section.NT"
EXT
"]
\n
"
"Wine test root driver=device_section,test_hardware_id
\n
"
"[device_section.NT"
EXT
"]
\n
"
"CopyFiles=file_section
\n
"
"[device_section.NT"
EXT
".Services]
\n
"
"AddService=winetest,0x2,svc_section
\n
"
"[file_section]
\n
"
"winetest.sys
\n
"
"[SourceDisksFiles]
\n
"
"winetest.sys=1
\n
"
"[SourceDisksNames]
\n
"
"1=,winetest.sys
\n
"
"[DestinationDirs]
\n
"
"DefaultDestDir=12
\n
"
"[svc_section]
\n
"
"ServiceBinary=%12%
\\
winetest.sys
\n
"
"ServiceType=1
\n
"
"StartType=3
\n
"
"ErrorControl=1
\n
"
"LoadOrderGroup=Extended Base
\n
"
"DisplayName=
\"
winetest bus driver
\"\n
"
"; they don't sleep anymore, on the beach
\n
"
;
GetCurrentDirectoryA
(
ARRAY_SIZE
(
cwd
),
cwd
);
GetTempPathA
(
ARRAY_SIZE
(
tempdir
),
tempdir
);
SetCurrentDirectoryA
(
tempdir
);
load_resource
(
L"driver_pnp.dll"
,
driver_filename
);
ret
=
MoveFileExW
(
driver_filename
,
L"winetest.sys"
,
MOVEFILE_COPY_ALLOWED
|
MOVEFILE_REPLACE_EXISTING
);
ok
(
ret
,
"failed to move file, error %u
\n
"
,
GetLastError
());
f
=
fopen
(
"winetest.inf"
,
"w"
);
ok
(
!!
f
,
"failed to open winetest.inf: %s
\n
"
,
strerror
(
errno
));
fputs
(
inf_text
,
f
);
fclose
(
f
);
/* Create the catalog file. */
catalog
=
CryptCATOpen
((
WCHAR
*
)
L"winetest.cat"
,
CRYPTCAT_OPEN_CREATENEW
,
0
,
CRYPTCAT_VERSION_1
,
0
);
ok
(
catalog
!=
INVALID_HANDLE_VALUE
,
"Failed to create catalog, error %#x
\n
"
,
GetLastError
());
ret
=
!!
CryptCATPutCatAttrInfo
(
catalog
,
(
WCHAR
*
)
L"HWID1"
,
CRYPTCAT_ATTR_NAMEASCII
|
CRYPTCAT_ATTR_DATAASCII
|
CRYPTCAT_ATTR_AUTHENTICATED
,
sizeof
(
L"test_hardware_id"
),
(
BYTE
*
)
L"test_hardware_id"
);
todo_wine
ok
(
ret
,
"failed to add attribute, error %#x
\n
"
,
GetLastError
());
ret
=
!!
CryptCATPutCatAttrInfo
(
catalog
,
(
WCHAR
*
)
L"OS"
,
CRYPTCAT_ATTR_NAMEASCII
|
CRYPTCAT_ATTR_DATAASCII
|
CRYPTCAT_ATTR_AUTHENTICATED
,
sizeof
(
L"VistaX64"
),
(
BYTE
*
)
L"VistaX64"
);
todo_wine
ok
(
ret
,
"failed to add attribute, error %#x
\n
"
,
GetLastError
());
add_file_to_catalog
(
catalog
,
L"winetest.sys"
);
add_file_to_catalog
(
catalog
,
L"winetest.inf"
);
ret
=
CryptCATPersistStore
(
catalog
);
todo_wine
ok
(
ret
,
"Failed to write catalog, error %u
\n
"
,
GetLastError
());
ret
=
CryptCATClose
(
catalog
);
ok
(
ret
,
"Failed to close catalog, error %u
\n
"
,
GetLastError
());
testsign_sign
(
ctx
,
L"winetest.cat"
);
/* Install the driver. */
set
=
SetupDiCreateDeviceInfoList
(
NULL
,
NULL
);
ok
(
set
!=
INVALID_HANDLE_VALUE
,
"failed to create device list, error %#x
\n
"
,
GetLastError
());
ret
=
SetupDiCreateDeviceInfoA
(
set
,
"root
\\
winetest
\\
0"
,
&
GUID_NULL
,
NULL
,
NULL
,
0
,
&
device
);
ok
(
ret
,
"failed to create device, error %#x
\n
"
,
GetLastError
());
ret
=
SetupDiSetDeviceRegistryPropertyA
(
set
,
&
device
,
SPDRP_HARDWAREID
,
(
const
BYTE
*
)
hardware_id
,
sizeof
(
hardware_id
)
);
ok
(
ret
,
"failed to create set hardware ID, error %#x
\n
"
,
GetLastError
());
ret
=
SetupDiCallClassInstaller
(
DIF_REGISTERDEVICE
,
set
,
&
device
);
ok
(
ret
,
"failed to register device, error %#x
\n
"
,
GetLastError
());
GetFullPathNameA
(
"winetest.inf"
,
sizeof
(
path
),
path
,
NULL
);
ret
=
UpdateDriverForPlugAndPlayDevicesA
(
NULL
,
hardware_id
,
path
,
INSTALLFLAG_FORCE
,
&
need_reboot
);
ok
(
ret
,
"failed to install device, error %#x
\n
"
,
GetLastError
());
ok
(
!
need_reboot
,
"expected no reboot necessary
\n
"
);
/* Tests. */
file
=
CreateFileA
(
"
\\\\
?
\\
root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}"
,
0
,
0
,
NULL
,
OPEN_EXISTING
,
0
,
NULL
);
ok
(
file
!=
INVALID_HANDLE_VALUE
,
"got error %u
\n
"
,
GetLastError
());
CloseHandle
(
file
);
/* Clean up. */
ret
=
SetupDiCallClassInstaller
(
DIF_REMOVE
,
set
,
&
device
);
ok
(
ret
,
"failed to remove device, error %#x
\n
"
,
GetLastError
());
file
=
CreateFileA
(
"
\\\\
?
\\
root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}"
,
0
,
0
,
NULL
,
OPEN_EXISTING
,
0
,
NULL
);
ok
(
file
==
INVALID_HANDLE_VALUE
,
"expected failure
\n
"
);
ok
(
GetLastError
()
==
ERROR_FILE_NOT_FOUND
,
"got error %u
\n
"
,
GetLastError
());
ret
=
SetupDiDestroyDeviceInfoList
(
set
);
ok
(
ret
,
"failed to destroy set, error %#x
\n
"
,
GetLastError
());
/* Windows stops the service but does not delete it. */
manager
=
OpenSCManagerA
(
NULL
,
NULL
,
SC_MANAGER_CONNECT
);
ok
(
!!
manager
,
"failed to open service manager, error %u
\n
"
,
GetLastError
());
service
=
OpenServiceA
(
manager
,
"winetest"
,
SERVICE_STOP
|
DELETE
);
ok
(
!!
service
,
"failed to open service, error %u
\n
"
,
GetLastError
());
unload_driver
(
service
);
CloseServiceHandle
(
manager
);
GetFullPathNameA
(
"winetest.inf"
,
sizeof
(
path
),
path
,
NULL
);
ret
=
SetupCopyOEMInfA
(
path
,
NULL
,
0
,
0
,
dest
,
sizeof
(
dest
),
NULL
,
&
filepart
);
ok
(
ret
,
"Failed to copy INF, error %#x
\n
"
,
GetLastError
());
ret
=
SetupUninstallOEMInfA
(
filepart
,
0
,
NULL
);
ok
(
ret
,
"Failed to uninstall INF, error %u
\n
"
,
GetLastError
());
ret
=
DeleteFileA
(
"winetest.cat"
);
ok
(
ret
,
"Failed to delete file, error %u
\n
"
,
GetLastError
());
ret
=
DeleteFileA
(
"winetest.inf"
);
ok
(
ret
,
"Failed to delete file, error %u
\n
"
,
GetLastError
());
ret
=
DeleteFileA
(
"winetest.sys"
);
ok
(
ret
,
"Failed to delete file, error %u
\n
"
,
GetLastError
());
/* Windows 10 apparently deletes the image in SetupUninstallOEMInf(). */
ret
=
DeleteFileA
(
"C:/windows/system32/drivers/winetest.sys"
);
ok
(
ret
||
GetLastError
()
==
ERROR_FILE_NOT_FOUND
,
"Failed to delete file, error %u
\n
"
,
GetLastError
());
SetCurrentDirectoryA
(
cwd
);
}
START_TEST
(
ntoskrnl
)
{
WCHAR
filename
[
MAX_PATH
],
filename2
[
MAX_PATH
];
...
...
@@ -1008,5 +1232,7 @@ START_TEST(ntoskrnl)
subtest
(
"driver4"
);
test_driver4
(
&
ctx
);
test_pnp_driver
(
&
ctx
);
testsign_cleanup
(
&
ctx
);
}
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