ReactOS  0.4.14-dev-337-gf981a68
ioctl.c File Reference
#include "precomp.h"
#include <debug.h>
Include dependency graph for ioctl.c:

Go to the source code of this file.

Functions

NTSTATUS NTAPI DeviceIoctl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
VOID NTAPI DeviceIoctlPassive (PDRIVE_INFO DriveInfo, PIRP Irp)
 

Function Documentation

◆ DeviceIoctl()

NTSTATUS NTAPI DeviceIoctl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 39 of file ioctl.c.

52 {
54  ASSERT(Irp);
55 
56  Irp->Tail.Overlay.DriverContext[0] = DeviceObject;
58 
59  return STATUS_PENDING;
60 }
_In_ PIRP Irp
Definition: csq.h:116
NTKERNELAPI VOID NTAPI IoCsqInsertIrp(_Inout_ PIO_CSQ Csq, _Inout_ PIRP Irp, _Out_opt_ PIO_CSQ_IRP_CONTEXT Context)
Insert an IRP into the CSQ.
Definition: csq.c:177
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_PENDING
Definition: ntstatus.h:82
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
IO_CSQ Csq
Definition: csqrtns.c:46

◆ DeviceIoctlPassive()

VOID NTAPI DeviceIoctlPassive ( PDRIVE_INFO  DriveInfo,
PIRP  Irp 
)

Definition at line 64 of file ioctl.c.

