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