5656static CONTROLLER_INFO gControllerInfo [MAX_CONTROLLERS ];
5757static ULONG gNumberOfControllers = 0 ;
5858
59+ NTSYSAPI
60+ NTSTATUS
61+ NTAPI
62+ ZwWaitForSingleObject (
63+ _In_ HANDLE Handle ,
64+ _In_ BOOLEAN Alertable ,
65+ _In_opt_ PLARGE_INTEGER Timeout );
66+
5967/* Queue thread management */
6068static KEVENT QueueThreadTerminate ;
6169static PVOID QueueThreadObject ;
6270
71+ static VOID
72+ Cleanup (PDRIVER_OBJECT DriverObject )
73+ {
74+ ULONG i , j ;
75+
76+ PAGED_CODE ();
77+ UNREFERENCED_PARAMETER (DriverObject );
78+
79+ if (QueueThreadObject )
80+ {
81+ KeSetEvent (& QueueThreadTerminate , 0 , FALSE);
82+ KeWaitForSingleObject (QueueThreadObject , Executive , KernelMode , FALSE, NULL );
83+ ObDereferenceObject (QueueThreadObject );
84+ QueueThreadObject = NULL ;
85+ }
86+
87+ for (i = 0 ; i < gNumberOfControllers ; i ++ )
88+ {
89+ for (j = 0 ; j < gControllerInfo [i ].NumberOfDrives ; j ++ )
90+ {
91+ if (!gControllerInfo [i ].DriveInfo [j ].Initialized )
92+ continue ;
93+
94+ if (gControllerInfo [i ].DriveInfo [j ].DeviceObject )
95+ {
96+ UNICODE_STRING Link ;
97+
98+ RtlInitUnicodeString (& Link , gControllerInfo [i ].DriveInfo [j ].ArcPathBuffer );
99+ IoDeassignArcName (& Link );
100+
101+ IoDeleteDevice (gControllerInfo [i ].DriveInfo [j ].DeviceObject );
102+ gControllerInfo [i ].DriveInfo [j ].DeviceObject = NULL ;
103+ }
104+
105+ gControllerInfo [i ].DriveInfo [j ].Initialized = FALSE;
106+ }
107+
108+ if (gControllerInfo [i ].InterruptObject )
109+ {
110+ IoDisconnectInterrupt (gControllerInfo [i ].InterruptObject );
111+ gControllerInfo [i ].InterruptObject = NULL ;
112+ }
113+
114+ if (gControllerInfo [i ].Initialized )
115+ {
116+ if (HwPowerOff (& gControllerInfo [i ]) != STATUS_SUCCESS )
117+ {
118+ WARN_ (FLOPPY , "cleanup: warning: HwPowerOff failed\n" );
119+ }
120+
121+ gControllerInfo [i ].Initialized = FALSE;
122+ }
123+ }
124+ }
125+
63126
64127static VOID NTAPI
65128MotorStopDpcFunc (PKDPC UnusedDpc , PVOID DeferredContext , PVOID SystemArgument1 , PVOID SystemArgument2 )
@@ -381,46 +444,11 @@ Unload(PDRIVER_OBJECT DriverObject)
381444 * DriverObject - The driver that is being unloaded
382445 */
383446{
384- ULONG i ,j ;
385-
386447 PAGED_CODE ();
387- UNREFERENCED_PARAMETER (DriverObject );
388448
389449 TRACE_ (FLOPPY , "unloading\n" );
390450
391- KeSetEvent (& QueueThreadTerminate , 0 , FALSE);
392- KeWaitForSingleObject (QueueThreadObject , Executive , KernelMode , FALSE, 0 );
393- ObDereferenceObject (QueueThreadObject );
394-
395- for (i = 0 ; i < gNumberOfControllers ; i ++ )
396- {
397- if (!gControllerInfo [i ].Initialized )
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- {
407- UNICODE_STRING Link ;
408-
409- RtlInitUnicodeString (& Link , gControllerInfo [i ].DriveInfo [j ].ArcPathBuffer );
410- IoDeassignArcName (& Link );
411-
412- IoDeleteDevice (gControllerInfo [i ].DriveInfo [j ].DeviceObject );
413- }
414- }
415-
416- IoDisconnectInterrupt (gControllerInfo [i ].InterruptObject );
417-
418- /* Power down the controller */
419- if (HwPowerOff (& gControllerInfo [i ]) != STATUS_SUCCESS )
420- {
421- WARN_ (FLOPPY , "unload: warning: HwPowerOff failed\n" );
422- }
423- }
451+ Cleanup (DriverObject );
424452}
425453
426454
@@ -1285,6 +1313,9 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
12851313 if (ObReferenceObjectByHandle (ThreadHandle , STANDARD_RIGHTS_ALL , * PsThreadType , KernelMode , & QueueThreadObject , NULL ) != STATUS_SUCCESS )
12861314 {
12871315 WARN_ (FLOPPY , "Unable to reference returned thread handle; failing init\n" );
1316+ KeSetEvent (& QueueThreadTerminate , 0 , FALSE);
1317+ ZwWaitForSingleObject (ThreadHandle , FALSE, NULL );
1318+ ZwClose (ThreadHandle );
12881319 return STATUS_UNSUCCESSFUL ;
12891320 }
12901321
@@ -1300,7 +1331,10 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
13001331 * it finds even one drive attached to one controller.
13011332 */
13021333 if (!AddControllers (DriverObject ))
1334+ {
1335+ Cleanup (DriverObject );
13031336 return STATUS_NO_SUCH_DEVICE ;
1337+ }
13041338
13051339 return STATUS_SUCCESS ;
13061340}
0 commit comments