4 * Copyright 2021 Huw Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define NONAMELESSUNION
25 #define WIN32_NO_STATUS
34 #include "wine/debug.h"
35 #include "nsiproxy_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(nsi
);
39 static void nsiproxy_enumerate_all( IRP
*irp
)
41 IO_STACK_LOCATION
*irpsp
= IoGetCurrentIrpStackLocation( irp
);
42 struct nsiproxy_enumerate_all
*in
= (struct nsiproxy_enumerate_all
*)irp
->AssociatedIrp
.SystemBuffer
;
43 DWORD in_len
= irpsp
->Parameters
.DeviceIoControl
.InputBufferLength
;
44 void *out
= irp
->AssociatedIrp
.SystemBuffer
;
45 DWORD out_len
= irpsp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
46 struct nsi_enumerate_all_ex enum_all
;
48 if (in_len
!= sizeof(*in
))
50 irp
->IoStatus
.u
.Status
= STATUS_INVALID_PARAMETER
;
54 if (out_len
< sizeof(DWORD
) + (in
->key_size
+ in
->rw_size
+ in
->dynamic_size
+ in
->static_size
) * in
->count
)
56 irp
->IoStatus
.u
.Status
= STATUS_INVALID_PARAMETER
;
60 enum_all
.unknown
[0] = 0;
61 enum_all
.unknown
[1] = 0;
62 enum_all
.first_arg
= in
->first_arg
;
63 enum_all
.second_arg
= in
->second_arg
;
64 enum_all
.module
= &in
->module
;
65 enum_all
.table
= in
->table
;
66 enum_all
.key_data
= (BYTE
*)out
+ sizeof(DWORD
);
67 enum_all
.key_size
= in
->key_size
;
68 enum_all
.rw_data
= (BYTE
*)enum_all
.key_data
+ in
->key_size
* in
->count
;
69 enum_all
.rw_size
= in
->rw_size
;
70 enum_all
.dynamic_data
= (BYTE
*)enum_all
.rw_data
+ in
->rw_size
* in
->count
;
71 enum_all
.dynamic_size
= in
->dynamic_size
;
72 enum_all
.static_data
= (BYTE
*)enum_all
.dynamic_data
+ in
->dynamic_size
* in
->count
;
73 enum_all
.static_size
= in
->static_size
;
74 enum_all
.count
= in
->count
;
76 irp
->IoStatus
.u
.Status
= nsi_enumerate_all_ex( &enum_all
);
77 if (irp
->IoStatus
.u
.Status
== STATUS_SUCCESS
|| irp
->IoStatus
.u
.Status
== STATUS_MORE_ENTRIES
)
79 irp
->IoStatus
.Information
= out_len
;
80 *(DWORD
*)out
= enum_all
.count
;
82 else irp
->IoStatus
.Information
= 0;
85 static void nsiproxy_get_all_parameters( IRP
*irp
)
87 IO_STACK_LOCATION
*irpsp
= IoGetCurrentIrpStackLocation( irp
);
88 struct nsiproxy_get_all_parameters
*in
= (struct nsiproxy_get_all_parameters
*)irp
->AssociatedIrp
.SystemBuffer
;
89 DWORD in_len
= irpsp
->Parameters
.DeviceIoControl
.InputBufferLength
;
90 BYTE
*out
= irp
->AssociatedIrp
.SystemBuffer
;
91 DWORD out_len
= irpsp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
92 struct nsi_get_all_parameters_ex get_all
;
94 if (in_len
< FIELD_OFFSET(struct nsiproxy_get_all_parameters
, key
[0]) ||
95 in_len
< FIELD_OFFSET(struct nsiproxy_get_all_parameters
, key
[in
->key_size
]))
97 irp
->IoStatus
.u
.Status
= STATUS_INVALID_PARAMETER
;
101 if (out_len
< in
->rw_size
+ in
->dynamic_size
+ in
->static_size
)
103 irp
->IoStatus
.u
.Status
= STATUS_INVALID_PARAMETER
;
107 get_all
.unknown
[0] = 0;
108 get_all
.unknown
[1] = 0;
109 get_all
.first_arg
= in
->first_arg
;
110 get_all
.unknown2
= 0;
111 get_all
.module
= &in
->module
;
112 get_all
.table
= in
->table
;
113 get_all
.key
= in
->key
;
114 get_all
.key_size
= in
->key_size
;
115 get_all
.rw_data
= out
;
116 get_all
.rw_size
= in
->rw_size
;
117 get_all
.dynamic_data
= out
+ in
->rw_size
;
118 get_all
.dynamic_size
= in
->dynamic_size
;
119 get_all
.static_data
= out
+ in
->rw_size
+ in
->dynamic_size
;
120 get_all
.static_size
= in
->static_size
;
122 irp
->IoStatus
.u
.Status
= nsi_get_all_parameters_ex( &get_all
);
123 irp
->IoStatus
.Information
= (irp
->IoStatus
.u
.Status
== STATUS_SUCCESS
) ? out_len
: 0;
126 static void nsiproxy_get_parameter( IRP
*irp
)
128 IO_STACK_LOCATION
*irpsp
= IoGetCurrentIrpStackLocation( irp
);
129 struct nsiproxy_get_parameter
*in
= (struct nsiproxy_get_parameter
*)irp
->AssociatedIrp
.SystemBuffer
;
130 DWORD in_len
= irpsp
->Parameters
.DeviceIoControl
.InputBufferLength
;
131 void *out
= irp
->AssociatedIrp
.SystemBuffer
;
132 DWORD out_len
= irpsp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
133 struct nsi_get_parameter_ex get_param
;
135 if (in_len
< FIELD_OFFSET(struct nsiproxy_get_parameter
, key
[0]) ||
136 in_len
< FIELD_OFFSET(struct nsiproxy_get_parameter
, key
[in
->key_size
]))
138 irp
->IoStatus
.u
.Status
= STATUS_INVALID_PARAMETER
;
142 get_param
.unknown
[0] = 0;
143 get_param
.unknown
[1] = 0;
144 get_param
.first_arg
= in
->first_arg
;
145 get_param
.unknown2
= 0;
146 get_param
.module
= &in
->module
;
147 get_param
.table
= in
->table
;
148 get_param
.key
= in
->key
;
149 get_param
.key_size
= in
->key_size
;
150 get_param
.param_type
= in
->param_type
;
151 get_param
.data
= out
;
152 get_param
.data_size
= out_len
;
153 get_param
.data_offset
= in
->data_offset
;
155 irp
->IoStatus
.u
.Status
= nsi_get_parameter_ex( &get_param
);
156 irp
->IoStatus
.Information
= irp
->IoStatus
.u
.Status
== STATUS_SUCCESS
? out_len
: 0;
159 static NTSTATUS WINAPI
nsi_ioctl( DEVICE_OBJECT
*device
, IRP
*irp
)
161 IO_STACK_LOCATION
*irpsp
= IoGetCurrentIrpStackLocation( irp
);
163 TRACE( "ioctl %x insize %u outsize %u\n",
164 irpsp
->Parameters
.DeviceIoControl
.IoControlCode
,
165 irpsp
->Parameters
.DeviceIoControl
.InputBufferLength
,
166 irpsp
->Parameters
.DeviceIoControl
.OutputBufferLength
);
168 switch (irpsp
->Parameters
.DeviceIoControl
.IoControlCode
)
170 case IOCTL_NSIPROXY_WINE_ENUMERATE_ALL
:
171 nsiproxy_enumerate_all( irp
);
174 case IOCTL_NSIPROXY_WINE_GET_ALL_PARAMETERS
:
175 nsiproxy_get_all_parameters( irp
);
178 case IOCTL_NSIPROXY_WINE_GET_PARAMETER
:
179 nsiproxy_get_parameter( irp
);
183 FIXME( "ioctl %x not supported\n", irpsp
->Parameters
.DeviceIoControl
.IoControlCode
);
184 irp
->IoStatus
.u
.Status
= STATUS_NOT_SUPPORTED
;
188 IoCompleteRequest( irp
, IO_NO_INCREMENT
);
189 return STATUS_SUCCESS
;
192 static int add_device( DRIVER_OBJECT
*driver
)
194 static const WCHAR name_str
[] = {'\\','D','e','v','i','c','e','\\','N','s','i',0};
195 static const WCHAR link_str
[] = {'\\','?','?','\\','N','s','i',0};
196 UNICODE_STRING name
, link
;
197 DEVICE_OBJECT
*device
;
200 RtlInitUnicodeString( &name
, name_str
);
201 RtlInitUnicodeString( &link
, link_str
);
203 if (!(status
= IoCreateDevice( driver
, 0, &name
, FILE_DEVICE_NETWORK
, FILE_DEVICE_SECURE_OPEN
, FALSE
, &device
)))
204 status
= IoCreateSymbolicLink( &link
, &name
);
207 FIXME( "failed to create device error %x\n", status
);
214 NTSTATUS WINAPI
DriverEntry( DRIVER_OBJECT
*driver
, UNICODE_STRING
*path
)
216 TRACE( "(%p, %s)\n", driver
, debugstr_w( path
->Buffer
) );
218 driver
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = nsi_ioctl
;
220 add_device( driver
);
222 return STATUS_SUCCESS
;