ReactOS 0.4.15-dev-8428-g6910fa6
fdo.c
Go to the documentation of this file.
1/*
2 * PROJECT: PCI IDE bus driver extension
3 * LICENSE: See COPYING in the top level directory
4 * PURPOSE: IRP_MJ_PNP operations for FDOs
5 * COPYRIGHT: Copyright 2005 Hervé Poussineau <hpoussin@reactos.org>
6 * Copyright 2023 Dmitry Borisov <di.sean@protonmail.com>
7 */
8
9#include "pciidex.h"
10
11#define NDEBUG
12#include <debug.h>
13
14static
15CODE_SEG("PAGE")
20{
21 PCM_PARTIAL_RESOURCE_DESCRIPTOR BusMasterDescriptor = NULL;
22 PVOID IoBase;
23 ULONG i;
24
25 PAGED_CODE();
26
29
30 for (i = 0; i < ResourcesTranslated->List[0].PartialResourceList.Count; ++i)
31 {
33
34 Descriptor = &ResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[i];
35 switch (Descriptor->Type)
36 {
39 {
40 switch (Descriptor->u.Port.Length)
41 {
42 /* Bus master port base */
43 case 16:
44 {
45 if (!BusMasterDescriptor)
46 BusMasterDescriptor = Descriptor;
47 break;
48 }
49
50 default:
51 break;
52 }
53 }
54
55 default:
56 break;
57 }
58 }
59
60 if (!BusMasterDescriptor)
62
63 if ((BusMasterDescriptor->Type == CmResourceTypePort) &&
64 (BusMasterDescriptor->Flags & CM_RESOURCE_PORT_IO))
65 {
66 IoBase = (PVOID)(ULONG_PTR)BusMasterDescriptor->u.Port.Start.QuadPart;
67 }
68 else
69 {
70 IoBase = MmMapIoSpace(BusMasterDescriptor->u.Memory.Start, 16, MmNonCached);
71 if (!IoBase)
73
74 FdoExtension->IoBaseMapped = TRUE;
75 }
76 FdoExtension->BusMasterPortBase = IoBase;
77
78 return STATUS_SUCCESS;
79}
80
81static
82CODE_SEG("PAGE")
87{
89 PIO_STACK_LOCATION IoStack;
90
91 PAGED_CODE();
92
94 {
96 }
97 Status = Irp->IoStatus.Status;
98 if (!NT_SUCCESS(Status))
99 {
100 return Status;
101 }
102
104
106 IoStack->Parameters.StartDevice.AllocatedResourcesTranslated);
107 if (!NT_SUCCESS(Status))
108 {
109 DPRINT1("Failed to parse resources 0x%lx\n", Status);
110 return Status;
111 }
112
114 if (!NT_SUCCESS(Status))
115 {
116 DPRINT1("Miniport initialization failed 0x%lx\n", Status);
117 return Status;
118 }
119
120 return STATUS_SUCCESS;
121}
122
123static
124CODE_SEG("PAGE")
125VOID
128{
129 PAGED_CODE();
130
131 if (FdoExtension->IoBaseMapped)
132 {
133 MmUnmapIoSpace(FdoExtension->BusMasterPortBase, 16);
134 FdoExtension->IoBaseMapped = FALSE;
135 }
136}
137
138static
139CODE_SEG("PAGE")
143{
144 PAGED_CODE();
145
147
148 return STATUS_SUCCESS;
149}
150
151static
152CODE_SEG("PAGE")
156 _In_ PIRP Irp)
157{
160 ULONG i;
161
162 PAGED_CODE();
163
165
166 ExAcquireFastMutex(&FdoExtension->DeviceSyncMutex);
167
168 for (i = 0; i < MAX_IDE_CHANNEL; ++i)
169 {
170 PdoExtension = FdoExtension->Channels[i];
171
172 if (PdoExtension)
173 {
174 IoDeleteDevice(PdoExtension->Common.Self);
175
176 FdoExtension->Channels[i] = NULL;
177 break;
178 }
179 }
180
181 ExReleaseFastMutex(&FdoExtension->DeviceSyncMutex);
182
183 Irp->IoStatus.Status = STATUS_SUCCESS;
186
188 IoDeleteDevice(FdoExtension->Common.Self);
189
190 return Status;
191}
192
193static
194CODE_SEG("PAGE")
198 _In_ PIRP Irp)
199{
200 PAGED_CODE();
201
202 if (FdoExtension->Common.PageFiles ||
203 FdoExtension->Common.HibernateFiles ||
204 FdoExtension->Common.DumpFiles)
205 {
206 Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
207 }
208
209 Irp->IoStatus.Status = STATUS_SUCCESS;
210
211 return STATUS_SUCCESS;
212}
213
214static
215CODE_SEG("PAGE")
219 _In_ ULONG ChannelNumber)
220{
223 WCHAR DeviceNameBuffer[sizeof("\\Device\\Ide\\PciIde999Channel9-FFF")];
227 static ULONG DeviceNumber = 0;
228
229 PAGED_CODE();
230
231 Status = RtlStringCbPrintfW(DeviceNameBuffer,
232 sizeof(DeviceNameBuffer),
233 L"\\Device\\Ide\\PciIde%uChannel%u-%x",
234 FdoExtension->ControllerNumber,
235 ChannelNumber,
236 DeviceNumber++);
238 RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
239
240 Status = IoCreateDevice(FdoExtension->Common.Self->DriverObject,
241 sizeof(*PdoExtension),
242 &DeviceName,
245 FALSE,
246 &Pdo);
247 if (!NT_SUCCESS(Status))
248 {
249 DPRINT1("Failed to create PDO 0x%lx\n", Status);
250 return NULL;
251 }
252
253 DPRINT("Created device object %p '%wZ'\n", Pdo, &DeviceName);
254
255 /* DMA buffers alignment */
256 Alignment = FdoExtension->Properties.AlignmentRequirement;
257 Alignment = max(Alignment, FdoExtension->Common.Self->AlignmentRequirement);
259 Pdo->AlignmentRequirement = Alignment;
260
261 PdoExtension = Pdo->DeviceExtension;
262
264 PdoExtension->Common.Self = Pdo;
265 PdoExtension->Channel = ChannelNumber;
266 PdoExtension->ParentController = FdoExtension;
267
268 Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
269 return PdoExtension;
270}
271
272static
273CODE_SEG("PAGE")
277 _In_ PIRP Irp)
278{
280 IDE_CHANNEL_STATE ChannelState;
281 PDEVICE_RELATIONS DeviceRelations;
282 ULONG i;
283
284 PAGED_CODE();
285
286 DeviceRelations = ExAllocatePoolWithTag(PagedPool,
288 Objects[MAX_IDE_CHANNEL]),
290 if (!DeviceRelations)
292
293 DeviceRelations->Count = 0;
294
295 ExAcquireFastMutex(&FdoExtension->DeviceSyncMutex);
296
297 for (i = 0; i < MAX_IDE_CHANNEL; ++i)
298 {
299 PdoExtension = FdoExtension->Channels[i];
300
301 /* Ignore disabled channels */
302 ChannelState = PciIdeXChannelState(FdoExtension, i);
303 if (ChannelState == ChannelDisabled)
304 {
305 if (PdoExtension)
306 {
307 PdoExtension->ReportedMissing = TRUE;
308 }
309
310 DPRINT("Channel %lu is disabled\n", i);
311 continue;
312 }
313
314 /* Need to create a PDO */
315 if (!PdoExtension)
316 {
318
319 FdoExtension->Channels[i] = PdoExtension;
320 }
321
322 if (PdoExtension && !PdoExtension->ReportedMissing)
323 {
324 DeviceRelations->Objects[DeviceRelations->Count++] = PdoExtension->Common.Self;
325 ObReferenceObject(PdoExtension->Common.Self);
326 }
327 }
328
329 ExReleaseFastMutex(&FdoExtension->DeviceSyncMutex);
330
331 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
332 return STATUS_SUCCESS;
333}
334
335static
336CODE_SEG("PAGE")
340 _In_ PIRP Irp)
341{
342 PIO_STACK_LOCATION IoStack;
344 volatile LONG* Counter;
345
346 PAGED_CODE();
347
349 {
350 return STATUS_UNSUCCESSFUL;
351 }
352 Status = Irp->IoStatus.Status;
353 if (!NT_SUCCESS(Status))
354 {
355 return Status;
356 }
357
359 switch (IoStack->Parameters.UsageNotification.Type)
360 {
362 Counter = &FdoExtension->Common.PageFiles;
363 break;
364
366 Counter = &FdoExtension->Common.HibernateFiles;
367 break;
368
370 Counter = &FdoExtension->Common.DumpFiles;
371 break;
372
373 default:
374 return Status;
375 }
376
378
379 return STATUS_SUCCESS;
380}
381
382static
383CODE_SEG("PAGE")
387 _In_ PIO_STACK_LOCATION IoStack)
388{
389 PAGED_CODE();
390
391 if (IsEqualGUIDAligned(IoStack->Parameters.QueryInterface.InterfaceType,
392 &GUID_TRANSLATOR_INTERFACE_STANDARD))
393 {
394 CM_RESOURCE_TYPE ResourceType;
396
397 ResourceType = (ULONG_PTR)IoStack->Parameters.QueryInterface.InterfaceSpecificData;
398
399 /* In native mode the IDE controller does not use any legacy interrupt resources */
400 if (FdoExtension->InNativeMode ||
401 ResourceType != CmResourceTypeInterrupt ||
402 IoStack->Parameters.QueryInterface.Size < sizeof(TRANSLATOR_INTERFACE))
403 {
405 }
406
408 0,
410 sizeof(TRANSLATOR_INTERFACE),
411 IoStack->Parameters.QueryInterface.Version,
412 (PTRANSLATOR_INTERFACE)IoStack->
413 Parameters.QueryInterface.Interface,
414 &BusNumber);
415 }
416
418}
419
420CODE_SEG("PAGE")
425{
426 PIO_STACK_LOCATION IoStack;
428
429 PAGED_CODE();
430
432 switch (IoStack->MinorFunction)
433 {
435 {
437
438 Irp->IoStatus.Status = Status;
440
441 return Status;
442 }
443
445 {
447 break;
448 }
449
452
454 {
456 break;
457 }
458
460 {
461 if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations)
462 break;
463
465 if (!NT_SUCCESS(Status))
466 {
467 Irp->IoStatus.Status = Status;
469
470 return Status;
471 }
472
473 Irp->IoStatus.Status = Status;
474 break;
475 }
476
478 {
480 break;
481 }
482
484 {
487 break;
488
489 Irp->IoStatus.Status = Status;
490 break;
491 }
492
498 Irp->IoStatus.Status = STATUS_SUCCESS;
499 break;
500
501 default:
502 break;
503 }
504
506 return IoCallDriver(FdoExtension->Ldo, Irp);
507}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
#define CODE_SEG(...)
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1230
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ULONG_PTR
Definition: config.h:101
@ PdoExtension
Definition: precomp.h:49
@ FdoExtension
Definition: precomp.h:48
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
union Alignment_ Alignment
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
@ InterfaceTypeUndefined
Definition: hwresource.cpp:136
@ PCIBus
Definition: hwresource.cpp:142
#define CmResourceTypePort
Definition: hwresource.cpp:123
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
IDE_CHANNEL_STATE
Definition: ide.h:196
@ ChannelDisabled
Definition: ide.h:197
#define MAX_IDE_CHANNEL
Definition: ide.h:30
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
#define CM_RESOURCE_PORT_IO
Definition: cmtypes.h:109
#define FILE_WORD_ALIGNMENT
Definition: nt_native.h:787
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCompleteRequest
Definition: irp.c:1240
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
#define IoCallDriver
Definition: irp.c:1225
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:619
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
#define L(x)
Definition: ntvdm.h:50
#define TAG_PCIIDEX
Definition: pciidex.h:19
long LONG
Definition: pedump.c:60
#define FILE_DEVICE_CONTROLLER
Definition: winioctl.h:49
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
NTSTATUS PciIdeXFdoDispatchPnp(_In_ PFDO_DEVICE_EXTENSION FdoExtension, _Inout_ PIRP Irp)
Definition: fdo.c:422
static NTSTATUS PciIdeXFdoQueryPnpDeviceState(_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: fdo.c:196
static NTSTATUS PciIdeXFdoQueryDeviceUsageNotification(_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: fdo.c:338
static NTSTATUS PciIdeXFdoParseResources(_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ PCM_RESOURCE_LIST ResourcesTranslated)
Definition: fdo.c:17
static PPDO_DEVICE_EXTENSION PciIdeXPdoCreateDevice(_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ ULONG ChannelNumber)
Definition: fdo.c:217
static NTSTATUS PciIdeXFdoRemoveDevice(_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: fdo.c:154
static NTSTATUS PciIdeXFdoQueryInterface(_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ PIO_STACK_LOCATION IoStack)
Definition: fdo.c:385
static NTSTATUS PciIdeXFdoStartDevice(_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: fdo.c:84
static NTSTATUS PciIdeXFdoQueryBusRelations(_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: fdo.c:275
static NTSTATUS PciIdeXFdoStopDevice(_In_ PFDO_DEVICE_EXTENSION FdoExtension)
Definition: fdo.c:141
static VOID PciIdeXFdoFreeResources(_In_ PFDO_DEVICE_EXTENSION FdoExtension)
Definition: fdo.c:126
IDE_CHANNEL_STATE PciIdeXChannelState(_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ ULONG Channel)
Definition: miniport.c:48
NTSTATUS PciIdeXStartMiniport(_In_ PFDO_DEVICE_EXTENSION FdoExtension)
Definition: miniport.c:18
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@389 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@389::@391 Port
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@389::@394 Memory
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
struct _IO_STACK_LOCATION::@3976::@4013 StartDevice
union _IO_STACK_LOCATION::@1567 Parameters
struct _IO_STACK_LOCATION::@3976::@4009 UsageNotification
struct _IO_STACK_LOCATION::@3976::@4001 QueryDeviceRelations
static LARGE_INTEGER Counter
Definition: clock.c:43
#define max(a, b)
Definition: svc.c:63
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFCMRESLIST _In_ WDFCMRESLIST ResourcesTranslated
Definition: wdfdevice.h:891
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_ WDFDRIVER _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ PDEVICE_OBJECT _In_opt_ PDEVICE_OBJECT _In_opt_ PDEVICE_OBJECT Pdo
Definition: wdfminiport.h:72
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:235
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:160
#define HalGetInterruptTranslator
Definition: haltypes.h:303
#define IoAdjustPagingPathCount(_Count, _Increment)
#define IRP_MN_CANCEL_STOP_DEVICE
@ BusRelations
Definition: iotypes.h:2152
#define IRP_MN_QUERY_PNP_DEVICE_STATE
#define PNP_DEVICE_NOT_DISABLEABLE
Definition: iotypes.h:1006
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_QUERY_INTERFACE
#define IRP_MN_START_DEVICE
#define IRP_MN_DEVICE_USAGE_NOTIFICATION
#define IRP_MN_REMOVE_DEVICE
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_STOP_DEVICE
@ DeviceUsageTypeHibernation
Definition: iotypes.h:1171
@ DeviceUsageTypeDumpFile
Definition: iotypes.h:1172
@ DeviceUsageTypePaging
Definition: iotypes.h:1170
#define IRP_MN_QUERY_REMOVE_DEVICE
@ MmNonCached
Definition: mmtypes.h:129
#define ObReferenceObject
Definition: obfuncs.h:204
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3287
__wchar_t WCHAR
Definition: xmlstorage.h:180