2 * PROJECT: ReactOS Storport Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Storport helper functions
5 * COPYRIGHT: Copyright 2017 Eric Kohl (eric.kohl@reactos.org)
8 /* INCLUDES *******************************************************************/
16 /* FUNCTIONS ******************************************************************/
21 ForwardIrpAndWaitCompletion(
22 _In_ PDEVICE_OBJECT DeviceObject
,
26 if (Irp
->PendingReturned
)
27 KeSetEvent((PKEVENT
)Context
, IO_NO_INCREMENT
, FALSE
);
28 return STATUS_MORE_PROCESSING_REQUIRED
;
34 _In_ PDEVICE_OBJECT LowerDevice
,
42 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
43 IoCopyCurrentIrpStackLocationToNext(Irp
);
45 IoSetCompletionRoutine(Irp
, ForwardIrpAndWaitCompletion
, &Event
, TRUE
, TRUE
, TRUE
);
47 Status
= IoCallDriver(LowerDevice
, Irp
);
48 if (Status
== STATUS_PENDING
)
50 Status
= KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
51 if (NT_SUCCESS(Status
))
52 Status
= Irp
->IoStatus
.Status
;
62 _In_ PDEVICE_OBJECT LowerDevice
,
67 IoSkipCurrentIrpStackLocation(Irp
);
68 return IoCallDriver(LowerDevice
, Irp
);
74 PDEVICE_OBJECT DeviceObject
)
80 Status
= IoGetDeviceProperty(DeviceObject
,
81 DevicePropertyBusTypeGuid
,
85 if (!NT_SUCCESS(Status
))
86 return InterfaceTypeUndefined
;
88 if (RtlCompareMemory(&Guid
, &GUID_BUS_TYPE_PCMCIA
, sizeof(GUID
)) == sizeof(GUID
))
90 else if (RtlCompareMemory(&Guid
, &GUID_BUS_TYPE_PCI
, sizeof(GUID
)) == sizeof(GUID
))
92 else if (RtlCompareMemory(&Guid
, &GUID_BUS_TYPE_ISAPNP
, sizeof(GUID
)) == sizeof(GUID
))
95 return InterfaceTypeUndefined
;
102 PCM_RESOURCE_LIST ResourceList
)
104 PCM_FULL_RESOURCE_DESCRIPTOR Descriptor
;
108 DPRINT1("GetResourceListSize(%p)\n", ResourceList
);
110 Size
= sizeof(CM_RESOURCE_LIST
);
111 if (ResourceList
->Count
== 0)
113 DPRINT1("Size: 0x%lx (%u)\n", Size
, Size
);
117 DPRINT1("ResourceList->Count: %lu\n", ResourceList
->Count
);
119 Descriptor
= &ResourceList
->List
[0];
120 for (i
= 0; i
< ResourceList
->Count
; i
++)
122 /* Process resources in CM_FULL_RESOURCE_DESCRIPTOR block number ix. */
124 DPRINT1("PartialResourceList->Count: %lu\n", Descriptor
->PartialResourceList
.Count
);
126 /* Add the size of the current full descriptor */
127 Size
+= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
128 (Descriptor
->PartialResourceList
.Count
- 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
130 /* Advance to next CM_FULL_RESOURCE_DESCRIPTOR block in memory. */
131 Descriptor
= (PCM_FULL_RESOURCE_DESCRIPTOR
)(Descriptor
->PartialResourceList
.PartialDescriptors
+
132 Descriptor
->PartialResourceList
.Count
);
135 DPRINT1("Size: 0x%lx (%u)\n", Size
, Size
);
143 PCM_RESOURCE_LIST Source
)
145 PCM_RESOURCE_LIST Destination
;
148 DPRINT1("CopyResourceList(%lu %p)\n",
151 /* Get the size of the resource list */
152 Size
= GetResourceListSize(Source
);
154 /* Allocate a new buffer */
155 Destination
= ExAllocatePoolWithTag(PoolType
,
158 if (Destination
== NULL
)
161 /* Copy the resource list */
162 RtlCopyMemory(Destination
,
172 PDEVICE_OBJECT DeviceObject
,
176 PBUS_INTERFACE_STANDARD Interface
,
177 PVOID InterfaceSpecificData
)
182 IO_STATUS_BLOCK IoStatus
;
183 PIO_STACK_LOCATION Stack
;
185 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
187 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_PNP
,
195 return STATUS_INSUFFICIENT_RESOURCES
;
197 Stack
= IoGetNextIrpStackLocation(Irp
);
199 Stack
->MajorFunction
= IRP_MJ_PNP
;
200 Stack
->MinorFunction
= IRP_MN_QUERY_INTERFACE
;
201 Stack
->Parameters
.QueryInterface
.InterfaceType
= Guid
;
202 Stack
->Parameters
.QueryInterface
.Size
= Size
;
203 Stack
->Parameters
.QueryInterface
.Version
= Version
;
204 Stack
->Parameters
.QueryInterface
.Interface
= (PINTERFACE
)Interface
;
205 Stack
->Parameters
.QueryInterface
.InterfaceSpecificData
= InterfaceSpecificData
;
207 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
209 Status
= IoCallDriver(DeviceObject
, Irp
);
210 if (Status
== STATUS_PENDING
)
212 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
214 Status
=IoStatus
.Status
;
222 TranslateResourceListAddress(
223 PFDO_DEVICE_EXTENSION DeviceExtension
,
224 INTERFACE_TYPE BusType
,
225 ULONG SystemIoBusNumber
,
226 STOR_PHYSICAL_ADDRESS IoAddress
,
229 PPHYSICAL_ADDRESS TranslatedAddress
)
231 PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptorA
, FullDescriptorT
;
232 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptorA
, PartialDescriptorT
;
235 DPRINT1("TranslateResourceListAddress(%p)\n", DeviceExtension
);
237 FullDescriptorA
= DeviceExtension
->AllocatedResources
->List
;
238 FullDescriptorT
= DeviceExtension
->TranslatedResources
->List
;
239 for (i
= 0; i
< DeviceExtension
->AllocatedResources
->Count
; i
++)
241 for (j
= 0; j
< FullDescriptorA
->PartialResourceList
.Count
; j
++)
243 PartialDescriptorA
= FullDescriptorA
->PartialResourceList
.PartialDescriptors
+ j
;
244 PartialDescriptorT
= FullDescriptorT
->PartialResourceList
.PartialDescriptors
+ j
;
246 switch (PartialDescriptorA
->Type
)
248 case CmResourceTypePort
:
249 DPRINT1("Port: 0x%I64x (0x%lx)\n",
250 PartialDescriptorA
->u
.Port
.Start
.QuadPart
,
251 PartialDescriptorA
->u
.Port
.Length
);
253 IoAddress
.QuadPart
>= PartialDescriptorA
->u
.Port
.Start
.QuadPart
&&
254 IoAddress
.QuadPart
+ NumberOfBytes
<= PartialDescriptorA
->u
.Port
.Start
.QuadPart
+ PartialDescriptorA
->u
.Port
.Length
)
256 TranslatedAddress
->QuadPart
= PartialDescriptorT
->u
.Port
.Start
.QuadPart
+
257 (IoAddress
.QuadPart
- PartialDescriptorA
->u
.Port
.Start
.QuadPart
);
262 case CmResourceTypeMemory
:
263 DPRINT1("Memory: 0x%I64x (0x%lx)\n",
264 PartialDescriptorA
->u
.Memory
.Start
.QuadPart
,
265 PartialDescriptorA
->u
.Memory
.Length
);
267 IoAddress
.QuadPart
>= PartialDescriptorA
->u
.Memory
.Start
.QuadPart
&&
268 IoAddress
.QuadPart
+ NumberOfBytes
<= PartialDescriptorA
->u
.Memory
.Start
.QuadPart
+ PartialDescriptorA
->u
.Memory
.Length
)
270 TranslatedAddress
->QuadPart
= PartialDescriptorT
->u
.Memory
.Start
.QuadPart
+
271 (IoAddress
.QuadPart
- PartialDescriptorA
->u
.Memory
.Start
.QuadPart
);
278 /* Advance to next CM_FULL_RESOURCE_DESCRIPTOR block in memory. */
279 FullDescriptorA
= (PCM_FULL_RESOURCE_DESCRIPTOR
)(FullDescriptorA
->PartialResourceList
.PartialDescriptors
+
280 FullDescriptorA
->PartialResourceList
.Count
);
282 FullDescriptorT
= (PCM_FULL_RESOURCE_DESCRIPTOR
)(FullDescriptorT
->PartialResourceList
.PartialDescriptors
+
283 FullDescriptorT
->PartialResourceList
.Count
);
291 GetResourceListInterrupt(
292 PFDO_DEVICE_EXTENSION DeviceExtension
,
295 KINTERRUPT_MODE
*InterruptMode
,
296 PBOOLEAN ShareVector
,
299 PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor
;
300 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
303 DPRINT1("GetResourceListInterrupt(%p)\n",
306 FullDescriptor
= DeviceExtension
->TranslatedResources
->List
;
307 for (i
= 0; i
< DeviceExtension
->TranslatedResources
->Count
; i
++)
309 for (j
= 0; j
< FullDescriptor
->PartialResourceList
.Count
; j
++)
311 PartialDescriptor
= FullDescriptor
->PartialResourceList
.PartialDescriptors
+ j
;
313 switch (PartialDescriptor
->Type
)
315 case CmResourceTypeInterrupt
:
316 DPRINT1("Interrupt: Level %lu Vector %lu\n",
317 PartialDescriptor
->u
.Interrupt
.Level
,
318 PartialDescriptor
->u
.Interrupt
.Vector
);
320 *Vector
= PartialDescriptor
->u
.Interrupt
.Vector
;
321 *Irql
= (KIRQL
)PartialDescriptor
->u
.Interrupt
.Level
;
322 *InterruptMode
= (PartialDescriptor
->Flags
& CM_RESOURCE_INTERRUPT_LATCHED
) ? Latched
: LevelSensitive
;
323 *ShareVector
= (PartialDescriptor
->ShareDisposition
== CmResourceShareShared
) ? TRUE
: FALSE
;
324 *Affinity
= PartialDescriptor
->u
.Interrupt
.Affinity
;
326 return STATUS_SUCCESS
;
330 /* Advance to next CM_FULL_RESOURCE_DESCRIPTOR block in memory. */
331 FullDescriptor
= (PCM_FULL_RESOURCE_DESCRIPTOR
)(FullDescriptor
->PartialResourceList
.PartialDescriptors
+
332 FullDescriptor
->PartialResourceList
.Count
);
335 return STATUS_NOT_FOUND
;
340 AllocateAddressMapping(
341 PMAPPED_ADDRESS
*MappedAddressList
,
342 STOR_PHYSICAL_ADDRESS IoAddress
,
347 PMAPPED_ADDRESS Mapping
;
349 DPRINT1("AllocateAddressMapping()\n");
351 Mapping
= ExAllocatePoolWithTag(NonPagedPool
,
352 sizeof(MAPPED_ADDRESS
),
353 TAG_ADDRESS_MAPPING
);
356 DPRINT1("No memory!\n");
357 return STATUS_NO_MEMORY
;
360 RtlZeroMemory(Mapping
, sizeof(MAPPED_ADDRESS
));
362 Mapping
->NextMappedAddress
= *MappedAddressList
;
363 *MappedAddressList
= Mapping
;
365 Mapping
->IoAddress
= IoAddress
;
366 Mapping
->MappedAddress
= MappedAddress
;
367 Mapping
->NumberOfBytes
= NumberOfBytes
;
368 Mapping
->BusNumber
= BusNumber
;
370 return STATUS_SUCCESS
;
373 #if defined(_M_AMD64)
374 /* KeQuerySystemTime is an inline function,
375 so we cannot forward the export to ntoskrnl */
379 StorPortQuerySystemTime(
380 _Out_ PLARGE_INTEGER CurrentTime
)
382 KeQuerySystemTime(CurrentTime
);
384 #endif /* defined(_M_AMD64) */