ReactOS 0.4.17-dev-1133-gc25e4fd
ioctl.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Storport Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Storport IOCTL handling
5 * COPYRIGHT: Copyright 2017 Eric Kohl (eric.kohl@reactos.org)
6 */
7
8/* INCLUDES *******************************************************************/
9
10#include "precomp.h"
11
12#define NDEBUG
13#include <debug.h>
14
15
16/* FUNCTIONS ******************************************************************/
17
18static
22 _In_ UINT32 MaxLength)
23{
25 UINT32 LastCharacterPosition = 0;
26
27 // scan the field and return last position which contains a valid character
28 for (Index = 0; Index < MaxLength; Index++)
29 {
30 if (Name[Index] != ' ')
31 {
32 // trim white spaces from field
33 LastCharacterPosition = Index;
34 }
35 }
36
37 // convert from zero based index to length
38 return LastCharacterPosition + 1;
39}
40
41
42static
47{
48 PIO_STACK_LOCATION IoStack;
49 PMINIPORT Miniport;
50 PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor;
53
55 Query = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer;
56 Miniport = &FdoExtension->Miniport;
57
58 do
59 {
60 /* check property type (handle only StorageAdapterProperty) */
61 if (Query->PropertyId != StorageAdapterProperty)
62 {
63 if (Query->PropertyId == StorageDeviceProperty ||
64 Query->PropertyId == StorageDeviceIdProperty)
65 {
67 }
68 else
69 {
71 }
72
73 break;
74 }
75
76 /* check query type */
77 if (Query->QueryType == PropertyExistsQuery)
78 {
79 /* device property / adapter property is supported */
81 break;
82 }
83
84 if (Query->QueryType != PropertyStandardQuery)
85 {
86 /* only standard query and exists query are supported */
88 break;
89 }
90
91 /* Check buffer length */
92 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength <
93 sizeof(*AdapterDescriptor))
94 {
95 PSTORAGE_DESCRIPTOR_HEADER DescriptorHeader = Irp->AssociatedIrp.SystemBuffer;
96
97 /* Fail request if the buffer is simply too small */
98 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength <
100 {
101 Status = STATUS_BUFFER_TOO_SMALL; /* FIXME: Is this code appropriate? */
102 break;
103 }
104
105 /* Return required size */
106 DescriptorHeader->Version = sizeof(*AdapterDescriptor);
107 DescriptorHeader->Size = sizeof(*AdapterDescriptor);
108 Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
110 break;
111 }
112
113 /* Return AdapterDescriptor */
114 AdapterDescriptor = Irp->AssociatedIrp.SystemBuffer;
115
116 /* Classpnp is built for NTDDI_WIN8 and reads SrbType and AddressType past our tail */
117 RtlZeroMemory(AdapterDescriptor, sizeof(*AdapterDescriptor));
118
119 AdapterDescriptor->Version = sizeof(*AdapterDescriptor);
120 AdapterDescriptor->Size = sizeof(*AdapterDescriptor);
121 AdapterDescriptor->MaximumTransferLength = Miniport->PortConfig.MaximumTransferLength;
122 AdapterDescriptor->MaximumPhysicalPages = Miniport->PortConfig.NumberOfPhysicalBreaks;
123 AdapterDescriptor->AlignmentMask = Miniport->PortConfig.AlignmentMask;
124 AdapterDescriptor->AdapterUsesPio = FALSE; /* Storport requirement */
125 AdapterDescriptor->AdapterScansDown = Miniport->PortConfig.AdapterScansDown;
126 AdapterDescriptor->CommandQueueing = TRUE; /* Storport requirement */
127 AdapterDescriptor->AcceleratedTransfer = TRUE;
128 AdapterDescriptor->BusType = BusTypeSata; /* FIXME: READ FROM REGISTRY */
129 AdapterDescriptor->BusMajorVersion = 2;
130 AdapterDescriptor->BusMinorVersion = 0;
131
132 Irp->IoStatus.Information = sizeof(*AdapterDescriptor);
134 }
135 while (0);
136
137 Irp->IoStatus.Status = Status;
139
140 return Status;
141}
142
143
145NTAPI
148 _In_ PIRP Irp)
149{
150 PIO_STACK_LOCATION IoStack;
152
154
155 switch (IoStack->Parameters.DeviceIoControl.IoControlCode)
156 {
158 return FdoDeviceControlQueryProperty(DeviceObject->DeviceExtension, Irp);
159
160 default:
161 // __debugbreak();
162 Status = Irp->IoStatus.Status;
163 break;
164 }
165
166 Irp->IoStatus.Status = Status;
167 Irp->IoStatus.Information = 0;
169
170 return Status;
171}
172
173
174static
178 _In_ PIRP Irp)
179{
180 PIO_STACK_LOCATION IoStack;
183
185 Query = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer;
186
187 do
188 {
189 /* check property type */
190 if (Query->PropertyId != StorageDeviceProperty &&
191 Query->PropertyId != StorageAdapterProperty)
192 {
193 // only device property / adapter property are supported
195 }
196
197 /* check query type */
198 if (Query->QueryType == PropertyExistsQuery)
199 {
200 /* device property / adapter property is supported */
202 break;
203 }
204
205 if (Query->QueryType != PropertyStandardQuery)
206 {
207 /* only standard query and exists query are supported */
209 break;
210 }
211
212
213
214 /* For different property types... */
215 switch (Query->PropertyId)
216 {
218 {
220 PINQUIRYDATA InquiryData = PdoExtension->InquiryBuffer;
221 ULONG VendorIdLength = GetFieldLength(InquiryData->VendorId, 8);
222 ULONG ProductIdLength = GetFieldLength(InquiryData->ProductId, 16);
223 ULONG RevisionLength = GetFieldLength(InquiryData->ProductRevisionLevel, 4);
225 PUCHAR Dest;
226
227 /*
228 * total length required is
229 * sizeof(STORAGE_DEVICE_DESCRIPTOR) + (String + NullByte) + (...) + ... - 1
230 * STORAGE_DEVICE_DESCRIPTOR contains 1 byte at the end already
231 */
233 VendorIdLength + 1 +
234 ProductIdLength + 1 +
235 RevisionLength + /* Null byte omitted */
236 1; /* Null byte for serial number */
237
238 /* Check buffer length */
239 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < TotalLength)
240 {
241 PSTORAGE_DESCRIPTOR_HEADER DescriptorHeader = Irp->AssociatedIrp.SystemBuffer;
242
243 /* Fail request if the buffer is simply too small */
244 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength <
246 {
247 Status = STATUS_BUFFER_TOO_SMALL; /* FIXME: Is this code appropriate? */
248 break;
249 }
250
251 /* Return required size */
252 DescriptorHeader->Version = TotalLength;
253 DescriptorHeader->Size = TotalLength;
254 Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
256 break;
257 }
258
259 /* Fill in data */
260 DeviceDescriptor = Irp->AssociatedIrp.SystemBuffer;
262 .Version = sizeof(STORAGE_DEVICE_DESCRIPTOR),
263 .Size = TotalLength,
264 .DeviceType = InquiryData->DeviceType,
265 .DeviceTypeModifier = InquiryData->DeviceTypeModifier,
266 .RemovableMedia = InquiryData->RemovableMedia,
267 .CommandQueueing = InquiryData->CommandQueue,
268 .BusType = BusTypeSata, /* FIXME: USE FDO BUS TYPE FROM REGISTRY */
269 };
270
271 /* Arbitrary data offsets, set them cascading */
272 DeviceDescriptor->VendorIdOffset =
273 FIELD_OFFSET(STORAGE_DEVICE_DESCRIPTOR, RawDeviceProperties);
274 DeviceDescriptor->ProductIdOffset = DeviceDescriptor->VendorIdOffset +
275 VendorIdLength + 1;
276 DeviceDescriptor->ProductRevisionOffset = DeviceDescriptor->ProductIdOffset +
277 ProductIdLength + 1;
278 DeviceDescriptor->SerialNumberOffset = DeviceDescriptor->ProductRevisionOffset +
279 RevisionLength + 1;
280
281 /* Fill the arbitrary data */
282 Dest = DeviceDescriptor->RawDeviceProperties;
283
284 RtlCopyMemory(Dest, InquiryData->VendorId, VendorIdLength);
285 Dest[VendorIdLength] = '\0';
286 Dest += VendorIdLength + 1;
287
288 RtlCopyMemory(Dest, InquiryData->ProductId, ProductIdLength);
289 Dest[ProductIdLength] = '\0';
290 Dest += ProductIdLength + 1;
291
292 RtlCopyMemory(Dest, InquiryData->ProductRevisionLevel, RevisionLength);
293 Dest[RevisionLength] = '\0';
294 Dest += RevisionLength + 1;
295
296 /* FIXME: Read serial number when enumerating devices */
297 *Dest = '\0';
298
299 /* TODO: Verify this doesnt overflow */
300 Irp->IoStatus.Information = TotalLength;
302 break;
303 }
305 {
307 return IoCallDriver(PdoExtension->FdoExtension->Device, Irp);
308 }
310 default:
311 {
313 break;
314 }
315 }
316 }
317 while (0);
318
319 Irp->IoStatus.Status = Status;
321
322 return Status;
323}
324
325
326static
329 _In_ PPDO_DEVICE_EXTENSION DeviceExtension,
330 _In_ PIRP Irp)
331{
333 PSCSI_ADDRESS ScsiAddress;
334 PIO_STACK_LOCATION IoStack;
335 PFDO_DEVICE_EXTENSION FdoDeviceExtension;
336
337 DPRINT("PdoDeviceControlScsiGetAddress(%p %p)\n", DeviceExtension, Irp);
338
340
341 NT_ASSERT(DeviceExtension->ExtensionType == PdoExtension);
342 FdoDeviceExtension = DeviceExtension->FdoExtension;
343
344 do
345 {
346 /* Check buffer length */
347 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SCSI_ADDRESS))
348 {
350 Irp->IoStatus.Information = 0;
351 break;
352 }
353
354 ScsiAddress = (PSCSI_ADDRESS)Irp->AssociatedIrp.SystemBuffer;
355 ScsiAddress->Length = sizeof(SCSI_ADDRESS);
356 ScsiAddress->PortNumber = FdoDeviceExtension->ScsiPortNumber;
357 ScsiAddress->PathId = DeviceExtension->Bus;
358 ScsiAddress->TargetId = DeviceExtension->Target;
359 ScsiAddress->Lun = DeviceExtension->Lun;
360
362 Irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
363
364 DPRINT("SCSI Address for PDO %p : (Path Target Lun)(%d %d %d)\n",
365 DeviceExtension->Device, ScsiAddress->PathId, ScsiAddress->TargetId, ScsiAddress->Lun);
366 }
367 while (0);
368
369 Irp->IoStatus.Status = Status;
371
372 return Status;
373}
374
375
377NTAPI
380 _In_ PIRP Irp)
381{
383 PIO_STACK_LOCATION IoStack;
384
386
387 switch (IoStack->Parameters.DeviceIoControl.IoControlCode)
388 {
390 return PdoDeviceControlQueryProperty(DeviceObject->DeviceExtension, Irp);
391
393 return PdoDeviceControlScsiGetAddress(DeviceObject->DeviceExtension, Irp);
394
395 default:
396 // DbgBreakPoint();
398 break;
399 }
400
401 Irp->IoStatus.Status = Status;
402 Irp->IoStatus.Information = 0;
404
405 return Status;
406}
407
408
409/* EOF */
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
LONG NTSTATUS
Definition: precomp.h:26
BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended)
Definition: query.c:292
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
LPWSTR Name
Definition: desk.c:124
_Check_return_ _In_ ULONG _Inout_ PDXGK_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: dispmprt.h:1263
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static UINT32 GetFieldLength(_In_ PUCHAR Name, _In_ UINT32 MaxLength)
Definition: ioctl.c:125
NTSTATUS NTAPI PortPdoDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: ioctl.c:378
static NTSTATUS FdoDeviceControlQueryProperty(_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: ioctl.c:44
NTSTATUS NTAPI PortFdoDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: ioctl.c:146
static NTSTATUS PdoDeviceControlQueryProperty(_In_ PPDO_DEVICE_EXTENSION PdoExtension, _In_ PIRP Irp)
Definition: ioctl.c:176
static NTSTATUS PdoDeviceControlScsiGetAddress(_In_ PPDO_DEVICE_EXTENSION DeviceExtension, _In_ PIRP Irp)
Definition: ioctl.c:328
@ PdoExtension
Definition: precomp.h:61
@ FdoExtension
Definition: precomp.h:60
Status
Definition: gdiplustypes.h:24
if(dx< 0)
Definition: linetemp.h:194
DeviceType
Definition: mmdrv.h:42
#define _In_
Definition: no_sal2.h:158
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCompleteRequest
Definition: irp.c:1272
#define IoCallDriver
Definition: irp.c:1257
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:570
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:569
#define IOCTL_STORAGE_QUERY_PROPERTY
Definition: ntddstor.h:178
@ BusTypeSata
Definition: ntddstor.h:449
@ StorageDeviceIdProperty
Definition: ntddstor.h:514
@ StorageAdapterProperty
Definition: ntddstor.h:513
@ StorageDevicePowerProperty
Definition: ntddstor.h:524
@ StorageDeviceProperty
Definition: ntddstor.h:512
struct _STORAGE_PROPERTY_QUERY * PSTORAGE_PROPERTY_QUERY
@ PropertyExistsQuery
Definition: ntddstor.h:506
@ PropertyStandardQuery
Definition: ntddstor.h:505
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
struct _SCSI_ADDRESS * PSCSI_ADDRESS
struct _SCSI_ADDRESS SCSI_ADDRESS
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define DPRINT
Definition: sndvol32.h:73
UCHAR CommandQueue
Definition: cdrw_hw.h:1125
UCHAR RemovableMedia
Definition: cdrw_hw.h:1119
UCHAR ProductId[16]
Definition: cdrw_hw.h:1133
UCHAR ProductRevisionLevel[4]
Definition: cdrw_hw.h:1134
UCHAR DeviceTypeModifier
Definition: cdrw_hw.h:1118
UCHAR VendorId[8]
Definition: cdrw_hw.h:1132
UCHAR DeviceType
Definition: cdrw_hw.h:1116
union _IO_STACK_LOCATION::@1813 Parameters
struct _IO_STACK_LOCATION::@1813::@1814 DeviceIoControl
PORT_CONFIGURATION_INFORMATION PortConfig
Definition: precomp.h:92
UCHAR PathId
Definition: scsi_port.h:149
UCHAR TargetId
Definition: scsi_port.h:150
ULONG Length
Definition: scsi_port.h:147
UCHAR PortNumber
Definition: scsi_port.h:148
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t UINT32
Definition: typedefs.h:59
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_In_ ULONG TotalLength
Definition: usbdlib.h:185
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
struct _STORAGE_DESCRIPTOR_HEADER STORAGE_DESCRIPTOR_HEADER
struct _STORAGE_DEVICE_DESCRIPTOR STORAGE_DEVICE_DESCRIPTOR
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define NT_ASSERT
Definition: rtlfuncs.h:3334