Windows: FileNetworkPhysicalNameInfo implementation
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSFileInfo.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: AFSFileInfo.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 //
42 // Function: AFSQueryFileInfo
43 //
44 // Description:
45 //
46 //      This function is the dispatch handler for the IRP_MJ_QUERY_FILE_INFORMATION request
47 //
48 // Return:
49 //
50 //      A status is returned for the function
51 //
52
53 NTSTATUS
54 AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
55                   IN PIRP Irp)
56 {
57
58     NTSTATUS ntStatus = STATUS_SUCCESS;
59     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
60     ULONG ulRequestType = 0;
61     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
62     AFSFcb *pFcb = NULL;
63     AFSCcb *pCcb = NULL;
64     PFILE_OBJECT pFileObject;
65     BOOLEAN bReleaseMain = FALSE;
66     LONG lLength;
67     FILE_INFORMATION_CLASS stFileInformationClass;
68     PVOID pBuffer;
69
70     __try
71     {
72
73         //
74         // Determine the type of request this request is
75         //
76
77         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
78
79         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
80
81         if( pFcb == NULL)
82         {
83
84             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
85                           AFS_TRACE_LEVEL_ERROR,
86                           "AFSQueryFileInfo Attempted access (%08lX) when pFcb == NULL\n",
87                           Irp);
88
89             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
90         }
91
92         lLength = (LONG)pIrpSp->Parameters.QueryFile.Length;
93         stFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
94         pBuffer = Irp->AssociatedIrp.SystemBuffer;
95
96         //
97         // Grab the main shared right off the bat
98         //
99
100         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
101                       AFS_TRACE_LEVEL_VERBOSE,
102                       "AFSQueryFileInfo Acquiring Fcb lock %08lX SHARED %08lX\n",
103                       &pFcb->NPFcb->Resource,
104                       PsGetCurrentThread());
105
106         AFSAcquireShared( &pFcb->NPFcb->Resource,
107                           TRUE);
108
109         bReleaseMain = TRUE;
110
111         //
112         // Don't allow requests against IOCtl nodes
113         //
114
115         if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
116         {
117
118             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
119                           AFS_TRACE_LEVEL_VERBOSE,
120                           "AFSQueryFileInfo Processing request against SpecialShare Fcb\n");
121
122             ntStatus = AFSProcessShareQueryInfo( Irp,
123                                                  pFcb,
124                                                  pCcb);
125
126             try_return( ntStatus);
127         }
128         else if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
129         {
130             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
131                           AFS_TRACE_LEVEL_VERBOSE,
132                           "AFSQueryFileInfo request against PIOCtl Fcb\n");
133
134             ntStatus = AFSProcessPIOCtlQueryInfo( Irp,
135                                                   pFcb,
136                                                   pCcb,
137                                                   &lLength);
138
139             try_return( ntStatus);
140         }
141
142         //
143         // Process the request
144         //
145
146         switch( stFileInformationClass)
147         {
148
149             case FileAllInformation:
150             {
151
152                 PFILE_ALL_INFORMATION pAllInfo;
153
154                 //
155                 //  For the all information class we'll typecast a local
156                 //  pointer to the output buffer and then call the
157                 //  individual routines to fill in the buffer.
158                 //
159
160                 pAllInfo = (PFILE_ALL_INFORMATION)pBuffer;
161
162                 ntStatus = AFSQueryBasicInfo( Irp,
163                                               pCcb->DirectoryCB,
164                                               &pAllInfo->BasicInformation,
165                                               &lLength);
166
167                 if( !NT_SUCCESS( ntStatus))
168                 {
169
170                     try_return( ntStatus);
171                 }
172
173                 ntStatus = AFSQueryStandardInfo( Irp,
174                                                  pCcb->DirectoryCB,
175                                                  &pAllInfo->StandardInformation,
176                                                  &lLength);
177
178                 if( !NT_SUCCESS( ntStatus))
179                 {
180
181                     try_return( ntStatus);
182                 }
183
184                 ntStatus = AFSQueryInternalInfo( Irp,
185                                                  pFcb,
186                                                  &pAllInfo->InternalInformation,
187                                                  &lLength);
188
189                 if( !NT_SUCCESS( ntStatus))
190                 {
191
192                     try_return( ntStatus);
193                 }
194
195                 ntStatus = AFSQueryEaInfo( Irp,
196                                            pCcb->DirectoryCB,
197                                            &pAllInfo->EaInformation,
198                                            &lLength);
199
200                 if( !NT_SUCCESS( ntStatus))
201                 {
202
203                     try_return( ntStatus);
204                 }
205
206                 ntStatus = AFSQueryAccess( Irp,
207                                            pFcb,
208                                            &pAllInfo->AccessInformation,
209                                            &lLength);
210
211                 if( !NT_SUCCESS( ntStatus))
212                 {
213
214                     try_return( ntStatus);
215                 }
216
217                 ntStatus = AFSQueryPositionInfo( Irp,
218                                                  pFcb,
219                                                  &pAllInfo->PositionInformation,
220                                                  &lLength);
221
222                 if( !NT_SUCCESS( ntStatus))
223                 {
224
225                     try_return( ntStatus);
226                 }
227
228                 ntStatus = AFSQueryMode( Irp,
229                                          pFcb,
230                                          &pAllInfo->ModeInformation,
231                                          &lLength);
232
233                 if( !NT_SUCCESS( ntStatus))
234                 {
235
236                     try_return( ntStatus);
237                 }
238
239                 ntStatus = AFSQueryAlignment( Irp,
240                                               pFcb,
241                                               &pAllInfo->AlignmentInformation,
242                                               &lLength);
243
244                 if( !NT_SUCCESS( ntStatus))
245                 {
246
247                     try_return( ntStatus);
248                 }
249
250                 ntStatus = AFSQueryNameInfo( Irp,
251                                              pCcb->DirectoryCB,
252                                              &pAllInfo->NameInformation,
253                                              &lLength);
254
255                 if( !NT_SUCCESS( ntStatus))
256                 {
257
258                     try_return( ntStatus);
259                 }
260
261                 break;
262             }
263
264             case FileBasicInformation:
265             {
266
267                 ntStatus = AFSQueryBasicInfo( Irp,
268                                               pCcb->DirectoryCB,
269                                               (PFILE_BASIC_INFORMATION)pBuffer,
270                                               &lLength);
271
272                 break;
273             }
274
275             case FileStandardInformation:
276             {
277
278                 ntStatus = AFSQueryStandardInfo( Irp,
279                                                  pCcb->DirectoryCB,
280                                                  (PFILE_STANDARD_INFORMATION)pBuffer,
281                                                  &lLength);
282
283                 break;
284             }
285
286             case FileInternalInformation:
287             {
288
289                 ntStatus = AFSQueryInternalInfo( Irp,
290                                                  pFcb,
291                                                  (PFILE_INTERNAL_INFORMATION)pBuffer,
292                                                  &lLength);
293
294                 break;
295             }
296
297             case FileEaInformation:
298             {
299
300                 ntStatus = AFSQueryEaInfo( Irp,
301                                            pCcb->DirectoryCB,
302                                            (PFILE_EA_INFORMATION)pBuffer,
303                                            &lLength);
304
305                 break;
306             }
307
308             case FilePositionInformation:
309             {
310
311                 ntStatus = AFSQueryPositionInfo( Irp,
312                                       pFcb,
313                                       (PFILE_POSITION_INFORMATION)pBuffer,
314                                       &lLength);
315
316                 break;
317             }
318
319             case FileNameInformation:
320             {
321
322                 ntStatus = AFSQueryNameInfo( Irp,
323                                   pCcb->DirectoryCB,
324                                   (PFILE_NAME_INFORMATION)pBuffer,
325                                   &lLength);
326
327                 break;
328             }
329
330             case FileAlternateNameInformation:
331             {
332
333                 ntStatus = AFSQueryShortNameInfo( Irp,
334                                        pCcb->DirectoryCB,
335                                        (PFILE_NAME_INFORMATION)pBuffer,
336                                        &lLength);
337
338                 break;
339             }
340
341             case FileNetworkOpenInformation:
342             {
343
344                 ntStatus = AFSQueryNetworkInfo( Irp,
345                                      pCcb->DirectoryCB,
346                                      (PFILE_NETWORK_OPEN_INFORMATION)pBuffer,
347                                      &lLength);
348
349                 break;
350             }
351
352             case FileStreamInformation:
353             {
354
355                 ntStatus = AFSQueryStreamInfo( Irp,
356                                                pCcb->DirectoryCB,
357                                                (FILE_STREAM_INFORMATION *)pBuffer,
358                                                &lLength);
359
360                 break;
361             }
362
363
364             case FileAttributeTagInformation:
365             {
366
367                 ntStatus = AFSQueryAttribTagInfo( Irp,
368                                                   pCcb->DirectoryCB,
369                                                   (FILE_ATTRIBUTE_TAG_INFORMATION *)pBuffer,
370                                                   &lLength);
371
372                 break;
373             }
374
375             case FileRemoteProtocolInformation:
376             {
377
378                     ntStatus = AFSQueryRemoteProtocolInfo( Irp,
379                                                            pCcb->DirectoryCB,
380                                                            (FILE_REMOTE_PROTOCOL_INFORMATION *)pBuffer,
381                                                            &lLength);
382
383                 break;
384             }
385
386             case FileNetworkPhysicalNameInformation:
387             {
388
389                 ntStatus = AFSQueryPhysicalNameInfo( Irp,
390                                                      pCcb->DirectoryCB,
391                                                      (FILE_NETWORK_PHYSICAL_NAME_INFORMATION *)pBuffer,
392                                                      &lLength);
393
394                 break;
395             }
396
397             default:
398             {
399                 ntStatus = STATUS_INVALID_PARAMETER;
400                 break;
401             }
402         }
403
404 try_exit:
405
406         Irp->IoStatus.Information = pIrpSp->Parameters.QueryFile.Length - lLength;
407
408         if( bReleaseMain)
409         {
410
411             AFSReleaseResource( &pFcb->NPFcb->Resource);
412         }
413
414         if( !NT_SUCCESS( ntStatus) &&
415             ntStatus != STATUS_INVALID_PARAMETER &&
416             ntStatus != STATUS_BUFFER_OVERFLOW)
417         {
418
419             if( pCcb != NULL &&
420                 pCcb->DirectoryCB != NULL)
421             {
422
423                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
424                               AFS_TRACE_LEVEL_ERROR,
425                               "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
426                               &pCcb->DirectoryCB->NameInformation.FileName,
427                               pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
428                               pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
429                               pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
430                               pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
431                               ntStatus);
432             }
433         }
434     }
435     __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
436     {
437
438         AFSDbgLogMsg( 0,
439                       0,
440                       "EXCEPTION - AFSQueryFileInfo\n");
441
442         ntStatus = STATUS_UNSUCCESSFUL;
443
444         if( bReleaseMain)
445         {
446
447             AFSReleaseResource( &pFcb->NPFcb->Resource);
448         }
449     }
450
451     AFSCompleteRequest( Irp,
452                         ntStatus);
453
454     return ntStatus;
455 }
456
457 //
458 // Function: AFSSetFileInfo
459 //
460 // Description:
461 //
462 //      This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request
463 //
464 // Return:
465 //
466 //      A status is returned for the function
467 //
468
469 NTSTATUS
470 AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
471                 IN PIRP Irp)
472 {
473
474     NTSTATUS ntStatus = STATUS_SUCCESS;
475     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
476     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
477     AFSFcb *pFcb = NULL;
478     AFSCcb *pCcb = NULL;
479     BOOLEAN bCompleteRequest = TRUE;
480     FILE_INFORMATION_CLASS FileInformationClass;
481     BOOLEAN bCanQueueRequest = FALSE;
482     PFILE_OBJECT pFileObject = NULL;
483     BOOLEAN bReleaseMain = FALSE;
484     BOOLEAN bUpdateFileInfo = FALSE;
485     AFSFileID stParentFileId;
486
487     __try
488     {
489
490         pFileObject = pIrpSp->FileObject;
491
492         pFcb = (AFSFcb *)pFileObject->FsContext;
493         pCcb = (AFSCcb *)pFileObject->FsContext2;
494
495         if( pFcb == NULL)
496         {
497
498             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
499                           AFS_TRACE_LEVEL_ERROR,
500                           "AFSSetFileInfo Attempted access (%08lX) when pFcb == NULL\n",
501                           Irp);
502
503             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
504         }
505
506         bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
507         FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
508
509         //
510         // Grab the Fcb EXCL
511         //
512
513         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
514                       AFS_TRACE_LEVEL_VERBOSE,
515                       "AFSSetFileInfo Acquiring Fcb lock %08lX EXCL %08lX\n",
516                       &pFcb->NPFcb->Resource,
517                       PsGetCurrentThread());
518
519         AFSAcquireExcl( &pFcb->NPFcb->Resource,
520                         TRUE);
521
522         bReleaseMain = TRUE;
523
524         //
525         // Don't allow requests against IOCtl nodes
526         //
527
528         if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
529         {
530
531             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
532                           AFS_TRACE_LEVEL_ERROR,
533                           "AFSSetFileInfo Failing request against PIOCtl Fcb\n");
534
535             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
536         }
537         else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
538         {
539
540             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
541                           AFS_TRACE_LEVEL_VERBOSE,
542                           "AFSSetFileInfo Processing request against SpecialShare Fcb\n");
543
544             ntStatus = AFSProcessShareSetInfo( Irp,
545                                                pFcb,
546                                                pCcb);
547
548             try_return( ntStatus);
549         }
550
551         if( BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
552         {
553
554             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
555                           AFS_TRACE_LEVEL_ERROR,
556                           "AFSSetFileInfo Request failed due to read only volume\n",
557                           Irp);
558
559             try_return( ntStatus = STATUS_ACCESS_DENIED);
560         }
561
562         //
563         // Ensure rename operations are synchronous
564         //
565
566         if( FileInformationClass == FileRenameInformation)
567         {
568
569             bCanQueueRequest = FALSE;
570         }
571
572         //
573         // Store away the parent fid
574         //
575
576         RtlZeroMemory( &stParentFileId,
577                        sizeof( AFSFileID));
578
579         if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
580         {
581             stParentFileId = pFcb->ObjectInformation->ParentObjectInformation->FileId;
582         }
583
584         //
585         // Process the request
586         //
587
588         switch( FileInformationClass)
589         {
590
591             case FileBasicInformation:
592             {
593
594                 bUpdateFileInfo = TRUE;
595
596                 ntStatus = AFSSetBasicInfo( Irp,
597                                             pCcb->DirectoryCB);
598
599                 break;
600             }
601
602             case FileDispositionInformation:
603             {
604
605                 ntStatus = AFSSetDispositionInfo( Irp,
606                                                   pCcb->DirectoryCB);
607
608                 break;
609             }
610
611             case FileRenameInformation:
612             {
613
614                 ntStatus = AFSSetRenameInfo( Irp);
615
616                 break;
617             }
618
619             case FilePositionInformation:
620             {
621
622                 ntStatus = AFSSetPositionInfo( Irp,
623                                                pCcb->DirectoryCB);
624
625                 break;
626             }
627
628             case FileLinkInformation:
629             {
630
631                 ntStatus = STATUS_INVALID_DEVICE_REQUEST;
632
633                 break;
634             }
635
636             case FileAllocationInformation:
637             {
638
639                 ntStatus = AFSSetAllocationInfo( Irp,
640                                                  pCcb->DirectoryCB);
641
642                 break;
643             }
644
645             case FileEndOfFileInformation:
646             {
647
648                 ntStatus = AFSSetEndOfFileInfo( Irp,
649                                                 pCcb->DirectoryCB);
650
651                 break;
652             }
653
654             default:
655
656                 ntStatus = STATUS_INVALID_PARAMETER;
657
658                 break;
659         }
660
661 try_exit:
662
663         if( bReleaseMain)
664         {
665
666             AFSReleaseResource( &pFcb->NPFcb->Resource);
667         }
668
669         if( NT_SUCCESS( ntStatus) &&
670             bUpdateFileInfo)
671         {
672
673             ntStatus = AFSUpdateFileInformation( &stParentFileId,
674                                                  pFcb->ObjectInformation,
675                                                  &pFcb->AuthGroup);
676
677             if( !NT_SUCCESS( ntStatus))
678             {
679
680                 AFSAcquireExcl( &pFcb->NPFcb->Resource,
681                                 TRUE);
682
683                 //
684                 // Unwind the update and fail the request
685                 //
686
687                 AFSUnwindFileInfo( pFcb,
688                                    pCcb);
689
690                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
691                               AFS_TRACE_LEVEL_ERROR,
692                               "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
693                               &pCcb->DirectoryCB->NameInformation.FileName,
694                               pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
695                               pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
696                               pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
697                               pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
698                               ntStatus);
699
700                 AFSReleaseResource( &pFcb->NPFcb->Resource);
701             }
702         }
703
704         if( !NT_SUCCESS( ntStatus))
705         {
706
707             if( pCcb != NULL &&
708                 pCcb->DirectoryCB != NULL)
709             {
710
711                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
712                               AFS_TRACE_LEVEL_ERROR,
713                               "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
714                               &pCcb->DirectoryCB->NameInformation.FileName,
715                               pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
716                               pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
717                               pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
718                               pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
719                               ntStatus);
720             }
721         }
722     }
723     __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
724     {
725
726         AFSDbgLogMsg( 0,
727                       0,
728                       "EXCEPTION - AFSSetFileInfo\n");
729
730         ntStatus = STATUS_UNSUCCESSFUL;
731     }
732
733     AFSCompleteRequest( Irp,
734                         ntStatus);
735
736     return ntStatus;
737 }
738
739 //
740 // Function: AFSQueryBasicInfo
741 //
742 // Description:
743 //
744 //      This function is the handler for the query basic information request
745 //
746 // Return:
747 //
748 //      A status is returned for the function
749 //
750
751 NTSTATUS
752 AFSQueryBasicInfo( IN PIRP Irp,
753                    IN AFSDirectoryCB *DirectoryCB,
754                    IN OUT PFILE_BASIC_INFORMATION Buffer,
755                    IN OUT PLONG Length)
756 {
757     NTSTATUS ntStatus = STATUS_SUCCESS;
758     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
759     ULONG ulFileAttribs = 0;
760     AFSFcb *pFcb = NULL;
761     AFSCcb *pCcb = NULL;
762     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
763     AFSFileInfoCB stFileInfo;
764     AFSDirectoryCB *pParentDirectoryCB = NULL;
765     UNICODE_STRING uniParentPath;
766
767     if( *Length >= sizeof( FILE_BASIC_INFORMATION))
768     {
769
770         RtlZeroMemory( Buffer,
771                        *Length);
772
773         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
774
775         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
776         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
777
778         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
779         {
780
781             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
782
783             AFSRetrieveParentPath( &pCcb->FullFileName,
784                                    &uniParentPath);
785
786             RtlZeroMemory( &stFileInfo,
787                            sizeof( AFSFileInfoCB));
788
789             //
790             // Can't hold the Fcb while evaluating the path, leads to lock inversion
791             //
792
793             AFSReleaseResource( &pFcb->NPFcb->Resource);
794
795             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
796                                                        DirectoryCB,
797                                                        &uniParentPath,
798                                                        NULL,
799                                                        &stFileInfo)))
800             {
801                 ulFileAttribs = stFileInfo.FileAttributes;
802
803                 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
804             }
805
806             AFSAcquireShared( &pFcb->NPFcb->Resource,
807                               TRUE);
808         }
809
810         Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
811         Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
812         Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
813         Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
814         Buffer->FileAttributes = ulFileAttribs;
815
816         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
817             BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
818         {
819
820             if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
821             {
822                 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
823             }
824             else
825             {
826                 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
827             }
828         }
829
830         *Length -= sizeof( FILE_BASIC_INFORMATION);
831     }
832     else
833     {
834
835         ntStatus = STATUS_BUFFER_TOO_SMALL;
836     }
837
838     return ntStatus;
839 }
840
841 NTSTATUS
842 AFSQueryStandardInfo( IN PIRP Irp,
843                       IN AFSDirectoryCB *DirectoryCB,
844                       IN OUT PFILE_STANDARD_INFORMATION Buffer,
845                       IN OUT PLONG Length)
846 {
847
848     NTSTATUS ntStatus = STATUS_SUCCESS;
849     AFSFcb *pFcb = NULL;
850     AFSCcb *pCcb = NULL;
851     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
852     AFSFileInfoCB stFileInfo;
853     AFSDirectoryCB *pParentDirectoryCB = NULL;
854     UNICODE_STRING uniParentPath;
855     ULONG ulFileAttribs = 0;
856
857     if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
858     {
859
860         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
861         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
862
863         RtlZeroMemory( Buffer,
864                        *Length);
865
866         Buffer->NumberOfLinks = 1;
867         Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
868
869         Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
870
871         Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
872
873         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
874
875         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
876         {
877
878             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
879
880             AFSRetrieveParentPath( &pCcb->FullFileName,
881                                    &uniParentPath);
882
883             RtlZeroMemory( &stFileInfo,
884                            sizeof( AFSFileInfoCB));
885
886             //
887             // Can't hold the Fcb while evaluating the path, leads to lock inversion
888             //
889
890             AFSReleaseResource( &pFcb->NPFcb->Resource);
891
892             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
893                                                        DirectoryCB,
894                                                        &uniParentPath,
895                                                        NULL,
896                                                        &stFileInfo)))
897             {
898                 ulFileAttribs = stFileInfo.FileAttributes;
899             }
900
901             AFSAcquireShared( &pFcb->NPFcb->Resource,
902                               TRUE);
903         }
904
905         Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
906
907         *Length -= sizeof( FILE_STANDARD_INFORMATION);
908     }
909     else
910     {
911
912         ntStatus = STATUS_BUFFER_TOO_SMALL;
913     }
914
915     return ntStatus;
916 }
917
918 NTSTATUS
919 AFSQueryInternalInfo( IN PIRP Irp,
920                       IN AFSFcb *Fcb,
921                       IN OUT PFILE_INTERNAL_INFORMATION Buffer,
922                       IN OUT PLONG Length)
923 {
924
925     NTSTATUS ntStatus = STATUS_SUCCESS;
926
927     if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
928     {
929
930         Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Volume;
931
932         Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Vnode;
933
934         *Length -= sizeof( FILE_INTERNAL_INFORMATION);
935     }
936     else
937     {
938
939         ntStatus = STATUS_BUFFER_TOO_SMALL;
940     }
941
942     return ntStatus;
943 }
944
945 NTSTATUS
946 AFSQueryEaInfo( IN PIRP Irp,
947                 IN AFSDirectoryCB *DirectoryCB,
948                 IN OUT PFILE_EA_INFORMATION Buffer,
949                 IN OUT PLONG Length)
950 {
951
952     NTSTATUS ntStatus = STATUS_SUCCESS;
953
954     RtlZeroMemory( Buffer,
955                    *Length);
956
957     if( *Length >= sizeof( FILE_EA_INFORMATION))
958     {
959
960         Buffer->EaSize = 0;
961
962         *Length -= sizeof( FILE_EA_INFORMATION);
963     }
964     else
965     {
966
967         ntStatus = STATUS_BUFFER_TOO_SMALL;
968     }
969
970     return ntStatus;
971 }
972
973 NTSTATUS
974 AFSQueryPositionInfo( IN PIRP Irp,
975                       IN AFSFcb *Fcb,
976                       IN OUT PFILE_POSITION_INFORMATION Buffer,
977                       IN OUT PLONG Length)
978 {
979
980     NTSTATUS ntStatus = STATUS_SUCCESS;
981     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
982
983     if( *Length >= sizeof( FILE_POSITION_INFORMATION))
984     {
985
986         RtlZeroMemory( Buffer,
987                        *Length);
988
989         Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
990
991         *Length -= sizeof( FILE_POSITION_INFORMATION);
992     }
993     else
994     {
995
996         ntStatus = STATUS_BUFFER_TOO_SMALL;
997     }
998
999     return ntStatus;
1000 }
1001
1002 NTSTATUS
1003 AFSQueryAccess( IN PIRP Irp,
1004                 IN AFSFcb *Fcb,
1005                 IN OUT PFILE_ACCESS_INFORMATION Buffer,
1006                 IN OUT PLONG Length)
1007 {
1008
1009     NTSTATUS ntStatus = STATUS_SUCCESS;
1010
1011     if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
1012     {
1013
1014         RtlZeroMemory( Buffer,
1015                        *Length);
1016
1017         Buffer->AccessFlags = 0;
1018
1019         *Length -= sizeof( FILE_ACCESS_INFORMATION);
1020     }
1021     else
1022     {
1023
1024         ntStatus = STATUS_BUFFER_TOO_SMALL;
1025     }
1026
1027     return ntStatus;
1028 }
1029
1030 NTSTATUS
1031 AFSQueryMode( IN PIRP Irp,
1032               IN AFSFcb *Fcb,
1033               IN OUT PFILE_MODE_INFORMATION Buffer,
1034               IN OUT PLONG Length)
1035 {
1036
1037     NTSTATUS ntStatus = STATUS_SUCCESS;
1038
1039     if( *Length >= sizeof( FILE_MODE_INFORMATION))
1040     {
1041
1042         RtlZeroMemory( Buffer,
1043                        *Length);
1044
1045         Buffer->Mode = 0;
1046
1047         *Length -= sizeof( FILE_MODE_INFORMATION);
1048     }
1049     else
1050     {
1051
1052         ntStatus = STATUS_BUFFER_TOO_SMALL;
1053     }
1054
1055     return ntStatus;
1056 }
1057
1058 NTSTATUS
1059 AFSQueryAlignment( IN PIRP Irp,
1060                    IN AFSFcb *Fcb,
1061                    IN OUT PFILE_ALIGNMENT_INFORMATION Buffer,
1062                    IN OUT PLONG Length)
1063 {
1064
1065     NTSTATUS ntStatus = STATUS_SUCCESS;
1066
1067     if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
1068     {
1069
1070         RtlZeroMemory( Buffer,
1071                        *Length);
1072
1073         Buffer->AlignmentRequirement = 1;
1074
1075         *Length -= sizeof( FILE_ALIGNMENT_INFORMATION);
1076     }
1077     else
1078     {
1079
1080         ntStatus = STATUS_BUFFER_TOO_SMALL;
1081     }
1082
1083     return ntStatus;
1084 }
1085
1086 NTSTATUS
1087 AFSQueryNameInfo( IN PIRP Irp,
1088                   IN AFSDirectoryCB *DirectoryCB,
1089                   IN OUT PFILE_NAME_INFORMATION Buffer,
1090                   IN OUT PLONG Length)
1091 {
1092
1093     NTSTATUS ntStatus = STATUS_SUCCESS;
1094     ULONG ulCopyLength = 0;
1095     ULONG cchCopied = 0;
1096     AFSFcb *pFcb = NULL;
1097     AFSCcb *pCcb = NULL;
1098     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1099     BOOLEAN bAddLeadingSlash = FALSE;
1100     BOOLEAN bAddTrailingSlash = FALSE;
1101     USHORT usFullNameLength = 0;
1102
1103     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1104
1105     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1106
1107     if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1108     {
1109
1110         RtlZeroMemory( Buffer,
1111                        *Length);
1112
1113         if( pCcb->FullFileName.Length == 0 ||
1114             pCcb->FullFileName.Buffer[ 0] != L'\\')
1115         {
1116             bAddLeadingSlash = TRUE;
1117         }
1118
1119         if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1120             pCcb->FullFileName.Length > 0 &&
1121             pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
1122         {
1123             bAddTrailingSlash = TRUE;
1124         }
1125
1126         usFullNameLength = sizeof( WCHAR) +
1127                                     AFSServerName.Length +
1128                                     pCcb->FullFileName.Length;
1129
1130         if( bAddLeadingSlash)
1131         {
1132             usFullNameLength += sizeof( WCHAR);
1133         }
1134
1135         if( bAddTrailingSlash)
1136         {
1137             usFullNameLength += sizeof( WCHAR);
1138         }
1139
1140         if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1141         {
1142
1143             ulCopyLength = (LONG)usFullNameLength;
1144         }
1145         else
1146         {
1147
1148             ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1149
1150             ntStatus = STATUS_BUFFER_OVERFLOW;
1151         }
1152
1153         Buffer->FileNameLength = (ULONG)usFullNameLength;
1154
1155         *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1156
1157         if( ulCopyLength > 0)
1158         {
1159
1160             Buffer->FileName[ 0] = L'\\';
1161             ulCopyLength -= sizeof( WCHAR);
1162
1163             *Length -= sizeof( WCHAR);
1164             cchCopied += 1;
1165
1166             if( ulCopyLength >= AFSServerName.Length)
1167             {
1168
1169                 RtlCopyMemory( &Buffer->FileName[ 1],
1170                                AFSServerName.Buffer,
1171                                AFSServerName.Length);
1172
1173                 ulCopyLength -= AFSServerName.Length;
1174                 *Length -= AFSServerName.Length;
1175                 cchCopied += AFSServerName.Length/sizeof( WCHAR);
1176
1177                 if ( ulCopyLength > 0 &&
1178                      bAddLeadingSlash)
1179                 {
1180
1181                     Buffer->FileName[ cchCopied] = L'\\';
1182
1183                     ulCopyLength -= sizeof( WCHAR);
1184                     *Length -= sizeof( WCHAR);
1185                     cchCopied++;
1186                 }
1187
1188                 if( ulCopyLength >= pCcb->FullFileName.Length)
1189                 {
1190
1191                     RtlCopyMemory( &Buffer->FileName[ cchCopied],
1192                                    pCcb->FullFileName.Buffer,
1193                                    pCcb->FullFileName.Length);
1194
1195                     ulCopyLength -= pCcb->FullFileName.Length;
1196                     *Length -= pCcb->FullFileName.Length;
1197                     cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1198
1199                     if( ulCopyLength > 0 &&
1200                         bAddTrailingSlash)
1201                     {
1202                         Buffer->FileName[ cchCopied] = L'\\';
1203
1204                         *Length -= sizeof( WCHAR);
1205                     }
1206                 }
1207                 else
1208                 {
1209
1210                     RtlCopyMemory( &Buffer->FileName[ cchCopied],
1211                                    pCcb->FullFileName.Buffer,
1212                                    ulCopyLength);
1213
1214                     *Length -= ulCopyLength;
1215                 }
1216             }
1217         }
1218     }
1219     else
1220     {
1221
1222         ntStatus = STATUS_BUFFER_TOO_SMALL;
1223     }
1224
1225     return ntStatus;
1226 }
1227
1228 NTSTATUS
1229 AFSQueryShortNameInfo( IN PIRP Irp,
1230                        IN AFSDirectoryCB *DirectoryCB,
1231                        IN OUT PFILE_NAME_INFORMATION Buffer,
1232                        IN OUT PLONG Length)
1233 {
1234
1235     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1236     ULONG ulCopyLength = 0;
1237
1238     RtlZeroMemory( Buffer,
1239                    *Length);
1240
1241     if( DirectoryCB->NameInformation.ShortNameLength == 0)
1242     {
1243
1244         //
1245         // The short name IS the long name
1246         //
1247
1248         if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1249         {
1250
1251             if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1252             {
1253
1254                 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1255
1256                 ntStatus = STATUS_SUCCESS;
1257             }
1258             else
1259             {
1260
1261                 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1262
1263                 ntStatus = STATUS_BUFFER_OVERFLOW;
1264             }
1265
1266             Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1267
1268             *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1269
1270             if( ulCopyLength > 0)
1271             {
1272
1273                 RtlCopyMemory( Buffer->FileName,
1274                                DirectoryCB->NameInformation.FileName.Buffer,
1275                                ulCopyLength);
1276
1277                 *Length -= ulCopyLength;
1278             }
1279         }
1280     }
1281     else
1282     {
1283
1284         if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1285         {
1286
1287             if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1288             {
1289
1290                 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1291
1292                 ntStatus = STATUS_SUCCESS;
1293             }
1294             else
1295             {
1296
1297                 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1298
1299                 ntStatus = STATUS_BUFFER_OVERFLOW;
1300             }
1301
1302             Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1303
1304             *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1305
1306             if( ulCopyLength > 0)
1307             {
1308
1309                 RtlCopyMemory( Buffer->FileName,
1310                                DirectoryCB->NameInformation.ShortName,
1311                                Buffer->FileNameLength);
1312
1313                 *Length -= ulCopyLength;
1314             }
1315         }
1316     }
1317
1318     return ntStatus;
1319 }
1320
1321 NTSTATUS
1322 AFSQueryNetworkInfo( IN PIRP Irp,
1323                      IN AFSDirectoryCB *DirectoryCB,
1324                      IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1325                      IN OUT PLONG Length)
1326 {
1327
1328     NTSTATUS ntStatus = STATUS_SUCCESS;
1329     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1330     AFSFcb *pFcb = NULL;
1331     AFSCcb *pCcb = NULL;
1332     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1333     AFSFileInfoCB stFileInfo;
1334     AFSDirectoryCB *pParentDirectoryCB = NULL;
1335     UNICODE_STRING uniParentPath;
1336     ULONG ulFileAttribs = 0;
1337
1338     RtlZeroMemory( Buffer,
1339                    *Length);
1340
1341     if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
1342     {
1343
1344         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1345
1346         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1347         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1348
1349         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1350         {
1351
1352             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1353
1354             AFSRetrieveParentPath( &pCcb->FullFileName,
1355                                    &uniParentPath);
1356
1357             RtlZeroMemory( &stFileInfo,
1358                            sizeof( AFSFileInfoCB));
1359
1360             //
1361             // Can't hold the Fcb while evaluating the path, leads to lock inversion
1362             //
1363
1364             AFSReleaseResource( &pFcb->NPFcb->Resource);
1365
1366             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1367                                                        DirectoryCB,
1368                                                        &uniParentPath,
1369                                                        NULL,
1370                                                        &stFileInfo)))
1371             {
1372                 ulFileAttribs = stFileInfo.FileAttributes;
1373
1374                 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1375             }
1376
1377             AFSAcquireShared( &pFcb->NPFcb->Resource,
1378                               TRUE);
1379         }
1380
1381         Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1382         Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1383         Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1384         Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1385
1386         Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1387         Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1388
1389         Buffer->FileAttributes = ulFileAttribs;
1390
1391         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1392             BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1393         {
1394
1395             if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1396             {
1397
1398                 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1399             }
1400             else
1401             {
1402
1403                 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1404             }
1405         }
1406
1407         *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1408     }
1409     else
1410     {
1411
1412         ntStatus = STATUS_BUFFER_TOO_SMALL;
1413     }
1414
1415     return ntStatus;
1416 }
1417
1418 NTSTATUS
1419 AFSQueryStreamInfo( IN PIRP Irp,
1420                     IN AFSDirectoryCB *DirectoryCB,
1421                     IN OUT FILE_STREAM_INFORMATION *Buffer,
1422                     IN OUT PLONG Length)
1423 {
1424
1425     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1426     ULONG ulCopyLength = 0;
1427     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1428
1429     if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1430     {
1431
1432         RtlZeroMemory( Buffer,
1433                        *Length);
1434
1435         Buffer->NextEntryOffset = 0;
1436
1437
1438         if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1439         {
1440
1441             if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14))  // ::$DATA
1442             {
1443
1444                 ulCopyLength = 14;
1445
1446                 ntStatus = STATUS_SUCCESS;
1447             }
1448             else
1449             {
1450
1451                 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1452
1453                 ntStatus = STATUS_BUFFER_OVERFLOW;
1454             }
1455
1456             Buffer->StreamNameLength = 14; // ::$DATA
1457
1458             Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1459
1460             Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1461
1462             *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1463
1464             if( ulCopyLength > 0)
1465             {
1466
1467                 RtlCopyMemory( Buffer->StreamName,
1468                                L"::$DATA",
1469                                ulCopyLength);
1470
1471                 *Length -= ulCopyLength;
1472             }
1473         }
1474         else
1475         {
1476
1477             Buffer->StreamNameLength = 0;       // No stream for a directory
1478
1479             // The response size is zero
1480
1481             ntStatus = STATUS_SUCCESS;
1482         }
1483     }
1484
1485     return ntStatus;
1486 }
1487
1488 NTSTATUS
1489 AFSQueryAttribTagInfo( IN PIRP Irp,
1490                        IN AFSDirectoryCB *DirectoryCB,
1491                        IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1492                        IN OUT PLONG Length)
1493 {
1494
1495     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1496     ULONG ulCopyLength = 0;
1497     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1498     AFSFcb *pFcb = NULL;
1499     AFSCcb *pCcb = NULL;
1500     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1501     AFSFileInfoCB stFileInfo;
1502     AFSDirectoryCB *pParentDirectoryCB = NULL;
1503     UNICODE_STRING uniParentPath;
1504     ULONG ulFileAttribs = 0;
1505
1506     if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1507     {
1508
1509         RtlZeroMemory( Buffer,
1510                        *Length);
1511
1512         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1513
1514         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1515         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1516
1517         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1518         {
1519
1520             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1521
1522             AFSRetrieveParentPath( &pCcb->FullFileName,
1523                                    &uniParentPath);
1524
1525             RtlZeroMemory( &stFileInfo,
1526                            sizeof( AFSFileInfoCB));
1527
1528             //
1529             // Can't hold the Fcb while evaluating the path, leads to lock inversion
1530             //
1531
1532             AFSReleaseResource( &pFcb->NPFcb->Resource);
1533
1534             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1535                                                        DirectoryCB,
1536                                                        &uniParentPath,
1537                                                        NULL,
1538                                                        &stFileInfo)))
1539             {
1540                 ulFileAttribs = stFileInfo.FileAttributes;
1541
1542                 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1543             }
1544
1545             AFSAcquireShared( &pFcb->NPFcb->Resource,
1546                               TRUE);
1547         }
1548
1549         Buffer->FileAttributes = ulFileAttribs;
1550
1551         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1552             BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1553         {
1554
1555             if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1556             {
1557
1558                 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1559             }
1560             else
1561             {
1562
1563                 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1564             }
1565         }
1566
1567         if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1568         {
1569             Buffer->ReparseTag = IO_REPARSE_TAG_OPENAFS_DFS;
1570         }
1571
1572         *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1573
1574         ntStatus = STATUS_SUCCESS;
1575     }
1576
1577     return ntStatus;
1578 }
1579
1580 NTSTATUS
1581 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1582                             IN AFSDirectoryCB *DirectoryCB,
1583                             IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1584                             IN OUT PLONG Length)
1585 {
1586
1587     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1588     ULONG ulCopyLength = 0;
1589     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1590
1591     if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1592     {
1593
1594         RtlZeroMemory( Buffer,
1595                        *Length);
1596
1597         Buffer->StructureVersion = 1;
1598
1599         Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1600
1601         Buffer->Protocol = WNNC_NET_OPENAFS;
1602
1603         Buffer->ProtocolMajorVersion = 3;
1604
1605         Buffer->ProtocolMinorVersion = 0;
1606
1607         Buffer->ProtocolRevision = 0;
1608
1609         *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1610
1611         ntStatus = STATUS_SUCCESS;
1612     }
1613
1614     return ntStatus;
1615 }
1616
1617 NTSTATUS
1618 AFSQueryPhysicalNameInfo( IN PIRP Irp,
1619                           IN AFSDirectoryCB *DirectoryCB,
1620                           IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
1621                           IN OUT PLONG Length)
1622 {
1623
1624     NTSTATUS ntStatus = STATUS_SUCCESS;
1625     ULONG ulCopyLength = 0;
1626     ULONG cchCopied = 0;
1627     AFSFcb *pFcb = NULL;
1628     AFSCcb *pCcb = NULL;
1629     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1630     BOOLEAN bAddLeadingSlash = FALSE;
1631     USHORT usFullNameLength = 0;
1632
1633     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1634
1635     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1636
1637     if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
1638     {
1639
1640         RtlZeroMemory( Buffer,
1641                        *Length);
1642
1643         if( pCcb->FullFileName.Length == 0 ||
1644             pCcb->FullFileName.Buffer[ 0] != L'\\')
1645         {
1646             bAddLeadingSlash = TRUE;
1647         }
1648
1649         usFullNameLength = pCcb->FullFileName.Length;
1650
1651         if( bAddLeadingSlash)
1652         {
1653             usFullNameLength += sizeof( WCHAR);
1654         }
1655
1656         if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1657         {
1658             ulCopyLength = (LONG)usFullNameLength;
1659         }
1660         else
1661         {
1662
1663             ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1664
1665             ntStatus = STATUS_BUFFER_OVERFLOW;
1666         }
1667
1668         Buffer->FileNameLength = (ULONG)usFullNameLength;
1669
1670         *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1671
1672         if( ulCopyLength > 0)
1673         {
1674
1675             if( bAddLeadingSlash)
1676             {
1677
1678                 Buffer->FileName[ cchCopied] = L'\\';
1679
1680                 ulCopyLength -= sizeof( WCHAR);
1681                 *Length -= sizeof( WCHAR);
1682                 cchCopied++;
1683             }
1684
1685             if( ulCopyLength >= pCcb->FullFileName.Length)
1686             {
1687
1688                 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1689                                pCcb->FullFileName.Buffer,
1690                                pCcb->FullFileName.Length);
1691
1692                 ulCopyLength -= pCcb->FullFileName.Length;
1693                 *Length -= pCcb->FullFileName.Length;
1694                 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1695             }
1696             else
1697             {
1698
1699                 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1700                                pCcb->FullFileName.Buffer,
1701                                ulCopyLength);
1702
1703                 *Length -= ulCopyLength;
1704             }
1705         }
1706     }
1707     else
1708     {
1709
1710         ntStatus = STATUS_BUFFER_TOO_SMALL;
1711     }
1712
1713     return ntStatus;
1714 }
1715
1716 NTSTATUS
1717 AFSSetBasicInfo( IN PIRP Irp,
1718                  IN AFSDirectoryCB *DirectoryCB)
1719 {
1720     NTSTATUS ntStatus = STATUS_SUCCESS;
1721     PFILE_BASIC_INFORMATION pBuffer;
1722     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1723     ULONG ulNotifyFilter = 0;
1724     AFSCcb *pCcb = NULL;
1725
1726     __Enter
1727     {
1728
1729         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1730
1731         pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1732
1733         pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1734
1735         if( pBuffer->FileAttributes != (ULONGLONG)0)
1736         {
1737
1738             if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
1739                 BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1740             {
1741
1742                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1743             }
1744
1745             if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1746             {
1747
1748                 pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1749             }
1750
1751             pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1752
1753             DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
1754
1755             ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1756
1757             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1758         }
1759
1760         pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
1761
1762         if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
1763             pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
1764         {
1765
1766             pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1767
1768             DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
1769
1770             ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
1771
1772             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
1773         }
1774
1775         pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
1776
1777         if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
1778             pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
1779         {
1780
1781             pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1782
1783             DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
1784
1785             ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1786
1787             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
1788         }
1789
1790         pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
1791
1792         if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
1793             pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
1794         {
1795
1796             pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1797
1798             DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
1799
1800             ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
1801
1802             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
1803         }
1804
1805         pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
1806
1807         if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
1808             pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
1809         {
1810
1811             pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1812
1813             DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
1814
1815             ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1816
1817             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
1818         }
1819
1820         if( ulNotifyFilter > 0)
1821         {
1822
1823             if( DirectoryCB->ObjectInformation->ParentObjectInformation != NULL)
1824             {
1825
1826                 AFSFsRtlNotifyFullReportChange( DirectoryCB->ObjectInformation->ParentObjectInformation,
1827                                                 pCcb,
1828                                                 (ULONG)ulNotifyFilter,
1829                                                 (ULONG)FILE_ACTION_MODIFIED);
1830             }
1831         }
1832
1833 try_exit:
1834
1835         NOTHING;
1836     }
1837
1838     return ntStatus;
1839 }
1840
1841 NTSTATUS
1842 AFSSetDispositionInfo( IN PIRP Irp,
1843                        IN AFSDirectoryCB *DirectoryCB)
1844 {
1845     NTSTATUS ntStatus = STATUS_SUCCESS;
1846     PFILE_DISPOSITION_INFORMATION pBuffer;
1847     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1848     AFSFcb *pFcb = NULL;
1849     AFSCcb *pCcb = NULL;
1850
1851     __Enter
1852     {
1853
1854         pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1855
1856         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1857
1858         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1859
1860         //
1861         // Can't delete the root
1862         //
1863
1864         if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
1865         {
1866
1867             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1868                           AFS_TRACE_LEVEL_ERROR,
1869                           "AFSSetDispositionInfo Attempt to delete root entry\n");
1870
1871             try_return( ntStatus = STATUS_CANNOT_DELETE);
1872         }
1873
1874         //
1875         // If the file is read only then do not allow the delete
1876         //
1877
1878         if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
1879         {
1880
1881             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1882                           AFS_TRACE_LEVEL_ERROR,
1883                           "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
1884                           &DirectoryCB->NameInformation.FileName);
1885
1886             try_return( ntStatus = STATUS_CANNOT_DELETE);
1887         }
1888
1889         if( pBuffer->DeleteFile)
1890         {
1891
1892             //
1893             // Check if the caller can delete the file
1894             //
1895
1896             ntStatus = AFSNotifyDelete( DirectoryCB,
1897                                         TRUE);
1898
1899             if( !NT_SUCCESS( ntStatus))
1900             {
1901
1902                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1903                               AFS_TRACE_LEVEL_ERROR,
1904                               "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
1905                               &DirectoryCB->NameInformation.FileName,
1906                               ntStatus);
1907
1908                 try_return( ntStatus);
1909             }
1910
1911             if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1912             {
1913
1914                 //
1915                 // Check if this is a directory that there are not currently other opens
1916                 //
1917
1918                 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
1919                 {
1920
1921                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1922                                   AFS_TRACE_LEVEL_ERROR,
1923                                   "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
1924                                   &DirectoryCB->NameInformation.FileName,
1925                                   pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount);
1926
1927                     try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
1928                 }
1929
1930                 if( !AFSIsDirectoryEmptyForDelete( pFcb))
1931                 {
1932
1933                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1934                                   AFS_TRACE_LEVEL_ERROR,
1935                                   "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
1936                                   &DirectoryCB->NameInformation.FileName);
1937
1938                     try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
1939                 }
1940             }
1941             else
1942             {
1943
1944                 //
1945                 // Attempt to flush any outstanding data
1946                 //
1947
1948                 if( !MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
1949                                           MmFlushForDelete))
1950                 {
1951
1952                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1953                                   AFS_TRACE_LEVEL_ERROR,
1954                                   "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
1955                                   &DirectoryCB->NameInformation.FileName);
1956
1957                     try_return( ntStatus = STATUS_CANNOT_DELETE);
1958                 }
1959
1960                 //
1961                 // Purge the cache as well
1962                 //
1963
1964                 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1965                 {
1966
1967                     CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
1968                                          NULL,
1969                                          0,
1970                                          TRUE);
1971                 }
1972             }
1973
1974             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1975                           AFS_TRACE_LEVEL_VERBOSE,
1976                           "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry  %p Name %wZ\n",
1977                           DirectoryCB,
1978                           &DirectoryCB->NameInformation.FileName);
1979
1980             SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
1981         }
1982         else
1983         {
1984
1985             ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
1986         }
1987
1988         //
1989         // OK, should be good to go, set the flag in the file object
1990         //
1991
1992         pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
1993
1994 try_exit:
1995
1996         NOTHING;
1997     }
1998
1999     return ntStatus;
2000 }
2001
2002 NTSTATUS
2003 AFSSetRenameInfo( IN PIRP Irp)
2004 {
2005
2006     NTSTATUS ntStatus = STATUS_SUCCESS;
2007     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2008     IO_STATUS_BLOCK stIoSb = {0,0};
2009     AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2010     AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2011     PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2012     PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2013     PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2014     UNICODE_STRING uniTargetName, uniSourceName;
2015     BOOLEAN bReplaceIfExists = FALSE;
2016     UNICODE_STRING uniShortName;
2017     AFSDirectoryCB *pTargetDirEntry = NULL;
2018     ULONG ulTargetCRC = 0;
2019     BOOLEAN bTargetEntryExists = FALSE;
2020     AFSObjectInfoCB *pSrcObject = NULL, *pTargetObject = NULL;
2021     AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2022     AFSFileID stNewFid, stTmpTargetFid;
2023     ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2024     UNICODE_STRING uniFullTargetPath;
2025     BOOLEAN bCommonParent = FALSE;
2026     ULONG oldFileIndex;
2027     BOOLEAN bReleaseVolumeLock = FALSE;
2028     BOOLEAN bReleaseTargetDirLock = FALSE;
2029     BOOLEAN bReleaseSourceDirLock = FALSE;
2030     PERESOURCE  pSourceDirLock = NULL;
2031
2032     __Enter
2033     {
2034
2035         bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2036
2037         pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2038         pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2039
2040         pSrcObject = pSrcFcb->ObjectInformation;
2041
2042         //
2043         // Perform some basic checks to ensure FS integrity
2044         //
2045
2046         if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2047         {
2048
2049             //
2050             // Can't rename the root directory
2051             //
2052
2053             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2054                           AFS_TRACE_LEVEL_ERROR,
2055                           "AFSSetRenameInfo Attempt to rename root entry\n");
2056
2057             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2058         }
2059
2060         if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2061         {
2062
2063             //
2064             // If there are any open children then fail the rename
2065             //
2066
2067             if( pSrcFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2068             {
2069
2070                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2071                               AFS_TRACE_LEVEL_ERROR,
2072                               "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2073                               &pSrcCcb->DirectoryCB->NameInformation.FileName);
2074
2075                 try_return( ntStatus = STATUS_ACCESS_DENIED);
2076             }
2077         }
2078         else
2079         {
2080
2081             if( pSrcFcb->OpenHandleCount > 1)
2082             {
2083
2084                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2085                               AFS_TRACE_LEVEL_ERROR,
2086                               "AFSSetRenameInfo Attempt to rename directory with open references %wZ\n",
2087                               &pSrcCcb->DirectoryCB->NameInformation.FileName);
2088
2089                 try_return( ntStatus = STATUS_ACCESS_DENIED);
2090             }
2091         }
2092
2093         //
2094         // Resolve the target fileobject
2095         //
2096
2097         if( pTargetFileObj == NULL)
2098         {
2099
2100             //
2101             // This is a simple rename. Here the target directory is the same as the source parent directory
2102             // and the name is retrieved from the system buffer information
2103             //
2104
2105             pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2106
2107             pTargetParentObject = pSrcFcb->ObjectInformation->ParentObjectInformation;
2108
2109             pTargetDcb = pTargetParentObject->Fcb;
2110
2111             uniTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2112             uniTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2113         }
2114         else
2115         {
2116
2117             //
2118             // So here we have the target directory taken from the targetfile object
2119             //
2120
2121             pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2122
2123             pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2124
2125             pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2126
2127             //
2128             // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2129             // it is only the target component of the rename operation
2130             //
2131
2132             uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2133         }
2134
2135         //
2136         // We do not allow cross-volume renames to occur
2137         //
2138
2139         if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2140         {
2141
2142             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2143                           AFS_TRACE_LEVEL_ERROR,
2144                           "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2145                           &pSrcCcb->DirectoryCB->NameInformation.FileName);
2146
2147             try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2148         }
2149
2150         AFSAcquireExcl( pTargetParentObject->VolumeCB->VolumeLock,
2151                         TRUE);
2152
2153         bReleaseVolumeLock = TRUE;
2154
2155         ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2156                                       FALSE);
2157
2158         AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2159                         TRUE);
2160
2161         bReleaseTargetDirLock = TRUE;
2162
2163         if( pTargetParentObject != pSrcFcb->ObjectInformation->ParentObjectInformation)
2164         {
2165             AFSAcquireExcl( pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2166                             TRUE);
2167
2168             bReleaseSourceDirLock = TRUE;
2169
2170             pSourceDirLock = pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock;
2171         }
2172
2173         AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2174                                         ulTargetCRC,
2175                                         &pTargetDirEntry);
2176
2177         if( pTargetDirEntry == NULL)
2178         {
2179
2180             //
2181             // Missed so perform a case insensitive lookup
2182             //
2183
2184             ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2185                                           TRUE);
2186
2187             AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2188                                               ulTargetCRC,
2189                                               &pTargetDirEntry);
2190         }
2191
2192         if( pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2193                                                                NULL,
2194                                                                NULL))
2195         {
2196             //
2197             // Try the short name
2198             //
2199             AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2200                                         ulTargetCRC,
2201                                         &pTargetDirEntry);
2202         }
2203
2204         //
2205         // Increment our ref count on the dir entry
2206         //
2207
2208         if( pTargetDirEntry != NULL)
2209         {
2210
2211             ASSERT( pTargetParentObject == pTargetDirEntry->ObjectInformation->ParentObjectInformation);
2212
2213             InterlockedIncrement( &pTargetDirEntry->OpenReferenceCount);
2214
2215             if( !bReplaceIfExists)
2216             {
2217
2218                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2219                               AFS_TRACE_LEVEL_ERROR,
2220                               "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
2221                               &pSrcCcb->DirectoryCB->NameInformation.FileName,
2222                               &pTargetDirEntry->NameInformation.FileName);
2223
2224                 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2225             }
2226
2227             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2228                           AFS_TRACE_LEVEL_ERROR,
2229                           "AFSSetRenameInfo Target %wZ exists DE %p Count %08lX, performing delete of target\n",
2230                           &pTargetDirEntry->NameInformation.FileName,
2231                           pTargetDirEntry,
2232                           pTargetDirEntry->OpenReferenceCount);
2233
2234             //
2235             // Pull the directory entry from the parent
2236             //
2237
2238             AFSRemoveDirNodeFromParent( pTargetParentObject,
2239                                         pTargetDirEntry,
2240                                         FALSE);
2241
2242             bTargetEntryExists = TRUE;
2243         }
2244         else
2245         {
2246             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2247                           AFS_TRACE_LEVEL_ERROR,
2248                           "AFSSetRenameInfo Target Target does NOT exist, normal rename\n");
2249         }
2250
2251         //
2252         // Extract off the final component name from the Fcb
2253         //
2254
2255         uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2256         uniSourceName.MaximumLength = uniSourceName.Length;
2257
2258         uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2259
2260         //
2261         // The quick check to see if they are not really performing a rename
2262         // Do the names match? Only do this where the parent directories are
2263         // the same
2264         //
2265
2266         if( pTargetParentObject == pSrcFcb->ObjectInformation->ParentObjectInformation)
2267         {
2268
2269             bCommonParent = TRUE;
2270
2271             if( FsRtlAreNamesEqual( &uniTargetName,
2272                                     &uniSourceName,
2273                                     FALSE,
2274                                     NULL))
2275             {
2276                 try_return( ntStatus = STATUS_SUCCESS);
2277             }
2278         }
2279         else
2280         {
2281
2282             bCommonParent = FALSE;
2283         }
2284
2285         //
2286         // We need to remove the DirEntry from the parent node, update the index
2287         // and reinsert it into the parent tree. Note that for entries with the
2288         // same parent we do not pull the node from the enumeration list
2289         //
2290
2291         AFSRemoveDirNodeFromParent( pSrcFcb->ObjectInformation->ParentObjectInformation,
2292                                     pSrcCcb->DirectoryCB,
2293                                     !bCommonParent);
2294
2295         oldFileIndex = pSrcCcb->DirectoryCB->FileIndex;
2296
2297         if( !bCommonParent)
2298         {
2299
2300             //
2301             // We always need to update the FileIndex since this entry will be put at the 'end'
2302             // of the enumeraiton list. If we don't it will cause recursion ... We do this
2303             // here to cover any failures which might occur below
2304             //
2305
2306             pSrcCcb->DirectoryCB->FileIndex =
2307                             (ULONG)InterlockedIncrement( &pTargetDcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.ContentIndex);
2308         }
2309
2310         //
2311         // OK, this is a simple rename. Issue the rename
2312         // request to the service.
2313         //
2314
2315         ntStatus = AFSNotifyRename( pSrcFcb->ObjectInformation,
2316                                     pSrcFcb->ObjectInformation->ParentObjectInformation,
2317                                     pTargetDcb->ObjectInformation,
2318                                     pSrcCcb->DirectoryCB,
2319                                     &uniTargetName,
2320                                     &stNewFid);
2321
2322         if( !NT_SUCCESS( ntStatus))
2323         {
2324
2325             //
2326             // Attempt to re-insert the directory entry
2327             //
2328
2329             pSrcCcb->DirectoryCB->FileIndex = oldFileIndex;
2330             AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2331                                     pSrcCcb->DirectoryCB,
2332                                     !bCommonParent);
2333
2334             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2335                           AFS_TRACE_LEVEL_ERROR,
2336                           "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
2337                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
2338                           &uniTargetName,
2339                           ntStatus);
2340
2341             try_return( ntStatus);
2342         }
2343
2344         //
2345         // Set the notification up for the source file
2346         //
2347
2348         if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation == pTargetParentObject &&
2349             !bTargetEntryExists)
2350         {
2351
2352             ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
2353         }
2354         else
2355         {
2356
2357             ulNotificationAction = FILE_ACTION_REMOVED;
2358         }
2359
2360         if( pSrcCcb->DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
2361         {
2362
2363             ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2364         }
2365         else
2366         {
2367
2368             ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2369         }
2370
2371         AFSFsRtlNotifyFullReportChange( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation,
2372                                         pSrcCcb,
2373                                         (ULONG)ulNotifyFilter,
2374                                         (ULONG)ulNotificationAction);
2375
2376         //
2377         // Update the name in the dir entry.
2378         //
2379
2380         ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
2381                                           &uniTargetName);
2382
2383         if( !NT_SUCCESS( ntStatus))
2384         {
2385
2386             //
2387             // Attempt to re-insert the directory entry
2388             //
2389
2390             pSrcCcb->DirectoryCB->FileIndex = oldFileIndex;
2391             AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2392                                     pSrcCcb->DirectoryCB,
2393                                     !bCommonParent);
2394
2395             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2396                           AFS_TRACE_LEVEL_ERROR,
2397                           "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
2398                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
2399                           &uniTargetName,
2400                           ntStatus);
2401
2402             try_return( ntStatus);
2403         }
2404
2405         //
2406         // Update the object information block, if needed
2407         //
2408
2409         if( !AFSIsEqualFID( &pSrcObject->FileId,
2410                             &stNewFid))
2411         {
2412
2413             //
2414             // Remove the old information entry
2415             //
2416
2417             AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2418                                 &pSrcObject->TreeEntry);
2419
2420             RtlCopyMemory( &pSrcObject->FileId,
2421                            &stNewFid,
2422                            sizeof( AFSFileID));
2423
2424             //
2425             // Insert the entry into the new object table.
2426             //
2427
2428             pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
2429
2430             if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
2431             {
2432
2433                 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
2434             }
2435             else
2436             {
2437
2438                 AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2439                                     &pSrcObject->TreeEntry);
2440             }
2441         }
2442
2443         //
2444         // Update the hash values for the name trees.
2445         //
2446
2447         pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2448                                                                                  FALSE);
2449
2450         pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2451                                                                                    TRUE);
2452
2453         if( pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
2454             !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2455                                      NULL,
2456                                      NULL))
2457         {
2458
2459             uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
2460             uniShortName.MaximumLength = uniShortName.Length;
2461             uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
2462
2463             pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
2464                                                                                            TRUE);
2465
2466             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2467                           AFS_TRACE_LEVEL_VERBOSE,
2468                           "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
2469                           &uniShortName,
2470                           &pSrcCcb->DirectoryCB->NameInformation.FileName);
2471         }
2472         else
2473         {
2474
2475             pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
2476         }
2477
2478         if( !bCommonParent)
2479         {
2480
2481             //
2482             // Update the file index for the object in the new parent
2483             //
2484
2485             pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
2486         }
2487
2488         //
2489         // Re-insert the directory entry
2490         //
2491
2492         AFSInsertDirectoryNode( pTargetParentObject,
2493                                 pSrcCcb->DirectoryCB,
2494                                 !bCommonParent);
2495
2496         //
2497         // Update the parent pointer in the source object if they are different
2498         //
2499
2500         if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation != pTargetParentObject)
2501         {
2502
2503             InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2504
2505             InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2506
2507             InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
2508
2509             InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
2510
2511             pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation = pTargetParentObject;
2512
2513             ulNotificationAction = FILE_ACTION_ADDED;
2514         }
2515         else
2516         {
2517
2518             ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
2519         }
2520
2521         //
2522         // Now update the notification for the target file
2523         //
2524
2525         AFSFsRtlNotifyFullReportChange( pTargetParentObject->ParentObjectInformation,
2526                                         pSrcCcb,
2527                                         (ULONG)ulNotifyFilter,
2528                                         (ULONG)ulNotificationAction);
2529
2530         //
2531         // If we performed the rename of the target because it existed, we now need to
2532         // delete the tmp target we created above
2533         //
2534
2535         if( bTargetEntryExists)
2536         {
2537
2538             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2539                           AFS_TRACE_LEVEL_VERBOSE,
2540                           "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
2541                           pTargetDirEntry,
2542                           &pTargetDirEntry->NameInformation.FileName);
2543
2544             SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2545
2546             //
2547             // Try and purge the cache map if this is a file
2548             //
2549
2550             if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
2551                 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
2552                 pTargetDirEntry->OpenReferenceCount > 1)
2553             {
2554
2555                 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
2556
2557                 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
2558                                 TRUE);
2559
2560                 //
2561                 // Close the section in the event it was mapped
2562                 //
2563
2564                 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
2565                                            TRUE))
2566                 {
2567
2568                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2569                                   AFS_TRACE_LEVEL_ERROR,
2570                                   "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
2571                                   &pTargetDirEntry->NameInformation.FileName);
2572                 }
2573
2574                 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
2575             }
2576
2577             ASSERT( pTargetDirEntry->OpenReferenceCount > 0);
2578
2579             InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount); // The count we added above
2580
2581             if( pTargetDirEntry->OpenReferenceCount == 0)
2582             {
2583
2584                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2585                               AFS_TRACE_LEVEL_VERBOSE,
2586                               "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
2587                               pTargetDirEntry,
2588                               &pTargetDirEntry->NameInformation.FileName);
2589
2590                 AFSDeleteDirEntry( pTargetParentObject,
2591                                    pTargetDirEntry);
2592             }
2593
2594             pTargetDirEntry = NULL;
2595         }
2596
2597 try_exit:
2598
2599
2600         if( !NT_SUCCESS( ntStatus))
2601         {
2602
2603             if( bTargetEntryExists)
2604             {
2605                 AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
2606                                         pTargetDirEntry,
2607                                         FALSE);
2608             }
2609         }
2610
2611         if( pTargetDirEntry != NULL)
2612         {
2613
2614             InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
2615         }
2616
2617         if( bReleaseVolumeLock)
2618         {
2619             AFSReleaseResource( pTargetParentObject->VolumeCB->VolumeLock);
2620         }
2621
2622         if( bReleaseTargetDirLock)
2623         {
2624             AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2625         }
2626
2627         if( bReleaseSourceDirLock)
2628         {
2629             AFSReleaseResource( pSourceDirLock);
2630         }
2631     }
2632
2633     return ntStatus;
2634 }
2635
2636 NTSTATUS
2637 AFSSetPositionInfo( IN PIRP Irp,
2638                     IN AFSDirectoryCB *DirectoryCB)
2639 {
2640     NTSTATUS ntStatus = STATUS_SUCCESS;
2641     PFILE_POSITION_INFORMATION pBuffer;
2642     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2643
2644     pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2645
2646     pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
2647
2648     return ntStatus;
2649 }
2650
2651 NTSTATUS
2652 AFSSetAllocationInfo( IN PIRP Irp,
2653                       IN AFSDirectoryCB *DirectoryCB)
2654 {
2655     NTSTATUS ntStatus = STATUS_SUCCESS;
2656     PFILE_ALLOCATION_INFORMATION pBuffer;
2657     BOOLEAN bReleasePaging = FALSE;
2658     BOOLEAN bTellCc = FALSE;
2659     BOOLEAN bTellService = FALSE;
2660     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2661     PFILE_OBJECT pFileObject = pIrpSp->FileObject;
2662     AFSFcb *pFcb = NULL;
2663     AFSCcb *pCcb = NULL;
2664     LARGE_INTEGER liSaveAlloc;
2665     LARGE_INTEGER liSaveFileSize;
2666     LARGE_INTEGER liSaveVDL;
2667
2668     pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2669
2670     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2671
2672     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2673
2674     //
2675     // save values to put back
2676     //
2677     liSaveAlloc = pFcb->Header.AllocationSize;
2678     liSaveFileSize = pFcb->Header.FileSize;
2679     liSaveVDL = pFcb->Header.ValidDataLength;
2680
2681     if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
2682         pIrpSp->Parameters.SetFile.AdvanceOnly)
2683     {
2684         return STATUS_SUCCESS ;
2685     }
2686
2687     if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
2688     {
2689         //
2690         // Truncating the file
2691         //
2692         if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
2693                                    &pBuffer->AllocationSize))
2694         {
2695
2696             ntStatus = STATUS_USER_MAPPED_FILE ;
2697         }
2698         else
2699         {
2700             //
2701             // If this is a truncation we need to grab the paging IO resource.
2702             //
2703             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2704                           AFS_TRACE_LEVEL_VERBOSE,
2705                           "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2706                           &pFcb->NPFcb->PagingResource,
2707                           PsGetCurrentThread());
2708
2709             AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2710                             TRUE);
2711
2712             bReleasePaging = TRUE;
2713
2714
2715             pFcb->Header.AllocationSize = pBuffer->AllocationSize;
2716
2717             pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
2718
2719             //
2720             // Tell Cc that Allocation is moved.
2721             //
2722             bTellCc = TRUE;
2723
2724             if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
2725             {
2726                 //
2727                 // We are pulling the EOF back as well so we need to tell
2728                 // the service.
2729                 //
2730                 bTellService = TRUE;
2731
2732                 pFcb->Header.FileSize = pBuffer->AllocationSize;
2733
2734                 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
2735             }
2736
2737         }
2738     }
2739     else
2740     {
2741         //
2742         // Tell Cc if allocation is increased.
2743         //
2744         bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
2745
2746         pFcb->Header.AllocationSize = pBuffer->AllocationSize;
2747
2748         pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
2749     }
2750
2751     //
2752     // Now Tell the server if we have to
2753     //
2754     if (bTellService)
2755     {
2756         ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
2757                                              pFcb->ObjectInformation,
2758                                              &pFcb->AuthGroup);
2759     }
2760
2761     if (NT_SUCCESS(ntStatus))
2762     {
2763         //
2764         // Trim extents if we told the service - the update has done an implicit
2765         // trim at the service.
2766         //
2767         if (bTellService)
2768         {
2769             AFSTrimExtents( pFcb,
2770                             &pFcb->Header.FileSize);
2771         }
2772
2773         KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
2774
2775         SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2776
2777         if (bTellCc &&
2778             CcIsFileCached( pFileObject))
2779         {
2780             CcSetFileSizes( pFileObject,
2781                             (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
2782         }
2783     }
2784     else
2785     {
2786         //
2787         // Put the saved values back
2788         //
2789         pFcb->Header.ValidDataLength = liSaveVDL;
2790         pFcb->Header.FileSize = liSaveFileSize;
2791         pFcb->Header.AllocationSize = liSaveAlloc;
2792         pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
2793         pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
2794     }
2795
2796     if( bReleasePaging)
2797     {
2798
2799         AFSReleaseResource( &pFcb->NPFcb->PagingResource);
2800     }
2801
2802     return ntStatus;
2803 }
2804
2805 NTSTATUS
2806 AFSSetEndOfFileInfo( IN PIRP Irp,
2807                      IN AFSDirectoryCB *DirectoryCB)
2808 {
2809     NTSTATUS ntStatus = STATUS_SUCCESS;
2810     PFILE_END_OF_FILE_INFORMATION pBuffer;
2811     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2812     PFILE_OBJECT pFileObject = pIrpSp->FileObject;
2813     LARGE_INTEGER liSaveSize;
2814     LARGE_INTEGER liSaveVDL;
2815     LARGE_INTEGER liSaveAlloc;
2816     BOOLEAN bModified = FALSE;
2817     BOOLEAN bReleasePaging = FALSE;
2818     BOOLEAN bTruncated = FALSE;
2819     AFSFcb *pFcb = NULL;
2820     AFSCcb *pCcb = NULL;
2821
2822     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2823
2824     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2825
2826     pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2827
2828     liSaveSize = pFcb->Header.FileSize;
2829     liSaveAlloc = pFcb->Header.AllocationSize;
2830     liSaveVDL = pFcb->Header.ValidDataLength;
2831
2832     if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
2833         !pIrpSp->Parameters.SetFile.AdvanceOnly)
2834     {
2835
2836         if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
2837         {
2838
2839             // Truncating the file
2840             if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
2841                                        &pBuffer->EndOfFile))
2842             {
2843
2844                 ntStatus = STATUS_USER_MAPPED_FILE;
2845             }
2846             else
2847             {
2848                 //
2849                 // If this is a truncation we need to grab the paging
2850                 // IO resource.
2851                 //
2852                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2853                               AFS_TRACE_LEVEL_VERBOSE,
2854                               "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2855                               &pFcb->NPFcb->PagingResource,
2856                               PsGetCurrentThread());
2857
2858                 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2859                                 TRUE);
2860
2861                 bReleasePaging = TRUE;
2862
2863                 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
2864
2865                 pFcb->Header.FileSize = pBuffer->EndOfFile;
2866
2867                 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
2868
2869                 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
2870
2871                 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
2872                 {
2873
2874                     pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
2875                 }
2876
2877                 bTruncated = TRUE;
2878
2879                 bModified = TRUE;
2880             }
2881         }
2882         else
2883         {
2884             //
2885             // extending the file, move EOF
2886             //
2887
2888             pFcb->Header.FileSize = pBuffer->EndOfFile;
2889
2890             pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
2891
2892             if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
2893             {
2894                 //
2895                 // And Allocation as needed.
2896                 //
2897                 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
2898
2899                 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
2900             }
2901
2902             bModified = TRUE;
2903         }
2904     }
2905
2906     if (bModified)
2907     {
2908
2909         KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
2910
2911         SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2912
2913         //
2914         // Tell the server
2915         //
2916
2917         ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
2918                                              pFcb->ObjectInformation,
2919                                              &pFcb->AuthGroup);
2920
2921         if( NT_SUCCESS(ntStatus))
2922         {
2923             //
2924             // We are now good to go so tell CC.
2925             //
2926             CcSetFileSizes( pFileObject,
2927                             (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
2928
2929             //
2930             // And give up those extents
2931             //
2932             if( bTruncated)
2933             {
2934
2935                 AFSTrimExtents( pFcb,
2936                                 &pFcb->Header.FileSize);
2937             }
2938         }
2939         else
2940         {
2941             pFcb->Header.ValidDataLength = liSaveVDL;
2942             pFcb->Header.FileSize = liSaveSize;
2943             pFcb->Header.AllocationSize = liSaveAlloc;
2944             pFcb->ObjectInformation->EndOfFile = liSaveSize;
2945             pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
2946         }
2947     }
2948
2949     if( bReleasePaging)
2950     {
2951
2952         AFSReleaseResource( &pFcb->NPFcb->PagingResource);
2953     }
2954
2955     return ntStatus;
2956 }
2957
2958 NTSTATUS
2959 AFSProcessShareSetInfo( IN IRP *Irp,
2960                         IN AFSFcb *Fcb,
2961                         IN AFSCcb *Ccb)
2962 {
2963
2964     NTSTATUS ntStatus = STATUS_SUCCESS;
2965     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2966     ULONG ulOutputBufferLen = 0, ulInputBufferLen;
2967     FILE_INFORMATION_CLASS ulFileInformationClass;
2968     void *pPipeInfo = NULL;
2969
2970     __Enter
2971     {
2972         ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
2973
2974         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
2975                       AFS_TRACE_LEVEL_VERBOSE,
2976                       "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
2977                       &Ccb->DirectoryCB->NameInformation.FileName,
2978                       ulFileInformationClass);
2979
2980         pPipeInfo = AFSLockSystemBuffer( Irp,
2981                                          pIrpSp->Parameters.SetFile.Length);
2982
2983         if( pPipeInfo == NULL)
2984         {
2985
2986             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
2987                           AFS_TRACE_LEVEL_ERROR,
2988                           "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
2989                           &Ccb->DirectoryCB->NameInformation.FileName);
2990
2991             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2992         }
2993
2994         //
2995         // Send the request to the service
2996         //
2997
2998         ntStatus = AFSNotifySetPipeInfo( Ccb,
2999                                          (ULONG)ulFileInformationClass,
3000                                          pIrpSp->Parameters.SetFile.Length,
3001                                          pPipeInfo);
3002
3003         if( !NT_SUCCESS( ntStatus))
3004         {
3005
3006             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3007                           AFS_TRACE_LEVEL_ERROR,
3008                           "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3009                           &Ccb->DirectoryCB->NameInformation.FileName,
3010                           ntStatus);
3011
3012             try_return( ntStatus);
3013         }
3014
3015         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3016                       AFS_TRACE_LEVEL_VERBOSE,
3017                       "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
3018                       &Ccb->DirectoryCB->NameInformation.FileName,
3019                       ulFileInformationClass);
3020
3021 try_exit:
3022
3023         NOTHING;
3024     }
3025
3026     return ntStatus;
3027 }
3028
3029 NTSTATUS
3030 AFSProcessShareQueryInfo( IN IRP *Irp,
3031                           IN AFSFcb *Fcb,
3032                           IN AFSCcb *Ccb)
3033 {
3034
3035     NTSTATUS ntStatus = STATUS_SUCCESS;
3036     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3037     ULONG ulOutputBufferLen = 0, ulInputBufferLen;
3038     FILE_INFORMATION_CLASS ulFileInformationClass;
3039     void *pPipeInfo = NULL;
3040
3041     __Enter
3042     {
3043
3044         ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3045
3046         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3047                       AFS_TRACE_LEVEL_VERBOSE,
3048                       "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
3049                       &Ccb->DirectoryCB->NameInformation.FileName,
3050                       ulFileInformationClass);
3051
3052         pPipeInfo = AFSLockSystemBuffer( Irp,
3053                                          pIrpSp->Parameters.QueryFile.Length);
3054
3055         if( pPipeInfo == NULL)
3056         {
3057
3058             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3059                           AFS_TRACE_LEVEL_ERROR,
3060                           "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
3061                           &Ccb->DirectoryCB->NameInformation.FileName);
3062
3063             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3064         }
3065
3066         //
3067         // Send the request to the service
3068         //
3069
3070         ntStatus = AFSNotifyQueryPipeInfo( Ccb,
3071                                            (ULONG)ulFileInformationClass,
3072                                            pIrpSp->Parameters.QueryFile.Length,
3073                                            pPipeInfo,
3074                                            (ULONG *)&Irp->IoStatus.Information);
3075
3076         if( !NT_SUCCESS( ntStatus))
3077         {
3078
3079             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3080                           AFS_TRACE_LEVEL_ERROR,
3081                           "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3082                           &Ccb->DirectoryCB->NameInformation.FileName,
3083                           ntStatus);
3084
3085             try_return( ntStatus);
3086         }
3087
3088         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3089                       AFS_TRACE_LEVEL_VERBOSE,
3090                       "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
3091                       &Ccb->DirectoryCB->NameInformation.FileName,
3092                       ulFileInformationClass);
3093
3094 try_exit:
3095
3096         NOTHING;
3097     }
3098
3099     return ntStatus;
3100 }
3101
3102 NTSTATUS
3103 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
3104                            IN AFSFcb *Fcb,
3105                            IN AFSCcb *Ccb,
3106                            IN OUT LONG *Length)
3107 {
3108
3109     NTSTATUS ntStatus = STATUS_SUCCESS;
3110     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3111     FILE_INFORMATION_CLASS ulFileInformationClass;
3112
3113     __Enter
3114     {
3115
3116         ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3117
3118         switch( ulFileInformationClass)
3119         {
3120
3121             case FileBasicInformation:
3122             {
3123
3124                 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
3125                 {
3126                     PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3127
3128                     pBasic->CreationTime.QuadPart = 0;
3129                     pBasic->LastAccessTime.QuadPart = 0;
3130                     pBasic->ChangeTime.QuadPart = 0;
3131                     pBasic->LastWriteTime.QuadPart = 0;
3132                     pBasic->FileAttributes = FILE_ATTRIBUTE_SYSTEM;
3133
3134                     *Length -= sizeof( FILE_BASIC_INFORMATION);
3135                 }
3136                 else
3137                 {
3138                     ntStatus = STATUS_BUFFER_OVERFLOW;
3139                 }
3140
3141                 break;
3142             }
3143
3144             case FileStandardInformation:
3145             {
3146
3147                 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
3148                 {
3149                     PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3150
3151                     pStandard->NumberOfLinks = 1;
3152                     pStandard->DeletePending = 0;
3153                     pStandard->AllocationSize.QuadPart = 4096;
3154                     pStandard->EndOfFile.QuadPart = 4096;
3155                     pStandard->Directory = 0;
3156
3157                     *Length -= sizeof( FILE_STANDARD_INFORMATION);
3158                 }
3159                 else
3160                 {
3161                     ntStatus = STATUS_BUFFER_OVERFLOW;
3162                 }
3163
3164                 break;
3165             }
3166
3167             case FileNameInformation:
3168             {
3169
3170                 ULONG ulCopyLength = 0;
3171                 AFSFcb *pFcb = NULL;
3172                 AFSCcb *pCcb = NULL;
3173                 USHORT usFullNameLength = 0;
3174                 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3175                 UNICODE_STRING uniName;
3176
3177                 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3178                 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3179
3180                 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
3181                 {
3182                     ntStatus = STATUS_BUFFER_TOO_SMALL;
3183                     break;
3184                 }
3185
3186                 RtlZeroMemory( pNameInfo,
3187                                *Length);
3188
3189                 usFullNameLength = sizeof( WCHAR) +
3190                                             AFSServerName.Length +
3191                                             pCcb->FullFileName.Length;
3192
3193                 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
3194                 {
3195                     ulCopyLength = (LONG)usFullNameLength;
3196                 }
3197                 else
3198                 {
3199                     ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
3200                     ntStatus = STATUS_BUFFER_OVERFLOW;
3201                 }
3202
3203                 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
3204
3205                 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
3206
3207                 if( ulCopyLength > 0)
3208                 {
3209
3210                     pNameInfo->FileName[ 0] = L'\\';
3211                     ulCopyLength -= sizeof( WCHAR);
3212
3213                     *Length -= sizeof( WCHAR);
3214
3215                     if( ulCopyLength >= AFSServerName.Length)
3216                     {
3217
3218                         RtlCopyMemory( &pNameInfo->FileName[ 1],
3219                                        AFSServerName.Buffer,
3220                                        AFSServerName.Length);
3221
3222                         ulCopyLength -= AFSServerName.Length;
3223                         *Length -= AFSServerName.Length;
3224
3225                         if( ulCopyLength >= pCcb->FullFileName.Length)
3226                         {
3227
3228                             RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
3229                                            pCcb->FullFileName.Buffer,
3230                                            pCcb->FullFileName.Length);
3231
3232                             ulCopyLength -= pCcb->FullFileName.Length;
3233                             *Length -= pCcb->FullFileName.Length;
3234
3235                             uniName.Length = (USHORT)pNameInfo->FileNameLength;
3236                             uniName.MaximumLength = uniName.Length;
3237                             uniName.Buffer = pNameInfo->FileName;
3238                         }
3239                         else
3240                         {
3241
3242                             RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
3243                                            pCcb->FullFileName.Buffer,
3244                                            ulCopyLength);
3245
3246                             *Length -= ulCopyLength;
3247
3248                             uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
3249                             uniName.MaximumLength = uniName.Length;
3250                             uniName.Buffer = pNameInfo->FileName;
3251                         }
3252
3253                         AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3254                                       AFS_TRACE_LEVEL_VERBOSE,
3255                                       "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
3256                                       &uniName);
3257                     }
3258                 }
3259
3260                 break;
3261             }
3262
3263             case FileInternalInformation:
3264             {
3265
3266                 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3267
3268                 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
3269                 {
3270
3271                     pInternalInfo->IndexNumber.HighPart = 0;
3272
3273                     pInternalInfo->IndexNumber.LowPart = 0;
3274
3275                     *Length -= sizeof( FILE_INTERNAL_INFORMATION);
3276                 }
3277                 else
3278                 {
3279
3280                     ntStatus = STATUS_BUFFER_TOO_SMALL;
3281                 }
3282
3283                 break;
3284             }
3285
3286             default:
3287             {
3288                 ntStatus = STATUS_INVALID_PARAMETER;
3289
3290                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3291                               AFS_TRACE_LEVEL_WARNING,
3292                               "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
3293                               ulFileInformationClass);
3294
3295                 break;
3296             }
3297         }
3298     }
3299
3300     return ntStatus;
3301 }
3302