5de9bc9252258f6b174bd209c0b8feb04dea322e
[openafs.git] / src / WINNT / afsrdr / kernel / fs / AFSLibrarySupport.cpp
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3  * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * - Redistributions of source code must retain the above copyright notice,
11  *   this list of conditions and the following disclaimer.
12  * - Redistributions in binary form must reproduce the above copyright
13  *   notice,
14  *   this list of conditions and the following disclaimer in the
15  *   documentation
16  *   and/or other materials provided with the distribution.
17  * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18  *   nor the names of their contributors may be used to endorse or promote
19  *   products derived from this software without specific prior written
20  *   permission from Kernel Drivers, LLC and Your File System, Inc.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 //
36 // File: AFSLibrarySupport.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 NTSTATUS
42 AFSLoadLibrary( IN ULONG Flags,
43                 IN UNICODE_STRING *ServicePath)
44 {
45     UNREFERENCED_PARAMETER(Flags);
46
47     NTSTATUS ntStatus = STATUS_SUCCESS;
48     AFSDeviceExt       *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
49     UNICODE_STRING uniLibraryName;
50     AFSDeviceExt *pLibDevExt = NULL;
51     PFILE_OBJECT pLibraryFileObject = NULL;
52     PDEVICE_OBJECT pLibraryDeviceObject = NULL;
53
54     __Enter
55     {
56
57         //
58         // Wait on the load library event so we don't race with any
59         // other requests coming through
60         //
61
62         AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
63                       AFS_TRACE_LEVEL_VERBOSE,
64                       "%s Start load library\n",
65                       __FUNCTION__);
66
67         ntStatus = KeWaitForSingleObject( &pDevExt->Specific.Control.LoadLibraryEvent,
68                                           Executive,
69                                           KernelMode,
70                                           FALSE,
71                                           NULL);
72
73         if( !NT_SUCCESS( ntStatus))
74         {
75
76             AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
77                           AFS_TRACE_LEVEL_ERROR,
78                           "AFSLoadLibrary Wait for LoadLibraryEvent failure %08lX\n",
79                           ntStatus);
80
81             try_return( ntStatus);
82         }
83
84         //
85         // Check our current state to ensure we currently do not have a library loaded
86         //
87
88         if( BooleanFlagOn( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED))
89         {
90
91             AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
92                           AFS_TRACE_LEVEL_VERBOSE,
93                           "%s Library already loaded\n",
94                           __FUNCTION__);
95
96             try_return( ntStatus = STATUS_DEVICE_NOT_READY);
97         }
98
99         pDevExt->Specific.Control.LibraryServicePath.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
100                                                                                                  ServicePath->Length,
101                                                                                                  AFS_GENERIC_MEMORY_25_TAG);
102
103         if( pDevExt->Specific.Control.LibraryServicePath.Buffer == NULL)
104         {
105
106             AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
107                           AFS_TRACE_LEVEL_ERROR,
108                           "AFSLoadLibrary AFS_GENERIC_MEMORY_25_TAG allocation error\n");
109
110             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
111         }
112
113         RtlZeroMemory( pDevExt->Specific.Control.LibraryServicePath.Buffer,
114                        ServicePath->Length);
115
116         pDevExt->Specific.Control.LibraryServicePath.Length = ServicePath->Length;
117         pDevExt->Specific.Control.LibraryServicePath.MaximumLength = pDevExt->Specific.Control.LibraryServicePath.Length;
118
119         RtlCopyMemory( pDevExt->Specific.Control.LibraryServicePath.Buffer,
120                        ServicePath->Buffer,
121                        pDevExt->Specific.Control.LibraryServicePath.Length);
122
123         //
124         // Load the library
125         //
126
127         ntStatus = ZwLoadDriver( ServicePath);
128
129         if( !NT_SUCCESS( ntStatus))
130         {
131
132             AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
133                           AFS_TRACE_LEVEL_ERROR,
134                           "%s Failed to load library Status %08lX\n",
135                           __FUNCTION__,
136                           ntStatus);
137
138             try_return( ntStatus);
139         }
140
141         //
142         // Open up the control device and grab teh entry points for the library
143         //
144
145         RtlInitUnicodeString( &uniLibraryName,
146                               AFS_LIBRARY_CONTROL_DEVICE_NAME);
147
148         ntStatus = IoGetDeviceObjectPointer( &uniLibraryName,
149                                              FILE_ALL_ACCESS,
150                                              &pLibraryFileObject,
151                                              &pLibraryDeviceObject);
152
153         if( !NT_SUCCESS( ntStatus))
154         {
155             AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
156                           AFS_TRACE_LEVEL_ERROR,
157                           "AFSLoadLibrary IoGetDeviceObjectPointer failure %08lX\n",
158                           ntStatus);
159
160             try_return( ntStatus);
161         }
162
163         //
164         // We have our reference to the library device object. Grab the
165         // device extension and setup our callbacks
166         //
167
168         pLibDevExt = (AFSDeviceExt *)pLibraryDeviceObject->DeviceExtension;
169
170         //
171         // Save off our references
172         //
173
174         pDevExt->Specific.Control.LibraryFileObject = pLibraryFileObject;
175
176         pDevExt->Specific.Control.LibraryDeviceObject = pLibraryDeviceObject;
177
178         //
179         // Reset the state for our library
180         //
181
182         AFSAcquireExcl( &pDevExt->Specific.Control.LibraryStateLock,
183                         TRUE);
184
185         SetFlag( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED);
186
187         ClearFlag( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_QUEUE_CANCELLED);
188
189         AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
190                       AFS_TRACE_LEVEL_VERBOSE,
191                       "%s Completed load library, processing queued requests\n",
192                       __FUNCTION__);
193
194         AFSReleaseResource( &pDevExt->Specific.Control.LibraryStateLock);
195
196         //
197         // Process the queued requests
198         //
199
200         AFSProcessQueuedResults( FALSE);
201
202 try_exit:
203
204         AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
205                       AFS_TRACE_LEVEL_VERBOSE,
206                       "%s Library load complete Status %08lX\n",
207                       __FUNCTION__,
208                       ntStatus);
209
210         if( !NT_SUCCESS( ntStatus))
211         {
212
213             if( pDevExt->Specific.Control.LibraryServicePath.Buffer != NULL)
214             {
215
216                 ZwUnloadDriver( &pDevExt->Specific.Control.LibraryServicePath);
217
218                 ExFreePool( pDevExt->Specific.Control.LibraryServicePath.Buffer);
219
220                 pDevExt->Specific.Control.LibraryServicePath.Buffer = NULL;
221                 pDevExt->Specific.Control.LibraryServicePath.Length = 0;
222                 pDevExt->Specific.Control.LibraryServicePath.MaximumLength = 0;
223             }
224         }
225
226         KeSetEvent( &pDevExt->Specific.Control.LoadLibraryEvent,
227                     0,
228                     FALSE);
229     }
230
231     return ntStatus;
232 }
233
234 NTSTATUS
235 AFSUnloadLibrary( IN BOOLEAN CancelQueue)
236 {
237
238     NTSTATUS ntStatus = STATUS_SUCCESS;
239     AFSDeviceExt       *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
240     LARGE_INTEGER       liTimeout;
241
242     __Enter
243     {
244
245         //
246         // Wait on the load library event so we don't race with any
247         // other requests coming through
248         //
249
250         AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
251                       AFS_TRACE_LEVEL_VERBOSE,
252                       "%s Start unload library\n",
253                       __FUNCTION__);
254
255         ntStatus = KeWaitForSingleObject( &pDevExt->Specific.Control.LoadLibraryEvent,
256                                           Executive,
257                                           KernelMode,
258                                           FALSE,
259                                           NULL);
260
261         if( !NT_SUCCESS( ntStatus))
262         {
263             try_return( ntStatus);
264         }
265
266         if( !BooleanFlagOn( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED))
267         {
268             try_return( ntStatus = STATUS_DEVICE_NOT_READY);
269         }
270
271         //
272         // Clear all outstanding requests
273         //
274
275         AFSAcquireExcl( &pDevExt->Specific.Control.LibraryStateLock,
276                         TRUE);
277
278         ClearFlag( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED);
279
280         if( CancelQueue)
281         {
282             SetFlag( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_QUEUE_CANCELLED);
283         }
284
285         //
286         // We'll wait on the inflight event to be set, checking for the inflight
287         // request count to reach zero
288         //
289
290         while( pDevExt->Specific.Control.InflightLibraryRequests > 0)
291         {
292
293             liTimeout.QuadPart = -(AFS_ONE_SECOND);
294
295             //
296             // If the count is non-zero make sure the event is cleared
297             //
298
299             KeClearEvent( &pDevExt->Specific.Control.InflightLibraryEvent);
300
301             AFSReleaseResource( &pDevExt->Specific.Control.LibraryStateLock);
302
303             ntStatus = KeWaitForSingleObject( &pDevExt->Specific.Control.InflightLibraryEvent,
304                                               Executive,
305                                               KernelMode,
306                                               FALSE,
307                                               &liTimeout);
308
309             AFSAcquireExcl( &pDevExt->Specific.Control.LibraryStateLock,
310                             TRUE);
311
312             if( ntStatus != STATUS_TIMEOUT &&
313                 ntStatus != STATUS_SUCCESS)
314             {
315
316                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
317                               AFS_TRACE_LEVEL_VERBOSE,
318                               "%s Failed request event Status %08lX\n",
319                               __FUNCTION__,
320                               ntStatus);
321
322                 SetFlag( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED);
323
324                 AFSReleaseResource( &pDevExt->Specific.Control.LibraryStateLock);
325
326                 AFSProcessQueuedResults( TRUE);
327
328                 try_return( ntStatus);
329             }
330
331             AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
332                           AFS_TRACE_LEVEL_VERBOSE,
333                           "%s Wait for inflight requests to complete %08lX\n",
334                           __FUNCTION__,
335                           pDevExt->Specific.Control.InflightLibraryRequests);
336         }
337
338         AFSReleaseResource( &pDevExt->Specific.Control.LibraryStateLock);
339
340         AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
341                       AFS_TRACE_LEVEL_VERBOSE,
342                       "%s Processing queued results\n",
343                       __FUNCTION__);
344
345         AFSProcessQueuedResults( TRUE);
346
347         //
348         // Unload the current library implementation
349         //
350
351         if( pDevExt->Specific.Control.LibraryFileObject != NULL)
352         {
353             ObDereferenceObject( pDevExt->Specific.Control.LibraryFileObject);
354         }
355
356         pDevExt->Specific.Control.LibraryFileObject = NULL;
357
358         pDevExt->Specific.Control.LibraryDeviceObject = NULL;
359
360         ZwUnloadDriver( &pDevExt->Specific.Control.LibraryServicePath);
361
362         ExFreePool( pDevExt->Specific.Control.LibraryServicePath.Buffer);
363
364         pDevExt->Specific.Control.LibraryServicePath.Length = 0;
365
366         pDevExt->Specific.Control.LibraryServicePath.MaximumLength = 0;
367
368         pDevExt->Specific.Control.LibraryServicePath.Buffer = NULL;
369
370 try_exit:
371
372         AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
373                       AFS_TRACE_LEVEL_VERBOSE,
374                       "%s Library unload complete Status %08lX\n",
375                       __FUNCTION__,
376                       ntStatus);
377
378         KeSetEvent( &pDevExt->Specific.Control.LoadLibraryEvent,
379                     0,
380                     FALSE);
381     }
382
383     return ntStatus;
384 }
385
386 NTSTATUS
387 AFSCheckLibraryState( IN PIRP Irp)
388 {
389
390     NTSTATUS ntStatus = STATUS_SUCCESS;
391     AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
392     AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
393     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
394
395     __Enter
396     {
397
398         AFSAcquireShared( &pDevExt->Specific.Control.LibraryStateLock,
399                           TRUE);
400
401         AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
402                       AFS_TRACE_LEVEL_VERBOSE,
403                       "%s Entry State %08lX Irp %p Function %08lX\n",
404                       __FUNCTION__,
405                       pRDRDevExt->DeviceFlags,
406                       Irp,
407                       pIrpSp->MajorFunction);
408
409         if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
410         {
411
412             try_return( ntStatus = STATUS_DEVICE_NOT_READY);
413         }
414
415         if( !BooleanFlagOn( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED))
416         {
417
418             if( Irp != NULL)
419             {
420
421                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
422                               AFS_TRACE_LEVEL_VERBOSE,
423                               "%s Queuing request %p\n",
424                               __FUNCTION__,
425                               Irp);
426
427                 ntStatus = AFSQueueLibraryRequest( Irp);
428
429                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
430                               AFS_TRACE_LEVEL_VERBOSE,
431                               "%s Queued request %p Status %08lX\n",
432                               __FUNCTION__,
433                               Irp,
434                               ntStatus);
435             }
436             else
437             {
438
439                 ntStatus = STATUS_TOO_LATE;
440
441                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
442                               AFS_TRACE_LEVEL_VERBOSE,
443                               "%s Failing request %p\n",
444                               __FUNCTION__,
445                               Irp);
446             }
447
448             try_return( ntStatus);
449         }
450
451         if( InterlockedIncrement( &pDevExt->Specific.Control.InflightLibraryRequests) == 1)
452         {
453             KeClearEvent( &pDevExt->Specific.Control.InflightLibraryEvent);
454         }
455
456 try_exit:
457
458         AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
459                       AFS_TRACE_LEVEL_VERBOSE,
460                       "%s Completed Irp %p Status %08lX Inflight Count %08lX\n",
461                       __FUNCTION__,
462                       Irp,
463                       ntStatus,
464                       pDevExt->Specific.Control.InflightLibraryRequests);
465
466         AFSReleaseResource( &pDevExt->Specific.Control.LibraryStateLock);
467     }
468
469     return ntStatus;
470 }
471
472 NTSTATUS
473 AFSClearLibraryRequest()
474 {
475
476     NTSTATUS ntStatus = STATUS_SUCCESS;
477     AFSDeviceExt       *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
478
479     __Enter
480     {
481         AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
482                       AFS_TRACE_LEVEL_VERBOSE,
483                       "%s Inflight Count %08lX\n",
484                       __FUNCTION__,
485                       pDevExt->Specific.Control.InflightLibraryRequests);
486
487         if( InterlockedDecrement( &pDevExt->Specific.Control.InflightLibraryRequests) == 0)
488         {
489
490             KeSetEvent( &pDevExt->Specific.Control.InflightLibraryEvent,
491                         0,
492                         FALSE);
493         }
494
495     }
496
497     return ntStatus;
498 }
499
500 NTSTATUS
501 AFSQueueLibraryRequest( IN PIRP Irp)
502 {
503
504     NTSTATUS ntStatus = STATUS_SUCCESS;
505     AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
506     AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
507     AFSLibraryQueueRequestCB *pRequest = NULL;
508     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
509
510     __Enter
511     {
512
513         AFSAcquireExcl( &pDevExt->Specific.Control.LibraryQueueLock,
514                         TRUE);
515
516         AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
517                       AFS_TRACE_LEVEL_VERBOSE,
518                       "%s Entry for Irp %p Function %08lX\n",
519                       __FUNCTION__,
520                       Irp,
521                       pIrpSp->MajorFunction);
522
523         //
524         // Has the load processing timed out and we are no longer
525         // queuing requests?
526         //
527
528         if( BooleanFlagOn( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_QUEUE_CANCELLED) ||
529             BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
530         {
531
532             AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
533                           AFS_TRACE_LEVEL_ERROR,
534                           "%s Library not loaded for Irp %p\n",
535                           __FUNCTION__,
536                           Irp);
537
538             try_return( ntStatus = STATUS_DEVICE_NOT_READY);
539         }
540
541         pRequest = (AFSLibraryQueueRequestCB *)AFSExAllocatePoolWithTag( PagedPool,
542                                                                          sizeof( AFSLibraryQueueRequestCB),
543                                                                          AFS_LIBRARY_QUEUE_TAG);
544
545         if( pRequest == NULL)
546         {
547             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
548         }
549
550         RtlZeroMemory( pRequest,
551                        sizeof( AFSLibraryQueueRequestCB));
552
553         pRequest->Irp = Irp;
554
555         if( pDevExt->Specific.Control.LibraryQueueHead == NULL)
556         {
557             pDevExt->Specific.Control.LibraryQueueHead = pRequest;
558         }
559         else
560         {
561             pDevExt->Specific.Control.LibraryQueueTail->fLink = pRequest;
562         }
563
564         pDevExt->Specific.Control.LibraryQueueTail = pRequest;
565
566         IoMarkIrpPending( Irp);
567
568         ntStatus = STATUS_PENDING;
569
570 try_exit:
571
572         AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
573                       AFS_TRACE_LEVEL_VERBOSE,
574                       "%s Completed for Irp %p Status %08lX\n",
575                       __FUNCTION__,
576                       Irp,
577                       ntStatus);
578
579         AFSReleaseResource( &pDevExt->Specific.Control.LibraryQueueLock);
580     }
581
582     return ntStatus;
583 }
584
585 NTSTATUS
586 AFSProcessQueuedResults( IN BOOLEAN CancelRequest)
587 {
588
589     NTSTATUS ntStatus = STATUS_SUCCESS;
590     AFSLibraryQueueRequestCB *pRequest = NULL;
591     AFSDeviceExt       *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
592
593     __Enter
594     {
595
596         AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
597                       AFS_TRACE_LEVEL_VERBOSE,
598                       "%s Entry\n",
599                       __FUNCTION__);
600
601         //
602         // Loop through the queue either resubmitting requests or cancelling them
603         //
604
605         while( TRUE)
606         {
607
608             AFSAcquireExcl( &pDevExt->Specific.Control.LibraryQueueLock,
609                             TRUE);
610
611             if( pDevExt->Specific.Control.LibraryQueueHead == NULL)
612             {
613
614                 AFSReleaseResource( &pDevExt->Specific.Control.LibraryQueueLock);
615
616                 break;
617             }
618
619             pRequest = pDevExt->Specific.Control.LibraryQueueHead;
620
621             pDevExt->Specific.Control.LibraryQueueHead = pRequest->fLink;
622
623             if( pDevExt->Specific.Control.LibraryQueueHead == NULL)
624             {
625
626                 pDevExt->Specific.Control.LibraryQueueTail = NULL;
627             }
628
629             AFSReleaseResource( &pDevExt->Specific.Control.LibraryQueueLock);
630
631             if( CancelRequest)
632             {
633
634                 pRequest->Irp->IoStatus.Status = STATUS_CANCELLED;
635
636                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
637                               AFS_TRACE_LEVEL_VERBOSE,
638                               "%s Cancelling request Irp %p\n",
639                               __FUNCTION__,
640                               pRequest->Irp);
641
642                 IoCompleteRequest( pRequest->Irp,
643                                    IO_NO_INCREMENT);
644             }
645             else
646             {
647
648                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
649                               AFS_TRACE_LEVEL_VERBOSE,
650                               "%s Resubmitting request Irp %p\n",
651                               __FUNCTION__,
652                               pRequest->Irp);
653
654                 AFSSubmitLibraryRequest( pRequest->Irp);
655             }
656
657             ExFreePool( pRequest);
658         }
659
660         AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
661                       AFS_TRACE_LEVEL_VERBOSE,
662                       "%s Completed\n",
663                       __FUNCTION__);
664     }
665
666     return ntStatus;
667 }
668
669 NTSTATUS
670 AFSSubmitLibraryRequest( IN PIRP Irp)
671 {
672
673     NTSTATUS ntStatus = STATUS_SUCCESS;
674     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
675
676     __Enter
677     {
678
679         AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY,
680                       AFS_TRACE_LEVEL_VERBOSE,
681                       "%s Submitting Irp %p Function %08lX\n",
682                       __FUNCTION__,
683                       Irp,
684                       pIrpSp->MajorFunction);
685
686         switch( pIrpSp->MajorFunction)
687         {
688
689             case IRP_MJ_CREATE:
690             {
691                 AFSCreate( AFSRDRDeviceObject,
692                            Irp);
693                 break;
694             }
695
696             case IRP_MJ_CLOSE:
697             {
698                 AFSClose( AFSRDRDeviceObject,
699                           Irp);
700                 break;
701             }
702
703             case IRP_MJ_READ:
704             {
705                 AFSRead( AFSRDRDeviceObject,
706                          Irp);
707                 break;
708             }
709
710             case IRP_MJ_WRITE:
711             {
712                 AFSWrite( AFSRDRDeviceObject,
713                           Irp);
714                 break;
715             }
716
717             case IRP_MJ_QUERY_INFORMATION:
718             {
719                 AFSQueryFileInfo( AFSRDRDeviceObject,
720                                   Irp);
721                 break;
722             }
723
724             case IRP_MJ_SET_INFORMATION:
725             {
726                 AFSSetFileInfo( AFSRDRDeviceObject,
727                                 Irp);
728                 break;
729             }
730
731             case IRP_MJ_QUERY_EA:
732             {
733                 AFSQueryEA( AFSRDRDeviceObject,
734                             Irp);
735                 break;
736             }
737
738             case IRP_MJ_SET_EA:
739             {
740                 AFSSetEA( AFSRDRDeviceObject,
741                           Irp);
742                 break;
743             }
744
745             case IRP_MJ_FLUSH_BUFFERS:
746             {
747                 AFSFlushBuffers( AFSRDRDeviceObject,
748                                  Irp);
749                 break;
750             }
751
752             case IRP_MJ_QUERY_VOLUME_INFORMATION:
753             {
754                 AFSQueryVolumeInfo( AFSRDRDeviceObject,
755                                     Irp);
756                 break;
757             }
758
759             case IRP_MJ_SET_VOLUME_INFORMATION:
760             {
761                 AFSSetVolumeInfo( AFSRDRDeviceObject,
762                                   Irp);
763                 break;
764             }
765
766             case IRP_MJ_DIRECTORY_CONTROL:
767             {
768                 AFSDirControl( AFSRDRDeviceObject,
769                                Irp);
770                 break;
771             }
772
773             case IRP_MJ_FILE_SYSTEM_CONTROL:
774             {
775                 AFSFSControl( AFSRDRDeviceObject,
776                               Irp);
777                 break;
778             }
779
780             case IRP_MJ_DEVICE_CONTROL:
781             {
782                 AFSDevControl( AFSRDRDeviceObject,
783                                Irp);
784                 break;
785             }
786
787             case IRP_MJ_INTERNAL_DEVICE_CONTROL:
788             {
789                 AFSInternalDevControl( AFSRDRDeviceObject,
790                                        Irp);
791                 break;
792             }
793
794             case IRP_MJ_SHUTDOWN:
795             {
796                 AFSShutdown( AFSRDRDeviceObject,
797                              Irp);
798                 break;
799             }
800
801             case IRP_MJ_LOCK_CONTROL:
802             {
803                 AFSLockControl( AFSRDRDeviceObject,
804                                 Irp);
805                 break;
806             }
807
808             case IRP_MJ_CLEANUP:
809             {
810                 AFSCleanup( AFSRDRDeviceObject,
811                             Irp);
812                 break;
813             }
814
815             case IRP_MJ_QUERY_SECURITY:
816             {
817                 AFSQuerySecurity( AFSRDRDeviceObject,
818                                   Irp);
819                 break;
820             }
821
822             case IRP_MJ_SET_SECURITY:
823             {
824                 AFSSetSecurity( AFSRDRDeviceObject,
825                                 Irp);
826                 break;
827             }
828
829             case IRP_MJ_SYSTEM_CONTROL:
830             {
831                 AFSSystemControl( AFSRDRDeviceObject,
832                                   Irp);
833                 break;
834             }
835
836             default:
837             {
838                 AFSDefaultDispatch( AFSRDRDeviceObject,
839                                     Irp);
840                 break;
841             }
842         }
843     }
844
845     return ntStatus;
846 }
847
848 NTSTATUS
849 AFSInitializeLibrary( IN AFSFileID *GlobalRootFid,
850                       IN BOOLEAN QueueRootEnumeration)
851 {
852     UNREFERENCED_PARAMETER(QueueRootEnumeration);
853
854     NTSTATUS ntStatus = STATUS_SUCCESS;
855     AFSLibraryInitCB    stInitLib;
856     AFSDeviceExt       *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
857     AFSDeviceExt       *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
858
859     __Enter
860     {
861
862         RtlZeroMemory( &stInitLib,
863                        sizeof( AFSLibraryInitCB));
864
865         //
866         // Initialize the parameters to pass to the library
867         //
868
869         stInitLib.AFSControlDeviceObject = AFSDeviceObject;
870
871         stInitLib.AFSRDRDeviceObject = AFSRDRDeviceObject;
872
873         stInitLib.AFSServerName = AFSServerName;
874
875         stInitLib.AFSMountRootName = AFSMountRootName;
876
877         stInitLib.AFSDebugFlags = AFSDebugFlags;
878
879         if( GlobalRootFid != NULL)
880         {
881             stInitLib.GlobalRootFid = *GlobalRootFid;
882         }
883
884         stInitLib.AFSCacheManagerCallbacks = &AFSCacheManagerCallbacks;
885
886         stInitLib.AFSCacheBaseAddress = pRDRDevExt->Specific.RDR.CacheBaseAddress;
887
888         stInitLib.AFSCacheLength = pRDRDevExt->Specific.RDR.CacheLength;
889
890         //
891         // Initialize the callback functions for the library
892         //
893
894         stInitLib.AFSProcessRequest = AFSProcessRequest;
895
896         stInitLib.AFSDbgLogMsg = AFSDbgLogMsg;
897
898         stInitLib.AFSAddConnectionEx = AFSAddConnectionEx;
899
900         stInitLib.AFSExAllocatePoolWithTag = AFSExAllocatePoolWithTag;
901
902         stInitLib.AFSExFreePoolWithTag = AFSExFreePoolWithTag;
903
904         stInitLib.AFSDumpTraceFiles = AFSDumpTraceFiles;
905
906         stInitLib.AFSRetrieveAuthGroup = AFSRetrieveAuthGroup;
907
908         ntStatus = AFSSendDeviceIoControl( pDevExt->Specific.Control.LibraryDeviceObject,
909                                            IOCTL_AFS_INITIALIZE_LIBRARY_DEVICE,
910                                            &stInitLib,
911                                            sizeof( AFSLibraryInitCB),
912                                            NULL,
913                                            0,
914                                            NULL);
915
916         if ( !NT_SUCCESS( ntStatus))
917         {
918
919             AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
920                           AFS_TRACE_LEVEL_ERROR,
921                           "AFSInitializeLibrary AFSSendDeviceIoControl failure %08lX\n",
922                           ntStatus);
923         }
924     }
925
926     return ntStatus;
927 }