ReactOS 0.4.15-dev-7788-g1ad9096
floppy.c
Go to the documentation of this file.
1/*
2 * ReactOS Floppy Driver
3 * Copyright (C) 2004, Vizzini (vizzini@plasmic.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * PROJECT: ReactOS Floppy Driver
20 * FILE: floppy.c
21 * PURPOSE: Main floppy driver routines
22 * PROGRAMMER: Vizzini (vizzini@plasmic.com)
23 * REVISIONS:
24 * 15-Feb-2004 vizzini - Created
25 * NOTES:
26 * - This driver is only designed to work with ISA-bus floppy controllers. This
27 * won't work on PCI-based controllers or on anything else with level-sensitive
28 * interrupts without modification. I don't think these controllers exist.
29 *
30 * ---- General to-do items ----
31 * TODO: Figure out why CreateClose isn't called any more. Seems to correspond
32 * with the driver not being unloadable.
33 * TODO: Think about StopDpcQueued -- could be a race; too tired atm to tell
34 * TODO: Clean up drive start/stop responsibilities (currently a mess...)
35 *
36 * ---- Support for proper media detection ----
37 * TODO: Handle MFM flag
38 * TODO: Un-hardcode the data rate from various places
39 * TODO: Proper media detection (right now we're hardcoded to 1.44)
40 * TODO: Media detection based on sector 1
41 */
42
43#include "precomp.h"
44
45#include <ntddk.h>
46#include <debug.h>
47
48#include "ioctl.h"
49#include "readwrite.h"
50
51/*
52 * Global controller info structures. Each controller gets one. Since the system
53 * will probably have only one, with four being a very unlikely maximum, a static
54 * global array is easiest to deal with.
55 */
58
59/* Queue thread management */
62
63
64static VOID NTAPI
66/*
67 * FUNCTION: Stop the floppy motor
68 * ARGUMENTS:
69 * UnusedDpc: DPC object that's going off
70 * DeferredContext: called with DRIVE_INFO for drive to turn off
71 * SystemArgument1: unused
72 * SystemArgument2: unused
73 * NOTES:
74 * - Must set an event to let other threads know we're done turning off the motor
75 * - Called back at DISPATCH_LEVEL
76 */
77{
79
82 UNREFERENCED_PARAMETER(UnusedDpc);
83
85 ASSERT(ControllerInfo);
86
87 TRACE_(FLOPPY, "MotorStopDpcFunc called\n");
88
89 HwTurnOffMotor(ControllerInfo);
90 ControllerInfo->StopDpcQueued = FALSE;
92}
93
94
97/*
98 * FUNCTION: Start the motor, taking into account proper handling of the timer race
99 * ARGUMENTS:
100 * DriveInfo: drive to start
101 * NOTES:
102 * - Never call HwTurnOnMotor() directly
103 * - This protocol manages a race between the cancel timer and the requesting thread.
104 * You wouldn't want to turn on the motor and then cancel the timer, because the
105 * cancel dpc might fire in the meantime, and that'd un-do what you just did. If you
106 * cancel the timer first, but KeCancelTimer returns false, the dpc is already running,
107 * so you have to wait until the dpc is completely done running, or else you'll race
108 * with the turner-offer
109 * - PAGED_CODE because we wait
110 */
111{
112 PAGED_CODE();
113 ASSERT(DriveInfo);
114
115 TRACE_(FLOPPY, "StartMotor called\n");
116
117 if(DriveInfo->ControllerInfo->StopDpcQueued && !KeCancelTimer(&DriveInfo->ControllerInfo->MotorTimer))
118 {
119 /* Motor turner-offer is already running; wait for it to finish */
120 INFO_(FLOPPY, "StartMotor: motor turner-offer is already running; waiting for it\n");
121 KeWaitForSingleObject(&DriveInfo->ControllerInfo->MotorStoppedEvent, Executive, KernelMode, FALSE, NULL);
122 INFO_(FLOPPY, "StartMotor: wait satisfied\n");
123 }
124
125 DriveInfo->ControllerInfo->StopDpcQueued = FALSE;
126
127 if(HwTurnOnMotor(DriveInfo) != STATUS_SUCCESS)
128 {
129 WARN_(FLOPPY, "StartMotor(): warning: HwTurnOnMotor failed\n");
130 }
131}
132
133
136/*
137 * FUNCTION: Stop all motors on the controller
138 * ARGUMENTS:
139 * DriveInfo: Drive to stop
140 * NOTES:
141 * - Never call HwTurnOffMotor() directly
142 * - This manages the timer cancelation race (see StartMotor for details).
143 * All we have to do is set up a timer.
144 */
145{
146 LARGE_INTEGER StopTime;
147
148 ASSERT(ControllerInfo);
149
150 TRACE_(FLOPPY, "StopMotor called\n");
151
152 /* one relative second, in 100-ns units */
153 StopTime.QuadPart = 10000000;
154 StopTime.QuadPart *= -1;
155
156 KeClearEvent(&ControllerInfo->MotorStoppedEvent);
157 KeSetTimer(&ControllerInfo->MotorTimer, StopTime, &ControllerInfo->MotorStopDpc);
158 ControllerInfo->StopDpcQueued = TRUE;
159}
160
161
164/*
165 * FUNCTION: Wait for the controller to interrupt, and then clear the event
166 * ARGUMENTS:
167 * ControllerInfo: Controller to wait for
168 * Timeout: How long to wait for
169 * NOTES:
170 * - There is a small chance that an unexpected or spurious interrupt could
171 * be lost with this clear/wait/clear scheme used in this driver. This is
172 * deemed to be an acceptable risk due to the unlikeliness of the scenario,
173 * and the fact that it'll probably work fine next time.
174 * - PAGED_CODE because it waits
175 */
176{
178
179 PAGED_CODE();
180 ASSERT(ControllerInfo);
181
183 KeClearEvent(&ControllerInfo->SynchEvent);
184
185 return Status;
186}
187
190 PIRP Irp)
191/*
192 * FUNCTION: Dispatch function called for Create and Close IRPs
193 * ARGUMENTS:
194 * DeviceObject: DeviceObject that is the target of the IRP
195 * Irp: IRP to process
196 * RETURNS:
197 * STATUS_SUCCESS in all cases
198 * NOTES:
199 * - The Microsoft sample drivers tend to return FILE_OPENED in Information, so I do too.
200 * - No reason to fail the device open
201 * - No state to track, so this routine is easy
202 * - Can be called <= DISPATCH_LEVEL
203 *
204 * TODO: Figure out why this isn't getting called
205 */
206{
208
209 TRACE_(FLOPPY, "CreateClose called\n");
210
211 Irp->IoStatus.Status = STATUS_SUCCESS;
212 Irp->IoStatus.Information = FILE_OPENED;
213
215
216 return STATUS_SUCCESS;
217}
218
219
220static NTSTATUS NTAPI
222/*
223 * FUNCTION: Start the recalibration process
224 * ARGUMENTS:
225 * DriveInfo: Pointer to the driveinfo struct associated with the targeted drive
226 * RETURNS:
227 * STATUS_SUCCESS on successful starting of the process
228 * STATUS_IO_DEVICE_ERROR if it fails
229 * NOTES:
230 * - Sometimes you have to do two recalibrations, particularly if the disk has <80 tracks.
231 * - PAGED_CODE because we wait
232 */
233{
235 ULONG i;
236
237 PAGED_CODE();
238 ASSERT(DriveInfo);
239
240 /* first turn on the motor */
241 /* Must stop after every start, prior to return */
242 StartMotor(DriveInfo);
243
244 /* set the data rate */
245 WARN_(FLOPPY, "FIXME: UN-HARDCODE DATA RATE\n");
246 if(HwSetDataRate(DriveInfo->ControllerInfo, 0) != STATUS_SUCCESS)
247 {
248 WARN_(FLOPPY, "Recalibrate: HwSetDataRate failed\n");
249 StopMotor(DriveInfo->ControllerInfo);
251 }
252
253 /* clear the event just in case the last call forgot */
254 KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
255
256 /* sometimes you have to do this twice; we'll just do it twice all the time since
257 * we don't know if the people calling this Recalibrate routine expect a disk to
258 * even be in the drive, and if so, if that disk is formatted.
259 */
260 for(i = 0; i < 2; i++)
261 {
262 /* Send the command */
263 Status = HwRecalibrate(DriveInfo);
265 {
266 WARN_(FLOPPY, "Recalibrate: HwRecalibrate returned error\n");
267 continue;
268 }
269
271
272 /* Get the results */
275 {
276 WARN_(FLOPPY, "Recalibrate: HwRecalibrateResult returned error\n");
277 break;
278 }
279 }
280
281 KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
282
283 /* Must stop after every start, prior to return */
284 StopMotor(DriveInfo->ControllerInfo);
285
286 return Status;
287}
288
289
292/*
293 * FUNCTION: Reset the drive's change flag (as reflected in the DIR)
294 * ARGUMENTS:
295 * DriveInfo: the drive to reset
296 * RETURNS:
297 * STATUS_SUCCESS if the changeline is cleared
298 * STATUS_NO_MEDIA_IN_DEVICE if the changeline cannot be cleared
299 * STATUS_IO_DEVICE_ERROR if the controller cannot be communicated with
300 * NOTES:
301 * - Change reset procedure: recalibrate, seek 1, seek 0
302 * - If the line is still set after that, there's clearly no disk in the
303 * drive, so we return STATUS_NO_MEDIA_IN_DEVICE
304 * - PAGED_CODE because we wait
305 */
306{
307 BOOLEAN DiskChanged;
308
309 PAGED_CODE();
310 ASSERT(DriveInfo);
311
312 TRACE_(FLOPPY, "ResetChangeFlag called\n");
313
314 /* Try to recalibrate. We don't care if it works. */
315 Recalibrate(DriveInfo);
316
317 /* clear spurious interrupts in prep for seeks */
318 KeClearEvent(&DriveInfo->ControllerInfo->SynchEvent);
319
320 /* must re-start the drive because Recalibrate() stops it */
321 StartMotor(DriveInfo);
322
323 /* Seek to 1 */
324 if(HwSeek(DriveInfo, 1) != STATUS_SUCCESS)
325 {
326 WARN_(FLOPPY, "ResetChangeFlag(): HwSeek failed; returning STATUS_IO_DEVICE_ERROR\n");
327 StopMotor(DriveInfo->ControllerInfo);
329 }
330
332
334 {
335 WARN_(FLOPPY, "ResetChangeFlag(): HwSenseInterruptStatus failed; bailing out\n");
336 StopMotor(DriveInfo->ControllerInfo);
338 }
339
340 /* Seek back to 0 */
341 if(HwSeek(DriveInfo, 0) != STATUS_SUCCESS)
342 {
343 WARN_(FLOPPY, "ResetChangeFlag(): HwSeek failed; returning STATUS_IO_DEVICE_ERROR\n");
344 StopMotor(DriveInfo->ControllerInfo);
346 }
347
349
351 {
352 WARN_(FLOPPY, "ResetChangeFlag(): HwSenseInterruptStatus #2 failed; bailing\n");
353 StopMotor(DriveInfo->ControllerInfo);
355 }
356
357 /* Check the change bit */
358 if(HwDiskChanged(DriveInfo, &DiskChanged) != STATUS_SUCCESS)
359 {
360 WARN_(FLOPPY, "ResetChangeFlag(): HwDiskChanged failed; returning STATUS_IO_DEVICE_ERROR\n");
361 StopMotor(DriveInfo->ControllerInfo);
363 }
364
365 StopMotor(DriveInfo->ControllerInfo);
366
367 /* if the change flag is still set, there's probably no media in the drive. */
368 if(DiskChanged)
370
371 /* else we're done! */
372 return STATUS_SUCCESS;
373}
374
375
376static VOID NTAPI
378/*
379 * FUNCTION: Unload the driver from memory
380 * ARGUMENTS:
381 * DriverObject - The driver that is being unloaded
382 */
383{
384 ULONG i,j;
385
386 PAGED_CODE();
388
389 TRACE_(FLOPPY, "unloading\n");
390
394
395 for(i = 0; i < gNumberOfControllers; i++)
396 {
398 continue;
399
400 for(j = 0; j < gControllerInfo[i].NumberOfDrives; j++)
401 {
402 if(!gControllerInfo[i].DriveInfo[j].Initialized)
403 continue;
404
405 if(gControllerInfo[i].DriveInfo[j].DeviceObject)
406 {
408
409 RtlInitUnicodeString(&Link, gControllerInfo[i].DriveInfo[j].ArcPathBuffer);
411
413 }
414 }
415
417
418 /* Power down the controller */
420 {
421 WARN_(FLOPPY, "unload: warning: HwPowerOff failed\n");
422 }
423 }
424}
425
426
427static NTSTATUS NTAPI
429 PUNICODE_STRING PathName,
433 CONFIGURATION_TYPE ControllerType,
434 ULONG ControllerNumber,
435 PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
436 CONFIGURATION_TYPE PeripheralType,
437 ULONG PeripheralNumber,
438 PKEY_VALUE_FULL_INFORMATION *PeripheralInformation)
439/*
440 * FUNCTION: Callback to IoQueryDeviceDescription, which tells us about our controllers
441 * ARGUMENTS:
442 * Context: Unused
443 * PathName: Unused
444 * BusType: Type of the bus that our controller is on
445 * BusNumber: Number of the bus that our controller is on
446 * BusInformation: Unused
447 * ControllerType: Unused
448 * ControllerNumber: Number of the controller that we're adding
449 * ControllerInformation: Full configuration information for our controller
450 * PeripheralType: Unused
451 * PeripheralNumber: Unused
452 * PeripheralInformation: Full configuration information for each drive on our controller
453 * RETURNS:
454 * STATUS_SUCCESS in all cases
455 * NOTES:
456 * - The only documentation I've found about the contents of these structures is
457 * from the various Microsoft floppy samples and from the DDK headers. They're
458 * very vague, though, so I'm only mostly sure that this stuff is correct, as
459 * the MS samples do things completely differently than I have done them. Seems
460 * to work in my VMWare, though.
461 * - Basically, the function gets all of the information (port, dma, irq) about the
462 * controller, and then loops through all of the drives presented in PeripheralInformation.
463 * - Each controller has a CONTROLLER_INFO created for it, and each drive has a DRIVE_INFO.
464 * - Device objects are created for each drive (not controller), as that's the targeted
465 * device in the eyes of the rest of the OS. Each DRIVE_INFO points to a single CONTROLLER_INFO.
466 * - We only support up to four controllers in the whole system, each of which supports up to four
467 * drives.
468 */
469{
470 PKEY_VALUE_FULL_INFORMATION ControllerFullDescriptor = ControllerInformation[IoQueryDeviceConfigurationData];
471 PCM_FULL_RESOURCE_DESCRIPTOR ControllerResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PCHAR)ControllerFullDescriptor +
472 ControllerFullDescriptor->DataOffset);
473
474 PKEY_VALUE_FULL_INFORMATION PeripheralFullDescriptor = PeripheralInformation[IoQueryDeviceConfigurationData];
475 PCM_FULL_RESOURCE_DESCRIPTOR PeripheralResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PCHAR)PeripheralFullDescriptor +
476 PeripheralFullDescriptor->DataOffset);
477
478 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
479 PCM_FLOPPY_DEVICE_DATA FloppyDeviceData;
480 UCHAR i;
481
482 PAGED_CODE();
483 UNREFERENCED_PARAMETER(PeripheralType);
484 UNREFERENCED_PARAMETER(PeripheralNumber);
487 UNREFERENCED_PARAMETER(ControllerType);
488 UNREFERENCED_PARAMETER(PathName);
489
490
491 TRACE_(FLOPPY, "ConfigCallback called with ControllerNumber %d\n", ControllerNumber);
492
496
497 /* Get controller interrupt level/vector, dma channel, and port base */
498 for(i = 0; i < ControllerResourceDescriptor->PartialResourceList.Count; i++)
499 {
501
502 PartialDescriptor = &ControllerResourceDescriptor->PartialResourceList.PartialDescriptors[i];
503
504 if(PartialDescriptor->Type == CmResourceTypeInterrupt)
505 {
506 gControllerInfo[gNumberOfControllers].Level = PartialDescriptor->u.Interrupt.Level;
507 gControllerInfo[gNumberOfControllers].Vector = PartialDescriptor->u.Interrupt.Vector;
508
509 if(PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
511 else
513 }
514
515 else if(PartialDescriptor->Type == CmResourceTypePort)
516 {
518 ULONG AddressSpace = 0x1; /* I/O Port Range */
519
520 if(!HalTranslateBusAddress(BusType, BusNumber, PartialDescriptor->u.Port.Start, &AddressSpace, &TranslatedAddress))
521 {
522 WARN_(FLOPPY, "HalTranslateBusAddress failed; returning\n");
524 }
525
526 if(AddressSpace == 0)
528 else
530 }
531
532 else if(PartialDescriptor->Type == CmResourceTypeDma)
533 gControllerInfo[gNumberOfControllers].Dma = PartialDescriptor->u.Dma.Channel;
534 }
535
536 /* Start with 0 drives, then go looking */
538
539 /* learn about drives attached to controller */
540 for(i = 0; i < PeripheralResourceDescriptor->PartialResourceList.Count; i++)
541 {
543
544 PartialDescriptor = &PeripheralResourceDescriptor->PartialResourceList.PartialDescriptors[i];
545
546 if(PartialDescriptor->Type != CmResourceTypeDeviceSpecific)
547 continue;
548
549 FloppyDeviceData = (PCM_FLOPPY_DEVICE_DATA)(PartialDescriptor + 1);
550
552 DriveInfo->UnitNumber = i;
553
554 DriveInfo->FloppyDeviceData.MaxDensity = FloppyDeviceData->MaxDensity;
555 DriveInfo->FloppyDeviceData.MountDensity = FloppyDeviceData->MountDensity;
557 DriveInfo->FloppyDeviceData.HeadLoadTime = FloppyDeviceData->HeadLoadTime;
558 DriveInfo->FloppyDeviceData.MotorOffTime = FloppyDeviceData->MotorOffTime;
559 DriveInfo->FloppyDeviceData.SectorLengthCode = FloppyDeviceData->SectorLengthCode;
560 DriveInfo->FloppyDeviceData.SectorPerTrack = FloppyDeviceData->SectorPerTrack;
561 DriveInfo->FloppyDeviceData.ReadWriteGapLength = FloppyDeviceData->ReadWriteGapLength;
562 DriveInfo->FloppyDeviceData.FormatGapLength = FloppyDeviceData->FormatGapLength;
563 DriveInfo->FloppyDeviceData.FormatFillCharacter = FloppyDeviceData->FormatFillCharacter;
564 DriveInfo->FloppyDeviceData.HeadSettleTime = FloppyDeviceData->HeadSettleTime;
565 DriveInfo->FloppyDeviceData.MotorSettleTime = FloppyDeviceData->MotorSettleTime;
566 DriveInfo->FloppyDeviceData.MaximumTrackValue = FloppyDeviceData->MaximumTrackValue;
567 DriveInfo->FloppyDeviceData.DataTransferLength = FloppyDeviceData->DataTransferLength;
568
569 /* Once it's all set up, acknowledge its existence in the controller info object */
571 }
572
575
576 return STATUS_SUCCESS;
577}
578
579
580static BOOLEAN NTAPI
582/*
583 * FUNCTION: Interrupt service routine for the controllers
584 * ARGUMENTS:
585 * Interrupt: Interrupt object representing the interrupt that occured
586 * ServiceContext: Pointer to the ControllerInfo object that caused the interrupt
587 * RETURNS:
588 * TRUE in all cases (see notes)
589 * NOTES:
590 * - We should always be the target of the interrupt, being an edge-triggered ISA interrupt, but
591 * this won't be the case with a level-sensitive system like PCI
592 * - Note that it probably doesn't matter if the interrupt isn't dismissed, as it's edge-triggered.
593 * It probably won't keep re-interrupting.
594 * - There are two different ways to dismiss a floppy interrupt. If the command has a result phase
595 * (see intel datasheet), you dismiss the interrupt by reading the first data byte. If it does
596 * not, you dismiss the interrupt by doing a Sense Interrupt command. Again, because it's edge-
597 * triggered, this is safe to not do here, as we can just wait for the DPC.
598 * - Either way, we don't want to do this here. The controller shouldn't interrupt again, so we'll
599 * schedule a DPC to take care of it.
600 * - This driver really cannot share interrupts, as I don't know how to conclusively say
601 * whether it was our controller that interrupted or not. I just have to assume that any time
602 * my ISR gets called, it was my board that called it. Dumb design, yes, but it goes back to
603 * the semantics of ISA buses. That, and I don't know much about ISA drivers. :-)
604 * UPDATE: The high bit of Status Register A seems to work on non-AT controllers.
605 * - Called at DIRQL
606 */
607{
609
611
612 ASSERT(ControllerInfo);
613
614 TRACE_(FLOPPY, "ISR called\n");
615
616 /*
617 * Due to the stupidity of the drive/controller relationship on the floppy drive, only one device object
618 * can have an active interrupt pending. Due to the nature of these IRPs, though, there will only ever
619 * be one thread expecting an interrupt at a time, and furthermore, Interrupts (outside of spurious ones)
620 * won't ever happen unless a thread is expecting them. Therefore, all we have to do is signal an event
621 * and we're done. Queue a DPC and leave.
622 */
623 KeInsertQueueDpc(&ControllerInfo->Dpc, NULL, NULL);
624
625 return TRUE;
626}
627
628
631/*
632 * FUNCTION: This DPC gets queued by every ISR. Does the real per-interrupt work.
633 * ARGUMENTS:
634 * UnusedDpc: Pointer to the DPC object that represents our function
635 * DeviceObject: Device that this DPC is running for
636 * Irp: Unused
637 * Context: Pointer to our ControllerInfo struct
638 * NOTES:
639 * - This function just kicks off whatever the SynchEvent is and returns. We depend on
640 * the thing that caused the drive to interrupt to handle the work of clearing the interrupt.
641 * This enables us to get back to PASSIVE_LEVEL and not hog system time on a really stupid,
642 * slow, screwed-up piece of hardware.
643 * - If nothing is waiting for us to set the event, the interrupt is effectively lost and will
644 * never be dismissed. I wonder if this will become a problem.
645 * - Called at DISPATCH_LEVEL
646 */
647{
648 PCONTROLLER_INFO ControllerInfo = (PCONTROLLER_INFO)Context;
649
650 UNREFERENCED_PARAMETER(UnusedDpc);
653
654 ASSERT(ControllerInfo);
655
656 TRACE_(FLOPPY, "DpcForIsr called\n");
657
658 KeSetEvent(&ControllerInfo->SynchEvent, EVENT_INCREMENT, FALSE);
659}
660
661
662static NTSTATUS NTAPI
664/*
665 * FUNCTION: Initialize a newly-found controller
666 * ARGUMENTS:
667 * ControllerInfo: pointer to the controller to be initialized
668 * RETURNS:
669 * STATUS_SUCCESS if the controller is successfully initialized
670 * STATUS_IO_DEVICE_ERROR otherwise
671 */
672{
673 int i;
674 UCHAR HeadLoadTime;
675 UCHAR HeadUnloadTime;
676 UCHAR StepRateTime;
677 UCHAR ControllerVersion;
678
679 PAGED_CODE();
680 ASSERT(ControllerInfo);
681
682 TRACE_(FLOPPY, "InitController called with Controller 0x%p\n", ControllerInfo);
683
684 /* Get controller in a known state */
685 if(HwConfigure(ControllerInfo, FALSE, TRUE, TRUE, 0, 0) != STATUS_SUCCESS)
686 {
687 WARN_(FLOPPY, "InitController: unable to configure controller\n");
689 }
690
691 /* Get the controller version */
692 ControllerVersion = HwGetVersion(ControllerInfo);
693
694 KeClearEvent(&ControllerInfo->SynchEvent);
695
696 /* Reset the controller */
697 if(HwReset(ControllerInfo) != STATUS_SUCCESS)
698 {
699 WARN_(FLOPPY, "InitController: unable to reset controller\n");
701 }
702
703 INFO_(FLOPPY, "InitController: waiting for initial interrupt\n");
704
705 /* Wait for an interrupt */
706 WaitForControllerInterrupt(ControllerInfo, NULL);
707
708 /* Reset means you have to clear each of the four interrupts (one per drive) */
709 for(i = 0; i < MAX_DRIVES_PER_CONTROLLER; i++)
710 {
711 INFO_(FLOPPY, "InitController: Sensing interrupt %d\n", i);
712
713 if(HwSenseInterruptStatus(ControllerInfo) != STATUS_SUCCESS)
714 {
715 WARN_(FLOPPY, "InitController: Unable to clear interrupt 0x%x\n", i);
717 }
718 }
719
720 INFO_(FLOPPY, "InitController: done sensing interrupts\n");
721
722 /* Next, see if we have the right version to do implied seek */
723 if(ControllerVersion == VERSION_ENHANCED)
724 {
725 /* If so, set that up -- all defaults below except first TRUE for EIS */
726 if(HwConfigure(ControllerInfo, TRUE, TRUE, TRUE, 0, 0) != STATUS_SUCCESS)
727 {
728 WARN_(FLOPPY, "InitController: unable to set up implied seek\n");
729 ControllerInfo->ImpliedSeeks = FALSE;
730 }
731 else
732 {
733 INFO_(FLOPPY, "InitController: implied seeks set!\n");
734 ControllerInfo->ImpliedSeeks = TRUE;
735 }
736
737 /*
738 * FIXME: Figure out the answer to the below
739 *
740 * I must admit that I'm really confused about the Model 30 issue. At least one
741 * important bit (the disk change bit in the DIR) is flipped if this is a Model 30
742 * controller. However, at least one other floppy driver believes that there are only
743 * two computers that are guaranteed to have a Model 30 controller:
744 * - IBM Thinkpad 750
745 * - IBM PS2e
746 *
747 * ...and another driver only lists a config option for "thinkpad", that flips
748 * the change line. A third driver doesn't mention the Model 30 issue at all.
749 *
750 * What I can't tell is whether or not the average, run-of-the-mill computer now has
751 * a Model 30 controller. For the time being, I'm going to wire this to FALSE,
752 * and just not support the computers mentioned above, while I try to figure out
753 * how ubiquitous these newfangled 30 thingies are.
754 */
755 //ControllerInfo->Model30 = TRUE;
756 ControllerInfo->Model30 = FALSE;
757 }
758 else
759 {
760 INFO_(FLOPPY, "InitController: enhanced version not supported; disabling implied seeks\n");
761 ControllerInfo->ImpliedSeeks = FALSE;
762 ControllerInfo->Model30 = FALSE;
763 }
764
765 /* Specify */
766 WARN_(FLOPPY, "FIXME: Figure out speed\n");
767 HeadLoadTime = SPECIFY_HLT_500K;
768 HeadUnloadTime = SPECIFY_HUT_500K;
769 StepRateTime = SPECIFY_SRT_500K;
770
771 INFO_(FLOPPY, "InitController: setting data rate\n");
772
773 /* Set data rate */
774 if(HwSetDataRate(ControllerInfo, DRSR_DSEL_500KBPS) != STATUS_SUCCESS)
775 {
776 WARN_(FLOPPY, "InitController: unable to set data rate\n");
778 }
779
780 INFO_(FLOPPY, "InitController: issuing specify command to controller\n");
781
782 /* Don't disable DMA --> enable dma (dumb & confusing) */
783 if(HwSpecify(ControllerInfo, HeadLoadTime, HeadUnloadTime, StepRateTime, FALSE) != STATUS_SUCCESS)
784 {
785 WARN_(FLOPPY, "InitController: unable to specify options\n");
787 }
788
789 /* Init the stop stuff */
790 KeInitializeDpc(&ControllerInfo->MotorStopDpc, MotorStopDpcFunc, ControllerInfo);
791 KeInitializeTimer(&ControllerInfo->MotorTimer);
793 ControllerInfo->StopDpcQueued = FALSE;
794
795 /*
796 * Recalibrate each drive on the controller (depends on StartMotor, which depends on the timer stuff above)
797 * We don't even know if there is a disk in the drive, so this may not work, but that's OK.
798 */
799 for(i = 0; i < ControllerInfo->NumberOfDrives; i++)
800 {
801 INFO_(FLOPPY, "InitController: recalibrating drive 0x%x on controller 0x%p\n", i, ControllerInfo);
802 Recalibrate(&ControllerInfo->DriveInfo[i]);
803 }
804
805 INFO_(FLOPPY, "InitController: done initializing; returning STATUS_SUCCESS\n");
806
807 return STATUS_SUCCESS;
808}
809
810
811static VOID NTAPI
812ReportToMountMgr(UCHAR ControlerId, UCHAR DriveId)
813/*
814 * FUNCTION: Called to report a new controler to the MountMgr
815 * ARGUMENTS:
816 * ControlerId: ID of the controler
817 * DriveId: ID of the device for the controler
818 * RETURNS:
819 * Nothing
820 * NOTES:
821 * - This is a hack to allow MountMgr handling our devices
822 */
823{
825 UNICODE_STRING MountMgrDevice;
828 PMOUNTMGR_TARGET_NAME MountTarget;
829 ULONG DeviceLen;
830 PIRP Irp;
833
834 /* First, get MountMgr DeviceObject */
838
839 if(!NT_SUCCESS(Status))
840 {
841 WARN_(FLOPPY, "ReportToMountMgr: Can't get MountMgr pointers %lx\n", Status);
842 return;
843 }
844
845 DeviceLen = wcslen(&gControllerInfo[ControlerId].DriveInfo[DriveId].DeviceNameBuffer[0]) * sizeof(WCHAR);
846
847 /* Allocate input buffer to report our floppy device */
848 MountTarget = ExAllocatePool(NonPagedPool,
849 sizeof(MOUNTMGR_TARGET_NAME) + DeviceLen);
850
851 if(!MountTarget)
852 {
853 WARN_(FLOPPY, "ReportToMountMgr: Allocation of mountTarget failed\n");
855 return;
856 }
857
858 MountTarget->DeviceNameLength = DeviceLen;
859 RtlCopyMemory(MountTarget->DeviceName,
860 gControllerInfo[ControlerId].DriveInfo[DriveId].DeviceNameBuffer,
861 DeviceLen);
862
864
865 /* Build the IRP used to communicate with the MountMgr */
868 MountTarget,
869 sizeof(MOUNTMGR_TARGET_NAME) + DeviceLen,
870 NULL,
871 0,
872 FALSE,
873 &Event,
874 &IoStatus);
875
876 if(!Irp)
877 {
878 WARN_(FLOPPY, "ReportToMountMgr: Allocation of irp failed\n");
879 ExFreePool(MountTarget);
881 return;
882 }
883
884 /* Call the MountMgr */
886
887 if (Status == STATUS_PENDING) {
889 Status = IoStatus.Status;
890 }
891
892 /* We're done */
893
894 INFO_(FLOPPY, "Reported to the MountMgr: %lx\n", Status);
895
896 ExFreePool(MountTarget);
898
899 return;
900}
901
902
903static BOOLEAN NTAPI
905/*
906 * FUNCTION: Called on initialization to find our controllers and build device and controller objects for them
907 * ARGUMENTS:
908 * DriverObject: Our driver's DriverObject (so we can create devices against it)
909 * RETURNS:
910 * FALSE if we can't allocate a device, adapter, or interrupt object, or if we fail to find any controllers
911 * TRUE otherwise (i.e. we have at least one fully-configured controller)
912 * NOTES:
913 * - Currently we only support ISA buses.
914 * - BUG: Windows 2000 seems to clobber the response from the IoQueryDeviceDescription callback, so now we
915 * just test a boolean value in the first object to see if it was completely populated. The same value
916 * is tested for each controller before we build device objects for it.
917 * TODO:
918 * - Report resource usage to the HAL
919 */
920{
922 CONFIGURATION_TYPE ControllerType = DiskController;
926 UCHAR i;
927 UCHAR j;
928
929 PAGED_CODE();
930
931 /* Find our controllers on all ISA buses */
933 NULL,
934 &ControllerType,
935 NULL,
936 &PeripheralType,
937 NULL,
939 NULL);
940
941 /*
942 * w2k breaks the return val from ConfigCallback, so we have to hack around it, rather than just
943 * looking for a return value from ConfigCallback. We expect at least one controller.
944 */
945 if(!gControllerInfo[0].Populated)
946 {
947 WARN_(FLOPPY, "AddControllers: failed to get controller info from registry\n");
948 return FALSE;
949 }
950
951 /* Now that we have a controller, set it up with the system */
953 {
954 /* 0: Report resource usage to the kernel, to make sure they aren't assigned to anyone else */
955 /* FIXME: Implement me. */
956
957 /* 1: Set up interrupt */
960 &gControllerInfo[i].MappedLevel, &Affinity);
961
962 /* Must set up the DPC before we connect the interrupt */
964
965 INFO_(FLOPPY, "Connecting interrupt %d to controller%d (object 0x%p)\n", gControllerInfo[i].MappedVector,
966 i, &gControllerInfo[i]);
967
968 /* NOTE: We cannot share our interrupt, even on level-triggered buses. See Isr() for details. */
970 gControllerInfo[i].MappedLevel, gControllerInfo[i].MappedLevel, gControllerInfo[i].InterruptMode,
972 {
973 WARN_(FLOPPY, "AddControllers: unable to connect interrupt\n");
974 continue;
975 }
976
977 /* 2: Set up DMA */
983 DeviceDescription.MaximumLength = 2*18*512; /* based on a 1.44MB floppy */
984
985 /* DMA 0,1,2,3 are 8-bit; 4,5,6,7 are 16-bit (4 is chain i think) */
987
989
990 if(!gControllerInfo[i].AdapterObject)
991 {
992 WARN_(FLOPPY, "AddControllers: unable to allocate an adapter object\n");
994 continue;
995 }
996
997 /* 2b: Initialize the new controller */
999 {
1000 WARN_(FLOPPY, "AddControllers(): Unable to set up controller %d - initialization failed\n", i);
1002 continue;
1003 }
1004
1005 /* 2c: Set the controller's initialized flag so we know to release stuff in Unload */
1007
1008 /* 3: per-drive setup */
1009 for(j = 0; j < gControllerInfo[i].NumberOfDrives; j++)
1010 {
1012 UNICODE_STRING ArcPath;
1013 UCHAR DriveNumber;
1014
1015 INFO_(FLOPPY, "AddControllers(): Configuring drive %d on controller %d\n", i, j);
1016
1017 /*
1018 * 3a: create a device object for the drive
1019 * Controllers and drives are 0-based, so the combos are:
1020 * 0: 0,0
1021 * 1: 0,1
1022 * 2: 0,2
1023 * 3: 0,3
1024 * 4: 1,0
1025 * 5: 1,1
1026 * ...
1027 * 14: 3,2
1028 * 15: 3,3
1029 */
1030
1031 DriveNumber = (UCHAR)(i*4 + j); /* loss of precision is OK; there are only 16 of 'em */
1032
1033 swprintf(gControllerInfo[i].DriveInfo[j].DeviceNameBuffer, L"\\Device\\Floppy%d", DriveNumber);
1034 RtlInitUnicodeString(&DeviceName, gControllerInfo[i].DriveInfo[j].DeviceNameBuffer);
1035
1039 {
1040 WARN_(FLOPPY, "AddControllers: unable to register a Device object\n");
1042 continue; /* continue on to next drive */
1043 }
1044
1045 INFO_(FLOPPY, "AddControllers: New device: %S (0x%p)\n",
1046 gControllerInfo[i].DriveInfo[j].DeviceNameBuffer,
1047 gControllerInfo[i].DriveInfo[j].DeviceObject);
1048
1049 /* 3b.5: Create an ARC path in case we're booting from this drive */
1050 swprintf(gControllerInfo[i].DriveInfo[j].ArcPathBuffer,
1051 L"\\ArcName\\multi(%d)disk(%d)fdisk(%d)", gControllerInfo[i].BusNumber, i, DriveNumber);
1052
1053 RtlInitUnicodeString(&ArcPath, gControllerInfo[i].DriveInfo[j].ArcPathBuffer);
1054 IoAssignArcName(&ArcPath, &DeviceName);
1055
1056 /* 3c: Set flags up */
1058
1059 /* 3d: Increase global floppy drives count */
1061
1062 /* 3e: Set up the DPC */
1064
1065 /* 3f: Point the device extension at our DriveInfo struct */
1067
1068 /* 3g: neat comic strip */
1069
1070 /* 3h: set the initial media type to unknown */
1071 memset(&gControllerInfo[i].DriveInfo[j].DiskGeometry, 0, sizeof(DISK_GEOMETRY));
1073
1074 /* 3i: Now that we're done, set the Initialized flag so we know to free this in Unload */
1076
1077 /* 3j: Clear the DO_DEVICE_INITIALIZING flag */
1078 gControllerInfo[i].DriveInfo[j].DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1079
1080 /* 3k: Report to the MountMgr */
1082
1083 /* 3l: Attempt to get drive info - if a floppy is already present */
1084 StartMotor(&gControllerInfo[i].DriveInfo[j]);
1086 StopMotor(gControllerInfo[i].DriveInfo[j].ControllerInfo);
1087 }
1088 }
1089
1090 INFO_(FLOPPY, "AddControllers: --------------------------------------------> finished adding controllers\n");
1091
1092 return (IoGetConfigurationInformation()->FloppyCount != 0);
1093}
1094
1095
1096VOID NTAPI
1098/*
1099 * FUNCTION: Process an IRP when the media has changed, and possibly notify the user
1100 * ARGUMENTS:
1101 * DeviceObject: DeviceObject associated with the IRP
1102 * Irp: IRP that we're failing due to change
1103 * NOTES:
1104 * - This procedure is documented in the DDK by "Notifying the File System of Possible Media Changes",
1105 * "IoSetHardErrorOrVerifyDevice", and by "Responding to Check-Verify Requests from the File System".
1106 * - Callable at <= DISPATCH_LEVEL
1107 */
1108{
1109 PDRIVE_INFO DriveInfo = DeviceObject->DeviceExtension;
1110
1111 TRACE_(FLOPPY, "SignalMediaChanged called\n");
1112
1113 DriveInfo->DiskChangeCount++;
1114
1115 /* If volume is not mounted, do NOT set verify and return STATUS_IO_DEVICE_ERROR */
1116 if(!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
1117 {
1118 Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
1119 Irp->IoStatus.Information = 0;
1120 return;
1121 }
1122
1123 /* Notify the filesystem that it will need to verify the volume */
1125 Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
1126 Irp->IoStatus.Information = 0;
1127
1128 /*
1129 * If this is a user-based, threaded request, let the IO manager know to pop up a box asking
1130 * the user to supply the correct media, but only if the error (which we just picked out above)
1131 * is deemed by the IO manager to be "user induced". The reason we don't just unconditionally
1132 * call IoSetHardError... is because MS might change the definition of "user induced" some day,
1133 * and we don't want to have to remember to re-code this.
1134 */
1135 if(Irp->Tail.Overlay.Thread && IoIsErrorUserInduced(Irp->IoStatus.Status))
1137}
1138
1139
1140static VOID NTAPI
1142/*
1143 * FUNCTION: Thread that manages the queue and dispatches any queued requests
1144 * ARGUMENTS:
1145 * Context: unused
1146 */
1147{
1148 PIRP Irp;
1151 PVOID Objects[2];
1152
1153 PAGED_CODE();
1155
1156 Objects[0] = &QueueSemaphore;
1157 Objects[1] = &QueueThreadTerminate;
1158
1159 for(;;)
1160 {
1162
1164 {
1165 INFO_(FLOPPY, "QueueThread terminating\n");
1166 return;
1167 }
1168
1169 INFO_(FLOPPY, "QueueThread: servicing an IRP\n");
1170
1171 Irp = IoCsqRemoveNextIrp(&Csq, 0);
1172
1173 /* we won't get an irp if it was canceled */
1174 if(!Irp)
1175 {
1176 INFO_(FLOPPY, "QueueThread: IRP queue empty\n");
1177 continue;
1178 }
1179
1180 DeviceObject = (PDEVICE_OBJECT)Irp->Tail.Overlay.DriverContext[0];
1181
1183
1185
1186 /* Decide what to do with the IRP */
1187 switch(Stack->MajorFunction)
1188 {
1189 case IRP_MJ_READ:
1190 case IRP_MJ_WRITE:
1191 ReadWritePassive(DeviceObject->DeviceExtension, Irp);
1192 break;
1193
1195 DeviceIoctlPassive(DeviceObject->DeviceExtension, Irp);
1196 break;
1197
1198 default:
1199 WARN_(FLOPPY, "QueueThread(): Unrecognized irp: mj: 0x%x\n", Stack->MajorFunction);
1200 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
1201 Irp->IoStatus.Information = 0;
1203 }
1204 }
1205}
1206
1207
1210/*
1211 * FUNCTION: Entry-point for the driver
1212 * ARGUMENTS:
1213 * DriverObject: Our driver object
1214 * RegistryPath: Unused
1215 * RETURNS:
1216 * STATUS_SUCCESS on successful initialization of at least one drive
1217 * STATUS_NO_SUCH_DEVICE if we didn't find even one drive
1218 * STATUS_UNSUCCESSFUL otherwise
1219 */
1220{
1221 HANDLE ThreadHandle;
1222
1224
1225 /*
1226 * Set up dispatch routines
1227 */
1233
1234 DriverObject->DriverUnload = Unload;
1235
1236 /*
1237 * We depend on some zeroes in these structures. I know this is supposed to be
1238 * initialized to 0 by the complier but this makes me feel beter.
1239 */
1241
1242 /*
1243 * Set up queue. This routine cannot fail (trust me, I wrote it).
1244 */
1247
1248 /*
1249 * ...and its lock
1250 */
1252
1253 /*
1254 * ...and the queue list itself
1255 */
1257
1258 /*
1259 * The queue is counted by a semaphore. The queue management thread
1260 * blocks on this semaphore, so if requests come in faster than the queue
1261 * thread can handle them, the semaphore count goes up.
1262 */
1263 KeInitializeSemaphore(&QueueSemaphore, 0, 0x7fffffff);
1264
1265 /*
1266 * Event to terminate that thread
1267 */
1269
1270 /*
1271 * Create the queue processing thread. Save its handle in the global variable
1272 * ThreadHandle so we can wait on its termination during Unload.
1273 */
1274 if(PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, 0, 0, 0, QueueThread, 0) != STATUS_SUCCESS)
1275 {
1276 WARN_(FLOPPY, "Unable to create system thread; failing init\n");
1278 }
1279
1281 {
1282 WARN_(FLOPPY, "Unable to reference returned thread handle; failing init\n");
1283 return STATUS_UNSUCCESSFUL;
1284 }
1285
1286 /*
1287 * Close the handle, now that we have the object pointer and a reference of our own.
1288 * The handle will certainly not be valid in the context of the caller next time we
1289 * need it, as handles are process-specific.
1290 */
1291 ZwClose(ThreadHandle);
1292
1293 /*
1294 * Start the device discovery process. Returns STATUS_SUCCESS if
1295 * it finds even one drive attached to one controller.
1296 */
1298 return STATUS_NO_SUCH_DEVICE;
1299
1300 return STATUS_SUCCESS;
1301}
#define PAGED_CODE()
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
@ DiskController
Definition: arcname.c:68
DRIVER_INITIALIZE DriverEntry
Definition: floppy.c:347
_In_ PIRP Irp
Definition: csq.h:116
NTKERNELAPI NTSTATUS NTAPI IoCsqInitialize(_Out_ PIO_CSQ Csq, _In_ PIO_CSQ_INSERT_IRP CsqInsertIrp, _In_ PIO_CSQ_REMOVE_IRP CsqRemoveIrp, _In_ PIO_CSQ_PEEK_NEXT_IRP CsqPeekNextIrp, _In_ PIO_CSQ_ACQUIRE_LOCK CsqAcquireLock, _In_ PIO_CSQ_RELEASE_LOCK CsqReleaseLock, _In_ PIO_CSQ_COMPLETE_CANCELED_IRP CsqCompleteCanceledIrp)
Set up a CSQ struct to initialize the queue.
Definition: csq.c:103
NTKERNELAPI PIRP NTAPI IoCsqRemoveNextIrp(_Inout_ PIO_CSQ Csq, _In_opt_ PVOID PeekContext)
IoCsqRemoveNextIrp - Removes the next IRP from the queue.
Definition: csq.c:398
KSPIN_LOCK IrpQueueLock
Definition: csqrtns.c:50
KSEMAPHORE QueueSemaphore
Definition: csqrtns.c:51
LIST_ENTRY IrpQueue
Definition: csqrtns.c:49
IO_CSQ Csq
Definition: csqrtns.c:46
#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:32
ULONG_PTR KAFFINITY
Definition: compat.h:85
#define TRACE_(x)
Definition: compat.h:76
#define swprintf
Definition: precomp.h:40
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:725
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
struct _CONTROLLER_INFO * PCONTROLLER_INFO
#define MAX_DRIVES_PER_CONTROLLER
Definition: fdc.h:16
#define MAX_CONTROLLERS
Definition: fdc.h:17
NTSTATUS NTAPI HwRecalibrateResult(PCONTROLLER_INFO ControllerInfo)
Definition: hardware.c:394
NTSTATUS NTAPI HwTurnOnMotor(PDRIVE_INFO DriveInfo)
Definition: hardware.c:245
NTSTATUS NTAPI HwConfigure(PCONTROLLER_INFO ControllerInfo, BOOLEAN EIS, BOOLEAN EFIFO, BOOLEAN POLL, UCHAR FIFOTHR, UCHAR PRETRK)
Definition: hardware.c:703
NTSTATUS NTAPI HwGetVersion(PCONTROLLER_INFO ControllerInfo)
Definition: hardware.c:749
NTSTATUS NTAPI HwSeek(PDRIVE_INFO DriveInfo, UCHAR Cylinder)
Definition: hardware.c:659
NTSTATUS NTAPI HwSetDataRate(PCONTROLLER_INFO ControllerInfo, UCHAR DataRate)
Definition: hardware.c:204
NTSTATUS NTAPI HwReset(PCONTROLLER_INFO ControllerInfo)
Definition: hardware.c:973
NTSTATUS NTAPI HwRecalibrate(PDRIVE_INFO DriveInfo)
Definition: hardware.c:503
NTSTATUS NTAPI HwSpecify(PCONTROLLER_INFO ControllerInfo, UCHAR HeadLoadTime, UCHAR HeadUnloadTime, UCHAR StepRateTime, BOOLEAN NonDma)
Definition: hardware.c:925
NTSTATUS NTAPI HwSenseInterruptStatus(PCONTROLLER_INFO ControllerInfo)
Definition: hardware.c:539
NTSTATUS NTAPI HwDiskChanged(PDRIVE_INFO DriveInfo, PBOOLEAN DiskChanged)
Definition: hardware.c:785
NTSTATUS NTAPI HwTurnOffMotor(PCONTROLLER_INFO ControllerInfo)
Definition: hardware.c:223
NTSTATUS NTAPI HwPowerOff(PCONTROLLER_INFO ControllerInfo)
Definition: hardware.c:1010
#define VERSION_ENHANCED
Definition: hardware.h:239
#define SPECIFY_HLT_500K
Definition: hardware.h:219
#define FDC_PORT_BYTES
Definition: hardware.h:40
#define SPECIFY_HUT_500K
Definition: hardware.h:223
#define DRSR_DSEL_500KBPS
Definition: hardware.h:106
#define SPECIFY_SRT_500K
Definition: hardware.h:227
VOID NTAPI DeviceIoctlPassive(PDRIVE_INFO DriveInfo, PIRP Irp)
Definition: ioctl.c:64
DRIVER_DISPATCH DeviceIoctl
Definition: ioctl.h:29
VOID NTAPI ReadWritePassive(PDRIVE_INFO DriveInfo, PIRP Irp)
Definition: readwrite.c:403
NTSTATUS NTAPI RWDetermineMediaType(PDRIVE_INFO DriveInfo, BOOLEAN OneShot)
Definition: readwrite.c:153
NTHALAPI ULONG NTAPI HalGetInterruptVector(INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY)
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
struct _DEVICE_OBJECT * PDEVICE_OBJECT
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
LONG NTAPI KeReadStateEvent(IN PKEVENT Event)
Definition: eventobj.c:120
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
static NTSTATUS NTAPI InitController(PCONTROLLER_INFO ControllerInfo)
Definition: floppy.c:663
static VOID NTAPI QueueThread(PVOID Context)
Definition: floppy.c:1141
static NTSTATUS NTAPI Recalibrate(PDRIVE_INFO DriveInfo)
Definition: floppy.c:221
static VOID NTAPI Unload(PDRIVER_OBJECT DriverObject)
Definition: floppy.c:377
NTSTATUS NTAPI WaitForControllerInterrupt(PCONTROLLER_INFO ControllerInfo, PLARGE_INTEGER Timeout)
Definition: floppy.c:163
static CONTROLLER_INFO gControllerInfo[MAX_CONTROLLERS]
Definition: floppy.c:56
static PVOID QueueThreadObject
Definition: floppy.c:61
NTSTATUS NTAPI ResetChangeFlag(PDRIVE_INFO DriveInfo)
Definition: floppy.c:291
static DRIVER_DISPATCH CreateClose
Definition: floppy.c:188
static BOOLEAN NTAPI AddControllers(PDRIVER_OBJECT DriverObject)
Definition: floppy.c:904
VOID NTAPI SignalMediaChanged(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: floppy.c:1097
static NTSTATUS NTAPI ConfigCallback(PVOID Context, PUNICODE_STRING PathName, INTERFACE_TYPE BusType, ULONG BusNumber, PKEY_VALUE_FULL_INFORMATION *BusInformation, CONFIGURATION_TYPE ControllerType, ULONG ControllerNumber, PKEY_VALUE_FULL_INFORMATION *ControllerInformation, CONFIGURATION_TYPE PeripheralType, ULONG PeripheralNumber, PKEY_VALUE_FULL_INFORMATION *PeripheralInformation)
Definition: floppy.c:428
static VOID NTAPI MotorStopDpcFunc(PKDPC UnusedDpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
Definition: floppy.c:65
static ULONG gNumberOfControllers
Definition: floppy.c:57
VOID NTAPI DpcForIsr(PKDPC UnusedDpc, PVOID Context, PVOID SystemArgument1, PVOID SystemArgument2)
Definition: floppy.c:630
static KEVENT QueueThreadTerminate
Definition: floppy.c:60
VOID NTAPI StartMotor(PDRIVE_INFO DriveInfo)
Definition: floppy.c:96
VOID NTAPI StopMotor(PCONTROLLER_INFO ControllerInfo)
Definition: floppy.c:135
static VOID NTAPI ReportToMountMgr(UCHAR ControlerId, UCHAR DriveId)
Definition: floppy.c:812
static BOOLEAN NTAPI Isr(PKINTERRUPT Interrupt, PVOID ServiceContext)
Definition: floppy.c:581
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
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 GLint GLint j
Definition: glfuncs.h:250
BOOLEAN NTAPI HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN PHYSICAL_ADDRESS BusAddress, IN OUT PULONG AddressSpace, OUT PPHYSICAL_ADDRESS TranslatedAddress)
Definition: bus.c:140
PADAPTER_OBJECT NTAPI HalGetAdapter(IN PDEVICE_DESCRIPTION DeviceDescription, OUT PULONG NumberOfMapRegisters)
Definition: dma.c:22
struct _CM_FULL_RESOURCE_DESCRIPTOR * PCM_FULL_RESOURCE_DESCRIPTOR
#define CmResourceTypeDma
Definition: hwresource.cpp:126
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
@ Isa
Definition: hwresource.cpp:138
enum _INTERFACE_TYPE INTERFACE_TYPE
#define CmResourceTypePort
Definition: hwresource.cpp:123
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
@ Unknown
Definition: i8042prt.h:114
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Returns a pointer to the I/O manager's global configuration information structure.
Definition: iorsrce.c:998
NTSTATUS NTAPI IoQueryDeviceDescription(_In_opt_ PINTERFACE_TYPE BusType, _In_opt_ PULONG BusNumber, _In_opt_ PCONFIGURATION_TYPE ControllerType, _In_opt_ PULONG ControllerNumber, _In_opt_ PCONFIGURATION_TYPE PeripheralType, _In_opt_ PULONG PeripheralNumber, _In_ PIO_QUERY_DEVICE_ROUTINE CalloutRoutine, _In_opt_ PVOID Context)
Reads and returns Hardware information from the appropriate hardware registry key.
Definition: iorsrce.c:1213
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
#define ASSERT(a)
Definition: mode.c:44
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
#define IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION
Definition: imports.h:130
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define KernelMode
Definition: asm.h:34
#define CM_RESOURCE_INTERRUPT_LATCHED
Definition: cmtypes.h:144
@ InterruptObject
Definition: ketypes.h:428
@ Initialized
Definition: ketypes.h:388
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
DRIVER_DISPATCH(nfs41_FsdDispatch)
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STANDARD_RIGHTS_ALL
Definition: nt_native.h:69
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
#define FILE_OPENED
Definition: nt_native.h:769
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
@ NotificationEvent
@ WaitAny
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 IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
#define IoCompleteRequest
Definition: irp.c:1240
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:141
NTSTATUS NTAPI IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave)
Definition: irq.c:22
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
NTSTATUS NTAPI KeWaitForMultipleObjects(IN ULONG Count, IN PVOID Object[], IN WAIT_TYPE WaitType, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL, OUT PKWAIT_BLOCK WaitBlockArray OPTIONAL)
Definition: wait.c:586
POBJECT_TYPE PsThreadType
Definition: thread.c:20
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
static ULONG Timeout
Definition: ping.c:61
#define FILE_DEVICE_DISK
Definition: winioctl.h:113
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
DRIVER_DISPATCH ReadWrite
Definition: readwrite.h:29
@ Latched
Definition: miniport.h:81
@ LevelSensitive
Definition: miniport.h:80
@ Width16Bits
Definition: miniport.h:106
@ Width8Bits
Definition: miniport.h:105
@ FloppyDiskPeripheral
Definition: arc.h:130
enum _CONFIGURATION_TYPE CONFIGURATION_TYPE
#define INFO_(ch,...)
Definition: debug.h:159
#define WARN_(ch,...)
Definition: debug.h:157
#define memset(x, y, z)
Definition: compat.h:39
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
#define STATUS_SUCCESS
Definition: shellext.h:65
UCHAR StepRateHeadUnloadTime
Definition: cmtypes.h:489
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@393 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@393::@396 Interrupt
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@393::@395 Port
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@393::@399 Dma
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
BOOLEAN StopDpcQueued
Definition: floppy.h:86
KEVENT SynchEvent
Definition: floppy.h:74
BOOLEAN Initialized
Definition: floppy.h:60
ULONG Level
Definition: floppy.h:64
UCHAR NumberOfDrives
Definition: fdc.h:58
BOOLEAN Model30
Definition: floppy.h:82
PADAPTER_OBJECT AdapterObject
Definition: floppy.h:77
KTIMER MotorTimer
Definition: floppy.h:84
ULONG MappedVector
Definition: floppy.h:67
KINTERRUPT_MODE InterruptMode
Definition: floppy.h:68
INTERFACE_TYPE InterfaceType
Definition: floppy.h:62
KEVENT MotorStoppedEvent
Definition: floppy.h:83
DRIVE_INFO DriveInfo[MAX_DRIVES_PER_CONTROLLER]
Definition: fdc.h:60
ULONG Vector
Definition: floppy.h:66
ULONG BusNumber
Definition: floppy.h:63
KDPC MotorStopDpc
Definition: floppy.h:85
BOOLEAN ImpliedSeeks
Definition: floppy.h:79
PUCHAR BaseAddress
Definition: fdc.h:49
BOOLEAN Populated
Definition: fdc.h:39
ULONG ControllerNumber
Definition: floppy.h:61
PVOID DeviceExtension
Definition: env_spec_w32.h:418
MEDIA_TYPE MediaType
Definition: ntdddisk.h:406
struct _CONTROLLER_INFO * ControllerInfo
Definition: fdc.h:23
PDEVICE_OBJECT DeviceObject
Definition: fdc.h:26
CM_FLOPPY_DEVICE_DATA FloppyDeviceData
Definition: fdc.h:27
ULONG DiskChangeCount
Definition: floppy.h:53
WCHAR DeviceNameBuffer[MAX_DEVICE_NAME]
Definition: floppy.h:52
BOOLEAN Initialized
Definition: floppy.h:54
DISK_GEOMETRY DiskGeometry
Definition: floppy.h:49
UCHAR UnitNumber
Definition: fdc.h:24
Definition: ketypes.h:699
USHORT DeviceNameLength
Definition: imports.h:154
WCHAR DeviceName[1]
Definition: imports.h:155
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
static int Link(const char **args)
Definition: vfdcmd.c:2414
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFDEVICE _In_ PPNP_BUS_INFORMATION BusInformation
Definition: wdfdevice.h:3915
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID InterfaceType
Definition: wdffdo.h:463
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:379
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING DeviceDescription
Definition: wdfpdo.h:432
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
struct _CM_FLOPPY_DEVICE_DATA * PCM_FLOPPY_DEVICE_DATA
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:160
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:174
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE BusType
Definition: halfuncs.h:159
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2817
_In_ PIO_CSQ_INSERT_IRP _In_ PIO_CSQ_REMOVE_IRP _In_ PIO_CSQ_PEEK_NEXT_IRP _In_ PIO_CSQ_ACQUIRE_LOCK _In_ PIO_CSQ_RELEASE_LOCK _In_ PIO_CSQ_COMPLETE_CANCELED_IRP CsqCompleteCanceledIrp
Definition: iofuncs.h:1893
_In_ PIO_CSQ_INSERT_IRP CsqInsertIrp
Definition: iofuncs.h:1888
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:806
FORCEINLINE VOID IoInitializeDpcRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIO_DPC_ROUTINE DpcRoutine)
Definition: iofuncs.h:2840
#define IoDeassignArcName
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG _Out_ PPHYSICAL_ADDRESS TranslatedAddress
Definition: iofuncs.h:2275
#define IoAssignArcName(_ArcName, _DeviceName)
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2274
_In_ PIO_CSQ_INSERT_IRP _In_ PIO_CSQ_REMOVE_IRP _In_ PIO_CSQ_PEEK_NEXT_IRP CsqPeekNextIrp
Definition: iofuncs.h:1890
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
_In_ PIO_CSQ_INSERT_IRP _In_ PIO_CSQ_REMOVE_IRP _In_ PIO_CSQ_PEEK_NEXT_IRP _In_ PIO_CSQ_ACQUIRE_LOCK CsqAcquireLock
Definition: iofuncs.h:1891
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:801
_In_ PIO_CSQ_INSERT_IRP _In_ PIO_CSQ_REMOVE_IRP CsqRemoveIrp
Definition: iofuncs.h:1889
_In_ PIO_CSQ_INSERT_IRP _In_ PIO_CSQ_REMOVE_IRP _In_ PIO_CSQ_PEEK_NEXT_IRP _In_ PIO_CSQ_ACQUIRE_LOCK _In_ PIO_CSQ_RELEASE_LOCK CsqReleaseLock
Definition: iofuncs.h:1892
#define EVENT_INCREMENT
Definition: iotypes.h:597
#define VPB_MOUNTED
Definition: iotypes.h:1807
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define DEVICE_DESCRIPTION_VERSION
Definition: iotypes.h:2063
@ IoQueryDeviceConfigurationData
Definition: iotypes.h:4449
DRIVER_DISPATCH * PDRIVER_DISPATCH
Definition: iotypes.h:2262
IO_DPC_ROUTINE * PIO_DPC_ROUTINE
Definition: iotypes.h:2847
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
@ Suspended
Definition: ketypes.h:420
@ Executive
Definition: ketypes.h:415
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:687
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689
@ MmNonCached
Definition: mmtypes.h:129
#define ObDereferenceObject
Definition: obfuncs.h:203
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180