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
a72f91f5
Commit
a72f91f5
authored
Jul 25, 2023
by
Paul Gofman
Committed by
Alexandre Julliard
Aug 01, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nsi: Forward request to nsiproxy from NsiRequestChangeNotification().
parent
dbe9f348
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
108 additions
and
16 deletions
+108
-16
nsi.c
dlls/nsi/nsi.c
+47
-10
nsi.c
dlls/nsi/tests/nsi.c
+7
-6
device.c
dlls/nsiproxy.sys/device.c
+46
-0
nsi.h
include/wine/nsi.h
+8
-0
No files found.
dlls/nsi/nsi.c
View file @
a72f91f5
...
...
@@ -31,6 +31,7 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
nsi
);
static
HANDLE
nsi_device
=
INVALID_HANDLE_VALUE
;
static
HANDLE
nsi_device_async
=
INVALID_HANDLE_VALUE
;
BOOL
WINAPI
DllMain
(
HINSTANCE
hinst
,
DWORD
reason
,
void
*
reserved
)
{
...
...
@@ -41,23 +42,26 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved)
break
;
case
DLL_PROCESS_DETACH
:
if
(
nsi_device
!=
INVALID_HANDLE_VALUE
)
CloseHandle
(
nsi_device
);
if
(
nsi_device_async
!=
INVALID_HANDLE_VALUE
)
CloseHandle
(
nsi_device_async
);
break
;
}
return
TRUE
;
}
static
inline
HANDLE
get_nsi_device
(
void
)
static
inline
HANDLE
get_nsi_device
(
BOOL
async
)
{
HANDLE
*
cached_device
=
async
?
&
nsi_device_async
:
&
nsi_device
;
HANDLE
device
;
if
(
nsi
_device
==
INVALID_HANDLE_VALUE
)
if
(
*
cached
_device
==
INVALID_HANDLE_VALUE
)
{
device
=
CreateFileW
(
L"
\\\\
.
\\
Nsi"
,
0
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
OPEN_EXISTING
,
0
,
NULL
);
device
=
CreateFileW
(
L"
\\\\
.
\\
Nsi"
,
0
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
OPEN_EXISTING
,
async
?
FILE_FLAG_OVERLAPPED
:
0
,
NULL
);
if
(
device
!=
INVALID_HANDLE_VALUE
&&
InterlockedCompareExchangePointer
(
&
nsi
_device
,
device
,
INVALID_HANDLE_VALUE
)
!=
INVALID_HANDLE_VALUE
)
&&
InterlockedCompareExchangePointer
(
cached
_device
,
device
,
INVALID_HANDLE_VALUE
)
!=
INVALID_HANDLE_VALUE
)
CloseHandle
(
device
);
}
return
nsi
_device
;
return
*
cached
_device
;
}
DWORD
WINAPI
NsiAllocateAndGetTable
(
DWORD
unk
,
const
NPI_MODULEID
*
module
,
DWORD
table
,
void
**
key_data
,
DWORD
key_size
,
...
...
@@ -155,7 +159,7 @@ DWORD WINAPI NsiEnumerateObjectsAllParameters( DWORD unk, DWORD unk2, const NPI_
DWORD
WINAPI
NsiEnumerateObjectsAllParametersEx
(
struct
nsi_enumerate_all_ex
*
params
)
{
DWORD
out_size
,
received
,
err
=
ERROR_SUCCESS
;
HANDLE
device
=
get_nsi_device
();
HANDLE
device
=
get_nsi_device
(
FALSE
);
struct
nsiproxy_enumerate_all
in
;
BYTE
*
out
,
*
ptr
;
...
...
@@ -235,7 +239,7 @@ DWORD WINAPI NsiGetAllParameters( DWORD unk, const NPI_MODULEID *module, DWORD t
DWORD
WINAPI
NsiGetAllParametersEx
(
struct
nsi_get_all_parameters_ex
*
params
)
{
HANDLE
device
=
get_nsi_device
();
HANDLE
device
=
get_nsi_device
(
FALSE
);
struct
nsiproxy_get_all_parameters
*
in
;
ULONG
in_size
=
FIELD_OFFSET
(
struct
nsiproxy_get_all_parameters
,
key
[
params
->
key_size
]
),
received
;
ULONG
out_size
=
params
->
rw_size
+
params
->
dynamic_size
+
params
->
static_size
;
...
...
@@ -304,7 +308,7 @@ DWORD WINAPI NsiGetParameter( DWORD unk, const NPI_MODULEID *module, DWORD table
DWORD
WINAPI
NsiGetParameterEx
(
struct
nsi_get_parameter_ex
*
params
)
{
HANDLE
device
=
get_nsi_device
();
HANDLE
device
=
get_nsi_device
(
FALSE
);
struct
nsiproxy_get_parameter
*
in
;
ULONG
in_size
=
FIELD_OFFSET
(
struct
nsiproxy_get_parameter
,
key
[
params
->
key_size
]
),
received
;
DWORD
err
=
ERROR_SUCCESS
;
...
...
@@ -345,7 +349,40 @@ DWORD WINAPI NsiRequestChangeNotification( DWORD unk, const NPI_MODULEID *module
DWORD
WINAPI
NsiRequestChangeNotificationEx
(
struct
nsi_request_change_notification_ex
*
params
)
{
FIXME
(
"%p stub.
\n
"
,
params
);
HANDLE
device
=
get_nsi_device
(
TRUE
);
struct
nsiproxy_request_notification
*
in
;
ULONG
in_size
=
sizeof
(
struct
nsiproxy_get_parameter
),
received
;
OVERLAPPED
overlapped
,
*
ovr
;
DWORD
err
=
ERROR_SUCCESS
;
DWORD
len
;
return
ERROR_NOT_SUPPORTED
;
TRACE
(
"%p.
\n
"
,
params
);
if
(
params
->
unk
)
FIXME
(
"unknown parameter %#lx.
\n
"
,
params
->
unk
);
if
(
device
==
INVALID_HANDLE_VALUE
)
return
GetLastError
();
in
=
malloc
(
in_size
);
if
(
!
in
)
return
ERROR_OUTOFMEMORY
;
in
->
module
=
*
params
->
module
;
in
->
table
=
params
->
table
;
if
(
!
(
ovr
=
params
->
ovr
))
{
overlapped
.
hEvent
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
);
ovr
=
&
overlapped
;
}
if
(
!
DeviceIoControl
(
device
,
IOCTL_NSIPROXY_WINE_CHANGE_NOTIFICATION
,
in
,
in_size
,
NULL
,
0
,
&
received
,
ovr
))
err
=
GetLastError
();
if
(
ovr
==
&
overlapped
)
{
if
(
err
==
ERROR_IO_PENDING
)
err
=
GetOverlappedResult
(
device
,
ovr
,
&
len
,
TRUE
)
?
0
:
GetLastError
();
CloseHandle
(
overlapped
.
hEvent
);
}
else
if
(
params
->
handle
&&
ovr
&&
err
==
ERROR_IO_PENDING
)
*
params
->
handle
=
device
;
free
(
in
);
return
err
;
}
dlls/nsi/tests/nsi.c
View file @
a72f91f5
...
...
@@ -1039,7 +1039,7 @@ void test_change_notifications(void)
handle
=
(
HANDLE
)
0xdeadbeef
;
ret
=
NsiRequestChangeNotification
(
0
,
&
NPI_MS_NDIS_MODULEID
,
NSI_NDIS_IFINFO_TABLE
,
&
ovr
,
&
handle
);
todo_wine
ok
(
ret
==
ERROR_IO_PENDING
,
"got %lu.
\n
"
,
ret
);
ok
(
ret
==
ERROR_IO_PENDING
,
"got %lu.
\n
"
,
ret
);
memset
(
&
params
,
0
,
sizeof
(
params
)
);
handle2
=
(
HANDLE
)
0xdeadbeef
;
...
...
@@ -1049,11 +1049,11 @@ void test_change_notifications(void)
params
.
ovr
=
&
ovr2
;
params
.
handle
=
&
handle2
;
ret
=
NsiRequestChangeNotificationEx
(
&
params
);
todo_wine
ok
(
ret
==
ERROR_IO_PENDING
,
"got %lu.
\n
"
,
ret
);
ok
(
ret
==
ERROR_IO_PENDING
,
"got %lu.
\n
"
,
ret
);
ok
(
handle2
==
handle
,
"got %p, %p.
\n
"
,
handle
,
handle2
);
bret
=
GetOverlappedResult
(
handle
,
&
ovr
,
&
bytes
,
FALSE
);
todo_wine
ok
(
!
bret
&&
GetLastError
()
==
ERROR_IO_INCOMPLETE
,
"got bret %d, err %lu.
\n
"
,
bret
,
GetLastError
()
);
ok
(
!
bret
&&
GetLastError
()
==
ERROR_IO_INCOMPLETE
,
"got bret %d, err %lu.
\n
"
,
bret
,
GetLastError
()
);
ret
=
NsiCancelChangeNotification
(
NULL
);
todo_wine
ok
(
ret
==
ERROR_NOT_FOUND
,
"got %lu.
\n
"
,
ret
);
...
...
@@ -1063,12 +1063,13 @@ void test_change_notifications(void)
bytes
=
0xdeadbeef
;
bret
=
GetOverlappedResult
(
handle
,
&
ovr
,
&
bytes
,
FALSE
);
todo_wine
ok
(
!
bret
&&
GetLastError
()
==
ERROR_OPERATION_ABORTED
,
"got bret %d, err %lu.
\n
"
,
bret
,
GetLastError
()
);
todo_wine
ok
(
ovr
.
Internal
==
(
ULONG
)
STATUS_CANCELLED
,
"got %Ix.
\n
"
,
ovr
.
Internal
);
ok
(
!
bytes
,
"got %lu.
\n
"
,
bytes
);
todo_wine
ok
(
!
bytes
,
"got %lu.
\n
"
,
bytes
);
bret
=
GetOverlappedResult
(
handle2
,
&
ovr2
,
&
bytes
,
FALSE
);
todo_wine
ok
(
!
bret
&&
GetLastError
()
==
ERROR_IO_INCOMPLETE
,
"got bret %d, err %lu.
\n
"
,
bret
,
GetLastError
()
);
ok
(
!
bret
&&
GetLastError
()
==
ERROR_IO_INCOMPLETE
,
"got bret %d, err %lu.
\n
"
,
bret
,
GetLastError
()
);
ret
=
NsiCancelChangeNotification
(
&
ovr2
);
todo_wine
ok
(
!
ret
,
"got %lu.
\n
"
,
ret
);
bret
=
GetOverlappedResult
(
handle
,
&
ovr
,
&
bytes
,
FALSE
);
...
...
@@ -1078,7 +1079,7 @@ void test_change_notifications(void)
todo_wine
ok
(
ret
==
ERROR_INVALID_PARAMETER
,
"got %lu.
\n
"
,
ret
);
ret
=
NsiRequestChangeNotification
(
0
,
&
NPI_MS_IPV4_MODULEID
,
NSI_IP_FORWARD_TABLE
,
&
ovr
,
&
handle
);
todo_wine
ok
(
ret
==
ERROR_IO_PENDING
,
"got %lu.
\n
"
,
ret
);
ok
(
ret
==
ERROR_IO_PENDING
,
"got %lu.
\n
"
,
ret
);
ret
=
NsiCancelChangeNotification
(
&
ovr
);
todo_wine
ok
(
!
ret
,
"got %lu.
\n
"
,
ret
);
bret
=
GetOverlappedResult
(
handle
,
&
ovr
,
&
bytes
,
FALSE
);
...
...
dlls/nsiproxy.sys/device.c
View file @
a72f91f5
...
...
@@ -49,6 +49,7 @@ DECLARE_CRITICAL_SECTION( nsiproxy_cs );
#define LIST_ENTRY_INIT( list ) { .Flink = &(list), .Blink = &(list) }
static
LIST_ENTRY
request_queue
=
LIST_ENTRY_INIT
(
request_queue
);
static
LIST_ENTRY
notification_queue
=
LIST_ENTRY_INIT
(
notification_queue
);
static
NTSTATUS
nsiproxy_call
(
unsigned
int
code
,
void
*
args
)
{
...
...
@@ -261,6 +262,47 @@ static NTSTATUS nsiproxy_icmp_echo( IRP *irp )
return
STATUS_PENDING
;
}
static
void
WINAPI
change_notification_cancel
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
{
TRACE
(
"device %p, irp %p.
\n
"
,
device
,
irp
);
IoReleaseCancelSpinLock
(
irp
->
CancelIrql
);
EnterCriticalSection
(
&
nsiproxy_cs
);
RemoveEntryList
(
&
irp
->
Tail
.
Overlay
.
ListEntry
);
LeaveCriticalSection
(
&
nsiproxy_cs
);
irp
->
IoStatus
.
Status
=
STATUS_CANCELLED
;
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
}
static
NTSTATUS
nsiproxy_change_notification
(
IRP
*
irp
)
{
IO_STACK_LOCATION
*
irpsp
=
IoGetCurrentIrpStackLocation
(
irp
);
struct
nsiproxy_request_notification
*
in
=
(
struct
nsiproxy_request_notification
*
)
irp
->
AssociatedIrp
.
SystemBuffer
;
DWORD
in_len
=
irpsp
->
Parameters
.
DeviceIoControl
.
InputBufferLength
;
FIXME
(
"
\n
"
);
if
(
in_len
<
sizeof
(
*
in
))
return
STATUS_INVALID_PARAMETER
;
/* FIXME: validate module and table. */
EnterCriticalSection
(
&
nsiproxy_cs
);
IoSetCancelRoutine
(
irp
,
change_notification_cancel
);
if
(
irp
->
Cancel
&&
!
IoSetCancelRoutine
(
irp
,
NULL
))
{
/* IRP was canceled before we set cancel routine */
InitializeListHead
(
&
irp
->
Tail
.
Overlay
.
ListEntry
);
LeaveCriticalSection
(
&
nsiproxy_cs
);
return
STATUS_CANCELLED
;
}
InsertTailList
(
&
notification_queue
,
&
irp
->
Tail
.
Overlay
.
ListEntry
);
IoMarkIrpPending
(
irp
);
LeaveCriticalSection
(
&
nsiproxy_cs
);
return
STATUS_PENDING
;
}
static
NTSTATUS
WINAPI
nsi_ioctl
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
{
IO_STACK_LOCATION
*
irpsp
=
IoGetCurrentIrpStackLocation
(
irp
);
...
...
@@ -289,6 +331,10 @@ static NTSTATUS WINAPI nsi_ioctl( DEVICE_OBJECT *device, IRP *irp )
status
=
nsiproxy_icmp_echo
(
irp
);
break
;
case
IOCTL_NSIPROXY_WINE_CHANGE_NOTIFICATION
:
status
=
nsiproxy_change_notification
(
irp
);
break
;
default:
FIXME
(
"ioctl %lx not supported
\n
"
,
irpsp
->
Parameters
.
DeviceIoControl
.
IoControlCode
);
status
=
STATUS_NOT_SUPPORTED
;
...
...
include/wine/nsi.h
View file @
a72f91f5
...
...
@@ -380,6 +380,7 @@ struct nsi_udp_endpoint_static
#define IOCTL_NSIPROXY_WINE_GET_ALL_PARAMETERS CTL_CODE(FILE_DEVICE_NETWORK, 0x401, METHOD_BUFFERED, 0)
#define IOCTL_NSIPROXY_WINE_GET_PARAMETER CTL_CODE(FILE_DEVICE_NETWORK, 0x402, METHOD_BUFFERED, 0)
#define IOCTL_NSIPROXY_WINE_ICMP_ECHO CTL_CODE(FILE_DEVICE_NETWORK, 0x403, METHOD_BUFFERED, 0)
#define IOCTL_NSIPROXY_WINE_CHANGE_NOTIFICATION CTL_CODE(FILE_DEVICE_NETWORK, 0x404, METHOD_BUFFERED, 0)
/* input for IOCTL_NSIPROXY_WINE_ENUMERATE_ALL */
struct
nsiproxy_enumerate_all
...
...
@@ -436,6 +437,13 @@ struct nsiproxy_icmp_echo
BYTE
data
[
1
];
/* ((opt_size + 3) & ~3) + req_size */
};
/* input for IOCTL_NSIPROXY_WINE_CHANGE_NOTIFICATION */
struct
nsiproxy_request_notification
{
NPI_MODULEID
module
;
UINT
table
;
};
/* Undocumented Nsi api */
#define NSI_PARAM_TYPE_RW 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