71 {
73  ULONG OutputLength = Stack->Parameters.DeviceIoControl.OutputBufferLength;
74  PVOID OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
75  ULONG Code = Stack->Parameters.DeviceIoControl.IoControlCode;
76  BOOLEAN DiskChanged;
78  PMOUNTDEV_UNIQUE_ID UniqueId;
79 
80  TRACE_(FLOPPY, "DeviceIoctl called\n");
81  Irp->IoStatus.Status = STATUS_SUCCESS;
82  Irp->IoStatus.Information = 0;
83 
84  /*
85  * First the non-change-sensitive ioctls
86  */
88  {
89  PDISK_GEOMETRY Geometry = OutputBuffer;
90  INFO_(FLOPPY, "IOCTL_DISK_GET_MEDIA_TYPES Called\n");
91 
92  if(OutputLength < sizeof(DISK_GEOMETRY))
93  {
94  INFO_(FLOPPY, "IOCTL_DISK_GET_MEDIA_TYPES: insufficient buffer; returning STATUS_INVALID_PARAMETER\n");
95  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
97  return;
98  }
99 
100  /*
101  * for now, this driver only supports 3.5" HD media
102  */
103  Geometry->MediaType = F3_1Pt44_512;
104  Geometry->Cylinders.QuadPart = 80;
105  Geometry->TracksPerCylinder = 2 * 18;
106  Geometry->SectorsPerTrack = 18;
107  Geometry->BytesPerSector = 512;
108 
109  Irp->IoStatus.Status = STATUS_SUCCESS;
110  Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
111  INFO_(FLOPPY, "Ioctl: completing with STATUS_SUCCESS\n");
113 
114  return;
115  }
116 
117  /*
118  * Now, check to see if the volume needs to be verified. If so,
119  * return STATUS_VERIFY_REQUIRED.
120  *
121  * NOTE: This code, which is outside of the switch and if/else blocks,
122  * will implicity catch and correctly service IOCTL_DISK_CHECK_VERIFY.
123  * Therefore if we see one below in the switch, we can return STATUS_SUCCESS
124  * immediately.
125  */
126  if(DriveInfo->DeviceObject->Flags & DO_VERIFY_VOLUME && !(Stack->Flags & SL_OVERRIDE_VERIFY_VOLUME))
127  {
128  INFO_(FLOPPY, "DeviceIoctl(): completing with STATUS_VERIFY_REQUIRED\n");
129  Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
130  Irp->IoStatus.Information = 0;
132  return;
133  }
134 
135  /*
136  * Start the drive to see if the disk has changed
137  */
138  StartMotor(DriveInfo);
139 
140  /*
141  * Check the change line, and if it's set, return
142  */
143  if(HwDiskChanged(DriveInfo, &DiskChanged) != STATUS_SUCCESS)
144  {
145  WARN_(FLOPPY, "DeviceIoctl(): unable to sense disk change; completing with STATUS_UNSUCCESSFUL\n");
146  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
147  Irp->IoStatus.Information = 0;
149  StopMotor(DriveInfo->ControllerInfo);
150  return;
151  }
152 
153  if(DiskChanged)
154  {
155  INFO_(FLOPPY, "DeviceIoctl(): detected disk changed; signalling media change and completing\n");
156  SignalMediaChanged(DriveInfo->DeviceObject, Irp);
157 
158  /*
159  * Just guessing here - I have a choice of returning NO_MEDIA or VERIFY_REQUIRED. If there's
160  * really no disk in the drive, I'm thinking I can save time by just reporting that fact, rather
161  * than forcing windows to ask me twice. If this doesn't work, we'll need to split this up and
162  * handle the CHECK_VERIFY IOCTL separately.
163  */
165  Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
166 
168  StopMotor(DriveInfo->ControllerInfo);
169  return;
170  }
171 
172  switch(Code)
173  {
175  {
176  UCHAR Status;
177 
178  INFO_(FLOPPY, "IOCTL_DISK_IS_WRITABLE Called\n");
179 
180  /* This IRP always has 0 information */
181  Irp->IoStatus.Information = 0;
182 
183  if(HwSenseDriveStatus(DriveInfo) != STATUS_SUCCESS)
184  {
185  WARN_(FLOPPY, "IoctlDiskIsWritable(): unable to sense drive status\n");
186  Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
187  break;
188  }
189 
190  /* Now, read the drive's status back */
192  {
193  WARN_(FLOPPY, "IoctlDiskIsWritable(): unable to read drive status result\n");
194  Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
195  break;
196  }
197 
198  /* Check to see if the write flag is set. */
200  {
201  INFO_(FLOPPY, "IOCTL_DISK_IS_WRITABLE: disk is write protected\n");
202  Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED;
203  }
204  else
205  Irp->IoStatus.Status = STATUS_SUCCESS;
206  }
207  break;
208 
210  INFO_(FLOPPY, "IOCTL_DISK_CHECK_VERIFY called\n");
211  if (OutputLength != 0)
212  {
213  if (OutputLength < sizeof(ULONG))
214  {
215  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
216  Irp->IoStatus.Information = 0;
217  }
218  else
219  {
220  *((PULONG)OutputBuffer) = DriveInfo->DiskChangeCount;
221  Irp->IoStatus.Status = STATUS_SUCCESS;
222  Irp->IoStatus.Information = sizeof(ULONG);
223  }
224  }
225  else
226  {
227  Irp->IoStatus.Status = STATUS_SUCCESS;
228  Irp->IoStatus.Information = 0;
229  }
230  break;
231 
233  {
234  INFO_(FLOPPY, "IOCTL_DISK_GET_DRIVE_GEOMETRY Called\n");
235  if(OutputLength < sizeof(DISK_GEOMETRY))
236  {
237  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
238  break;
239  }
240 
241  /* This still works right even if DriveInfo->DiskGeometry->MediaType = Unknown */
242  memcpy(OutputBuffer, &DriveInfo->DiskGeometry, sizeof(DISK_GEOMETRY));
243  Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
244  break;
245  }
246 
249  ERR_(FLOPPY, "Format called; not supported yet\n");
250  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
251  Irp->IoStatus.Information = 0;
252  break;
253 
255  INFO_(FLOPPY, "IOCTL_DISK_GET_PARTITION_INFO Called; not supported by a floppy driver\n");
256  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
257  Irp->IoStatus.Information = 0;
258  break;
259 
261  if(OutputLength < sizeof(MOUNTDEV_UNIQUE_ID))
262  {
263  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
264  Irp->IoStatus.Information = 0;
265  break;
266  }
267 
268  UniqueId = Irp->AssociatedIrp.SystemBuffer;
269  UniqueId->UniqueIdLength = wcslen(&DriveInfo->DeviceNameBuffer[0]) * sizeof(WCHAR);
270 
271  if(OutputLength < FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + UniqueId->UniqueIdLength)
272  {
273  Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
274  Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
275  break;
276  }
277 
278  RtlCopyMemory(UniqueId->UniqueId, &DriveInfo->DeviceNameBuffer[0],
279  UniqueId->UniqueIdLength);
280 
281  Irp->IoStatus.Status = STATUS_SUCCESS;
282  Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + UniqueId->UniqueIdLength;
283  break;
284 
286  if(OutputLength < sizeof(MOUNTDEV_NAME))
287  {
288  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
289  Irp->IoStatus.Information = 0;
290  break;
291  }
292 
293  Name = Irp->AssociatedIrp.SystemBuffer;
294  Name->NameLength = wcslen(&DriveInfo->DeviceNameBuffer[0]) * sizeof(WCHAR);
295 
296  if(OutputLength < FIELD_OFFSET(MOUNTDEV_NAME, Name) + Name->NameLength)
297  {
298  Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
299  Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
300  break;
301  }
302 
303  RtlCopyMemory(Name->Name, &DriveInfo->DeviceNameBuffer[0],
304  Name->NameLength);
305 
306  Irp->IoStatus.Status = STATUS_SUCCESS;
307  Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_NAME, Name) + Name->NameLength;
308  break;
309 
310  default:
311  ERR_(FLOPPY, "UNKNOWN IOCTL CODE: 0x%x\n", Code);
312  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
313  Irp->IoStatus.Information = 0;
314  break;
315  }
316 
317  INFO_(FLOPPY, "ioctl: completing with status 0x%x\n", Irp->IoStatus.Status);
319 
320  StopMotor(DriveInfo->ControllerInfo);
321  return;
322 }
ULONG DiskChangeCount
Definition: floppy.h:53
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define INFO_(ch,...)
Definition: debug.h:159
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define ERR_(ch,...)
Definition: debug.h:156
USHORT UniqueIdLength
Definition: imports.h:138
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
NTSTATUS NTAPI HwDiskChanged(PDRIVE_INFO DriveInfo, PBOOLEAN DiskChanged)
Definition: hardware.c:785
VOID NTAPI StopMotor(PCONTROLLER_INFO ControllerInfo)
Definition: floppy.c:135
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
ULONG BytesPerSector
Definition: ntdddisk.h:381
ULONG TracksPerCylinder
Definition: ntdddisk.h:379
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
struct _CONTROLLER_INFO * ControllerInfo
Definition: fdc.h:23
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
PDEVICE_OBJECT DeviceObject
Definition: fdc.h:26
#define SR3_WRITE_PROTECT_STATUS_SIGNAL
Definition: hardware.h:161
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
#define IOCTL_DISK_FORMAT_TRACKS
Definition: cdrw_usr.h:171
struct NameRec_ * Name
Definition: cdprocs.h:464
struct _MOUNTDEV_NAME MOUNTDEV_NAME
unsigned char BOOLEAN
#define IoCompleteRequest
Definition: irp.c:1240
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1780
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
NTSTATUS NTAPI HwSenseDriveStatusResult(PCONTROLLER_INFO ControllerInfo, PUCHAR Status)
Definition: hardware.c:836
#define IOCTL_DISK_GET_MEDIA_TYPES
Definition: cdrw_usr.h:182
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
#define Code
Definition: deflate.h:80
#define TRACE_(x)
Definition: compat.h:66
NTSTATUS NTAPI ResetChangeFlag(PDRIVE_INFO DriveInfo)
Definition: floppy.c:291
struct _MOUNTDEV_UNIQUE_ID MOUNTDEV_UNIQUE_ID
__wchar_t WCHAR
Definition: xmlstorage.h:180
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:377
ULONG SectorsPerTrack
Definition: ntdddisk.h:380
MEDIA_TYPE MediaType
Definition: ntdddisk.h:378
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:88
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
DISK_GEOMETRY DiskGeometry
Definition: floppy.h:49
Status
Definition: gdiplustypes.h:24
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
struct _DISK_GEOMETRY DISK_GEOMETRY
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int * PULONG
Definition: retypes.h:1
#define IOCTL_DISK_FORMAT_TRACKS_EX
Definition: cdrw_usr.h:173
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
NTSTATUS NTAPI HwSenseDriveStatus(PDRIVE_INFO DriveInfo)
Definition: hardware.c:287
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define WARN_(ch,...)
Definition: debug.h:157
UCHAR UniqueId[1]
Definition: imports.h:139
VOID NTAPI SignalMediaChanged(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: floppy.c:1090
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
VOID NTAPI StartMotor(PDRIVE_INFO DriveInfo)
Definition: floppy.c:96
LONGLONG QuadPart
Definition: typedefs.h:112
WCHAR DeviceNameBuffer[MAX_DEVICE_NAME]
Definition: floppy.h:52

Referenced by QueueThread().