2 * Network Store Interface
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
28 #include "wine/heap.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(nsi
);
33 static inline HANDLE
get_nsi_device( void )
35 return CreateFileW( L
"\\\\.\\Nsi", 0, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
38 DWORD WINAPI
NsiAllocateAndGetTable( DWORD unk
, const NPI_MODULEID
*module
, DWORD table
, void **key_data
, DWORD key_size
,
39 void **rw_data
, DWORD rw_size
, void **dynamic_data
, DWORD dynamic_size
,
40 void **static_data
, DWORD static_size
, DWORD
*count
, DWORD unk2
)
43 void *data
[4] = { NULL
};
44 DWORD sizes
[4] = { key_size
, rw_size
, dynamic_size
, static_size
};
47 TRACE( "%ld %p %ld %p %ld %p %ld %p %ld %p %ld %p %ld\n", unk
, module
, table
, key_data
, key_size
,
48 rw_data
, rw_size
, dynamic_data
, dynamic_size
, static_data
, static_size
, count
, unk2
);
50 for (attempt
= 0; attempt
< 5; attempt
++)
52 for (i
= 0; i
< ARRAY_SIZE(data
); i
++)
56 data
[i
] = heap_alloc( sizes
[i
] * num
);
59 err
= ERROR_OUTOFMEMORY
;
65 err
= NsiEnumerateObjectsAllParameters( unk
, 0, module
, table
, data
[0], sizes
[0], data
[1], sizes
[1],
66 data
[2], sizes
[2], data
[3], sizes
[3], &num
);
67 if (err
!= ERROR_MORE_DATA
) break;
68 TRACE( "Short buffer, attempt %d.\n", attempt
);
69 NsiFreeTable( data
[0], data
[1], data
[2], data
[3] );
70 memset( data
, 0, sizeof(data
) );
71 err
= NsiEnumerateObjectsAllParameters( unk
, 0, module
, table
, NULL
, 0, NULL
, 0, NULL
, 0, NULL
, 0, &num
);
77 if (sizes
[0]) *key_data
= data
[0];
78 if (sizes
[1]) *rw_data
= data
[1];
79 if (sizes
[2]) *dynamic_data
= data
[2];
80 if (sizes
[3]) *static_data
= data
[3];
85 if (err
) NsiFreeTable( data
[0], data
[1], data
[2], data
[3] );
89 DWORD WINAPI
NsiEnumerateObjectsAllParameters( DWORD unk
, DWORD unk2
, const NPI_MODULEID
*module
, DWORD table
,
90 void *key_data
, DWORD key_size
, void *rw_data
, DWORD rw_size
,
91 void *dynamic_data
, DWORD dynamic_size
, void *static_data
, DWORD static_size
,
94 struct nsi_enumerate_all_ex params
;
97 TRACE( "%ld %ld %p %ld %p %ld %p %ld %p %ld %p %ld %p\n", unk
, unk2
, module
, table
, key_data
, key_size
,
98 rw_data
, rw_size
, dynamic_data
, dynamic_size
, static_data
, static_size
, count
);
100 params
.unknown
[0] = 0;
101 params
.unknown
[1] = 0;
102 params
.module
= module
;
103 params
.table
= table
;
104 params
.first_arg
= unk
;
105 params
.second_arg
= unk2
;
106 params
.key_data
= key_data
;
107 params
.key_size
= key_size
;
108 params
.rw_data
= rw_data
;
109 params
.rw_size
= rw_size
;
110 params
.dynamic_data
= dynamic_data
;
111 params
.dynamic_size
= dynamic_size
;
112 params
.static_data
= static_data
;
113 params
.static_size
= static_size
;
114 params
.count
= *count
;
116 err
= NsiEnumerateObjectsAllParametersEx( ¶ms
);
117 *count
= params
.count
;
121 DWORD WINAPI
NsiEnumerateObjectsAllParametersEx( struct nsi_enumerate_all_ex
*params
)
123 DWORD out_size
, received
, err
= ERROR_SUCCESS
;
124 HANDLE device
= get_nsi_device();
125 struct nsiproxy_enumerate_all in
;
128 if (device
== INVALID_HANDLE_VALUE
) return GetLastError();
130 out_size
= sizeof(DWORD
) +
131 (params
->key_size
+ params
->rw_size
+ params
->dynamic_size
+ params
->static_size
) * params
->count
;
133 out
= heap_alloc( out_size
);
136 CloseHandle( device
);
137 return ERROR_OUTOFMEMORY
;
140 in
.module
= *params
->module
;
141 in
.first_arg
= params
->first_arg
;
142 in
.second_arg
= params
->second_arg
;
143 in
.table
= params
->table
;
144 in
.key_size
= params
->key_size
;
145 in
.rw_size
= params
->rw_size
;
146 in
.dynamic_size
= params
->dynamic_size
;
147 in
.static_size
= params
->static_size
;
148 in
.count
= params
->count
;
150 if (!DeviceIoControl( device
, IOCTL_NSIPROXY_WINE_ENUMERATE_ALL
, &in
, sizeof(in
), out
, out_size
, &received
, NULL
))
151 err
= GetLastError();
152 if (err
== ERROR_SUCCESS
|| err
== ERROR_MORE_DATA
)
154 params
->count
= *(DWORD
*)out
;
155 ptr
= out
+ sizeof(DWORD
);
156 if (params
->key_size
) memcpy( params
->key_data
, ptr
, params
->key_size
* params
->count
);
157 ptr
+= params
->key_size
* in
.count
;
158 if (params
->rw_size
) memcpy( params
->rw_data
, ptr
, params
->rw_size
* params
->count
);
159 ptr
+= params
->rw_size
* in
.count
;
160 if (params
->dynamic_size
) memcpy( params
->dynamic_data
, ptr
, params
->dynamic_size
* params
->count
);
161 ptr
+= params
->dynamic_size
* in
.count
;
162 if (params
->static_size
) memcpy( params
->static_data
, ptr
, params
->static_size
* params
->count
);
166 CloseHandle( device
);
171 void WINAPI
NsiFreeTable( void *key_data
, void *rw_data
, void *dynamic_data
, void *static_data
)
173 TRACE( "%p %p %p %p\n", key_data
, rw_data
, dynamic_data
, static_data
);
174 heap_free( key_data
);
175 heap_free( rw_data
);
176 heap_free( dynamic_data
);
177 heap_free( static_data
);
180 DWORD WINAPI
NsiGetAllParameters( DWORD unk
, const NPI_MODULEID
*module
, DWORD table
, const void *key
, DWORD key_size
,
181 void *rw_data
, DWORD rw_size
, void *dynamic_data
, DWORD dynamic_size
,
182 void *static_data
, DWORD static_size
)
184 struct nsi_get_all_parameters_ex params
;
186 TRACE( "%ld %p %ld %p %ld %p %ld %p %ld %p %ld\n", unk
, module
, table
, key
, key_size
,
187 rw_data
, rw_size
, dynamic_data
, dynamic_size
, static_data
, static_size
);
189 params
.unknown
[0] = 0;
190 params
.unknown
[1] = 0;
191 params
.module
= module
;
192 params
.table
= table
;
193 params
.first_arg
= unk
;
196 params
.key_size
= key_size
;
197 params
.rw_data
= rw_data
;
198 params
.rw_size
= rw_size
;
199 params
.dynamic_data
= dynamic_data
;
200 params
.dynamic_size
= dynamic_size
;
201 params
.static_data
= static_data
;
202 params
.static_size
= static_size
;
204 return NsiGetAllParametersEx( ¶ms
);
207 DWORD WINAPI
NsiGetAllParametersEx( struct nsi_get_all_parameters_ex
*params
)
209 HANDLE device
= get_nsi_device();
210 struct nsiproxy_get_all_parameters
*in
;
211 ULONG in_size
= FIELD_OFFSET( struct nsiproxy_get_all_parameters
, key
[params
->key_size
] ), received
;
212 ULONG out_size
= params
->rw_size
+ params
->dynamic_size
+ params
->static_size
;
213 DWORD err
= ERROR_SUCCESS
;
216 if (device
== INVALID_HANDLE_VALUE
) return GetLastError();
218 in
= heap_alloc( in_size
);
219 out
= heap_alloc( out_size
);
222 err
= ERROR_OUTOFMEMORY
;
226 in
->module
= *params
->module
;
227 in
->first_arg
= params
->first_arg
;
228 in
->table
= params
->table
;
229 in
->key_size
= params
->key_size
;
230 in
->rw_size
= params
->rw_size
;
231 in
->dynamic_size
= params
->dynamic_size
;
232 in
->static_size
= params
->static_size
;
233 memcpy( in
->key
, params
->key
, params
->key_size
);
235 if (!DeviceIoControl( device
, IOCTL_NSIPROXY_WINE_GET_ALL_PARAMETERS
, in
, in_size
, out
, out_size
, &received
, NULL
))
236 err
= GetLastError();
237 if (err
== ERROR_SUCCESS
)
240 if (params
->rw_size
) memcpy( params
->rw_data
, ptr
, params
->rw_size
);
241 ptr
+= params
->rw_size
;
242 if (params
->dynamic_size
) memcpy( params
->dynamic_data
, ptr
, params
->dynamic_size
);
243 ptr
+= params
->dynamic_size
;
244 if (params
->static_size
) memcpy( params
->static_data
, ptr
, params
->static_size
);
250 CloseHandle( device
);
254 DWORD WINAPI
NsiGetParameter( DWORD unk
, const NPI_MODULEID
*module
, DWORD table
, const void *key
, DWORD key_size
,
255 DWORD param_type
, void *data
, DWORD data_size
, DWORD data_offset
)
257 struct nsi_get_parameter_ex params
;
259 TRACE( "%ld %p %ld %p %ld %ld %p %ld %ld\n", unk
, module
, table
, key
, key_size
,
260 param_type
, data
, data_size
, data_offset
);
262 params
.unknown
[0] = 0;
263 params
.unknown
[1] = 0;
264 params
.module
= module
;
265 params
.table
= table
;
266 params
.first_arg
= unk
;
269 params
.key_size
= key_size
;
270 params
.param_type
= param_type
;
272 params
.data_size
= data_size
;
273 params
.data_offset
= data_offset
;
274 return NsiGetParameterEx( ¶ms
);
277 DWORD WINAPI
NsiGetParameterEx( struct nsi_get_parameter_ex
*params
)
279 HANDLE device
= get_nsi_device();
280 struct nsiproxy_get_parameter
*in
;
281 ULONG in_size
= FIELD_OFFSET( struct nsiproxy_get_parameter
, key
[params
->key_size
] ), received
;
282 DWORD err
= ERROR_SUCCESS
;
284 if (device
== INVALID_HANDLE_VALUE
) return GetLastError();
286 in
= heap_alloc( in_size
);
289 err
= ERROR_OUTOFMEMORY
;
292 in
->module
= *params
->module
;
293 in
->first_arg
= params
->first_arg
;
294 in
->table
= params
->table
;
295 in
->key_size
= params
->key_size
;
296 in
->param_type
= params
->param_type
;
297 in
->data_offset
= params
->data_offset
;
298 memcpy( in
->key
, params
->key
, params
->key_size
);
300 if (!DeviceIoControl( device
, IOCTL_NSIPROXY_WINE_GET_PARAMETER
, in
, in_size
, params
->data
, params
->data_size
, &received
, NULL
))
301 err
= GetLastError();
305 CloseHandle( device
);