98811ac1945e77747350f9260dc431782f7d0d24
[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                                                  &pCcb->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                                                        &pCcb->AuthGroup,
800                                                        &stFileInfo)))
801             {
802                 ulFileAttribs = stFileInfo.FileAttributes;
803
804                 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
805             }
806
807             AFSAcquireShared( &pFcb->NPFcb->Resource,
808                               TRUE);
809         }
810
811
812         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
813                       AFS_TRACE_LEVEL_VERBOSE_2,
814                       "AFSQueryBasicInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
815                       &pCcb->DirectoryCB->NameInformation.FileName,
816                       pCcb->DirectoryCB->ObjectInformation->FileType,
817                       pCcb->DirectoryCB->ObjectInformation->FileAttributes,
818                       ulFileAttribs);
819
820         Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
821         Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
822         Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
823         Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
824         Buffer->FileAttributes = ulFileAttribs;
825
826         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
827             BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
828         {
829
830             if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
831             {
832                 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
833             }
834             else
835             {
836                 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
837             }
838         }
839
840         *Length -= sizeof( FILE_BASIC_INFORMATION);
841     }
842     else
843     {
844
845         ntStatus = STATUS_BUFFER_TOO_SMALL;
846     }
847
848     return ntStatus;
849 }
850
851 NTSTATUS
852 AFSQueryStandardInfo( IN PIRP Irp,
853                       IN AFSDirectoryCB *DirectoryCB,
854                       IN OUT PFILE_STANDARD_INFORMATION Buffer,
855                       IN OUT PLONG Length)
856 {
857
858     NTSTATUS ntStatus = STATUS_SUCCESS;
859     AFSFcb *pFcb = NULL;
860     AFSCcb *pCcb = NULL;
861     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
862     AFSFileInfoCB stFileInfo;
863     AFSDirectoryCB *pParentDirectoryCB = NULL;
864     UNICODE_STRING uniParentPath;
865     ULONG ulFileAttribs = 0;
866
867     if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
868     {
869
870         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
871         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
872
873         RtlZeroMemory( Buffer,
874                        *Length);
875
876         Buffer->NumberOfLinks = 1;
877         Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
878
879         Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
880
881         Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
882
883         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
884
885         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
886         {
887
888             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
889
890             AFSRetrieveParentPath( &pCcb->FullFileName,
891                                    &uniParentPath);
892
893             RtlZeroMemory( &stFileInfo,
894                            sizeof( AFSFileInfoCB));
895
896             //
897             // Can't hold the Fcb while evaluating the path, leads to lock inversion
898             //
899
900             AFSReleaseResource( &pFcb->NPFcb->Resource);
901
902             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
903                                                        DirectoryCB,
904                                                        &uniParentPath,
905                                                        NULL,
906                                                        &pCcb->AuthGroup,
907                                                        &stFileInfo)))
908             {
909                 ulFileAttribs = stFileInfo.FileAttributes;
910             }
911
912             AFSAcquireShared( &pFcb->NPFcb->Resource,
913                               TRUE);
914         }
915
916         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
917                       AFS_TRACE_LEVEL_VERBOSE_2,
918                       "AFSQueryStandardInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
919                       &pCcb->DirectoryCB->NameInformation.FileName,
920                       pCcb->DirectoryCB->ObjectInformation->FileType,
921                       pCcb->DirectoryCB->ObjectInformation->FileAttributes,
922                       ulFileAttribs);
923
924         Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
925
926         *Length -= sizeof( FILE_STANDARD_INFORMATION);
927     }
928     else
929     {
930
931         ntStatus = STATUS_BUFFER_TOO_SMALL;
932     }
933
934     return ntStatus;
935 }
936
937 NTSTATUS
938 AFSQueryInternalInfo( IN PIRP Irp,
939                       IN AFSFcb *Fcb,
940                       IN OUT PFILE_INTERNAL_INFORMATION Buffer,
941                       IN OUT PLONG Length)
942 {
943
944     NTSTATUS ntStatus = STATUS_SUCCESS;
945
946     if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
947     {
948
949         Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Volume;
950
951         Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Vnode;
952
953         *Length -= sizeof( FILE_INTERNAL_INFORMATION);
954     }
955     else
956     {
957
958         ntStatus = STATUS_BUFFER_TOO_SMALL;
959     }
960
961     return ntStatus;
962 }
963
964 NTSTATUS
965 AFSQueryEaInfo( IN PIRP Irp,
966                 IN AFSDirectoryCB *DirectoryCB,
967                 IN OUT PFILE_EA_INFORMATION Buffer,
968                 IN OUT PLONG Length)
969 {
970
971     NTSTATUS ntStatus = STATUS_SUCCESS;
972
973     RtlZeroMemory( Buffer,
974                    *Length);
975
976     if( *Length >= sizeof( FILE_EA_INFORMATION))
977     {
978
979         Buffer->EaSize = 0;
980
981         *Length -= sizeof( FILE_EA_INFORMATION);
982     }
983     else
984     {
985
986         ntStatus = STATUS_BUFFER_TOO_SMALL;
987     }
988
989     return ntStatus;
990 }
991
992 NTSTATUS
993 AFSQueryPositionInfo( IN PIRP Irp,
994                       IN AFSFcb *Fcb,
995                       IN OUT PFILE_POSITION_INFORMATION Buffer,
996                       IN OUT PLONG Length)
997 {
998
999     NTSTATUS ntStatus = STATUS_SUCCESS;
1000     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1001
1002     if( *Length >= sizeof( FILE_POSITION_INFORMATION))
1003     {
1004
1005         RtlZeroMemory( Buffer,
1006                        *Length);
1007
1008         Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
1009
1010         *Length -= sizeof( FILE_POSITION_INFORMATION);
1011     }
1012     else
1013     {
1014
1015         ntStatus = STATUS_BUFFER_TOO_SMALL;
1016     }
1017
1018     return ntStatus;
1019 }
1020
1021 NTSTATUS
1022 AFSQueryAccess( IN PIRP Irp,
1023                 IN AFSFcb *Fcb,
1024                 IN OUT PFILE_ACCESS_INFORMATION Buffer,
1025                 IN OUT PLONG Length)
1026 {
1027
1028     NTSTATUS ntStatus = STATUS_SUCCESS;
1029
1030     if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
1031     {
1032
1033         RtlZeroMemory( Buffer,
1034                        *Length);
1035
1036         Buffer->AccessFlags = 0;
1037
1038         *Length -= sizeof( FILE_ACCESS_INFORMATION);
1039     }
1040     else
1041     {
1042
1043         ntStatus = STATUS_BUFFER_TOO_SMALL;
1044     }
1045
1046     return ntStatus;
1047 }
1048
1049 NTSTATUS
1050 AFSQueryMode( IN PIRP Irp,
1051               IN AFSFcb *Fcb,
1052               IN OUT PFILE_MODE_INFORMATION Buffer,
1053               IN OUT PLONG Length)
1054 {
1055
1056     NTSTATUS ntStatus = STATUS_SUCCESS;
1057
1058     if( *Length >= sizeof( FILE_MODE_INFORMATION))
1059     {
1060
1061         RtlZeroMemory( Buffer,
1062                        *Length);
1063
1064         Buffer->Mode = 0;
1065
1066         *Length -= sizeof( FILE_MODE_INFORMATION);
1067     }
1068     else
1069     {
1070
1071         ntStatus = STATUS_BUFFER_TOO_SMALL;
1072     }
1073
1074     return ntStatus;
1075 }
1076
1077 NTSTATUS
1078 AFSQueryAlignment( IN PIRP Irp,
1079                    IN AFSFcb *Fcb,
1080                    IN OUT PFILE_ALIGNMENT_INFORMATION Buffer,
1081                    IN OUT PLONG Length)
1082 {
1083
1084     NTSTATUS ntStatus = STATUS_SUCCESS;
1085
1086     if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
1087     {
1088
1089         RtlZeroMemory( Buffer,
1090                        *Length);
1091
1092         Buffer->AlignmentRequirement = 1;
1093
1094         *Length -= sizeof( FILE_ALIGNMENT_INFORMATION);
1095     }
1096     else
1097     {
1098
1099         ntStatus = STATUS_BUFFER_TOO_SMALL;
1100     }
1101
1102     return ntStatus;
1103 }
1104
1105 NTSTATUS
1106 AFSQueryNameInfo( IN PIRP Irp,
1107                   IN AFSDirectoryCB *DirectoryCB,
1108                   IN OUT PFILE_NAME_INFORMATION Buffer,
1109                   IN OUT PLONG Length)
1110 {
1111
1112     NTSTATUS ntStatus = STATUS_SUCCESS;
1113     ULONG ulCopyLength = 0;
1114     ULONG cchCopied = 0;
1115     AFSFcb *pFcb = NULL;
1116     AFSCcb *pCcb = NULL;
1117     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1118     BOOLEAN bAddLeadingSlash = FALSE;
1119     BOOLEAN bAddTrailingSlash = FALSE;
1120     USHORT usFullNameLength = 0;
1121
1122     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1123
1124     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1125
1126     if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1127     {
1128
1129         RtlZeroMemory( Buffer,
1130                        *Length);
1131
1132         if( pCcb->FullFileName.Length == 0 ||
1133             pCcb->FullFileName.Buffer[ 0] != L'\\')
1134         {
1135             bAddLeadingSlash = TRUE;
1136         }
1137
1138         if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1139             pCcb->FullFileName.Length > 0 &&
1140             pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
1141         {
1142             bAddTrailingSlash = TRUE;
1143         }
1144
1145         usFullNameLength = sizeof( WCHAR) +
1146                                     AFSServerName.Length +
1147                                     pCcb->FullFileName.Length;
1148
1149         if( bAddLeadingSlash)
1150         {
1151             usFullNameLength += sizeof( WCHAR);
1152         }
1153
1154         if( bAddTrailingSlash)
1155         {
1156             usFullNameLength += sizeof( WCHAR);
1157         }
1158
1159         if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1160         {
1161
1162             ulCopyLength = (LONG)usFullNameLength;
1163         }
1164         else
1165         {
1166
1167             ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1168
1169             ntStatus = STATUS_BUFFER_OVERFLOW;
1170         }
1171
1172         Buffer->FileNameLength = (ULONG)usFullNameLength;
1173
1174         *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1175
1176         if( ulCopyLength > 0)
1177         {
1178
1179             Buffer->FileName[ 0] = L'\\';
1180             ulCopyLength -= sizeof( WCHAR);
1181
1182             *Length -= sizeof( WCHAR);
1183             cchCopied += 1;
1184
1185             if( ulCopyLength >= AFSServerName.Length)
1186             {
1187
1188                 RtlCopyMemory( &Buffer->FileName[ 1],
1189                                AFSServerName.Buffer,
1190                                AFSServerName.Length);
1191
1192                 ulCopyLength -= AFSServerName.Length;
1193                 *Length -= AFSServerName.Length;
1194                 cchCopied += AFSServerName.Length/sizeof( WCHAR);
1195
1196                 if ( ulCopyLength > 0 &&
1197                      bAddLeadingSlash)
1198                 {
1199
1200                     Buffer->FileName[ cchCopied] = L'\\';
1201
1202                     ulCopyLength -= sizeof( WCHAR);
1203                     *Length -= sizeof( WCHAR);
1204                     cchCopied++;
1205                 }
1206
1207                 if( ulCopyLength >= pCcb->FullFileName.Length)
1208                 {
1209
1210                     RtlCopyMemory( &Buffer->FileName[ cchCopied],
1211                                    pCcb->FullFileName.Buffer,
1212                                    pCcb->FullFileName.Length);
1213
1214                     ulCopyLength -= pCcb->FullFileName.Length;
1215                     *Length -= pCcb->FullFileName.Length;
1216                     cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1217
1218                     if( ulCopyLength > 0 &&
1219                         bAddTrailingSlash)
1220                     {
1221                         Buffer->FileName[ cchCopied] = L'\\';
1222
1223                         *Length -= sizeof( WCHAR);
1224                     }
1225                 }
1226                 else
1227                 {
1228
1229                     RtlCopyMemory( &Buffer->FileName[ cchCopied],
1230                                    pCcb->FullFileName.Buffer,
1231                                    ulCopyLength);
1232
1233                     *Length -= ulCopyLength;
1234                 }
1235             }
1236         }
1237     }
1238     else
1239     {
1240
1241         ntStatus = STATUS_BUFFER_TOO_SMALL;
1242     }
1243
1244     return ntStatus;
1245 }
1246
1247 NTSTATUS
1248 AFSQueryShortNameInfo( IN PIRP Irp,
1249                        IN AFSDirectoryCB *DirectoryCB,
1250                        IN OUT PFILE_NAME_INFORMATION Buffer,
1251                        IN OUT PLONG Length)
1252 {
1253
1254     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1255     ULONG ulCopyLength = 0;
1256
1257     RtlZeroMemory( Buffer,
1258                    *Length);
1259
1260     if( DirectoryCB->NameInformation.ShortNameLength == 0)
1261     {
1262
1263         //
1264         // The short name IS the long name
1265         //
1266
1267         if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1268         {
1269
1270             if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1271             {
1272
1273                 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1274
1275                 ntStatus = STATUS_SUCCESS;
1276             }
1277             else
1278             {
1279
1280                 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1281
1282                 ntStatus = STATUS_BUFFER_OVERFLOW;
1283             }
1284
1285             Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1286
1287             *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1288
1289             if( ulCopyLength > 0)
1290             {
1291
1292                 RtlCopyMemory( Buffer->FileName,
1293                                DirectoryCB->NameInformation.FileName.Buffer,
1294                                ulCopyLength);
1295
1296                 *Length -= ulCopyLength;
1297             }
1298         }
1299     }
1300     else
1301     {
1302
1303         if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1304         {
1305
1306             if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1307             {
1308
1309                 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1310
1311                 ntStatus = STATUS_SUCCESS;
1312             }
1313             else
1314             {
1315
1316                 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1317
1318                 ntStatus = STATUS_BUFFER_OVERFLOW;
1319             }
1320
1321             Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1322
1323             *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1324
1325             if( ulCopyLength > 0)
1326             {
1327
1328                 RtlCopyMemory( Buffer->FileName,
1329                                DirectoryCB->NameInformation.ShortName,
1330                                Buffer->FileNameLength);
1331
1332                 *Length -= ulCopyLength;
1333             }
1334         }
1335     }
1336
1337     return ntStatus;
1338 }
1339
1340 NTSTATUS
1341 AFSQueryNetworkInfo( IN PIRP Irp,
1342                      IN AFSDirectoryCB *DirectoryCB,
1343                      IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1344                      IN OUT PLONG Length)
1345 {
1346
1347     NTSTATUS ntStatus = STATUS_SUCCESS;
1348     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1349     AFSFcb *pFcb = NULL;
1350     AFSCcb *pCcb = NULL;
1351     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1352     AFSFileInfoCB stFileInfo;
1353     AFSDirectoryCB *pParentDirectoryCB = NULL;
1354     UNICODE_STRING uniParentPath;
1355     ULONG ulFileAttribs = 0;
1356
1357     RtlZeroMemory( Buffer,
1358                    *Length);
1359
1360     if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
1361     {
1362
1363         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1364
1365         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1366         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1367
1368         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1369         {
1370
1371             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1372
1373             AFSRetrieveParentPath( &pCcb->FullFileName,
1374                                    &uniParentPath);
1375
1376             RtlZeroMemory( &stFileInfo,
1377                            sizeof( AFSFileInfoCB));
1378
1379             //
1380             // Can't hold the Fcb while evaluating the path, leads to lock inversion
1381             //
1382
1383             AFSReleaseResource( &pFcb->NPFcb->Resource);
1384
1385             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1386                                                        DirectoryCB,
1387                                                        &uniParentPath,
1388                                                        NULL,
1389                                                        &pCcb->AuthGroup,
1390                                                        &stFileInfo)))
1391             {
1392                 ulFileAttribs = stFileInfo.FileAttributes;
1393
1394                 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1395             }
1396
1397             AFSAcquireShared( &pFcb->NPFcb->Resource,
1398                               TRUE);
1399         }
1400
1401         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1402                       AFS_TRACE_LEVEL_VERBOSE_2,
1403                       "AFSQueryNetworkInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1404                       &pCcb->DirectoryCB->NameInformation.FileName,
1405                       pCcb->DirectoryCB->ObjectInformation->FileType,
1406                       pCcb->DirectoryCB->ObjectInformation->FileAttributes,
1407                       ulFileAttribs);
1408
1409         Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1410         Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1411         Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1412         Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1413
1414         Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1415         Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1416
1417         Buffer->FileAttributes = ulFileAttribs;
1418
1419         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1420             BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1421         {
1422
1423             if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1424             {
1425
1426                 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1427             }
1428             else
1429             {
1430
1431                 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1432             }
1433         }
1434
1435         *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1436     }
1437     else
1438     {
1439
1440         ntStatus = STATUS_BUFFER_TOO_SMALL;
1441     }
1442
1443     return ntStatus;
1444 }
1445
1446 NTSTATUS
1447 AFSQueryStreamInfo( IN PIRP Irp,
1448                     IN AFSDirectoryCB *DirectoryCB,
1449                     IN OUT FILE_STREAM_INFORMATION *Buffer,
1450                     IN OUT PLONG Length)
1451 {
1452
1453     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1454     ULONG ulCopyLength = 0;
1455     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1456
1457     if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1458     {
1459
1460         RtlZeroMemory( Buffer,
1461                        *Length);
1462
1463         Buffer->NextEntryOffset = 0;
1464
1465
1466         if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1467         {
1468
1469             if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14))  // ::$DATA
1470             {
1471
1472                 ulCopyLength = 14;
1473
1474                 ntStatus = STATUS_SUCCESS;
1475             }
1476             else
1477             {
1478
1479                 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1480
1481                 ntStatus = STATUS_BUFFER_OVERFLOW;
1482             }
1483
1484             Buffer->StreamNameLength = 14; // ::$DATA
1485
1486             Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1487
1488             Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1489
1490             *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1491
1492             if( ulCopyLength > 0)
1493             {
1494
1495                 RtlCopyMemory( Buffer->StreamName,
1496                                L"::$DATA",
1497                                ulCopyLength);
1498
1499                 *Length -= ulCopyLength;
1500             }
1501         }
1502         else
1503         {
1504
1505             Buffer->StreamNameLength = 0;       // No stream for a directory
1506
1507             // The response size is zero
1508
1509             ntStatus = STATUS_SUCCESS;
1510         }
1511     }
1512
1513     return ntStatus;
1514 }
1515
1516 NTSTATUS
1517 AFSQueryAttribTagInfo( IN PIRP Irp,
1518                        IN AFSDirectoryCB *DirectoryCB,
1519                        IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1520                        IN OUT PLONG Length)
1521 {
1522
1523     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1524     ULONG ulCopyLength = 0;
1525     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1526     AFSFcb *pFcb = NULL;
1527     AFSCcb *pCcb = NULL;
1528     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1529     AFSFileInfoCB stFileInfo;
1530     AFSDirectoryCB *pParentDirectoryCB = NULL;
1531     UNICODE_STRING uniParentPath;
1532     ULONG ulFileAttribs = 0;
1533
1534     if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1535     {
1536
1537         RtlZeroMemory( Buffer,
1538                        *Length);
1539
1540         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1541
1542         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1543         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1544
1545         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1546         {
1547
1548             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1549
1550             AFSRetrieveParentPath( &pCcb->FullFileName,
1551                                    &uniParentPath);
1552
1553             RtlZeroMemory( &stFileInfo,
1554                            sizeof( AFSFileInfoCB));
1555
1556             //
1557             // Can't hold the Fcb while evaluating the path, leads to lock inversion
1558             //
1559
1560             AFSReleaseResource( &pFcb->NPFcb->Resource);
1561
1562             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1563                                                        DirectoryCB,
1564                                                        &uniParentPath,
1565                                                        NULL,
1566                                                        &pCcb->AuthGroup,
1567                                                        &stFileInfo)))
1568             {
1569                 ulFileAttribs = stFileInfo.FileAttributes;
1570
1571                 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1572             }
1573
1574             AFSAcquireShared( &pFcb->NPFcb->Resource,
1575                               TRUE);
1576         }
1577
1578         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1579                       AFS_TRACE_LEVEL_VERBOSE_2,
1580                       "AFSAttribTagInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1581                       &pCcb->DirectoryCB->NameInformation.FileName,
1582                       pCcb->DirectoryCB->ObjectInformation->FileType,
1583                       pCcb->DirectoryCB->ObjectInformation->FileAttributes,
1584                       ulFileAttribs);
1585
1586         Buffer->FileAttributes = ulFileAttribs;
1587
1588         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1589             BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1590         {
1591
1592             if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1593             {
1594
1595                 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1596             }
1597             else
1598             {
1599
1600                 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1601             }
1602         }
1603
1604         if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1605         {
1606             Buffer->ReparseTag = IO_REPARSE_TAG_OPENAFS_DFS;
1607         }
1608
1609         *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1610
1611         ntStatus = STATUS_SUCCESS;
1612     }
1613
1614     return ntStatus;
1615 }
1616
1617 NTSTATUS
1618 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1619                             IN AFSDirectoryCB *DirectoryCB,
1620                             IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1621                             IN OUT PLONG Length)
1622 {
1623
1624     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1625     ULONG ulCopyLength = 0;
1626     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1627
1628     if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1629     {
1630
1631         RtlZeroMemory( Buffer,
1632                        *Length);
1633
1634         Buffer->StructureVersion = 1;
1635
1636         Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1637
1638         Buffer->Protocol = WNNC_NET_OPENAFS;
1639
1640         Buffer->ProtocolMajorVersion = 3;
1641
1642         Buffer->ProtocolMinorVersion = 0;
1643
1644         Buffer->ProtocolRevision = 0;
1645
1646         *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1647
1648         ntStatus = STATUS_SUCCESS;
1649     }
1650
1651     return ntStatus;
1652 }
1653
1654 NTSTATUS
1655 AFSQueryPhysicalNameInfo( IN PIRP Irp,
1656                           IN AFSDirectoryCB *DirectoryCB,
1657                           IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
1658                           IN OUT PLONG Length)
1659 {
1660
1661     NTSTATUS ntStatus = STATUS_SUCCESS;
1662     ULONG ulCopyLength = 0;
1663     ULONG cchCopied = 0;
1664     AFSFcb *pFcb = NULL;
1665     AFSCcb *pCcb = NULL;
1666     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1667     BOOLEAN bAddLeadingSlash = FALSE;
1668     USHORT usFullNameLength = 0;
1669
1670     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1671
1672     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1673
1674     if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
1675     {
1676
1677         RtlZeroMemory( Buffer,
1678                        *Length);
1679
1680         if( pCcb->FullFileName.Length == 0 ||
1681             pCcb->FullFileName.Buffer[ 0] != L'\\')
1682         {
1683             bAddLeadingSlash = TRUE;
1684         }
1685
1686         usFullNameLength = pCcb->FullFileName.Length;
1687
1688         if( bAddLeadingSlash)
1689         {
1690             usFullNameLength += sizeof( WCHAR);
1691         }
1692
1693         if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1694         {
1695             ulCopyLength = (LONG)usFullNameLength;
1696         }
1697         else
1698         {
1699
1700             ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1701
1702             ntStatus = STATUS_BUFFER_OVERFLOW;
1703         }
1704
1705         Buffer->FileNameLength = (ULONG)usFullNameLength;
1706
1707         *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1708
1709         if( ulCopyLength > 0)
1710         {
1711
1712             if( bAddLeadingSlash)
1713             {
1714
1715                 Buffer->FileName[ cchCopied] = L'\\';
1716
1717                 ulCopyLength -= sizeof( WCHAR);
1718                 *Length -= sizeof( WCHAR);
1719                 cchCopied++;
1720             }
1721
1722             if( ulCopyLength >= pCcb->FullFileName.Length)
1723             {
1724
1725                 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1726                                pCcb->FullFileName.Buffer,
1727                                pCcb->FullFileName.Length);
1728
1729                 ulCopyLength -= pCcb->FullFileName.Length;
1730                 *Length -= pCcb->FullFileName.Length;
1731                 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1732             }
1733             else
1734             {
1735
1736                 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1737                                pCcb->FullFileName.Buffer,
1738                                ulCopyLength);
1739
1740                 *Length -= ulCopyLength;
1741             }
1742         }
1743     }
1744     else
1745     {
1746
1747         ntStatus = STATUS_BUFFER_TOO_SMALL;
1748     }
1749
1750     return ntStatus;
1751 }
1752
1753 NTSTATUS
1754 AFSSetBasicInfo( IN PIRP Irp,
1755                  IN AFSDirectoryCB *DirectoryCB)
1756 {
1757     NTSTATUS ntStatus = STATUS_SUCCESS;
1758     PFILE_BASIC_INFORMATION pBuffer;
1759     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1760     ULONG ulNotifyFilter = 0;
1761     AFSCcb *pCcb = NULL;
1762
1763     __Enter
1764     {
1765
1766         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1767
1768         pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1769
1770         pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1771
1772         if( pBuffer->FileAttributes != (ULONGLONG)0)
1773         {
1774
1775             if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
1776                 BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1777             {
1778
1779                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1780             }
1781
1782             if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1783             {
1784
1785                 pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1786             }
1787
1788             pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1789
1790             DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
1791
1792             ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1793
1794             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1795         }
1796
1797         pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
1798
1799         if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
1800             pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
1801         {
1802
1803             pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1804
1805             DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
1806
1807             ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
1808
1809             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
1810         }
1811
1812         pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
1813
1814         if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
1815             pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
1816         {
1817
1818             pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1819
1820             DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
1821
1822             ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1823
1824             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
1825         }
1826
1827         pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
1828
1829         if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
1830             pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
1831         {
1832
1833             pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1834
1835             DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
1836
1837             ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
1838
1839             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
1840         }
1841
1842         pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
1843
1844         if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
1845             pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
1846         {
1847
1848             pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1849
1850             DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
1851
1852             ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1853
1854             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
1855         }
1856
1857         if( ulNotifyFilter > 0)
1858         {
1859
1860             if( DirectoryCB->ObjectInformation->ParentObjectInformation != NULL)
1861             {
1862
1863                 AFSFsRtlNotifyFullReportChange( DirectoryCB->ObjectInformation->ParentObjectInformation,
1864                                                 pCcb,
1865                                                 (ULONG)ulNotifyFilter,
1866                                                 (ULONG)FILE_ACTION_MODIFIED);
1867             }
1868         }
1869
1870 try_exit:
1871
1872         NOTHING;
1873     }
1874
1875     return ntStatus;
1876 }
1877
1878 NTSTATUS
1879 AFSSetDispositionInfo( IN PIRP Irp,
1880                        IN AFSDirectoryCB *DirectoryCB)
1881 {
1882     NTSTATUS ntStatus = STATUS_SUCCESS;
1883     PFILE_DISPOSITION_INFORMATION pBuffer;
1884     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1885     AFSFcb *pFcb = NULL;
1886     AFSCcb *pCcb = NULL;
1887
1888     __Enter
1889     {
1890
1891         pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1892
1893         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1894
1895         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1896
1897         //
1898         // Can't delete the root
1899         //
1900
1901         if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
1902         {
1903
1904             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1905                           AFS_TRACE_LEVEL_ERROR,
1906                           "AFSSetDispositionInfo Attempt to delete root entry\n");
1907
1908             try_return( ntStatus = STATUS_CANNOT_DELETE);
1909         }
1910
1911         //
1912         // If the file is read only then do not allow the delete
1913         //
1914
1915         if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
1916         {
1917
1918             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1919                           AFS_TRACE_LEVEL_ERROR,
1920                           "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
1921                           &DirectoryCB->NameInformation.FileName);
1922
1923             try_return( ntStatus = STATUS_CANNOT_DELETE);
1924         }
1925
1926         if( pBuffer->DeleteFile)
1927         {
1928
1929             //
1930             // Check if the caller can delete the file
1931             //
1932
1933             ntStatus = AFSNotifyDelete( DirectoryCB,
1934                                         &pCcb->AuthGroup,
1935                                         TRUE);
1936
1937             if( !NT_SUCCESS( ntStatus))
1938             {
1939
1940                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1941                               AFS_TRACE_LEVEL_ERROR,
1942                               "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
1943                               &DirectoryCB->NameInformation.FileName,
1944                               ntStatus);
1945
1946                 try_return( ntStatus);
1947             }
1948
1949             if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1950             {
1951
1952                 //
1953                 // Check if this is a directory that there are not currently other opens
1954                 //
1955
1956                 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
1957                 {
1958
1959                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1960                                   AFS_TRACE_LEVEL_ERROR,
1961                                   "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
1962                                   &DirectoryCB->NameInformation.FileName,
1963                                   pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount);
1964
1965                     try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
1966                 }
1967
1968                 if( !AFSIsDirectoryEmptyForDelete( pFcb))
1969                 {
1970
1971                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1972                                   AFS_TRACE_LEVEL_ERROR,
1973                                   "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
1974                                   &DirectoryCB->NameInformation.FileName);
1975
1976                     try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
1977                 }
1978             }
1979             else
1980             {
1981
1982                 //
1983                 // Attempt to flush any outstanding data
1984                 //
1985
1986                 if( !MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
1987                                           MmFlushForDelete))
1988                 {
1989
1990                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1991                                   AFS_TRACE_LEVEL_ERROR,
1992                                   "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
1993                                   &DirectoryCB->NameInformation.FileName);
1994
1995                     try_return( ntStatus = STATUS_CANNOT_DELETE);
1996                 }
1997
1998                 //
1999                 // Purge the cache as well
2000                 //
2001
2002                 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2003                 {
2004
2005                     CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
2006                                          NULL,
2007                                          0,
2008                                          TRUE);
2009                 }
2010             }
2011
2012             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2013                           AFS_TRACE_LEVEL_VERBOSE,
2014                           "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry  %p Name %wZ\n",
2015                           DirectoryCB,
2016                           &DirectoryCB->NameInformation.FileName);
2017
2018             SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2019         }
2020         else
2021         {
2022
2023             ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2024         }
2025
2026         //
2027         // OK, should be good to go, set the flag in the file object
2028         //
2029
2030         pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2031
2032 try_exit:
2033
2034         NOTHING;
2035     }
2036
2037     return ntStatus;
2038 }
2039
2040 NTSTATUS
2041 AFSSetRenameInfo( IN PIRP Irp)
2042 {
2043
2044     NTSTATUS ntStatus = STATUS_SUCCESS;
2045     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2046     IO_STATUS_BLOCK stIoSb = {0,0};
2047     AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2048     AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2049     PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2050     PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2051     PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2052     UNICODE_STRING uniTargetName, uniSourceName;
2053     BOOLEAN bReplaceIfExists = FALSE;
2054     UNICODE_STRING uniShortName;
2055     AFSDirectoryCB *pTargetDirEntry = NULL;
2056     ULONG ulTargetCRC = 0;
2057     BOOLEAN bTargetEntryExists = FALSE;
2058     AFSObjectInfoCB *pSrcObject = NULL, *pTargetObject = NULL;
2059     AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2060     AFSFileID stNewFid, stTmpTargetFid;
2061     ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2062     UNICODE_STRING uniFullTargetPath;
2063     BOOLEAN bCommonParent = FALSE;
2064     BOOLEAN bReleaseTargetDirLock = FALSE;
2065     BOOLEAN bReleaseSourceDirLock = FALSE;
2066     PERESOURCE  pSourceDirLock = NULL;
2067
2068     __Enter
2069     {
2070
2071         bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2072
2073         pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2074         pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2075
2076         pSrcObject = pSrcFcb->ObjectInformation;
2077
2078         //
2079         // Perform some basic checks to ensure FS integrity
2080         //
2081
2082         if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2083         {
2084
2085             //
2086             // Can't rename the root directory
2087             //
2088
2089             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2090                           AFS_TRACE_LEVEL_ERROR,
2091                           "AFSSetRenameInfo Attempt to rename root entry\n");
2092
2093             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2094         }
2095
2096         if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2097         {
2098
2099             //
2100             // If there are any open children then fail the rename
2101             //
2102
2103             if( pSrcFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2104             {
2105
2106                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2107                               AFS_TRACE_LEVEL_ERROR,
2108                               "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2109                               &pSrcCcb->DirectoryCB->NameInformation.FileName);
2110
2111                 try_return( ntStatus = STATUS_ACCESS_DENIED);
2112             }
2113         }
2114         else
2115         {
2116
2117             if( pSrcFcb->OpenHandleCount > 1)
2118             {
2119
2120                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2121                               AFS_TRACE_LEVEL_ERROR,
2122                               "AFSSetRenameInfo Attempt to rename directory with open references %wZ\n",
2123                               &pSrcCcb->DirectoryCB->NameInformation.FileName);
2124
2125                 try_return( ntStatus = STATUS_ACCESS_DENIED);
2126             }
2127         }
2128
2129         //
2130         // Resolve the target fileobject
2131         //
2132
2133         if( pTargetFileObj == NULL)
2134         {
2135
2136             //
2137             // This is a simple rename. Here the target directory is the same as the source parent directory
2138             // and the name is retrieved from the system buffer information
2139             //
2140
2141             pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2142
2143             pTargetParentObject = pSrcFcb->ObjectInformation->ParentObjectInformation;
2144
2145             pTargetDcb = pTargetParentObject->Fcb;
2146
2147             uniTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2148             uniTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2149         }
2150         else
2151         {
2152
2153             //
2154             // So here we have the target directory taken from the targetfile object
2155             //
2156
2157             pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2158
2159             pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2160
2161             pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2162
2163             //
2164             // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2165             // it is only the target component of the rename operation
2166             //
2167
2168             uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2169         }
2170
2171         //
2172         // We do not allow cross-volume renames to occur
2173         //
2174
2175         if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2176         {
2177
2178             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2179                           AFS_TRACE_LEVEL_ERROR,
2180                           "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2181                           &pSrcCcb->DirectoryCB->NameInformation.FileName);
2182
2183             try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2184         }
2185
2186         ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2187                                       FALSE);
2188
2189         AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2190                         TRUE);
2191
2192         bReleaseTargetDirLock = TRUE;
2193
2194         if( pTargetParentObject != pSrcFcb->ObjectInformation->ParentObjectInformation)
2195         {
2196             AFSAcquireExcl( pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2197                             TRUE);
2198
2199             bReleaseSourceDirLock = TRUE;
2200
2201             pSourceDirLock = pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock;
2202         }
2203
2204         AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2205                                         ulTargetCRC,
2206                                         &pTargetDirEntry);
2207
2208         if( pTargetDirEntry == NULL)
2209         {
2210
2211             //
2212             // Missed so perform a case insensitive lookup
2213             //
2214
2215             ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2216                                           TRUE);
2217
2218             AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2219                                               ulTargetCRC,
2220                                               &pTargetDirEntry);
2221         }
2222
2223         if( pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2224                                                                NULL,
2225                                                                NULL))
2226         {
2227             //
2228             // Try the short name
2229             //
2230             AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2231                                         ulTargetCRC,
2232                                         &pTargetDirEntry);
2233         }
2234
2235         //
2236         // Increment our ref count on the dir entry
2237         //
2238
2239         if( pTargetDirEntry != NULL)
2240         {
2241
2242             ASSERT( pTargetParentObject == pTargetDirEntry->ObjectInformation->ParentObjectInformation);
2243
2244             InterlockedIncrement( &pTargetDirEntry->OpenReferenceCount);
2245
2246             if( !bReplaceIfExists)
2247             {
2248
2249                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2250                               AFS_TRACE_LEVEL_ERROR,
2251                               "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
2252                               &pSrcCcb->DirectoryCB->NameInformation.FileName,
2253                               &pTargetDirEntry->NameInformation.FileName);
2254
2255                 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2256             }
2257
2258             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2259                           AFS_TRACE_LEVEL_ERROR,
2260                           "AFSSetRenameInfo Target %wZ exists DE %p Count %08lX, performing delete of target\n",
2261                           &pTargetDirEntry->NameInformation.FileName,
2262                           pTargetDirEntry,
2263                           pTargetDirEntry->OpenReferenceCount);
2264
2265             //
2266             // Pull the directory entry from the parent
2267             //
2268
2269             AFSRemoveDirNodeFromParent( pTargetParentObject,
2270                                         pTargetDirEntry,
2271                                         FALSE);
2272
2273             bTargetEntryExists = TRUE;
2274         }
2275         else
2276         {
2277             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2278                           AFS_TRACE_LEVEL_VERBOSE,
2279                           "AFSSetRenameInfo Target does NOT exist, normal rename\n");
2280         }
2281
2282         //
2283         // Extract off the final component name from the Fcb
2284         //
2285
2286         uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2287         uniSourceName.MaximumLength = uniSourceName.Length;
2288
2289         uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2290
2291         //
2292         // The quick check to see if they are not really performing a rename
2293         // Do the names match? Only do this where the parent directories are
2294         // the same
2295         //
2296
2297         if( pTargetParentObject == pSrcFcb->ObjectInformation->ParentObjectInformation)
2298         {
2299
2300             bCommonParent = TRUE;
2301
2302             if( FsRtlAreNamesEqual( &uniTargetName,
2303                                     &uniSourceName,
2304                                     FALSE,
2305                                     NULL))
2306             {
2307                 try_return( ntStatus = STATUS_SUCCESS);
2308             }
2309         }
2310         else
2311         {
2312
2313             bCommonParent = FALSE;
2314         }
2315
2316         //
2317         // We need to remove the DirEntry from the parent node, update the index
2318         // and reinsert it into the parent tree. Note that for entries with the
2319         // same parent we do not pull the node from the enumeration list
2320         //
2321
2322         AFSRemoveDirNodeFromParent( pSrcFcb->ObjectInformation->ParentObjectInformation,
2323                                     pSrcCcb->DirectoryCB,
2324                                     !bCommonParent);
2325
2326         //
2327         // OK, this is a simple rename. Issue the rename
2328         // request to the service.
2329         //
2330
2331         ntStatus = AFSNotifyRename( pSrcFcb->ObjectInformation,
2332                                     &pSrcCcb->AuthGroup,
2333                                     pSrcFcb->ObjectInformation->ParentObjectInformation,
2334                                     pTargetDcb->ObjectInformation,
2335                                     pSrcCcb->DirectoryCB,
2336                                     &uniTargetName,
2337                                     &stNewFid);
2338
2339         if( !NT_SUCCESS( ntStatus))
2340         {
2341
2342             //
2343             // Attempt to re-insert the directory entry
2344             //
2345
2346             AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2347                                     pSrcCcb->DirectoryCB,
2348                                     !bCommonParent);
2349
2350             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2351                           AFS_TRACE_LEVEL_ERROR,
2352                           "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
2353                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
2354                           &uniTargetName,
2355                           ntStatus);
2356
2357             try_return( ntStatus);
2358         }
2359
2360         //
2361         // Set the notification up for the source file
2362         //
2363
2364         if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation == pTargetParentObject &&
2365             !bTargetEntryExists)
2366         {
2367
2368             ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
2369         }
2370         else
2371         {
2372
2373             ulNotificationAction = FILE_ACTION_REMOVED;
2374         }
2375
2376         if( pSrcCcb->DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
2377         {
2378
2379             ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2380         }
2381         else
2382         {
2383
2384             ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2385         }
2386
2387         AFSFsRtlNotifyFullReportChange( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation,
2388                                         pSrcCcb,
2389                                         (ULONG)ulNotifyFilter,
2390                                         (ULONG)ulNotificationAction);
2391
2392         //
2393         // Update the name in the dir entry.
2394         //
2395
2396         ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
2397                                           &uniTargetName);
2398
2399         if( !NT_SUCCESS( ntStatus))
2400         {
2401
2402             //
2403             // Attempt to re-insert the directory entry
2404             //
2405
2406             AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2407                                     pSrcCcb->DirectoryCB,
2408                                     !bCommonParent);
2409
2410             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2411                           AFS_TRACE_LEVEL_ERROR,
2412                           "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
2413                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
2414                           &uniTargetName,
2415                           ntStatus);
2416
2417             try_return( ntStatus);
2418         }
2419
2420         //
2421         // Update the object information block, if needed
2422         //
2423
2424         if( !AFSIsEqualFID( &pSrcObject->FileId,
2425                             &stNewFid))
2426         {
2427
2428             AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
2429                             TRUE);
2430
2431             //
2432             // Remove the old information entry
2433             //
2434
2435             AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2436                                 &pSrcObject->TreeEntry);
2437
2438             RtlCopyMemory( &pSrcObject->FileId,
2439                            &stNewFid,
2440                            sizeof( AFSFileID));
2441
2442             //
2443             // Insert the entry into the new object table.
2444             //
2445
2446             pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
2447
2448             if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
2449             {
2450
2451                 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
2452             }
2453             else
2454             {
2455
2456                 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2457                                                      &pSrcObject->TreeEntry)))
2458                 {
2459
2460                     //
2461                     // Lost a race, an ObjectInfo object already exists for this FID.
2462                     // Let this copy be garbage collected.
2463                     //
2464
2465                     ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
2466                 }
2467             }
2468
2469             AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
2470         }
2471
2472         //
2473         // Update the hash values for the name trees.
2474         //
2475
2476         pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2477                                                                                  FALSE);
2478
2479         pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2480                                                                                    TRUE);
2481
2482         if( pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
2483             !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2484                                      NULL,
2485                                      NULL))
2486         {
2487
2488             uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
2489             uniShortName.MaximumLength = uniShortName.Length;
2490             uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
2491
2492             pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
2493                                                                                            TRUE);
2494
2495             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2496                           AFS_TRACE_LEVEL_VERBOSE,
2497                           "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
2498                           &uniShortName,
2499                           &pSrcCcb->DirectoryCB->NameInformation.FileName);
2500         }
2501         else
2502         {
2503
2504             pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
2505         }
2506
2507         if( !bCommonParent)
2508         {
2509
2510             //
2511             // Update the file index for the object in the new parent
2512             //
2513
2514             pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
2515         }
2516
2517         //
2518         // Re-insert the directory entry
2519         //
2520
2521         AFSInsertDirectoryNode( pTargetParentObject,
2522                                 pSrcCcb->DirectoryCB,
2523                                 !bCommonParent);
2524
2525         //
2526         // Update the parent pointer in the source object if they are different
2527         //
2528
2529         if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation != pTargetParentObject)
2530         {
2531
2532             InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2533
2534             InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2535
2536             InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
2537
2538             InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
2539
2540             pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation = pTargetParentObject;
2541
2542             ulNotificationAction = FILE_ACTION_ADDED;
2543         }
2544         else
2545         {
2546
2547             ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
2548         }
2549
2550         //
2551         // Now update the notification for the target file
2552         //
2553
2554         AFSFsRtlNotifyFullReportChange( pTargetParentObject->ParentObjectInformation,
2555                                         pSrcCcb,
2556                                         (ULONG)ulNotifyFilter,
2557                                         (ULONG)ulNotificationAction);
2558
2559         //
2560         // If we performed the rename of the target because it existed, we now need to
2561         // delete the tmp target we created above
2562         //
2563
2564         if( bTargetEntryExists)
2565         {
2566
2567             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2568                           AFS_TRACE_LEVEL_VERBOSE,
2569                           "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
2570                           pTargetDirEntry,
2571                           &pTargetDirEntry->NameInformation.FileName);
2572
2573             SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2574
2575             //
2576             // Try and purge the cache map if this is a file
2577             //
2578
2579             if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
2580                 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
2581                 pTargetDirEntry->OpenReferenceCount > 1)
2582             {
2583
2584                 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
2585
2586                 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
2587                                 TRUE);
2588
2589                 //
2590                 // Close the section in the event it was mapped
2591                 //
2592
2593                 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
2594                                            TRUE))
2595                 {
2596
2597                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2598                                   AFS_TRACE_LEVEL_ERROR,
2599                                   "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
2600                                   &pTargetDirEntry->NameInformation.FileName);
2601                 }
2602
2603                 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
2604             }
2605
2606             ASSERT( pTargetDirEntry->OpenReferenceCount > 0);
2607
2608             InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount); // The count we added above
2609
2610             if( pTargetDirEntry->OpenReferenceCount == 0)
2611             {
2612
2613                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2614                               AFS_TRACE_LEVEL_VERBOSE,
2615                               "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
2616                               pTargetDirEntry,
2617                               &pTargetDirEntry->NameInformation.FileName);
2618
2619                 AFSDeleteDirEntry( pTargetParentObject,
2620                                    pTargetDirEntry);
2621             }
2622
2623             pTargetDirEntry = NULL;
2624         }
2625
2626 try_exit:
2627
2628
2629         if( !NT_SUCCESS( ntStatus))
2630         {
2631
2632             if( bTargetEntryExists)
2633             {
2634                 AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
2635                                         pTargetDirEntry,
2636                                         FALSE);
2637             }
2638         }
2639
2640         if( pTargetDirEntry != NULL)
2641         {
2642
2643             InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
2644         }
2645
2646         if( bReleaseTargetDirLock)
2647         {
2648             AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2649         }
2650
2651         if( bReleaseSourceDirLock)
2652         {
2653             AFSReleaseResource( pSourceDirLock);
2654         }
2655     }
2656
2657     return ntStatus;
2658 }
2659
2660 NTSTATUS
2661 AFSSetPositionInfo( IN PIRP Irp,
2662                     IN AFSDirectoryCB *DirectoryCB)
2663 {
2664     NTSTATUS ntStatus = STATUS_SUCCESS;
2665     PFILE_POSITION_INFORMATION pBuffer;
2666     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2667
2668     pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2669
2670     pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
2671
2672     return ntStatus;
2673 }
2674
2675 NTSTATUS
2676 AFSSetAllocationInfo( IN PIRP Irp,
2677                       IN AFSDirectoryCB *DirectoryCB)
2678 {
2679     NTSTATUS ntStatus = STATUS_SUCCESS;
2680     PFILE_ALLOCATION_INFORMATION pBuffer;
2681     BOOLEAN bReleasePaging = FALSE;
2682     BOOLEAN bTellCc = FALSE;
2683     BOOLEAN bTellService = FALSE;
2684     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2685     PFILE_OBJECT pFileObject = pIrpSp->FileObject;
2686     AFSFcb *pFcb = NULL;
2687     AFSCcb *pCcb = NULL;
2688     LARGE_INTEGER liSaveAlloc;
2689     LARGE_INTEGER liSaveFileSize;
2690     LARGE_INTEGER liSaveVDL;
2691
2692     pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2693
2694     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2695
2696     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2697
2698     //
2699     // save values to put back
2700     //
2701     liSaveAlloc = pFcb->Header.AllocationSize;
2702     liSaveFileSize = pFcb->Header.FileSize;
2703     liSaveVDL = pFcb->Header.ValidDataLength;
2704
2705     if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
2706         pIrpSp->Parameters.SetFile.AdvanceOnly)
2707     {
2708         return STATUS_SUCCESS ;
2709     }
2710
2711     if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
2712     {
2713         //
2714         // Truncating the file
2715         //
2716         if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
2717                                    &pBuffer->AllocationSize))
2718         {
2719
2720             ntStatus = STATUS_USER_MAPPED_FILE ;
2721         }
2722         else
2723         {
2724             //
2725             // If this is a truncation we need to grab the paging IO resource.
2726             //
2727             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2728                           AFS_TRACE_LEVEL_VERBOSE,
2729                           "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2730                           &pFcb->NPFcb->PagingResource,
2731                           PsGetCurrentThread());
2732
2733             AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2734                             TRUE);
2735
2736             bReleasePaging = TRUE;
2737
2738
2739             pFcb->Header.AllocationSize = pBuffer->AllocationSize;
2740
2741             pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
2742
2743             //
2744             // Tell Cc that Allocation is moved.
2745             //
2746             bTellCc = TRUE;
2747
2748             if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
2749             {
2750                 //
2751                 // We are pulling the EOF back as well so we need to tell
2752                 // the service.
2753                 //
2754                 bTellService = TRUE;
2755
2756                 pFcb->Header.FileSize = pBuffer->AllocationSize;
2757
2758                 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
2759             }
2760
2761         }
2762     }
2763     else
2764     {
2765         //
2766         // Tell Cc if allocation is increased.
2767         //
2768         bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
2769
2770         pFcb->Header.AllocationSize = pBuffer->AllocationSize;
2771
2772         pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
2773     }
2774
2775     //
2776     // Now Tell the server if we have to
2777     //
2778     if (bTellService)
2779     {
2780         ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
2781                                              pFcb->ObjectInformation,
2782                                              &pCcb->AuthGroup);
2783     }
2784
2785     if (NT_SUCCESS(ntStatus))
2786     {
2787         //
2788         // Trim extents if we told the service - the update has done an implicit
2789         // trim at the service.
2790         //
2791         if (bTellService)
2792         {
2793             AFSTrimExtents( pFcb,
2794                             &pFcb->Header.FileSize);
2795         }
2796
2797         KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
2798
2799         SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2800
2801         if (bTellCc &&
2802             CcIsFileCached( pFileObject))
2803         {
2804             CcSetFileSizes( pFileObject,
2805                             (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
2806         }
2807     }
2808     else
2809     {
2810         //
2811         // Put the saved values back
2812         //
2813         pFcb->Header.ValidDataLength = liSaveVDL;
2814         pFcb->Header.FileSize = liSaveFileSize;
2815         pFcb->Header.AllocationSize = liSaveAlloc;
2816         pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
2817         pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
2818     }
2819
2820     if( bReleasePaging)
2821     {
2822
2823         AFSReleaseResource( &pFcb->NPFcb->PagingResource);
2824     }
2825
2826     return ntStatus;
2827 }
2828
2829 NTSTATUS
2830 AFSSetEndOfFileInfo( IN PIRP Irp,
2831                      IN AFSDirectoryCB *DirectoryCB)
2832 {
2833     NTSTATUS ntStatus = STATUS_SUCCESS;
2834     PFILE_END_OF_FILE_INFORMATION pBuffer;
2835     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2836     PFILE_OBJECT pFileObject = pIrpSp->FileObject;
2837     LARGE_INTEGER liSaveSize;
2838     LARGE_INTEGER liSaveVDL;
2839     LARGE_INTEGER liSaveAlloc;
2840     BOOLEAN bModified = FALSE;
2841     BOOLEAN bReleasePaging = FALSE;
2842     BOOLEAN bTruncated = FALSE;
2843     AFSFcb *pFcb = NULL;
2844     AFSCcb *pCcb = NULL;
2845
2846     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2847
2848     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2849
2850     pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2851
2852     liSaveSize = pFcb->Header.FileSize;
2853     liSaveAlloc = pFcb->Header.AllocationSize;
2854     liSaveVDL = pFcb->Header.ValidDataLength;
2855
2856     if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
2857         !pIrpSp->Parameters.SetFile.AdvanceOnly)
2858     {
2859
2860         if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
2861         {
2862
2863             // Truncating the file
2864             if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
2865                                        &pBuffer->EndOfFile))
2866             {
2867
2868                 ntStatus = STATUS_USER_MAPPED_FILE;
2869             }
2870             else
2871             {
2872                 //
2873                 // If this is a truncation we need to grab the paging
2874                 // IO resource.
2875                 //
2876                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2877                               AFS_TRACE_LEVEL_VERBOSE,
2878                               "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2879                               &pFcb->NPFcb->PagingResource,
2880                               PsGetCurrentThread());
2881
2882                 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2883                                 TRUE);
2884
2885                 bReleasePaging = TRUE;
2886
2887                 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
2888
2889                 pFcb->Header.FileSize = pBuffer->EndOfFile;
2890
2891                 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
2892
2893                 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
2894
2895                 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
2896                 {
2897
2898                     pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
2899                 }
2900
2901                 bTruncated = TRUE;
2902
2903                 bModified = TRUE;
2904             }
2905         }
2906         else
2907         {
2908             //
2909             // extending the file, move EOF
2910             //
2911
2912             pFcb->Header.FileSize = pBuffer->EndOfFile;
2913
2914             pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
2915
2916             if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
2917             {
2918                 //
2919                 // And Allocation as needed.
2920                 //
2921                 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
2922
2923                 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
2924             }
2925
2926             bModified = TRUE;
2927         }
2928     }
2929
2930     if (bModified)
2931     {
2932
2933         KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
2934
2935         SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2936
2937         //
2938         // Tell the server
2939         //
2940
2941         ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
2942                                              pFcb->ObjectInformation,
2943                                              &pCcb->AuthGroup);
2944
2945         if( NT_SUCCESS(ntStatus))
2946         {
2947             //
2948             // We are now good to go so tell CC.
2949             //
2950             CcSetFileSizes( pFileObject,
2951                             (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
2952
2953             //
2954             // And give up those extents
2955             //
2956             if( bTruncated)
2957             {
2958
2959                 AFSTrimExtents( pFcb,
2960                                 &pFcb->Header.FileSize);
2961             }
2962         }
2963         else
2964         {
2965             pFcb->Header.ValidDataLength = liSaveVDL;
2966             pFcb->Header.FileSize = liSaveSize;
2967             pFcb->Header.AllocationSize = liSaveAlloc;
2968             pFcb->ObjectInformation->EndOfFile = liSaveSize;
2969             pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
2970         }
2971     }
2972
2973     if( bReleasePaging)
2974     {
2975
2976         AFSReleaseResource( &pFcb->NPFcb->PagingResource);
2977     }
2978
2979     return ntStatus;
2980 }
2981
2982 NTSTATUS
2983 AFSProcessShareSetInfo( IN IRP *Irp,
2984                         IN AFSFcb *Fcb,
2985                         IN AFSCcb *Ccb)
2986 {
2987
2988     NTSTATUS ntStatus = STATUS_SUCCESS;
2989     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2990     ULONG ulOutputBufferLen = 0, ulInputBufferLen;
2991     FILE_INFORMATION_CLASS ulFileInformationClass;
2992     void *pPipeInfo = NULL;
2993
2994     __Enter
2995     {
2996         ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
2997
2998         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
2999                       AFS_TRACE_LEVEL_VERBOSE,
3000                       "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
3001                       &Ccb->DirectoryCB->NameInformation.FileName,
3002                       ulFileInformationClass);
3003
3004         pPipeInfo = AFSLockSystemBuffer( Irp,
3005                                          pIrpSp->Parameters.SetFile.Length);
3006
3007         if( pPipeInfo == NULL)
3008         {
3009
3010             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3011                           AFS_TRACE_LEVEL_ERROR,
3012                           "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
3013                           &Ccb->DirectoryCB->NameInformation.FileName);
3014
3015             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3016         }
3017
3018         //
3019         // Send the request to the service
3020         //
3021
3022         ntStatus = AFSNotifySetPipeInfo( Ccb,
3023                                          (ULONG)ulFileInformationClass,
3024                                          pIrpSp->Parameters.SetFile.Length,
3025                                          pPipeInfo);
3026
3027         if( !NT_SUCCESS( ntStatus))
3028         {
3029
3030             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3031                           AFS_TRACE_LEVEL_ERROR,
3032                           "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3033                           &Ccb->DirectoryCB->NameInformation.FileName,
3034                           ntStatus);
3035
3036             try_return( ntStatus);
3037         }
3038
3039         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3040                       AFS_TRACE_LEVEL_VERBOSE,
3041                       "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
3042                       &Ccb->DirectoryCB->NameInformation.FileName,
3043                       ulFileInformationClass);
3044
3045 try_exit:
3046
3047         NOTHING;
3048     }
3049
3050     return ntStatus;
3051 }
3052
3053 NTSTATUS
3054 AFSProcessShareQueryInfo( IN IRP *Irp,
3055                           IN AFSFcb *Fcb,
3056                           IN AFSCcb *Ccb)
3057 {
3058
3059     NTSTATUS ntStatus = STATUS_SUCCESS;
3060     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3061     ULONG ulOutputBufferLen = 0, ulInputBufferLen;
3062     FILE_INFORMATION_CLASS ulFileInformationClass;
3063     void *pPipeInfo = NULL;
3064
3065     __Enter
3066     {
3067
3068         ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3069
3070         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3071                       AFS_TRACE_LEVEL_VERBOSE,
3072                       "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
3073                       &Ccb->DirectoryCB->NameInformation.FileName,
3074                       ulFileInformationClass);
3075
3076         pPipeInfo = AFSLockSystemBuffer( Irp,
3077                                          pIrpSp->Parameters.QueryFile.Length);
3078
3079         if( pPipeInfo == NULL)
3080         {
3081
3082             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3083                           AFS_TRACE_LEVEL_ERROR,
3084                           "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
3085                           &Ccb->DirectoryCB->NameInformation.FileName);
3086
3087             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3088         }
3089
3090         //
3091         // Send the request to the service
3092         //
3093
3094         ntStatus = AFSNotifyQueryPipeInfo( Ccb,
3095                                            (ULONG)ulFileInformationClass,
3096                                            pIrpSp->Parameters.QueryFile.Length,
3097                                            pPipeInfo,
3098                                            (ULONG *)&Irp->IoStatus.Information);
3099
3100         if( !NT_SUCCESS( ntStatus))
3101         {
3102
3103             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3104                           AFS_TRACE_LEVEL_ERROR,
3105                           "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3106                           &Ccb->DirectoryCB->NameInformation.FileName,
3107                           ntStatus);
3108
3109             try_return( ntStatus);
3110         }
3111
3112         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3113                       AFS_TRACE_LEVEL_VERBOSE,
3114                       "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
3115                       &Ccb->DirectoryCB->NameInformation.FileName,
3116                       ulFileInformationClass);
3117
3118 try_exit:
3119
3120         NOTHING;
3121     }
3122
3123     return ntStatus;
3124 }
3125
3126 NTSTATUS
3127 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
3128                            IN AFSFcb *Fcb,
3129                            IN AFSCcb *Ccb,
3130                            IN OUT LONG *Length)
3131 {
3132
3133     NTSTATUS ntStatus = STATUS_SUCCESS;
3134     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3135     FILE_INFORMATION_CLASS ulFileInformationClass;
3136
3137     __Enter
3138     {
3139
3140         ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3141
3142         switch( ulFileInformationClass)
3143         {
3144
3145             case FileBasicInformation:
3146             {
3147
3148                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3149                               AFS_TRACE_LEVEL_VERBOSE,
3150                               "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n");
3151
3152                 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
3153                 {
3154                     PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3155
3156                     pBasic->CreationTime.QuadPart = 0;
3157                     pBasic->LastAccessTime.QuadPart = 0;
3158                     pBasic->ChangeTime.QuadPart = 0;
3159                     pBasic->LastWriteTime.QuadPart = 0;
3160                     pBasic->FileAttributes = FILE_ATTRIBUTE_SYSTEM;
3161
3162                     *Length -= sizeof( FILE_BASIC_INFORMATION);
3163                 }
3164                 else
3165                 {
3166                     ntStatus = STATUS_BUFFER_TOO_SMALL;
3167                 }
3168
3169                 break;
3170             }
3171
3172             case FileStandardInformation:
3173             {
3174
3175                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3176                               AFS_TRACE_LEVEL_VERBOSE,
3177                               "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n");
3178
3179                 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
3180                 {
3181                     PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3182
3183                     pStandard->NumberOfLinks = 1;
3184                     pStandard->DeletePending = 0;
3185                     pStandard->AllocationSize.QuadPart = 0;
3186                     pStandard->EndOfFile.QuadPart = 0;
3187                     pStandard->Directory = 0;
3188
3189                     *Length -= sizeof( FILE_STANDARD_INFORMATION);
3190                 }
3191                 else
3192                 {
3193                     ntStatus = STATUS_BUFFER_TOO_SMALL;
3194                 }
3195
3196                 break;
3197             }
3198
3199             case FileNameInformation:
3200             {
3201
3202                 ULONG ulCopyLength = 0;
3203                 AFSFcb *pFcb = NULL;
3204                 AFSCcb *pCcb = NULL;
3205                 USHORT usFullNameLength = 0;
3206                 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3207                 UNICODE_STRING uniName;
3208
3209                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3210                               AFS_TRACE_LEVEL_VERBOSE,
3211                               "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n");
3212
3213                 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3214                 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3215
3216                 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
3217                 {
3218                     ntStatus = STATUS_BUFFER_TOO_SMALL;
3219                     break;
3220                 }
3221
3222                 RtlZeroMemory( pNameInfo,
3223                                *Length);
3224
3225                 usFullNameLength = sizeof( WCHAR) +
3226                                             AFSServerName.Length +
3227                                             pCcb->FullFileName.Length;
3228
3229                 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
3230                 {
3231                     ulCopyLength = (LONG)usFullNameLength;
3232                 }
3233                 else
3234                 {
3235                     ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
3236                     ntStatus = STATUS_BUFFER_OVERFLOW;
3237                 }
3238
3239                 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
3240
3241                 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
3242
3243                 if( ulCopyLength > 0)
3244                 {
3245
3246                     pNameInfo->FileName[ 0] = L'\\';
3247                     ulCopyLength -= sizeof( WCHAR);
3248
3249                     *Length -= sizeof( WCHAR);
3250
3251                     if( ulCopyLength >= AFSServerName.Length)
3252                     {
3253
3254                         RtlCopyMemory( &pNameInfo->FileName[ 1],
3255                                        AFSServerName.Buffer,
3256                                        AFSServerName.Length);
3257
3258                         ulCopyLength -= AFSServerName.Length;
3259                         *Length -= AFSServerName.Length;
3260
3261                         if( ulCopyLength >= pCcb->FullFileName.Length)
3262                         {
3263
3264                             RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
3265                                            pCcb->FullFileName.Buffer,
3266                                            pCcb->FullFileName.Length);
3267
3268                             ulCopyLength -= pCcb->FullFileName.Length;
3269                             *Length -= pCcb->FullFileName.Length;
3270
3271                             uniName.Length = (USHORT)pNameInfo->FileNameLength;
3272                             uniName.MaximumLength = uniName.Length;
3273                             uniName.Buffer = pNameInfo->FileName;
3274                         }
3275                         else
3276                         {
3277
3278                             RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
3279                                            pCcb->FullFileName.Buffer,
3280                                            ulCopyLength);
3281
3282                             *Length -= ulCopyLength;
3283
3284                             uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
3285                             uniName.MaximumLength = uniName.Length;
3286                             uniName.Buffer = pNameInfo->FileName;
3287                         }
3288
3289                         AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3290                                       AFS_TRACE_LEVEL_VERBOSE,
3291                                       "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
3292                                       &uniName);
3293                     }
3294                 }
3295
3296                 break;
3297             }
3298
3299             case FileInternalInformation:
3300             {
3301
3302                 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3303
3304                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3305                               AFS_TRACE_LEVEL_VERBOSE,
3306                               "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n");
3307
3308                 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
3309                 {
3310
3311                     pInternalInfo->IndexNumber.HighPart = 0;
3312
3313                     pInternalInfo->IndexNumber.LowPart = 0;
3314
3315                     *Length -= sizeof( FILE_INTERNAL_INFORMATION);
3316                 }
3317                 else
3318                 {
3319
3320                     ntStatus = STATUS_BUFFER_TOO_SMALL;
3321                 }
3322
3323                 break;
3324             }
3325
3326             case FileAllInformation:
3327             {
3328                 ntStatus = STATUS_INVALID_PARAMETER;
3329
3330                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3331                               AFS_TRACE_LEVEL_WARNING,
3332                               "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n");
3333
3334                 break;
3335             }
3336
3337             case FileEaInformation:
3338             {
3339                 ntStatus = STATUS_INVALID_PARAMETER;
3340
3341                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3342                               AFS_TRACE_LEVEL_WARNING,
3343                               "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n");
3344
3345                 break;
3346             }
3347
3348             case FilePositionInformation:
3349             {
3350                 ntStatus = STATUS_INVALID_PARAMETER;
3351
3352                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3353                               AFS_TRACE_LEVEL_WARNING,
3354                               "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n");
3355
3356                 break;
3357             }
3358
3359             case FileAlternateNameInformation:
3360             {
3361                 ntStatus = STATUS_INVALID_PARAMETER;
3362
3363                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3364                               AFS_TRACE_LEVEL_WARNING,
3365                               "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n");
3366
3367                 break;
3368             }
3369
3370             case FileNetworkOpenInformation:
3371             {
3372                 ntStatus = STATUS_INVALID_PARAMETER;
3373
3374                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3375                               AFS_TRACE_LEVEL_WARNING,
3376                               "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n");
3377
3378                 break;
3379             }
3380
3381             case FileStreamInformation:
3382             {
3383                 ntStatus = STATUS_INVALID_PARAMETER;
3384
3385                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3386                               AFS_TRACE_LEVEL_WARNING,
3387                               "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n");
3388
3389                 break;
3390             }
3391
3392             case FileAttributeTagInformation:
3393             {
3394                 ntStatus = STATUS_INVALID_PARAMETER;
3395
3396                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3397                               AFS_TRACE_LEVEL_WARNING,
3398                               "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n");
3399
3400                 break;
3401             }
3402
3403             case FileRemoteProtocolInformation:
3404             {
3405                 ntStatus = STATUS_INVALID_PARAMETER;
3406
3407                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3408                               AFS_TRACE_LEVEL_WARNING,
3409                               "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n");
3410
3411                 break;
3412             }
3413
3414             case FileNetworkPhysicalNameInformation:
3415             {
3416                 ntStatus = STATUS_INVALID_PARAMETER;
3417
3418                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3419                               AFS_TRACE_LEVEL_WARNING,
3420                               "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n");
3421
3422                 break;
3423             }
3424
3425             default:
3426             {
3427                 ntStatus = STATUS_INVALID_PARAMETER;
3428
3429                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3430                               AFS_TRACE_LEVEL_WARNING,
3431                               "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
3432                               ulFileInformationClass);
3433
3434                 break;
3435             }
3436         }
3437     }
3438
3439     AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3440                   AFS_TRACE_LEVEL_VERBOSE,
3441                   "AFSProcessPIOCtlQueryInfo ntStatus %08lX\n",
3442                   ntStatus);
3443
3444     return ntStatus;
3445 }
3446