ReactOS 0.4.15-dev-7931-gfd331f1
helpers.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver DLL
4 * FILE: dll/win32/msafd/misc/helpers.c
5 * PURPOSE: Helper DLL management
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Alex Ionescu (alex@relsoft.net)
8 * REVISIONS:
9 * CSH 01/09-2000 Created
10 * Alex 16/07/2004 - Complete Rewrite
11 */
12
13#include <msafd.h>
14
15#include <winreg.h>
16
19
20
21INT
28 PUNICODE_STRING TransportName,
29 PVOID *HelperDllContext,
30 PHELPER_DATA *HelperDllData,
32{
33 PHELPER_DATA HelperData;
34 PWSTR Transports;
35 PWSTR Transport;
37 PLIST_ENTRY Helpers;
38 INT Status;
39
40 TRACE("AddressFamily %p, SocketType %p, Protocol %p, Group %u, Flags %lx, TransportName %p, HelperDllContext %p, HelperDllData %p, Events %p\n",
41 AddressFamily, SocketType, Protocol, Group, Flags, TransportName, HelperDllContext, HelperDllData, Events);
42
43 /* Check in our Current Loaded Helpers */
44 for (Helpers = SockHelpersListHead.Flink;
45 Helpers != &SockHelpersListHead;
46 Helpers = Helpers->Flink ) {
47
48 HelperData = CONTAINING_RECORD(Helpers, HELPER_DATA, Helpers);
49
50 /* See if this Mapping works for us */
51 if (SockIsTripleInMapping (HelperData->Mapping,
54 *Protocol)) {
55
56 /* Call the Helper Dll function get the Transport Name */
57 if (HelperData->WSHOpenSocket2 == NULL ) {
58
59 /* DLL Doesn't support WSHOpenSocket2, call the old one */
60 HelperData->WSHOpenSocket(AddressFamily,
63 TransportName,
64 HelperDllContext,
65 Events
66 );
67 } else {
68 HelperData->WSHOpenSocket2(AddressFamily,
71 Group,
72 Flags,
73 TransportName,
74 HelperDllContext,
75 Events
76 );
77 }
78
79 /* Return the Helper Pointers */
80 *HelperDllData = HelperData;
81 return NO_ERROR;
82 }
83 }
84
85 /* Get the Transports available */
86 Status = SockLoadTransportList(&Transports);
87
88 /* Check for error */
89 if (Status) {
90 WARN("Can't get transport list\n");
91 return Status;
92 }
93
94 /* Loop through each transport until we find one that can satisfy us */
95 for (Transport = Transports;
96 *Transports != 0;
97 Transport += wcslen(Transport) + 1) {
98 TRACE("Transport: %S\n", Transports);
99
100 /* See what mapping this Transport supports */
102
103 /* Check for error */
104 if (Status) {
105 ERR("Can't get mapping for %S\n", Transports);
106 HeapFree(GlobalHeap, 0, Transports);
107 return Status;
108 }
109
110 /* See if this Mapping works for us */
112
113 /* It does, so load the DLL associated with it */
114 Status = SockLoadHelperDll(Transport, Mapping, &HelperData);
115
116 /* Check for error */
117 if (Status) {
118 ERR("Can't load helper DLL for Transport %S.\n", Transport);
119 HeapFree(GlobalHeap, 0, Transports);
121 return Status;
122 }
123
124 /* Call the Helper Dll function get the Transport Name */
125 if (HelperData->WSHOpenSocket2 == NULL) {
126 /* DLL Doesn't support WSHOpenSocket2, call the old one */
127 HelperData->WSHOpenSocket(AddressFamily,
129 Protocol,
130 TransportName,
131 HelperDllContext,
132 Events
133 );
134 } else {
135 HelperData->WSHOpenSocket2(AddressFamily,
137 Protocol,
138 Group,
139 Flags,
140 TransportName,
141 HelperDllContext,
142 Events
143 );
144 }
145
146 /* Return the Helper Pointers */
147 *HelperDllData = HelperData;
148 /* We actually cache these ... the can't be freed yet */
149 /*HeapFree(GlobalHeap, 0, Transports);*/
150 /*HeapFree(GlobalHeap, 0, Mapping);*/
151 return NO_ERROR;
152 }
153
155 }
156 HeapFree(GlobalHeap, 0, Transports);
157 return WSAEINVAL;
158}
159
160INT
162 PWSTR TransportName,
164{
165 PWSTR TransportKey;
167 ULONG MappingSize;
168 LONG Status;
169
170 TRACE("TransportName %ws\n", TransportName);
171
172 /* Allocate a Buffer */
173 TransportKey = HeapAlloc(GlobalHeap, 0, (54 + wcslen(TransportName)) * sizeof(WCHAR));
174
175 /* Check for error */
176 if (TransportKey == NULL) {
177 ERR("Buffer allocation failed\n");
178 return WSAEINVAL;
179 }
180
181 /* Generate the right key name */
182 wcscpy(TransportKey, L"System\\CurrentControlSet\\Services\\");
183 wcscat(TransportKey, TransportName);
184 wcscat(TransportKey, L"\\Parameters\\Winsock");
185
186 /* Open the Key */
188
189 /* We don't need the Transport Key anymore */
190 HeapFree(GlobalHeap, 0, TransportKey);
191
192 /* Check for error */
193 if (Status) {
194 ERR("Error reading transport mapping registry\n");
195 return WSAEINVAL;
196 }
197
198 /* Find out how much space we need for the Mapping */
199 Status = RegQueryValueExW(KeyHandle, L"Mapping", NULL, NULL, NULL, &MappingSize);
200
201 /* Check for error */
202 if (Status) {
203 ERR("Error reading transport mapping registry\n");
204 return WSAEINVAL;
205 }
206
207 /* Allocate Memory for the Mapping */
208 *Mapping = HeapAlloc(GlobalHeap, 0, MappingSize);
209
210 /* Check for error */
211 if (*Mapping == NULL) {
212 ERR("Buffer allocation failed\n");
213 return WSAEINVAL;
214 }
215
216 /* Read the Mapping */
217 Status = RegQueryValueExW(KeyHandle, L"Mapping", NULL, NULL, (LPBYTE)*Mapping, &MappingSize);
218
219 /* Check for error */
220 if (Status) {
221 ERR("Error reading transport mapping registry\n");
223 return WSAEINVAL;
224 }
225
226 /* Close key and return */
228 return 0;
229}
230
231INT
233 PWSTR *TransportList)
234{
235 ULONG TransportListSize;
237 LONG Status;
238
239 TRACE("Called\n");
240
241 /* Open the Transports Key */
243 L"SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters",
244 0,
245 KEY_READ,
246 &KeyHandle);
247
248 /* Check for error */
249 if (Status) {
250 ERR("Error reading transport list registry\n");
251 return WSAEINVAL;
252 }
253
254 /* Get the Transport List Size */
256 L"Transports",
257 NULL,
258 NULL,
259 NULL,
260 &TransportListSize);
261
262 /* Check for error */
263 if (Status) {
264 ERR("Error reading transport list registry\n");
265 return WSAEINVAL;
266 }
267
268 /* Allocate Memory for the Transport List */
269 *TransportList = HeapAlloc(GlobalHeap, 0, TransportListSize);
270
271 /* Check for error */
272 if (*TransportList == NULL) {
273 ERR("Buffer allocation failed\n");
274 return WSAEINVAL;
275 }
276
277 /* Get the Transports */
279 L"Transports",
280 NULL,
281 NULL,
282 (LPBYTE)*TransportList,
283 &TransportListSize);
284
285 /* Check for error */
286 if (Status) {
287 ERR("Error reading transport list registry\n");
288 HeapFree(GlobalHeap, 0, *TransportList);
289 return WSAEINVAL;
290 }
291
292 /* Close key and return */
294 return 0;
295}
296
297INT
299 PWSTR TransportName,
301 PHELPER_DATA *HelperDllData)
302{
303 PHELPER_DATA HelperData;
304 PWSTR HelperDllName;
305 PWSTR FullHelperDllName;
306 PWSTR HelperKey;
309 LONG Status;
310
311 /* Allocate space for the Helper Structure and TransportName */
312 HelperData = HeapAlloc(GlobalHeap, 0, sizeof(*HelperData) + (wcslen(TransportName) + 1) * sizeof(WCHAR));
313
314 /* Check for error */
315 if (HelperData == NULL) {
316 ERR("Buffer allocation failed\n");
317 return WSAEINVAL;
318 }
319
320 /* Allocate Space for the Helper DLL Key */
321 HelperKey = HeapAlloc(GlobalHeap, 0, (54 + wcslen(TransportName)) * sizeof(WCHAR));
322
323 /* Check for error */
324 if (HelperKey == NULL) {
325 ERR("Buffer allocation failed\n");
326 HeapFree(GlobalHeap, 0, HelperData);
327 return WSAEINVAL;
328 }
329
330 /* Generate the right key name */
331 wcscpy(HelperKey, L"System\\CurrentControlSet\\Services\\");
332 wcscat(HelperKey, TransportName);
333 wcscat(HelperKey, L"\\Parameters\\Winsock");
334
335 /* Open the Key */
337
338 HeapFree(GlobalHeap, 0, HelperKey);
339
340 /* Check for error */
341 if (Status) {
342 ERR("Error reading helper DLL parameters\n");
343 HeapFree(GlobalHeap, 0, HelperData);
344 return WSAEINVAL;
345 }
346
347 /* Read Size of SockAddr Structures */
348 DataSize = sizeof(HelperData->MinWSAddressLength);
349 HelperData->MinWSAddressLength = 16;
351 L"MinSockaddrLength",
352 NULL,
353 NULL,
354 (LPBYTE)&HelperData->MinWSAddressLength,
355 &DataSize);
356 DataSize = sizeof(HelperData->MinWSAddressLength);
357 HelperData->MaxWSAddressLength = 16;
359 L"MaxSockaddrLength",
360 NULL,
361 NULL,
362 (LPBYTE)&HelperData->MaxWSAddressLength,
363 &DataSize);
364
365 /* Size of TDI Structures */
366 HelperData->MinTDIAddressLength = HelperData->MinWSAddressLength + 6;
367 HelperData->MaxTDIAddressLength = HelperData->MaxWSAddressLength + 6;
368
369 /* Read Delayed Acceptance Setting */
370 DataSize = sizeof(DWORD);
371 HelperData->UseDelayedAcceptance = FALSE;
373 L"UseDelayedAcceptance",
374 NULL,
375 NULL,
376 (LPBYTE)&HelperData->UseDelayedAcceptance,
377 &DataSize);
378
379 /* Allocate Space for the Helper DLL Names */
380 HelperDllName = HeapAlloc(GlobalHeap, 0, 512);
381
382 /* Check for error */
383 if (HelperDllName == NULL) {
384 ERR("Buffer allocation failed\n");
385 HeapFree(GlobalHeap, 0, HelperData);
386 return WSAEINVAL;
387 }
388
389 FullHelperDllName = HeapAlloc(GlobalHeap, 0, 512);
390
391 /* Check for error */
392 if (FullHelperDllName == NULL) {
393 ERR("Buffer allocation failed\n");
394 HeapFree(GlobalHeap, 0, HelperDllName);
395 HeapFree(GlobalHeap, 0, HelperData);
396 return WSAEINVAL;
397 }
398
399 /* Get the name of the Helper DLL*/
400 DataSize = 512;
402 L"HelperDllName",
403 NULL,
404 NULL,
405 (LPBYTE)HelperDllName,
406 &DataSize);
407
408 /* Check for error */
409 if (Status) {
410 ERR("Error reading helper DLL parameters\n");
411 HeapFree(GlobalHeap, 0, FullHelperDllName);
412 HeapFree(GlobalHeap, 0, HelperDllName);
413 HeapFree(GlobalHeap, 0, HelperData);
414 return WSAEINVAL;
415 }
416
417 /* Get the Full name, expanding Environment Strings */
418 ExpandEnvironmentStringsW (HelperDllName,
419 FullHelperDllName,
420 256);
421
422 /* Load the DLL */
423 HelperData->hInstance = LoadLibraryW(FullHelperDllName);
424
425 HeapFree(GlobalHeap, 0, HelperDllName);
426 HeapFree(GlobalHeap, 0, FullHelperDllName);
427
428 if (HelperData->hInstance == NULL) {
429 ERR("Error loading helper DLL\n");
430 HeapFree(GlobalHeap, 0, HelperData);
431 return WSAEINVAL;
432 }
433
434 /* Close Key */
436
437 /* Get the Pointers to the Helper Routines */
438 HelperData->WSHOpenSocket = (PWSH_OPEN_SOCKET)
439 GetProcAddress(HelperData->hInstance,
440 "WSHOpenSocket");
441 HelperData->WSHOpenSocket2 = (PWSH_OPEN_SOCKET2)
442 GetProcAddress(HelperData->hInstance,
443 "WSHOpenSocket2");
444 HelperData->WSHJoinLeaf = (PWSH_JOIN_LEAF)
445 GetProcAddress(HelperData->hInstance,
446 "WSHJoinLeaf");
447 HelperData->WSHNotify = (PWSH_NOTIFY)
448 GetProcAddress(HelperData->hInstance, "WSHNotify");
450 GetProcAddress(HelperData->hInstance,
451 "WSHGetSocketInformation");
453 GetProcAddress(HelperData->hInstance,
454 "WSHSetSocketInformation");
456 GetProcAddress(HelperData->hInstance,
457 "WSHGetSockaddrType");
459 GetProcAddress(HelperData->hInstance,
460 "WSHGetWildcardSockaddr");
462 GetProcAddress(HelperData->hInstance,
463 "WSHGetBroadcastSockaddr");
465 GetProcAddress(HelperData->hInstance,
466 "WSHAddressToString");
468 GetProcAddress(HelperData->hInstance,
469 "WSHStringToAddress");
470 HelperData->WSHIoctl = (PWSH_IOCTL)
471 GetProcAddress(HelperData->hInstance,
472 "WSHIoctl");
473
474 /* Save the Mapping Structure and transport name */
475 HelperData->Mapping = Mapping;
476 wcscpy(HelperData->TransportName, TransportName);
477
478 /* Increment Reference Count */
479 HelperData->RefCount = 1;
480
481 /* Add it to our list */
483
484 /* Return Pointers */
485 *HelperDllData = HelperData;
486 return 0;
487}
488
489BOOL
495{
496 /* The Windows version returns more detailed information on which of the 3 parameters failed...we should do this later */
497 ULONG Row;
498
499 TRACE("Called, Mapping rows = %d\n", Mapping->Rows);
500
501 /* Loop through Mapping to Find a matching one */
502 for (Row = 0; Row < Mapping->Rows; Row++) {
503 TRACE("Examining: row %d: AF %d type %d proto %d\n",
504 Row,
505 (INT)Mapping->Mapping[Row].AddressFamily,
506 (INT)Mapping->Mapping[Row].SocketType,
507 (INT)Mapping->Mapping[Row].Protocol);
508
509 /* Check of all three values Match */
510 if (((INT)Mapping->Mapping[Row].AddressFamily == AddressFamily) &&
511 ((INT)Mapping->Mapping[Row].SocketType == SocketType) &&
512 ((INT)Mapping->Mapping[Row].Protocol == Protocol)) {
513 TRACE("Found\n");
514 return TRUE;
515 }
516 }
517 WARN("Not found\n");
518 return FALSE;
519}
520
521/* EOF */
HANDLE Events[3]
Definition: schedsvc.c:40
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
#define RegCloseKey(hKey)
Definition: registry.h:49
#define NO_ERROR
Definition: dderror.h:5
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define GetProcAddress(x, y)
Definition: compat.h:753
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define LoadLibraryW(x)
Definition: compat.h:747
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
LIST_ENTRY SockHelpersListHead
Definition: dllmain.c:25
HANDLE GlobalHeap
Definition: dllmain.c:19
CRITICAL_SECTION HelperDLLDatabaseLock
Definition: helpers.c:17
LIST_ENTRY HelperDLLDatabaseListHead
Definition: helpers.c:18
INT SockLoadTransportMapping(PWSTR TransportName, PWINSOCK_MAPPING *Mapping)
Definition: helpers.c:161
INT SockLoadHelperDll(PWSTR TransportName, PWINSOCK_MAPPING Mapping, PHELPER_DATA *HelperDllData)
Definition: helpers.c:298
INT SockGetTdiName(PINT AddressFamily, PINT SocketType, PINT Protocol, GROUP Group, DWORD Flags, PUNICODE_STRING TransportName, PVOID *HelperDllContext, PHELPER_DATA *HelperDllData, PDWORD Events)
Definition: helpers.c:22
BOOL SockIsTripleInMapping(PWINSOCK_MAPPING Mapping, INT AddressFamily, INT SocketType, INT Protocol)
Definition: helpers.c:490
INT SockLoadTransportList(PWSTR *TransportList)
Definition: helpers.c:232
static PVOID Mapping[EMS_PHYSICAL_PAGES]
Definition: emsdrv.c:41
#define InsertHeadList(ListHead, Entry)
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
IN PCO_ADDRESS_FAMILY AddressFamily
Definition: ndis.h:1906
_In_opt_ PSID Group
Definition: rtlfuncs.h:1646
#define KEY_READ
Definition: nt_native.h:1023
#define DWORD
Definition: nt_native.h:44
#define L(x)
Definition: ntvdm.h:50
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define TRACE(s)
Definition: solgame.cpp:4
BOOLEAN UseDelayedAcceptance
Definition: helpers.h:20
INT MaxTDIAddressLength
Definition: helpers.h:19
PWSH_GET_SOCKADDR_TYPE WSHGetSockaddrType
Definition: helpers.h:28
PWSH_JOIN_LEAF WSHJoinLeaf
Definition: helpers.h:24
HANDLE hInstance
Definition: helpers.h:15
PWSH_GET_SOCKET_INFORMATION WSHGetSocketInformation
Definition: helpers.h:26
INT MinWSAddressLength
Definition: helpers.h:16
PWSH_STRING_TO_ADDRESS WSHStringToAddress
Definition: helpers.h:32
PWSH_ADDRESS_TO_STRING WSHAddressToString
Definition: helpers.h:31
PWSH_IOCTL WSHIoctl
Definition: helpers.h:33
PWSH_OPEN_SOCKET WSHOpenSocket
Definition: helpers.h:22
PWSH_SET_SOCKET_INFORMATION WSHSetSocketInformation
Definition: helpers.h:27
PWSH_NOTIFY WSHNotify
Definition: helpers.h:25
INT MaxWSAddressLength
Definition: helpers.h:17
PWSH_GET_BROADCAST_SOCKADDR WSHGetBroadcastSockaddr
Definition: helpers.h:30
PWINSOCK_MAPPING Mapping
Definition: helpers.h:21
INT MinTDIAddressLength
Definition: helpers.h:18
LONG RefCount
Definition: helpers.h:14
WCHAR TransportName[1]
Definition: helpers.h:34
LIST_ENTRY Helpers
Definition: helpers.h:13
PWSH_OPEN_SOCKET2 WSHOpenSocket2
Definition: helpers.h:23
PWSH_GET_WILDCARD_SOCKADDR WSHGetWildcardSockaddr
Definition: helpers.h:29
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
int * PINT
Definition: windef.h:177
#define WSAEINVAL
Definition: winerror.h:1946
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
unsigned int GROUP
Definition: winsock2.h:640
INT(WINAPI * PWSH_GET_BROADCAST_SOCKADDR)(PVOID, PSOCKADDR, PINT)
Definition: wsahelp.h:69
INT(WINAPI * PWSH_GET_WILDCARD_SOCKADDR)(PVOID, PSOCKADDR, PINT)
Definition: wsahelp.h:73
INT(WINAPI * PWSH_SET_SOCKET_INFORMATION)(PVOID, SOCKET, HANDLE, HANDLE, INT, INT, PCHAR, INT)
Definition: wsahelp.h:83
INT(WINAPI * PWSH_GET_SOCKADDR_TYPE)(PSOCKADDR, DWORD, PSOCKADDR_INFO)
Definition: wsahelp.h:71
INT(WINAPI * PWSH_OPEN_SOCKET2)(PINT, PINT, PINT, GROUP, DWORD, PUNICODE_STRING, PVOID *, PDWORD)
Definition: wsahelp.h:82
INT(WINAPI * PWSH_NOTIFY)(PVOID, SOCKET, HANDLE, HANDLE, DWORD)
Definition: wsahelp.h:80
INT(WINAPI * PWSH_JOIN_LEAF)(PVOID, SOCKET, HANDLE, HANDLE, PVOID, SOCKET, PSOCKADDR, DWORD, LPWSABUF, LPWSABUF, LPQOS, LPQOS, DWORD)
Definition: wsahelp.h:78
INT(WINAPI * PWSH_STRING_TO_ADDRESS)(LPWSTR, DWORD, LPWSAPROTOCOL_INFOW, LPSOCKADDR, LPDWORD)
Definition: wsahelp.h:84
INT(WINAPI * PWSH_OPEN_SOCKET)(PINT, PINT, PINT, PUNICODE_STRING, PVOID, PDWORD)
Definition: wsahelp.h:81
INT(WINAPI * PWSH_IOCTL)(PVOID, SOCKET, HANDLE, HANDLE, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE, LPBOOL)
Definition: wsahelp.h:76
INT(WINAPI * PWSH_ADDRESS_TO_STRING)(LPSOCKADDR, INT, LPWSAPROTOCOL_INFOW, LPWSTR, LPDWORD)
Definition: wsahelp.h:67
INT(WINAPI * PWSH_GET_SOCKET_INFORMATION)(PVOID, SOCKET, HANDLE, HANDLE, INT, INT, PCHAR, LPINT)
Definition: wsahelp.h:72
_In_ USHORT SocketType
Definition: wsk.h:182
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
__wchar_t WCHAR
Definition: xmlstorage.h:180