Windows: Hold Fcb Resource across CcPurgeSection
[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     UNREFERENCED_PARAMETER(LibDeviceObject);
59     NTSTATUS ntStatus = STATUS_SUCCESS;
60     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
61     AFSFcb *pFcb = NULL;
62     AFSCcb *pCcb = NULL;
63     BOOLEAN bReleaseMain = FALSE;
64     LONG lLength = 0;
65     FILE_INFORMATION_CLASS stFileInformationClass;
66     GUID stAuthGroup;
67     PVOID pBuffer;
68
69     __try
70     {
71
72         //
73         // Determine the type of request this request is
74         //
75
76         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
77
78         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
79
80         if( pFcb == NULL)
81         {
82
83             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
84                           AFS_TRACE_LEVEL_ERROR,
85                           "AFSQueryFileInfo Attempted access (%p) when pFcb == NULL\n",
86                           Irp));
87
88             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
89         }
90
91         lLength = (LONG)pIrpSp->Parameters.QueryFile.Length;
92         stFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
93         pBuffer = Irp->AssociatedIrp.SystemBuffer;
94
95         if ( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
96         {
97
98             RtlZeroMemory( &stAuthGroup,
99                            sizeof( GUID));
100
101             AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
102                                      (ULONGLONG)PsGetCurrentThreadId(),
103                                      &stAuthGroup);
104
105             ntStatus = AFSVerifyEntry( &stAuthGroup,
106                                        pCcb->DirectoryCB,
107                                        FALSE);
108
109             if ( NT_SUCCESS( ntStatus))
110             {
111
112                 ClearFlag( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
113             }
114             else
115             {
116
117                 ntStatus = STATUS_SUCCESS;
118             }
119         }
120
121         //
122         // Grab the main shared right off the bat
123         //
124
125         AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
126                       AFS_TRACE_LEVEL_VERBOSE,
127                       "AFSQueryFileInfo Acquiring Fcb lock %p SHARED %08lX\n",
128                       &pFcb->NPFcb->Resource,
129                       PsGetCurrentThread()));
130
131         AFSAcquireShared( &pFcb->NPFcb->Resource,
132                           TRUE);
133
134         bReleaseMain = TRUE;
135
136         //
137         // Don't allow requests against IOCtl nodes
138         //
139
140         if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
141         {
142
143             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
144                           AFS_TRACE_LEVEL_VERBOSE,
145                           "AFSQueryFileInfo Processing request against SpecialShare Fcb\n"));
146
147             ntStatus = AFSProcessShareQueryInfo( Irp,
148                                                  pFcb,
149                                                  pCcb);
150
151             try_return( ntStatus);
152         }
153         else if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
154         {
155             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
156                           AFS_TRACE_LEVEL_VERBOSE,
157                           "AFSQueryFileInfo request against PIOCtl Fcb\n"));
158
159             ntStatus = AFSProcessPIOCtlQueryInfo( Irp,
160                                                   pFcb,
161                                                   pCcb,
162                                                   &lLength);
163
164             try_return( ntStatus);
165         }
166
167         else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
168         {
169             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
170                           AFS_TRACE_LEVEL_VERBOSE,
171                           "AFSQueryFileInfo request against Invalid Fcb\n"));
172
173             try_return( ntStatus = STATUS_ACCESS_DENIED);
174         }
175
176         //
177         // Process the request
178         //
179
180         switch( stFileInformationClass)
181         {
182
183             case FileAllInformation:
184             {
185
186                 PFILE_ALL_INFORMATION pAllInfo;
187
188                 //
189                 //  For the all information class we'll typecast a local
190                 //  pointer to the output buffer and then call the
191                 //  individual routines to fill in the buffer.
192                 //
193
194                 pAllInfo = (PFILE_ALL_INFORMATION)pBuffer;
195
196                 ntStatus = AFSQueryBasicInfo( Irp,
197                                               pCcb->DirectoryCB,
198                                               &pAllInfo->BasicInformation,
199                                               &lLength);
200
201                 if( !NT_SUCCESS( ntStatus))
202                 {
203
204                     try_return( ntStatus);
205                 }
206
207                 ntStatus = AFSQueryStandardInfo( Irp,
208                                                  pCcb->DirectoryCB,
209                                                  &pAllInfo->StandardInformation,
210                                                  &lLength);
211
212                 if( !NT_SUCCESS( ntStatus))
213                 {
214
215                     try_return( ntStatus);
216                 }
217
218                 ntStatus = AFSQueryInternalInfo( Irp,
219                                                  pFcb,
220                                                  &pAllInfo->InternalInformation,
221                                                  &lLength);
222
223                 if( !NT_SUCCESS( ntStatus))
224                 {
225
226                     try_return( ntStatus);
227                 }
228
229                 ntStatus = AFSQueryEaInfo( Irp,
230                                            pCcb->DirectoryCB,
231                                            &pAllInfo->EaInformation,
232                                            &lLength);
233
234                 if( !NT_SUCCESS( ntStatus))
235                 {
236
237                     try_return( ntStatus);
238                 }
239
240                 ntStatus = AFSQueryAccess( Irp,
241                                            pFcb,
242                                            &pAllInfo->AccessInformation,
243                                            &lLength);
244
245                 if( !NT_SUCCESS( ntStatus))
246                 {
247
248                     try_return( ntStatus);
249                 }
250
251                 ntStatus = AFSQueryPositionInfo( Irp,
252                                                  pFcb,
253                                                  &pAllInfo->PositionInformation,
254                                                  &lLength);
255
256                 if( !NT_SUCCESS( ntStatus))
257                 {
258
259                     try_return( ntStatus);
260                 }
261
262                 ntStatus = AFSQueryMode( Irp,
263                                          pFcb,
264                                          &pAllInfo->ModeInformation,
265                                          &lLength);
266
267                 if( !NT_SUCCESS( ntStatus))
268                 {
269
270                     try_return( ntStatus);
271                 }
272
273                 ntStatus = AFSQueryAlignment( Irp,
274                                               pFcb,
275                                               &pAllInfo->AlignmentInformation,
276                                               &lLength);
277
278                 if( !NT_SUCCESS( ntStatus))
279                 {
280
281                     try_return( ntStatus);
282                 }
283
284                 ntStatus = AFSQueryNameInfo( Irp,
285                                              pCcb->DirectoryCB,
286                                              &pAllInfo->NameInformation,
287                                              &lLength);
288
289                 if( !NT_SUCCESS( ntStatus))
290                 {
291
292                     try_return( ntStatus);
293                 }
294
295                 break;
296             }
297
298             case FileBasicInformation:
299             {
300
301                 ntStatus = AFSQueryBasicInfo( Irp,
302                                               pCcb->DirectoryCB,
303                                               (PFILE_BASIC_INFORMATION)pBuffer,
304                                               &lLength);
305
306                 break;
307             }
308
309             case FileStandardInformation:
310             {
311
312                 ntStatus = AFSQueryStandardInfo( Irp,
313                                                  pCcb->DirectoryCB,
314                                                  (PFILE_STANDARD_INFORMATION)pBuffer,
315                                                  &lLength);
316
317                 break;
318             }
319
320             case FileInternalInformation:
321             {
322
323                 ntStatus = AFSQueryInternalInfo( Irp,
324                                                  pFcb,
325                                                  (PFILE_INTERNAL_INFORMATION)pBuffer,
326                                                  &lLength);
327
328                 break;
329             }
330
331             case FileEaInformation:
332             {
333
334                 ntStatus = AFSQueryEaInfo( Irp,
335                                            pCcb->DirectoryCB,
336                                            (PFILE_EA_INFORMATION)pBuffer,
337                                            &lLength);
338
339                 break;
340             }
341
342             case FilePositionInformation:
343             {
344
345                 ntStatus = AFSQueryPositionInfo( Irp,
346                                       pFcb,
347                                       (PFILE_POSITION_INFORMATION)pBuffer,
348                                       &lLength);
349
350                 break;
351             }
352
353             case FileNormalizedNameInformation:
354             case FileNameInformation:
355             {
356
357                 ntStatus = AFSQueryNameInfo( Irp,
358                                   pCcb->DirectoryCB,
359                                   (PFILE_NAME_INFORMATION)pBuffer,
360                                   &lLength);
361
362                 break;
363             }
364
365             case FileAlternateNameInformation:
366             {
367
368                 ntStatus = AFSQueryShortNameInfo( Irp,
369                                        pCcb->DirectoryCB,
370                                        (PFILE_NAME_INFORMATION)pBuffer,
371                                        &lLength);
372
373                 break;
374             }
375
376             case FileNetworkOpenInformation:
377             {
378
379                 ntStatus = AFSQueryNetworkInfo( Irp,
380                                      pCcb->DirectoryCB,
381                                      (PFILE_NETWORK_OPEN_INFORMATION)pBuffer,
382                                      &lLength);
383
384                 break;
385             }
386
387             case FileStreamInformation:
388             {
389
390                 ntStatus = AFSQueryStreamInfo( Irp,
391                                                pCcb->DirectoryCB,
392                                                (FILE_STREAM_INFORMATION *)pBuffer,
393                                                &lLength);
394
395                 break;
396             }
397
398
399             case FileAttributeTagInformation:
400             {
401
402                 ntStatus = AFSQueryAttribTagInfo( Irp,
403                                                   pCcb->DirectoryCB,
404                                                   (FILE_ATTRIBUTE_TAG_INFORMATION *)pBuffer,
405                                                   &lLength);
406
407                 break;
408             }
409
410             case FileRemoteProtocolInformation:
411             {
412
413                     ntStatus = AFSQueryRemoteProtocolInfo( Irp,
414                                                            pCcb->DirectoryCB,
415                                                            (FILE_REMOTE_PROTOCOL_INFORMATION *)pBuffer,
416                                                            &lLength);
417
418                 break;
419             }
420
421             case FileNetworkPhysicalNameInformation:
422             {
423
424                 ntStatus = AFSQueryPhysicalNameInfo( Irp,
425                                                      pCcb->DirectoryCB,
426                                                      (FILE_NETWORK_PHYSICAL_NAME_INFORMATION *)pBuffer,
427                                                      &lLength);
428
429                 break;
430             }
431
432             default:
433             {
434                 ntStatus = STATUS_INVALID_PARAMETER;
435                 break;
436             }
437         }
438
439 try_exit:
440
441         Irp->IoStatus.Information = pIrpSp->Parameters.QueryFile.Length - lLength;
442
443         if( bReleaseMain)
444         {
445
446             AFSReleaseResource( &pFcb->NPFcb->Resource);
447         }
448
449         if( !NT_SUCCESS( ntStatus) &&
450             ntStatus != STATUS_INVALID_PARAMETER &&
451             ntStatus != STATUS_BUFFER_OVERFLOW)
452         {
453
454             if( pCcb != NULL &&
455                 pCcb->DirectoryCB != NULL)
456             {
457
458                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
459                               AFS_TRACE_LEVEL_ERROR,
460                               "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
461                               &pCcb->DirectoryCB->NameInformation.FileName,
462                               pFcb->ObjectInformation->FileId.Cell,
463                               pFcb->ObjectInformation->FileId.Volume,
464                               pFcb->ObjectInformation->FileId.Vnode,
465                               pFcb->ObjectInformation->FileId.Unique,
466                               ntStatus));
467             }
468         }
469     }
470     __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
471     {
472
473         AFSDbgTrace(( 0,
474                       0,
475                       "EXCEPTION - AFSQueryFileInfo\n"));
476
477         AFSDumpTraceFilesFnc();
478
479         ntStatus = STATUS_UNSUCCESSFUL;
480
481         if( bReleaseMain)
482         {
483
484             AFSReleaseResource( &pFcb->NPFcb->Resource);
485         }
486     }
487
488     AFSCompleteRequest( Irp,
489                         ntStatus);
490
491     return ntStatus;
492 }
493
494 //
495 // Function: AFSSetFileInfo
496 //
497 // Description:
498 //
499 //      This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request
500 //
501 // Return:
502 //
503 //      A status is returned for the function
504 //
505
506 NTSTATUS
507 AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
508                 IN PIRP Irp)
509 {
510
511     UNREFERENCED_PARAMETER(LibDeviceObject);
512     NTSTATUS ntStatus = STATUS_SUCCESS;
513     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
514     AFSFcb *pFcb = NULL;
515     AFSCcb *pCcb = NULL;
516     FILE_INFORMATION_CLASS FileInformationClass;
517     BOOLEAN bCanQueueRequest = FALSE;
518     PFILE_OBJECT pFileObject = NULL;
519     BOOLEAN bReleaseMain = FALSE;
520     BOOLEAN bUpdateFileInfo = FALSE;
521     AFSFileID stParentFileId;
522
523     __try
524     {
525
526         pFileObject = pIrpSp->FileObject;
527
528         pFcb = (AFSFcb *)pFileObject->FsContext;
529         pCcb = (AFSCcb *)pFileObject->FsContext2;
530
531         if( pFcb == NULL)
532         {
533
534             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
535                           AFS_TRACE_LEVEL_ERROR,
536                           "AFSSetFileInfo Attempted access (%p) when pFcb == NULL\n",
537                           Irp));
538
539             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
540         }
541
542         bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
543         FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
544
545         //
546         // Grab the Fcb EXCL
547         //
548
549         AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
550                       AFS_TRACE_LEVEL_VERBOSE,
551                       "AFSSetFileInfo Acquiring Fcb lock %p EXCL %08lX\n",
552                       &pFcb->NPFcb->Resource,
553                       PsGetCurrentThread()));
554
555         AFSAcquireExcl( &pFcb->NPFcb->Resource,
556                         TRUE);
557
558         bReleaseMain = TRUE;
559
560         //
561         // Don't allow requests against IOCtl nodes
562         //
563
564         if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
565         {
566
567             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
568                           AFS_TRACE_LEVEL_ERROR,
569                           "AFSSetFileInfo Failing request against PIOCtl Fcb\n"));
570
571             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
572         }
573         else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
574         {
575
576             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
577                           AFS_TRACE_LEVEL_VERBOSE,
578                           "AFSSetFileInfo Processing request against SpecialShare Fcb\n"));
579
580             ntStatus = AFSProcessShareSetInfo( Irp,
581                                                pFcb,
582                                                pCcb);
583
584             try_return( ntStatus);
585         }
586
587         if( BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
588         {
589
590             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
591                           AFS_TRACE_LEVEL_ERROR,
592                           "AFSSetFileInfo Request failed due to read only volume\n",
593                           Irp));
594
595             try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
596         }
597
598         if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB &&
599             FileInformationClass != FileDispositionInformation)
600         {
601             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
602                           AFS_TRACE_LEVEL_VERBOSE,
603                           "AFSSetFileInfo request against Invalid Fcb\n"));
604
605             try_return( ntStatus = STATUS_ACCESS_DENIED);
606         }
607
608         //
609         // Ensure rename operations are synchronous
610         //
611
612         if( FileInformationClass == FileRenameInformation)
613         {
614
615             bCanQueueRequest = FALSE;
616         }
617
618         //
619         // Store away the parent fid
620         //
621
622         RtlZeroMemory( &stParentFileId,
623                        sizeof( AFSFileID));
624
625         if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
626         {
627
628             stParentFileId = pFcb->ObjectInformation->ParentFileId;
629         }
630
631         //
632         // Process the request
633         //
634
635         switch( FileInformationClass)
636         {
637
638             case FileBasicInformation:
639             {
640
641                 bUpdateFileInfo = TRUE;
642
643                 ntStatus = AFSSetBasicInfo( Irp,
644                                             pCcb->DirectoryCB);
645
646                 break;
647             }
648
649             case FileDispositionInformation:
650             {
651
652                 ntStatus = AFSSetDispositionInfo( Irp,
653                                                   pCcb->DirectoryCB);
654
655                 break;
656             }
657
658             case FileRenameInformation:
659             {
660
661                 ntStatus = AFSSetRenameInfo( Irp);
662
663                 break;
664             }
665
666             case FilePositionInformation:
667             {
668
669                 ntStatus = AFSSetPositionInfo( Irp,
670                                                pCcb->DirectoryCB);
671
672                 break;
673             }
674
675             case FileLinkInformation:
676             {
677
678                 ntStatus = AFSSetFileLinkInfo( Irp);
679
680                 break;
681             }
682
683             case FileAllocationInformation:
684             {
685
686                 ntStatus = AFSSetAllocationInfo( Irp,
687                                                  pCcb->DirectoryCB);
688
689                 break;
690             }
691
692             case FileEndOfFileInformation:
693             {
694
695                 ntStatus = AFSSetEndOfFileInfo( Irp,
696                                                 pCcb->DirectoryCB);
697
698                 break;
699             }
700
701             default:
702
703                 ntStatus = STATUS_INVALID_PARAMETER;
704
705                 break;
706         }
707
708 try_exit:
709
710         if( bReleaseMain)
711         {
712
713             AFSReleaseResource( &pFcb->NPFcb->Resource);
714         }
715
716         if( NT_SUCCESS( ntStatus) &&
717             bUpdateFileInfo)
718         {
719
720             ntStatus = AFSUpdateFileInformation( &stParentFileId,
721                                                  pFcb->ObjectInformation,
722                                                  &pCcb->AuthGroup);
723
724             if( !NT_SUCCESS( ntStatus))
725             {
726
727                 AFSAcquireExcl( &pFcb->NPFcb->Resource,
728                                 TRUE);
729
730                 //
731                 // Unwind the update and fail the request
732                 //
733
734                 AFSUnwindFileInfo( pFcb,
735                                    pCcb);
736
737                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
738                               AFS_TRACE_LEVEL_ERROR,
739                               "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
740                               &pCcb->DirectoryCB->NameInformation.FileName,
741                               pFcb->ObjectInformation->FileId.Cell,
742                               pFcb->ObjectInformation->FileId.Volume,
743                               pFcb->ObjectInformation->FileId.Vnode,
744                               pFcb->ObjectInformation->FileId.Unique,
745                               ntStatus));
746
747                 AFSReleaseResource( &pFcb->NPFcb->Resource);
748             }
749         }
750
751         if( !NT_SUCCESS( ntStatus))
752         {
753
754             if( pCcb != NULL &&
755                 pCcb->DirectoryCB != NULL)
756             {
757
758                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
759                               AFS_TRACE_LEVEL_ERROR,
760                               "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
761                               &pCcb->DirectoryCB->NameInformation.FileName,
762                               pFcb->ObjectInformation->FileId.Cell,
763                               pFcb->ObjectInformation->FileId.Volume,
764                               pFcb->ObjectInformation->FileId.Vnode,
765                               pFcb->ObjectInformation->FileId.Unique,
766                               ntStatus));
767             }
768         }
769     }
770     __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
771     {
772
773         AFSDbgTrace(( 0,
774                       0,
775                       "EXCEPTION - AFSSetFileInfo\n"));
776
777         AFSDumpTraceFilesFnc();
778
779         ntStatus = STATUS_UNSUCCESSFUL;
780
781         if( bReleaseMain)
782         {
783
784             AFSReleaseResource( &pFcb->NPFcb->Resource);
785         }
786     }
787
788     AFSCompleteRequest( Irp,
789                         ntStatus);
790
791     return ntStatus;
792 }
793
794 //
795 // Function: AFSQueryBasicInfo
796 //
797 // Description:
798 //
799 //      This function is the handler for the query basic information request
800 //
801 // Return:
802 //
803 //      A status is returned for the function
804 //
805
806 NTSTATUS
807 AFSQueryBasicInfo( IN PIRP Irp,
808                    IN AFSDirectoryCB *DirectoryCB,
809                    IN OUT PFILE_BASIC_INFORMATION Buffer,
810                    IN OUT PLONG Length)
811 {
812     NTSTATUS ntStatus = STATUS_SUCCESS;
813     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
814     ULONG ulFileAttribs = 0;
815     AFSFcb *pFcb = NULL;
816     AFSCcb *pCcb = NULL;
817     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
818     AFSFileInfoCB stFileInfo;
819     AFSDirectoryCB *pParentDirectoryCB = NULL;
820     UNICODE_STRING uniParentPath;
821
822     if( *Length >= sizeof( FILE_BASIC_INFORMATION))
823     {
824
825         RtlZeroMemory( Buffer,
826                        *Length);
827
828         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
829
830         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
831         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
832
833         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
834         {
835
836             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
837
838             AFSRetrieveParentPath( &pCcb->FullFileName,
839                                    &uniParentPath);
840
841             RtlZeroMemory( &stFileInfo,
842                            sizeof( AFSFileInfoCB));
843
844             //
845             // Can't hold the Fcb while evaluating the path, leads to lock inversion
846             //
847
848             AFSReleaseResource( &pFcb->NPFcb->Resource);
849
850             //
851             // Its a reparse point regardless of whether the file attributes
852             // can be retrieved for the target.
853             //
854
855             if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
856             {
857
858                 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
859             }
860             else
861             {
862
863                 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
864             }
865
866             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
867                                                        DirectoryCB,
868                                                        &uniParentPath,
869                                                        pCcb->NameArray,
870                                                        &pCcb->AuthGroup,
871                                                        &stFileInfo)))
872             {
873
874                 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
875                 {
876
877                     ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
878                 }
879             }
880
881             AFSAcquireShared( &pFcb->NPFcb->Resource,
882                               TRUE);
883         }
884
885
886         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
887                       AFS_TRACE_LEVEL_VERBOSE_2,
888                       "AFSQueryBasicInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
889                       &pCcb->DirectoryCB->NameInformation.FileName,
890                       pFcb->ObjectInformation->FileType,
891                       pFcb->ObjectInformation->FileAttributes,
892                       ulFileAttribs));
893
894         Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
895         Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
896         Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
897         Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
898         Buffer->FileAttributes = ulFileAttribs;
899
900         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
901             BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
902         {
903
904             if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
905             {
906                 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
907             }
908             else
909             {
910                 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
911             }
912         }
913
914         *Length -= sizeof( FILE_BASIC_INFORMATION);
915     }
916     else
917     {
918
919         ntStatus = STATUS_BUFFER_TOO_SMALL;
920     }
921
922     return ntStatus;
923 }
924
925 NTSTATUS
926 AFSQueryStandardInfo( IN PIRP Irp,
927                       IN AFSDirectoryCB *DirectoryCB,
928                       IN OUT PFILE_STANDARD_INFORMATION Buffer,
929                       IN OUT PLONG Length)
930 {
931
932     NTSTATUS ntStatus = STATUS_SUCCESS;
933     AFSFcb *pFcb = NULL;
934     AFSCcb *pCcb = NULL;
935     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
936     AFSFileInfoCB stFileInfo;
937     AFSDirectoryCB *pParentDirectoryCB = NULL;
938     UNICODE_STRING uniParentPath;
939     ULONG ulFileAttribs = 0;
940
941     if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
942     {
943
944         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
945         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
946
947         RtlZeroMemory( Buffer,
948                        *Length);
949
950         Buffer->NumberOfLinks = 1;
951         Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
952
953         Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
954
955         Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
956
957         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
958
959         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
960         {
961
962             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
963
964             AFSRetrieveParentPath( &pCcb->FullFileName,
965                                    &uniParentPath);
966
967             RtlZeroMemory( &stFileInfo,
968                            sizeof( AFSFileInfoCB));
969
970             //
971             // Can't hold the Fcb while evaluating the path, leads to lock inversion
972             //
973
974             AFSReleaseResource( &pFcb->NPFcb->Resource);
975
976             //
977             // Its a reparse point regardless of whether or not the
978             // file attributes can be retrieved.
979             //
980
981             if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
982             {
983
984                 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
985             }
986             else
987             {
988
989                 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
990             }
991
992             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
993                                                        DirectoryCB,
994                                                        &uniParentPath,
995                                                        pCcb->NameArray,
996                                                        &pCcb->AuthGroup,
997                                                        &stFileInfo)))
998             {
999
1000                 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1001                 {
1002
1003                     ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1004                 }
1005             }
1006
1007             AFSAcquireShared( &pFcb->NPFcb->Resource,
1008                               TRUE);
1009         }
1010
1011         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1012                       AFS_TRACE_LEVEL_VERBOSE_2,
1013                       "AFSQueryStandardInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1014                       &pCcb->DirectoryCB->NameInformation.FileName,
1015                       pFcb->ObjectInformation->FileType,
1016                       pFcb->ObjectInformation->FileAttributes,
1017                       ulFileAttribs));
1018
1019         Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
1020
1021         *Length -= sizeof( FILE_STANDARD_INFORMATION);
1022     }
1023     else
1024     {
1025
1026         ntStatus = STATUS_BUFFER_TOO_SMALL;
1027     }
1028
1029     return ntStatus;
1030 }
1031
1032 NTSTATUS
1033 AFSQueryInternalInfo( IN PIRP Irp,
1034                       IN AFSFcb *Fcb,
1035                       IN OUT PFILE_INTERNAL_INFORMATION Buffer,
1036                       IN OUT PLONG Length)
1037 {
1038
1039     UNREFERENCED_PARAMETER(Irp);
1040     NTSTATUS ntStatus = STATUS_SUCCESS;
1041
1042     if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
1043     {
1044
1045         Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Vnode;
1046
1047         Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Unique;
1048
1049         *Length -= sizeof( FILE_INTERNAL_INFORMATION);
1050     }
1051     else
1052     {
1053
1054         ntStatus = STATUS_BUFFER_TOO_SMALL;
1055     }
1056
1057     return ntStatus;
1058 }
1059
1060 NTSTATUS
1061 AFSQueryEaInfo( IN PIRP Irp,
1062                 IN AFSDirectoryCB *DirectoryCB,
1063                 IN OUT PFILE_EA_INFORMATION Buffer,
1064                 IN OUT PLONG Length)
1065 {
1066
1067     UNREFERENCED_PARAMETER(Irp);
1068     UNREFERENCED_PARAMETER(DirectoryCB);
1069     NTSTATUS ntStatus = STATUS_SUCCESS;
1070
1071     RtlZeroMemory( Buffer,
1072                    *Length);
1073
1074     if( *Length >= sizeof( FILE_EA_INFORMATION))
1075     {
1076
1077         Buffer->EaSize = 0;
1078
1079         *Length -= sizeof( FILE_EA_INFORMATION);
1080     }
1081     else
1082     {
1083
1084         ntStatus = STATUS_BUFFER_TOO_SMALL;
1085     }
1086
1087     return ntStatus;
1088 }
1089
1090 NTSTATUS
1091 AFSQueryPositionInfo( IN PIRP Irp,
1092                       IN AFSFcb *Fcb,
1093                       IN OUT PFILE_POSITION_INFORMATION Buffer,
1094                       IN OUT PLONG Length)
1095 {
1096
1097     UNREFERENCED_PARAMETER(Fcb);
1098     NTSTATUS ntStatus = STATUS_SUCCESS;
1099     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1100
1101     if( *Length >= sizeof( FILE_POSITION_INFORMATION))
1102     {
1103
1104         RtlZeroMemory( Buffer,
1105                        *Length);
1106
1107         Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
1108
1109         *Length -= sizeof( FILE_POSITION_INFORMATION);
1110     }
1111     else
1112     {
1113
1114         ntStatus = STATUS_BUFFER_TOO_SMALL;
1115     }
1116
1117     return ntStatus;
1118 }
1119
1120 NTSTATUS
1121 AFSQueryAccess( IN PIRP Irp,
1122                 IN AFSFcb *Fcb,
1123                 IN OUT PFILE_ACCESS_INFORMATION Buffer,
1124                 IN OUT PLONG Length)
1125 {
1126
1127     UNREFERENCED_PARAMETER(Irp);
1128     UNREFERENCED_PARAMETER(Fcb);
1129     NTSTATUS ntStatus = STATUS_SUCCESS;
1130
1131     if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
1132     {
1133
1134         RtlZeroMemory( Buffer,
1135                        *Length);
1136
1137         Buffer->AccessFlags = 0;
1138
1139         *Length -= sizeof( FILE_ACCESS_INFORMATION);
1140     }
1141     else
1142     {
1143
1144         ntStatus = STATUS_BUFFER_TOO_SMALL;
1145     }
1146
1147     return ntStatus;
1148 }
1149
1150 NTSTATUS
1151 AFSQueryMode( IN PIRP Irp,
1152               IN AFSFcb *Fcb,
1153               IN OUT PFILE_MODE_INFORMATION Buffer,
1154               IN OUT PLONG Length)
1155 {
1156
1157     UNREFERENCED_PARAMETER(Irp);
1158     UNREFERENCED_PARAMETER(Fcb);
1159     NTSTATUS ntStatus = STATUS_SUCCESS;
1160
1161     if( *Length >= sizeof( FILE_MODE_INFORMATION))
1162     {
1163
1164         RtlZeroMemory( Buffer,
1165                        *Length);
1166
1167         Buffer->Mode = 0;
1168
1169         *Length -= sizeof( FILE_MODE_INFORMATION);
1170     }
1171     else
1172     {
1173
1174         ntStatus = STATUS_BUFFER_TOO_SMALL;
1175     }
1176
1177     return ntStatus;
1178 }
1179
1180 NTSTATUS
1181 AFSQueryAlignment( IN PIRP Irp,
1182                    IN AFSFcb *Fcb,
1183                    IN OUT PFILE_ALIGNMENT_INFORMATION Buffer,
1184                    IN OUT PLONG Length)
1185 {
1186
1187     UNREFERENCED_PARAMETER(Irp);
1188     UNREFERENCED_PARAMETER(Fcb);
1189     NTSTATUS ntStatus = STATUS_SUCCESS;
1190
1191     if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
1192     {
1193
1194         RtlZeroMemory( Buffer,
1195                        *Length);
1196
1197         Buffer->AlignmentRequirement = 1;
1198
1199         *Length -= sizeof( FILE_ALIGNMENT_INFORMATION);
1200     }
1201     else
1202     {
1203
1204         ntStatus = STATUS_BUFFER_TOO_SMALL;
1205     }
1206
1207     return ntStatus;
1208 }
1209
1210 NTSTATUS
1211 AFSQueryNameInfo( IN PIRP Irp,
1212                   IN AFSDirectoryCB *DirectoryCB,
1213                   IN OUT PFILE_NAME_INFORMATION Buffer,
1214                   IN OUT PLONG Length)
1215 {
1216
1217     UNREFERENCED_PARAMETER(DirectoryCB);
1218     NTSTATUS ntStatus = STATUS_SUCCESS;
1219     ULONG ulCopyLength = 0;
1220     ULONG cchCopied = 0;
1221     AFSFcb *pFcb = NULL;
1222     AFSCcb *pCcb = NULL;
1223     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1224     BOOLEAN bAddLeadingSlash = FALSE;
1225     BOOLEAN bAddTrailingSlash = FALSE;
1226     USHORT usFullNameLength = 0;
1227
1228     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1229
1230     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1231
1232     if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1233     {
1234
1235         RtlZeroMemory( Buffer,
1236                        *Length);
1237
1238         if( pCcb->FullFileName.Length == 0 ||
1239             pCcb->FullFileName.Buffer[ 0] != L'\\')
1240         {
1241             bAddLeadingSlash = TRUE;
1242         }
1243
1244         if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1245             pCcb->FullFileName.Length > 0 &&
1246             pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
1247         {
1248             bAddTrailingSlash = TRUE;
1249         }
1250
1251         usFullNameLength = sizeof( WCHAR) +
1252                                     AFSServerName.Length +
1253                                     pCcb->FullFileName.Length;
1254
1255         if( bAddLeadingSlash)
1256         {
1257             usFullNameLength += sizeof( WCHAR);
1258         }
1259
1260         if( bAddTrailingSlash)
1261         {
1262             usFullNameLength += sizeof( WCHAR);
1263         }
1264
1265         if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1266         {
1267
1268             ulCopyLength = (LONG)usFullNameLength;
1269         }
1270         else
1271         {
1272
1273             ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1274
1275             ntStatus = STATUS_BUFFER_OVERFLOW;
1276         }
1277
1278         Buffer->FileNameLength = (ULONG)usFullNameLength;
1279
1280         *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1281
1282         if( ulCopyLength > 0)
1283         {
1284
1285             Buffer->FileName[ 0] = L'\\';
1286             ulCopyLength -= sizeof( WCHAR);
1287
1288             *Length -= sizeof( WCHAR);
1289             cchCopied += 1;
1290
1291             if( ulCopyLength >= AFSServerName.Length)
1292             {
1293
1294                 RtlCopyMemory( &Buffer->FileName[ 1],
1295                                AFSServerName.Buffer,
1296                                AFSServerName.Length);
1297
1298                 ulCopyLength -= AFSServerName.Length;
1299                 *Length -= AFSServerName.Length;
1300                 cchCopied += AFSServerName.Length/sizeof( WCHAR);
1301
1302                 if ( ulCopyLength > 0 &&
1303                      bAddLeadingSlash)
1304                 {
1305
1306                     Buffer->FileName[ cchCopied] = L'\\';
1307
1308                     ulCopyLength -= sizeof( WCHAR);
1309                     *Length -= sizeof( WCHAR);
1310                     cchCopied++;
1311                 }
1312
1313                 if( ulCopyLength >= pCcb->FullFileName.Length)
1314                 {
1315
1316                     RtlCopyMemory( &Buffer->FileName[ cchCopied],
1317                                    pCcb->FullFileName.Buffer,
1318                                    pCcb->FullFileName.Length);
1319
1320                     ulCopyLength -= pCcb->FullFileName.Length;
1321                     *Length -= pCcb->FullFileName.Length;
1322                     cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1323
1324                     if( ulCopyLength > 0 &&
1325                         bAddTrailingSlash)
1326                     {
1327                         Buffer->FileName[ cchCopied] = L'\\';
1328
1329                         *Length -= sizeof( WCHAR);
1330                     }
1331                 }
1332                 else
1333                 {
1334
1335                     RtlCopyMemory( &Buffer->FileName[ cchCopied],
1336                                    pCcb->FullFileName.Buffer,
1337                                    ulCopyLength);
1338
1339                     *Length -= ulCopyLength;
1340                 }
1341             }
1342         }
1343     }
1344     else
1345     {
1346
1347         ntStatus = STATUS_BUFFER_TOO_SMALL;
1348     }
1349
1350     return ntStatus;
1351 }
1352
1353 NTSTATUS
1354 AFSQueryShortNameInfo( IN PIRP Irp,
1355                        IN AFSDirectoryCB *DirectoryCB,
1356                        IN OUT PFILE_NAME_INFORMATION Buffer,
1357                        IN OUT PLONG Length)
1358 {
1359
1360     UNREFERENCED_PARAMETER(Irp);
1361     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1362     ULONG ulCopyLength = 0;
1363
1364     RtlZeroMemory( Buffer,
1365                    *Length);
1366
1367     if( DirectoryCB->NameInformation.ShortNameLength == 0)
1368     {
1369
1370         //
1371         // The short name IS the long name
1372         //
1373
1374         if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1375         {
1376
1377             if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1378             {
1379
1380                 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1381
1382                 ntStatus = STATUS_SUCCESS;
1383             }
1384             else
1385             {
1386
1387                 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1388
1389                 ntStatus = STATUS_BUFFER_OVERFLOW;
1390             }
1391
1392             Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1393
1394             *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1395
1396             if( ulCopyLength > 0)
1397             {
1398
1399                 RtlCopyMemory( Buffer->FileName,
1400                                DirectoryCB->NameInformation.FileName.Buffer,
1401                                ulCopyLength);
1402
1403                 *Length -= ulCopyLength;
1404             }
1405         }
1406     }
1407     else
1408     {
1409
1410         if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1411         {
1412
1413             if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1414             {
1415
1416                 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1417
1418                 ntStatus = STATUS_SUCCESS;
1419             }
1420             else
1421             {
1422
1423                 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1424
1425                 ntStatus = STATUS_BUFFER_OVERFLOW;
1426             }
1427
1428             Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1429
1430             *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1431
1432             if( ulCopyLength > 0)
1433             {
1434
1435                 RtlCopyMemory( Buffer->FileName,
1436                                DirectoryCB->NameInformation.ShortName,
1437                                Buffer->FileNameLength);
1438
1439                 *Length -= ulCopyLength;
1440             }
1441         }
1442     }
1443
1444     return ntStatus;
1445 }
1446
1447 NTSTATUS
1448 AFSQueryNetworkInfo( IN PIRP Irp,
1449                      IN AFSDirectoryCB *DirectoryCB,
1450                      IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1451                      IN OUT PLONG Length)
1452 {
1453
1454     NTSTATUS ntStatus = STATUS_SUCCESS;
1455     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1456     AFSFcb *pFcb = NULL;
1457     AFSCcb *pCcb = NULL;
1458     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1459     AFSFileInfoCB stFileInfo;
1460     AFSDirectoryCB *pParentDirectoryCB = NULL;
1461     UNICODE_STRING uniParentPath;
1462     ULONG ulFileAttribs = 0;
1463
1464     RtlZeroMemory( Buffer,
1465                    *Length);
1466
1467     if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
1468     {
1469
1470         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1471
1472         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1473         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1474
1475         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1476         {
1477
1478             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1479
1480             AFSRetrieveParentPath( &pCcb->FullFileName,
1481                                    &uniParentPath);
1482
1483             RtlZeroMemory( &stFileInfo,
1484                            sizeof( AFSFileInfoCB));
1485
1486             //
1487             // Can't hold the Fcb while evaluating the path, leads to lock inversion
1488             //
1489
1490             AFSReleaseResource( &pFcb->NPFcb->Resource);
1491
1492             //
1493             // Its a reparse point regardless of whether the file attributes
1494             // can be retrieved for the target.
1495             //
1496
1497             if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1498             {
1499
1500                 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1501             }
1502             else
1503             {
1504
1505                 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1506             }
1507
1508             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1509                                                        DirectoryCB,
1510                                                        &uniParentPath,
1511                                                        pCcb->NameArray,
1512                                                        &pCcb->AuthGroup,
1513                                                        &stFileInfo)))
1514             {
1515
1516                 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1517                 {
1518
1519                     ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1520                 }
1521             }
1522
1523             AFSAcquireShared( &pFcb->NPFcb->Resource,
1524                               TRUE);
1525         }
1526
1527         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1528                       AFS_TRACE_LEVEL_VERBOSE_2,
1529                       "AFSQueryNetworkInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1530                       &pCcb->DirectoryCB->NameInformation.FileName,
1531                       pFcb->ObjectInformation->FileType,
1532                       pFcb->ObjectInformation->FileAttributes,
1533                       ulFileAttribs));
1534
1535         Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1536         Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1537         Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1538         Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1539
1540         Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1541         Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1542
1543         Buffer->FileAttributes = ulFileAttribs;
1544
1545         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1546             BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1547         {
1548
1549             if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1550             {
1551
1552                 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1553             }
1554             else
1555             {
1556
1557                 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1558             }
1559         }
1560
1561         *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1562     }
1563     else
1564     {
1565
1566         ntStatus = STATUS_BUFFER_TOO_SMALL;
1567     }
1568
1569     return ntStatus;
1570 }
1571
1572 NTSTATUS
1573 AFSQueryStreamInfo( IN PIRP Irp,
1574                     IN AFSDirectoryCB *DirectoryCB,
1575                     IN OUT FILE_STREAM_INFORMATION *Buffer,
1576                     IN OUT PLONG Length)
1577 {
1578
1579     UNREFERENCED_PARAMETER(Irp);
1580     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1581     ULONG ulCopyLength = 0;
1582
1583     if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1584     {
1585
1586         RtlZeroMemory( Buffer,
1587                        *Length);
1588
1589         Buffer->NextEntryOffset = 0;
1590
1591
1592         if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1593         {
1594
1595             if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14))  // ::$DATA
1596             {
1597
1598                 ulCopyLength = 14;
1599
1600                 ntStatus = STATUS_SUCCESS;
1601             }
1602             else
1603             {
1604
1605                 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1606
1607                 ntStatus = STATUS_BUFFER_OVERFLOW;
1608             }
1609
1610             Buffer->StreamNameLength = 14; // ::$DATA
1611
1612             Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1613
1614             Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1615
1616             *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1617
1618             if( ulCopyLength > 0)
1619             {
1620
1621                 RtlCopyMemory( Buffer->StreamName,
1622                                L"::$DATA",
1623                                ulCopyLength);
1624
1625                 *Length -= ulCopyLength;
1626             }
1627         }
1628         else
1629         {
1630
1631             Buffer->StreamNameLength = 0;       // No stream for a directory
1632
1633             // The response size is zero
1634
1635             ntStatus = STATUS_SUCCESS;
1636         }
1637     }
1638
1639     return ntStatus;
1640 }
1641
1642 NTSTATUS
1643 AFSQueryAttribTagInfo( IN PIRP Irp,
1644                        IN AFSDirectoryCB *DirectoryCB,
1645                        IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1646                        IN OUT PLONG Length)
1647 {
1648
1649     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1650     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1651     AFSFcb *pFcb = NULL;
1652     AFSCcb *pCcb = NULL;
1653     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1654     AFSFileInfoCB stFileInfo;
1655     AFSDirectoryCB *pParentDirectoryCB = NULL;
1656     UNICODE_STRING uniParentPath;
1657     ULONG ulFileAttribs = 0;
1658
1659     if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1660     {
1661
1662         RtlZeroMemory( Buffer,
1663                        *Length);
1664
1665         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1666
1667         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1668         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1669
1670         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1671         {
1672
1673             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1674
1675             AFSRetrieveParentPath( &pCcb->FullFileName,
1676                                    &uniParentPath);
1677
1678             RtlZeroMemory( &stFileInfo,
1679                            sizeof( AFSFileInfoCB));
1680
1681             //
1682             // Can't hold the Fcb while evaluating the path, leads to lock inversion
1683             //
1684
1685             AFSReleaseResource( &pFcb->NPFcb->Resource);
1686
1687             //
1688             // Its a reparse point regardless of whether the file attributes
1689             // can be retrieved for the target.
1690             //
1691
1692             if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1693             {
1694
1695                 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1696             }
1697             else
1698             {
1699
1700                 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1701             }
1702
1703             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1704                                                        DirectoryCB,
1705                                                        &uniParentPath,
1706                                                        pCcb->NameArray,
1707                                                        &pCcb->AuthGroup,
1708                                                        &stFileInfo)))
1709             {
1710
1711                 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1712                 {
1713
1714                     ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1715                 }
1716             }
1717
1718             AFSAcquireShared( &pFcb->NPFcb->Resource,
1719                               TRUE);
1720         }
1721
1722         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1723                       AFS_TRACE_LEVEL_VERBOSE_2,
1724                       "AFSAttribTagInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1725                       &pCcb->DirectoryCB->NameInformation.FileName,
1726                       pFcb->ObjectInformation->FileType,
1727                       pFcb->ObjectInformation->FileAttributes,
1728                       ulFileAttribs));
1729
1730         Buffer->FileAttributes = ulFileAttribs;
1731
1732         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1733             BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1734         {
1735
1736             if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1737             {
1738
1739                 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1740             }
1741             else
1742             {
1743
1744                 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1745             }
1746         }
1747
1748         if ( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1749         {
1750
1751             Buffer->ReparseTag = IO_REPARSE_TAG_SURROGATE|IO_REPARSE_TAG_OPENAFS_DFS;
1752         }
1753         else if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1754         {
1755
1756             Buffer->ReparseTag = IO_REPARSE_TAG_SYMLINK;
1757         }
1758
1759         *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1760
1761         ntStatus = STATUS_SUCCESS;
1762     }
1763
1764     return ntStatus;
1765 }
1766
1767 NTSTATUS
1768 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1769                             IN AFSDirectoryCB *DirectoryCB,
1770                             IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1771                             IN OUT PLONG Length)
1772 {
1773
1774     UNREFERENCED_PARAMETER(Irp);
1775     UNREFERENCED_PARAMETER(DirectoryCB);
1776     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1777
1778     if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1779     {
1780
1781         RtlZeroMemory( Buffer,
1782                        *Length);
1783
1784         Buffer->StructureVersion = 1;
1785
1786         Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1787
1788         Buffer->Protocol = WNNC_NET_OPENAFS;
1789
1790         Buffer->ProtocolMajorVersion = 3;
1791
1792         Buffer->ProtocolMinorVersion = 0;
1793
1794         Buffer->ProtocolRevision = 0;
1795
1796         *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1797
1798         ntStatus = STATUS_SUCCESS;
1799     }
1800
1801     return ntStatus;
1802 }
1803
1804 NTSTATUS
1805 AFSQueryPhysicalNameInfo( IN PIRP Irp,
1806                           IN AFSDirectoryCB *DirectoryCB,
1807                           IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
1808                           IN OUT PLONG Length)
1809 {
1810
1811     UNREFERENCED_PARAMETER(DirectoryCB);
1812     NTSTATUS ntStatus = STATUS_SUCCESS;
1813     ULONG ulCopyLength = 0;
1814     ULONG cchCopied = 0;
1815     AFSFcb *pFcb = NULL;
1816     AFSCcb *pCcb = NULL;
1817     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1818     BOOLEAN bAddLeadingSlash = FALSE;
1819     USHORT usFullNameLength = 0;
1820
1821     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1822
1823     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1824
1825     if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
1826     {
1827
1828         RtlZeroMemory( Buffer,
1829                        *Length);
1830
1831         if( pCcb->FullFileName.Length == 0 ||
1832             pCcb->FullFileName.Buffer[ 0] != L'\\')
1833         {
1834             bAddLeadingSlash = TRUE;
1835         }
1836
1837         usFullNameLength = pCcb->FullFileName.Length;
1838
1839         if( bAddLeadingSlash)
1840         {
1841             usFullNameLength += sizeof( WCHAR);
1842         }
1843
1844         if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1845         {
1846             ulCopyLength = (LONG)usFullNameLength;
1847         }
1848         else
1849         {
1850
1851             ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1852
1853             ntStatus = STATUS_BUFFER_OVERFLOW;
1854         }
1855
1856         Buffer->FileNameLength = (ULONG)usFullNameLength;
1857
1858         *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1859
1860         if( ulCopyLength > 0)
1861         {
1862
1863             if( bAddLeadingSlash)
1864             {
1865
1866                 Buffer->FileName[ cchCopied] = L'\\';
1867
1868                 ulCopyLength -= sizeof( WCHAR);
1869                 *Length -= sizeof( WCHAR);
1870                 cchCopied++;
1871             }
1872
1873             if( ulCopyLength >= pCcb->FullFileName.Length)
1874             {
1875
1876                 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1877                                pCcb->FullFileName.Buffer,
1878                                pCcb->FullFileName.Length);
1879
1880                 ulCopyLength -= pCcb->FullFileName.Length;
1881                 *Length -= pCcb->FullFileName.Length;
1882                 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1883             }
1884             else
1885             {
1886
1887                 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1888                                pCcb->FullFileName.Buffer,
1889                                ulCopyLength);
1890
1891                 *Length -= ulCopyLength;
1892             }
1893         }
1894     }
1895     else
1896     {
1897
1898         ntStatus = STATUS_BUFFER_TOO_SMALL;
1899     }
1900
1901     return ntStatus;
1902 }
1903
1904 NTSTATUS
1905 AFSSetBasicInfo( IN PIRP Irp,
1906                  IN AFSDirectoryCB *DirectoryCB)
1907 {
1908     NTSTATUS ntStatus = STATUS_SUCCESS;
1909     PFILE_BASIC_INFORMATION pBuffer;
1910     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1911     ULONG ulNotifyFilter = 0;
1912     AFSCcb *pCcb = NULL;
1913
1914     __Enter
1915     {
1916
1917         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1918
1919         pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1920
1921         pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1922
1923         if( pBuffer->FileAttributes != (ULONGLONG)0)
1924         {
1925
1926             if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
1927                 BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1928             {
1929
1930                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1931             }
1932
1933             if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1934             {
1935
1936                 pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1937             }
1938
1939             pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1940
1941             DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
1942
1943             ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1944
1945             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1946         }
1947
1948         pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
1949
1950         if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
1951             pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
1952         {
1953
1954             pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1955
1956             DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
1957
1958             ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
1959
1960             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
1961         }
1962
1963         pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
1964
1965         if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
1966             pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
1967         {
1968
1969             pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1970
1971             DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
1972
1973             ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1974
1975             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
1976         }
1977
1978         pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
1979
1980         if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
1981             pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
1982         {
1983
1984             pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1985
1986             DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
1987
1988             ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
1989
1990             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
1991         }
1992
1993         pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
1994
1995         if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
1996             pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
1997         {
1998
1999             pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
2000
2001             DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
2002
2003             ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
2004
2005             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2006         }
2007
2008         if( ulNotifyFilter > 0)
2009         {
2010
2011             if( BooleanFlagOn( DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2012             {
2013
2014                 AFSObjectInfoCB * pParentObjectInfo = AFSFindObjectInfo( DirectoryCB->ObjectInformation->VolumeCB,
2015                                                                          &DirectoryCB->ObjectInformation->ParentFileId,
2016                                                                          TRUE);
2017
2018                 if ( pParentObjectInfo != NULL)
2019                 {
2020                     AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2021                                                     pCcb,
2022                                                     (ULONG)ulNotifyFilter,
2023                                                     (ULONG)FILE_ACTION_MODIFIED);
2024
2025                     AFSReleaseObjectInfo( &pParentObjectInfo);
2026                 }
2027             }
2028         }
2029
2030 try_exit:
2031
2032         NOTHING;
2033     }
2034
2035     return ntStatus;
2036 }
2037
2038 NTSTATUS
2039 AFSSetDispositionInfo( IN PIRP Irp,
2040                        IN AFSDirectoryCB *DirectoryCB)
2041 {
2042     NTSTATUS ntStatus = STATUS_SUCCESS;
2043     PFILE_DISPOSITION_INFORMATION pBuffer;
2044     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2045     AFSFcb *pFcb = NULL;
2046     AFSCcb *pCcb = NULL;
2047
2048     __Enter
2049     {
2050
2051         pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2052
2053         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2054
2055         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2056
2057         //
2058         // Can't delete the root
2059         //
2060
2061         if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2062         {
2063
2064             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2065                           AFS_TRACE_LEVEL_ERROR,
2066                           "AFSSetDispositionInfo Attempt to delete root entry\n"));
2067
2068             try_return( ntStatus = STATUS_CANNOT_DELETE);
2069         }
2070
2071         //
2072         // If the file is read only then do not allow the delete
2073         //
2074
2075         if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
2076         {
2077
2078             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2079                           AFS_TRACE_LEVEL_ERROR,
2080                           "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
2081                           &DirectoryCB->NameInformation.FileName));
2082
2083             try_return( ntStatus = STATUS_CANNOT_DELETE);
2084         }
2085
2086         if( pBuffer->DeleteFile)
2087         {
2088
2089             //
2090             // Check if the caller can delete the file
2091             //
2092
2093             ntStatus = AFSNotifyDelete( DirectoryCB,
2094                                         &pCcb->AuthGroup,
2095                                         TRUE);
2096
2097             if( !NT_SUCCESS( ntStatus))
2098             {
2099
2100                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2101                               AFS_TRACE_LEVEL_ERROR,
2102                               "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
2103                               &DirectoryCB->NameInformation.FileName,
2104                               ntStatus));
2105
2106                 try_return( ntStatus);
2107             }
2108
2109             if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2110             {
2111
2112                 //
2113                 // Reduce the Link count in the object information block
2114                 // to correspond with the deletion of the directory entry.
2115                 //
2116
2117                 pFcb->ObjectInformation->Links--;
2118
2119                 //
2120                 // Check if this is a directory that there are not currently other opens
2121                 //
2122
2123                 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2124                 {
2125
2126                     AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2127                                   AFS_TRACE_LEVEL_ERROR,
2128                                   "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
2129                                   &DirectoryCB->NameInformation.FileName,
2130                                   pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount));
2131
2132                     try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2133                 }
2134
2135                 //
2136                 // Make sure the directory is enumerated before checking to see if it is empty.
2137                 //
2138
2139                 if( !BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2140                 {
2141
2142                     AFSAcquireExcl( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2143                                     TRUE);
2144
2145                     if( !BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2146                     {
2147
2148                         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2149                                       AFS_TRACE_LEVEL_VERBOSE,
2150                                       "AFSSetDispositionInfo Enumerating parent FID %08lX-%08lX-%08lX-%08lX\n",
2151                                       pFcb->ObjectInformation->FileId.Cell,
2152                                       pFcb->ObjectInformation->FileId.Volume,
2153                                       pFcb->ObjectInformation->FileId.Vnode,
2154                                       pFcb->ObjectInformation->FileId.Unique));
2155
2156                         ntStatus = AFSEnumerateDirectory( &pCcb->AuthGroup,
2157                                                           pFcb->ObjectInformation,
2158                                                           TRUE);
2159
2160                         if( !NT_SUCCESS( ntStatus))
2161                         {
2162
2163                             AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2164
2165                             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2166                                           AFS_TRACE_LEVEL_ERROR,
2167                                           "AFSSetDispositionInfo Failed to enumerate parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2168                                           pFcb->ObjectInformation->FileId.Cell,
2169                                           pFcb->ObjectInformation->FileId.Volume,
2170                                           pFcb->ObjectInformation->FileId.Vnode,
2171                                           pFcb->ObjectInformation->FileId.Unique,
2172                                           ntStatus));
2173
2174                             try_return( ntStatus);
2175                         }
2176                     }
2177
2178                     AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2179                 }
2180
2181                 if( !AFSIsDirectoryEmptyForDelete( pFcb))
2182                 {
2183
2184                     AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2185                                   AFS_TRACE_LEVEL_ERROR,
2186                                   "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
2187                                   &DirectoryCB->NameInformation.FileName));
2188
2189                     try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2190                 }
2191
2192                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2193                               AFS_TRACE_LEVEL_VERBOSE,
2194                               "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry  %p Name %wZ\n",
2195                               DirectoryCB,
2196                               &DirectoryCB->NameInformation.FileName));
2197
2198                 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2199             }
2200             else if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2201             {
2202                 BOOLEAN bMmFlushed;
2203
2204                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2205                               AFS_TRACE_LEVEL_VERBOSE,
2206                               "AFSSetDispositionInfo Acquiring Fcb lock %p EXCL %08lX\n",
2207                               &pFcb->NPFcb->Resource,
2208                               PsGetCurrentThread()));
2209
2210                 AFSAcquireExcl( &pFcb->NPFcb->Resource,
2211                                 TRUE);
2212
2213                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
2214                               AFS_TRACE_LEVEL_VERBOSE,
2215                               "AFSSetDispositionInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2216                               &pFcb->NPFcb->SectionObjectResource,
2217                               PsGetCurrentThread()));
2218
2219                 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
2220                                 TRUE);
2221
2222                 __try
2223                 {
2224
2225                     //
2226                     // Attempt to flush any outstanding data
2227                     //
2228
2229                     bMmFlushed = MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
2230                                                       MmFlushForDelete);
2231
2232                     if ( bMmFlushed)
2233                     {
2234
2235                         //
2236                         // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
2237                         // deadlock with Trend Micro's Enterprise anti-virus product
2238                         // which attempts to open the file which is being deleted.
2239                         //
2240
2241                         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2242                                       AFS_TRACE_LEVEL_VERBOSE,
2243                                       "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2244                                       DirectoryCB,
2245                                       &DirectoryCB->NameInformation.FileName));
2246
2247                         SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2248
2249                         //
2250                         // Purge the cache as well
2251                         //
2252
2253                         if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2254                         {
2255
2256                             if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
2257                                                        NULL,
2258                                                        0,
2259                                                        TRUE))
2260                             {
2261
2262                                 SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2263                             }
2264                         }
2265                     }
2266                 }
2267                 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
2268                 {
2269
2270                     bMmFlushed = FALSE;
2271
2272                     ntStatus = GetExceptionCode();
2273
2274                     AFSDbgTrace(( 0,
2275                                   0,
2276                                   "EXCEPTION - AFSSetDispositionInfo MmFlushImageSection failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2277                                   pFcb->ObjectInformation->FileId.Cell,
2278                                   pFcb->ObjectInformation->FileId.Volume,
2279                                   pFcb->ObjectInformation->FileId.Vnode,
2280                                   pFcb->ObjectInformation->FileId.Unique,
2281                                   ntStatus));
2282                 }
2283
2284                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
2285                               AFS_TRACE_LEVEL_VERBOSE,
2286                               "AFSSetDispositionInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2287                               &pFcb->NPFcb->SectionObjectResource,
2288                               PsGetCurrentThread()));
2289
2290                 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
2291
2292                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2293                               AFS_TRACE_LEVEL_VERBOSE,
2294                               "AFSSetDispositionInfo Releasing Fcb lock %p EXCL %08lX\n",
2295                               &pFcb->NPFcb->Resource,
2296                               PsGetCurrentThread()));
2297
2298                 AFSReleaseResource( &pFcb->NPFcb->Resource);
2299
2300                 if ( !bMmFlushed)
2301                 {
2302
2303                     AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2304                                   AFS_TRACE_LEVEL_ERROR,
2305                                   "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
2306                                   &DirectoryCB->NameInformation.FileName));
2307
2308                     try_return( ntStatus = STATUS_CANNOT_DELETE);
2309                 }
2310             }
2311             else if( pFcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2312                      pFcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2313                      pFcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2314                      pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2315             {
2316
2317                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2318                               AFS_TRACE_LEVEL_VERBOSE,
2319                               "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2320                               DirectoryCB,
2321                               &DirectoryCB->NameInformation.FileName));
2322
2323                 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2324             }
2325         }
2326         else
2327         {
2328
2329             ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2330         }
2331
2332         //
2333         // OK, should be good to go, set the flag in the file object
2334         //
2335
2336         pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2337
2338 try_exit:
2339
2340         NOTHING;
2341     }
2342
2343     return ntStatus;
2344 }
2345
2346 NTSTATUS
2347 AFSSetFileLinkInfo( IN PIRP Irp)
2348 {
2349
2350     NTSTATUS ntStatus = STATUS_SUCCESS;
2351     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2352     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2353     PFILE_LINK_INFORMATION pFileLinkInfo = NULL;
2354     PFILE_OBJECT pSrcFileObj = NULL;
2355     PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2356     AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL;
2357     AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2358     AFSObjectInfoCB *pSrcObject = NULL;
2359     AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2360     UNICODE_STRING uniSourceName, uniTargetName;
2361     UNICODE_STRING uniFullTargetName, uniTargetParentName;
2362     BOOLEAN bCommonParent = FALSE;
2363     AFSDirectoryCB *pTargetDirEntry = NULL;
2364     AFSDirectoryCB *pNewTargetDirEntry = NULL;
2365     ULONG ulTargetCRC;
2366     BOOLEAN bTargetEntryExists = FALSE;
2367     LONG lCount;
2368     BOOLEAN bReleaseTargetDirLock = FALSE;
2369     ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2370
2371     __Enter
2372     {
2373
2374         pSrcFileObj = pIrpSp->FileObject;
2375
2376         pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2377         pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2378
2379         pSrcObject = pSrcFcb->ObjectInformation;
2380
2381         if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2382         {
2383
2384             pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2385                                                   &pSrcObject->ParentFileId,
2386                                                   TRUE);
2387         }
2388
2389         if( pSrcParentObject == NULL)
2390         {
2391
2392             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2393                           AFS_TRACE_LEVEL_ERROR,
2394                           "AFSSetFileLinkInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2395
2396             ASSERT( FALSE);
2397
2398             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2399         }
2400
2401         pFileLinkInfo = (PFILE_LINK_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2402
2403         //
2404         // Perform some basic checks to ensure FS integrity
2405         //
2406
2407         if( pSrcFcb->Header.NodeTypeCode != AFS_FILE_FCB)
2408         {
2409
2410             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2411                           AFS_TRACE_LEVEL_ERROR,
2412                           "AFSSetFileLinkInfo Attempt to non-file (INVALID_PARAMETER)\n"));
2413
2414             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2415         }
2416
2417         if( pTargetFileObj == NULL)
2418         {
2419
2420             if ( pFileLinkInfo->RootDirectory)
2421             {
2422
2423                 //
2424                 // The target directory is provided by HANDLE
2425                 // RootDirectory is only set when the target directory is not the same
2426                 // as the source directory.
2427                 //
2428                 // AFS only supports hard links within a single directory.
2429                 //
2430                 // The IOManager should translate any Handle to a FileObject for us.
2431                 // However, the failure to receive a FileObject is treated as a fatal
2432                 // error.
2433                 //
2434
2435                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2436                               AFS_TRACE_LEVEL_ERROR,
2437                               "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory by handle INVALID_PARAMETER\n",
2438                               &pSrcCcb->DirectoryCB->NameInformation.FileName));
2439
2440                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2441             }
2442             else
2443             {
2444
2445                 uniFullTargetName.Length = (USHORT)pFileLinkInfo->FileNameLength;
2446
2447                 uniFullTargetName.Buffer = (PWSTR)&pFileLinkInfo->FileName;
2448
2449                 AFSRetrieveFinalComponent( &uniFullTargetName,
2450                                            &uniTargetName);
2451
2452                 AFSRetrieveParentPath( &uniFullTargetName,
2453                                        &uniTargetParentName);
2454
2455                 if ( uniTargetParentName.Length == 0)
2456                 {
2457
2458                     //
2459                     // This is a simple rename. Here the target directory is the same as the source parent directory
2460                     // and the name is retrieved from the system buffer information
2461                     //
2462
2463                     pTargetParentObject = pSrcParentObject;
2464                 }
2465                 else
2466                 {
2467                     //
2468                     // uniTargetParentName contains the directory the renamed object
2469                     // will be moved to.  Must obtain the TargetParentObject.
2470                     //
2471
2472                     AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2473                                   AFS_TRACE_LEVEL_ERROR,
2474                                   "AFSSetFileLinkInfo Attempt to link  %wZ to alternate directory %wZ (NOT_SAME_DEVICE)\n",
2475                                   &pSrcCcb->DirectoryCB->NameInformation.FileName,
2476                                   &uniFullTargetName));
2477
2478                     try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2479                 }
2480             }
2481
2482             pTargetDcb = pTargetParentObject->Fcb;
2483         }
2484         else
2485         {
2486
2487             //
2488             // So here we have the target directory taken from the targetfile object
2489             //
2490
2491             pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2492
2493             pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2494
2495             pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2496
2497             //
2498             // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2499             // it is only the target component of the rename operation
2500             //
2501
2502             uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2503         }
2504
2505         //
2506         // The quick check to see if they are self linking.
2507         // Do the names match? Only do this where the parent directories are
2508         // the same
2509         //
2510
2511         if( pTargetParentObject == pSrcParentObject)
2512         {
2513
2514             if( FsRtlAreNamesEqual( &uniTargetName,
2515                                     &uniSourceName,
2516                                     FALSE,
2517                                     NULL))
2518             {
2519                 try_return( ntStatus = STATUS_SUCCESS);
2520             }
2521
2522             bCommonParent = TRUE;
2523         }
2524         else
2525         {
2526
2527             //
2528             // We do not allow cross-volume hard links
2529             //
2530
2531             if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2532             {
2533
2534                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2535                               AFS_TRACE_LEVEL_ERROR,
2536                               "AFSSetFileLinkInfo Attempt to link to different volume %wZ\n",
2537                               &pSrcCcb->DirectoryCB->NameInformation.FileName));
2538
2539                 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2540             }
2541         }
2542
2543         ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2544                                       FALSE);
2545
2546         AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2547                         TRUE);
2548
2549         bReleaseTargetDirLock = TRUE;
2550
2551         AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2552                                         ulTargetCRC,
2553                                         &pTargetDirEntry);
2554
2555         if( pTargetDirEntry == NULL)
2556         {
2557
2558             //
2559             // Missed so perform a case insensitive lookup
2560             //
2561
2562             ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2563                                           TRUE);
2564
2565             AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2566                                               ulTargetCRC,
2567                                               &pTargetDirEntry);
2568         }
2569
2570         if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2571              pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2572                                                                 NULL,
2573                                                                 NULL))
2574         {
2575             //
2576             // Try the short name
2577             //
2578             AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2579                                         ulTargetCRC,
2580                                         &pTargetDirEntry);
2581         }
2582
2583         //
2584         // Increment our ref count on the dir entry
2585         //
2586
2587         if( pTargetDirEntry != NULL)
2588         {
2589
2590             ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2591                     AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
2592
2593             lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
2594
2595             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2596                           AFS_TRACE_LEVEL_VERBOSE,
2597                           "AFSSetFileLinkInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
2598                           &pTargetDirEntry->NameInformation.FileName,
2599                           pTargetDirEntry,
2600                           pSrcCcb,
2601                           lCount));
2602
2603             ASSERT( lCount >= 0);
2604
2605             if( !pFileLinkInfo->ReplaceIfExists)
2606             {
2607
2608                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2609                               AFS_TRACE_LEVEL_ERROR,
2610                               "AFSSetFileLinkInfo Attempt to link with target collision %wZ Target %wZ\n",
2611                               &pSrcCcb->DirectoryCB->NameInformation.FileName,
2612                               &pTargetDirEntry->NameInformation.FileName));
2613
2614                 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2615             }
2616
2617             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2618                           AFS_TRACE_LEVEL_ERROR,
2619                           "AFSSetFileLinkInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
2620                           &pTargetDirEntry->NameInformation.FileName,
2621                           pTargetDirEntry,
2622                           lCount));
2623
2624             //
2625             // Pull the directory entry from the parent
2626             //
2627
2628             AFSRemoveDirNodeFromParent( pTargetParentObject,
2629                                         pTargetDirEntry,
2630                                         FALSE);
2631
2632             bTargetEntryExists = TRUE;
2633         }
2634         else
2635         {
2636             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2637                           AFS_TRACE_LEVEL_VERBOSE,
2638                           "AFSSetFileLinkInfo Target does NOT exist, normal linking\n"));
2639         }
2640
2641         //
2642         // OK, this is a simple rename. Issue the rename
2643         // request to the service.
2644         //
2645
2646         ntStatus = AFSNotifyHardLink( pSrcObject,
2647                                       &pSrcCcb->AuthGroup,
2648                                       pSrcParentObject,
2649                                       pTargetDcb->ObjectInformation,
2650                                       pSrcCcb->DirectoryCB,
2651                                       &uniTargetName,
2652                                       pFileLinkInfo->ReplaceIfExists,
2653                                       &pNewTargetDirEntry);
2654
2655         if( ntStatus != STATUS_REPARSE &&
2656             !NT_SUCCESS( ntStatus))
2657         {
2658
2659             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2660                           AFS_TRACE_LEVEL_ERROR,
2661                           "AFSSetFileLinkInfo Failed link of %wZ to target %wZ Status %08lX\n",
2662                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
2663                           &uniTargetName,
2664                           ntStatus));
2665
2666             try_return( ntStatus);
2667         }
2668
2669         if ( ntStatus != STATUS_REPARSE)
2670         {
2671
2672             AFSInsertDirectoryNode( pTargetDcb->ObjectInformation,
2673                                     pNewTargetDirEntry,
2674                                     TRUE);
2675         }
2676
2677         //
2678         // Send notification for the target link file
2679         //
2680
2681         if( bTargetEntryExists || pNewTargetDirEntry)
2682         {
2683
2684             ulNotificationAction = FILE_ACTION_MODIFIED;
2685         }
2686         else
2687         {
2688
2689             ulNotificationAction = FILE_ACTION_ADDED;
2690         }
2691
2692         AFSFsRtlNotifyFullReportChange( pTargetParentObject,
2693                                         pSrcCcb,
2694                                         (ULONG)ulNotifyFilter,
2695                                         (ULONG)ulNotificationAction);
2696
2697       try_exit:
2698
2699         if( !NT_SUCCESS( ntStatus))
2700         {
2701
2702             if( bTargetEntryExists)
2703             {
2704
2705                 AFSInsertDirectoryNode( pTargetParentObject,
2706                                         pTargetDirEntry,
2707                                         FALSE);
2708             }
2709         }
2710
2711         if( pTargetDirEntry != NULL)
2712         {
2713
2714             //
2715             // Release DirOpenReferenceCount obtained above
2716             //
2717
2718             lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
2719
2720             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2721                           AFS_TRACE_LEVEL_VERBOSE,
2722                           "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2723                           &pTargetDirEntry->NameInformation.FileName,
2724                           pTargetDirEntry,
2725                           pSrcCcb,
2726                           lCount));
2727
2728             ASSERT( lCount >= 0);
2729         }
2730
2731         if( pNewTargetDirEntry != NULL)
2732         {
2733
2734             //
2735             // Release DirOpenReferenceCount obtained from AFSNotifyHardLink
2736             //
2737
2738             lCount = InterlockedDecrement( &pNewTargetDirEntry->DirOpenReferenceCount);
2739
2740             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2741                           AFS_TRACE_LEVEL_VERBOSE,
2742                           "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2743                           &pNewTargetDirEntry->NameInformation.FileName,
2744                           pNewTargetDirEntry,
2745                           pSrcCcb,
2746                           lCount));
2747
2748             ASSERT( lCount >= 0);
2749         }
2750
2751         if( bReleaseTargetDirLock)
2752         {
2753
2754             AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2755         }
2756
2757         if ( pSrcParentObject != NULL)
2758         {
2759
2760             AFSReleaseObjectInfo( &pSrcParentObject);
2761         }
2762
2763         //
2764         // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
2765         // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
2766         //
2767
2768         pTargetParentObject = NULL;
2769     }
2770
2771     return ntStatus;
2772 }
2773
2774 NTSTATUS
2775 AFSSetRenameInfo( IN PIRP Irp)
2776 {
2777
2778     NTSTATUS ntStatus = STATUS_SUCCESS;
2779     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2780     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2781     AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2782     AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2783     PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2784     PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2785     PFILE_OBJECT pTargetParentFileObj = NULL;
2786     PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2787     UNICODE_STRING uniTargetName, uniSourceName, uniTargetParentName;
2788     BOOLEAN bReplaceIfExists = FALSE;
2789     UNICODE_STRING uniShortName;
2790     AFSDirectoryCB *pTargetDirEntry = NULL;
2791     ULONG ulTargetCRC = 0;
2792     BOOLEAN bTargetEntryExists = FALSE;
2793     AFSObjectInfoCB *pSrcObject = NULL;
2794     AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2795     AFSFileID stNewFid;
2796     ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2797     UNICODE_STRING uniFullTargetName;
2798     BOOLEAN bCommonParent = FALSE;
2799     BOOLEAN bReleaseTargetDirLock = FALSE;
2800     BOOLEAN bReleaseSourceDirLock = FALSE;
2801     BOOLEAN bDereferenceTargetParentObject = FALSE;
2802     PERESOURCE  pSourceDirLock = NULL;
2803     LONG lCount;
2804
2805     __Enter
2806     {
2807
2808         bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2809
2810         pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2811
2812         pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2813         pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2814
2815         pSrcObject = pSrcFcb->ObjectInformation;
2816
2817         if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2818         {
2819
2820             pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2821                                                   &pSrcObject->ParentFileId,
2822                                                   TRUE);
2823         }
2824
2825         if( pSrcParentObject == NULL)
2826         {
2827
2828             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2829                           AFS_TRACE_LEVEL_ERROR,
2830                           "AFSSetRenameInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2831
2832             ASSERT( FALSE);
2833
2834             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2835         }
2836
2837         //
2838         // Perform some basic checks to ensure FS integrity
2839         //
2840
2841         if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2842         {
2843
2844             //
2845             // Can't rename the root directory
2846             //
2847
2848             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2849                           AFS_TRACE_LEVEL_ERROR,
2850                           "AFSSetRenameInfo Attempt to rename root entry\n"));
2851
2852             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2853         }
2854
2855         if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2856         {
2857
2858             //
2859             // If there are any open children then fail the rename
2860             //
2861
2862             if( pSrcObject->Specific.Directory.ChildOpenHandleCount > 0)
2863             {
2864
2865                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2866                               AFS_TRACE_LEVEL_ERROR,
2867                               "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2868                               &pSrcCcb->DirectoryCB->NameInformation.FileName));
2869
2870                 try_return( ntStatus = STATUS_ACCESS_DENIED);
2871             }
2872         }
2873
2874
2875         //
2876         // Extract off the final component name from the Fcb
2877         //
2878
2879         uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2880         uniSourceName.MaximumLength = uniSourceName.Length;
2881
2882         uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2883
2884         //
2885         // Resolve the target fileobject
2886         //
2887
2888         if( pTargetFileObj == NULL)
2889         {
2890
2891             if ( pRenameInfo->RootDirectory)
2892             {
2893
2894                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2895                               AFS_TRACE_LEVEL_ERROR,
2896                               "AFSSetRenameInfo Handle provided but no FileObject ntStatus INVALID_PARAMETER\n"));
2897
2898                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2899             }
2900             else
2901             {
2902
2903                 uniFullTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2904
2905                 uniFullTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2906
2907                 AFSRetrieveFinalComponent( &uniFullTargetName,
2908                                            &uniTargetName);
2909
2910                 AFSRetrieveParentPath( &uniFullTargetName,
2911                                        &uniTargetParentName);
2912
2913                 if ( uniTargetParentName.Length == 0)
2914                 {
2915
2916                     //
2917                     // This is a simple rename. Here the target directory is the same as the source parent directory
2918                     // and the name is retrieved from the system buffer information
2919                     //
2920
2921                     pTargetParentObject = pSrcParentObject;
2922                 }
2923                 else
2924                 {
2925                     //
2926                     // uniTargetParentName contains the directory the renamed object
2927                     // will be moved to.  Must obtain the TargetParentObject.
2928                     //
2929
2930                     AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2931                                   AFS_TRACE_LEVEL_ERROR,
2932                                   "AFSSetRenameInfo Attempt to move %wZ to %wZ -- not yet supported (NOT_SAME_DEVICE)\n",
2933                                   &pSrcCcb->DirectoryCB->NameInformation.FileName,
2934                                   &uniFullTargetName));
2935
2936                     try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2937                 }
2938             }
2939
2940             pTargetDcb = pTargetParentObject->Fcb;
2941         }
2942         else
2943         {
2944
2945             //
2946             // So here we have the target directory taken from the targetfile object
2947             //
2948
2949             pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2950
2951             pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2952
2953             pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2954
2955             //
2956             // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2957             // it is only the target component of the rename operation
2958             //
2959
2960             uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2961         }
2962
2963         //
2964         // The quick check to see if they are not really performing a rename
2965         // Do the names match? Only do this where the parent directories are
2966         // the same
2967         //
2968
2969         if( pTargetParentObject == pSrcParentObject)
2970         {
2971
2972             if( FsRtlAreNamesEqual( &uniTargetName,
2973                                     &uniSourceName,
2974                                     FALSE,
2975                                     NULL))
2976             {
2977                 try_return( ntStatus = STATUS_SUCCESS);
2978             }
2979
2980             bCommonParent = TRUE;
2981         }
2982         else
2983         {
2984
2985             bCommonParent = FALSE;
2986         }
2987
2988         //
2989         // We do not allow cross-volume renames to occur
2990         //
2991
2992         if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2993         {
2994
2995             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2996                           AFS_TRACE_LEVEL_ERROR,
2997                           "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2998                           &pSrcCcb->DirectoryCB->NameInformation.FileName));
2999
3000             try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
3001         }
3002
3003         ulTargetCRC = AFSGenerateCRC( &uniTargetName,
3004                                       FALSE);
3005
3006         AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
3007                         TRUE);
3008
3009         bReleaseTargetDirLock = TRUE;
3010
3011         if( pTargetParentObject != pSrcParentObject)
3012         {
3013             AFSAcquireExcl( pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
3014                             TRUE);
3015
3016             bReleaseSourceDirLock = TRUE;
3017
3018             pSourceDirLock = pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock;
3019         }
3020
3021         AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3022                                         ulTargetCRC,
3023                                         &pTargetDirEntry);
3024
3025         if( pTargetDirEntry == NULL)
3026         {
3027
3028             //
3029             // Missed so perform a case insensitive lookup
3030             //
3031
3032             ulTargetCRC = AFSGenerateCRC( &uniTargetName,
3033                                           TRUE);
3034
3035             AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3036                                               ulTargetCRC,
3037                                               &pTargetDirEntry);
3038         }
3039
3040         if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3041              pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
3042                                                                NULL,
3043                                                                NULL))
3044         {
3045             //
3046             // Try the short name
3047             //
3048             AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
3049                                         ulTargetCRC,
3050                                         &pTargetDirEntry);
3051         }
3052
3053         //
3054         // Increment our ref count on the dir entry
3055         //
3056
3057         if( pTargetDirEntry != NULL)
3058         {
3059
3060             ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
3061                     AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
3062
3063             lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
3064
3065             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3066                           AFS_TRACE_LEVEL_VERBOSE,
3067                           "AFSSetRenameInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
3068                           &pTargetDirEntry->NameInformation.FileName,
3069                           pTargetDirEntry,
3070                           pSrcCcb,
3071                           lCount));
3072
3073             ASSERT( lCount >= 0);
3074
3075             if( !bReplaceIfExists)
3076             {
3077
3078                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3079                               AFS_TRACE_LEVEL_ERROR,
3080                               "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
3081                               &pSrcCcb->DirectoryCB->NameInformation.FileName,
3082                               &pTargetDirEntry->NameInformation.FileName));
3083
3084                 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
3085             }
3086
3087             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3088                           AFS_TRACE_LEVEL_ERROR,
3089                           "AFSSetRenameInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
3090                           &pTargetDirEntry->NameInformation.FileName,
3091                           pTargetDirEntry,
3092                           lCount));
3093
3094             //
3095             // Pull the directory entry from the parent
3096             //
3097
3098             AFSRemoveDirNodeFromParent( pTargetParentObject,
3099                                         pTargetDirEntry,
3100                                         FALSE);
3101
3102             bTargetEntryExists = TRUE;
3103         }
3104         else
3105         {
3106             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3107                           AFS_TRACE_LEVEL_VERBOSE,
3108                           "AFSSetRenameInfo Target does NOT exist, normal rename\n"));
3109         }
3110
3111         //
3112         // We need to remove the DirEntry from the parent node, update the index
3113         // and reinsert it into the parent tree. Note that for entries with the
3114         // same parent we do not pull the node from the enumeration list
3115         //
3116
3117         AFSRemoveDirNodeFromParent( pSrcParentObject,
3118                                     pSrcCcb->DirectoryCB,
3119                                     !bCommonParent);
3120
3121         //
3122         // OK, this is a simple rename. Issue the rename
3123         // request to the service.
3124         //
3125
3126         ntStatus = AFSNotifyRename( pSrcObject,
3127                                     &pSrcCcb->AuthGroup,
3128                                     pSrcParentObject,
3129                                     pTargetDcb->ObjectInformation,
3130                                     pSrcCcb->DirectoryCB,
3131                                     &uniTargetName,
3132                                     &stNewFid);
3133
3134         if( !NT_SUCCESS( ntStatus))
3135         {
3136
3137             //
3138             // Attempt to re-insert the directory entry
3139             //
3140
3141             AFSInsertDirectoryNode( pSrcParentObject,
3142                                     pSrcCcb->DirectoryCB,
3143                                     !bCommonParent);
3144
3145             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3146                           AFS_TRACE_LEVEL_ERROR,
3147                           "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
3148                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
3149                           &uniTargetName,
3150                           ntStatus));
3151
3152             try_return( ntStatus);
3153         }
3154
3155         //
3156         // Set the notification up for the source file
3157         //
3158
3159         if( pSrcParentObject == pTargetParentObject &&
3160             !bTargetEntryExists)
3161         {
3162
3163             ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
3164         }
3165         else
3166         {
3167
3168             ulNotificationAction = FILE_ACTION_REMOVED;
3169         }
3170
3171         if( pSrcObject->FileType == AFS_FILE_TYPE_DIRECTORY)
3172         {
3173
3174             ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
3175         }
3176         else
3177         {
3178
3179             ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
3180         }
3181
3182         AFSFsRtlNotifyFullReportChange( pSrcParentObject,
3183                                         pSrcCcb,
3184                                         (ULONG)ulNotifyFilter,
3185                                         (ULONG)ulNotificationAction);
3186
3187         //
3188         // Update the name in the dir entry.
3189         //
3190
3191         ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
3192                                           &uniTargetName);
3193
3194         if( !NT_SUCCESS( ntStatus))
3195         {
3196
3197             //
3198             // Attempt to re-insert the directory entry
3199             //
3200
3201             AFSInsertDirectoryNode( pSrcParentObject,
3202                                     pSrcCcb->DirectoryCB,
3203                                     !bCommonParent);
3204
3205             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3206                           AFS_TRACE_LEVEL_ERROR,
3207                           "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
3208                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
3209                           &uniTargetName,
3210                           ntStatus));
3211
3212             try_return( ntStatus);
3213         }
3214
3215         //
3216         // Update the object information block, if needed
3217         //
3218
3219         if( !AFSIsEqualFID( &pSrcObject->FileId,
3220                             &stNewFid))
3221         {
3222
3223             AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
3224                             TRUE);
3225
3226             //
3227             // Remove the old information entry
3228             //
3229
3230             AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3231                                 &pSrcObject->TreeEntry);
3232
3233             RtlCopyMemory( &pSrcObject->FileId,
3234                            &stNewFid,
3235                            sizeof( AFSFileID));
3236
3237             //
3238             // Insert the entry into the new object table.
3239             //
3240
3241             pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
3242
3243             if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
3244             {
3245
3246                 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
3247             }
3248             else
3249             {
3250
3251                 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3252                                                      &pSrcObject->TreeEntry)))
3253                 {
3254
3255                     //
3256                     // Lost a race, an ObjectInfo object already exists for this FID.
3257                     // Let this copy be garbage collected.
3258                     //
3259
3260                     ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
3261                 }
3262             }
3263
3264             AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
3265         }
3266
3267         //
3268         // Update the hash values for the name trees.
3269         //
3270
3271         pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3272                                                                                  FALSE);
3273
3274         pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3275                                                                                    TRUE);
3276
3277         if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3278             pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
3279             !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3280                                      NULL,
3281                                      NULL))
3282         {
3283
3284             uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
3285             uniShortName.MaximumLength = uniShortName.Length;
3286             uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
3287
3288             pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
3289                                                                                            TRUE);
3290
3291             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3292                           AFS_TRACE_LEVEL_VERBOSE,
3293                           "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
3294                           &uniShortName,
3295                           &pSrcCcb->DirectoryCB->NameInformation.FileName));
3296         }
3297         else
3298         {
3299
3300             pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
3301         }
3302
3303         if( !bCommonParent)
3304         {
3305
3306             //
3307             // Update the file index for the object in the new parent
3308             //
3309
3310             pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
3311         }
3312
3313         //
3314         // Re-insert the directory entry
3315         //
3316
3317         AFSInsertDirectoryNode( pTargetParentObject,
3318                                 pSrcCcb->DirectoryCB,
3319                                 !bCommonParent);
3320
3321         //
3322         // Update the parent pointer in the source object if they are different
3323         //
3324
3325         if( pSrcParentObject != pTargetParentObject)
3326         {
3327
3328             lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenHandleCount);
3329
3330             lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenReferenceCount);
3331
3332             lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
3333
3334             lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
3335
3336
3337             //
3338             // Guaranteed to be in the same volume
3339             //
3340
3341             AFSAcquireExcl( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock,
3342                             TRUE);
3343
3344             lCount = AFSObjectInfoIncrement( pTargetParentObject,
3345                                              AFS_OBJECT_REFERENCE_CHILD);
3346
3347             AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3348                           AFS_TRACE_LEVEL_VERBOSE,
3349                           "AFSSetRenameInfo Increment count on parent object %p Cnt %d\n",
3350                           pTargetParentObject,
3351                           lCount));
3352
3353             lCount = AFSObjectInfoDecrement( pSrcParentObject,
3354                                              AFS_OBJECT_REFERENCE_CHILD);
3355
3356             AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3357                           AFS_TRACE_LEVEL_VERBOSE,
3358                           "AFSSetRenameInfo Decrement count on parent object %p Cnt %d\n",
3359                           pSrcParentObject,
3360                           lCount));
3361
3362             pSrcObject->ParentFileId = pTargetParentObject->FileId;
3363
3364             SetFlag( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
3365
3366             AFSReleaseResource( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock);
3367
3368             ulNotificationAction = FILE_ACTION_ADDED;
3369         }
3370         else
3371         {
3372
3373             ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
3374         }
3375
3376         //
3377         // Now update the notification for the target file
3378         //
3379
3380         AFSFsRtlNotifyFullReportChange( pTargetParentObject,
3381                                         pSrcCcb,
3382                                         (ULONG)ulNotifyFilter,
3383                                         (ULONG)ulNotificationAction);
3384
3385         //
3386         // If we performed the rename of the target because it existed, we now need to
3387         // delete the tmp target we created above
3388         //
3389
3390         if( bTargetEntryExists)
3391         {
3392
3393             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3394                           AFS_TRACE_LEVEL_VERBOSE,
3395                           "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
3396                           pTargetDirEntry,
3397                           &pTargetDirEntry->NameInformation.FileName));
3398
3399             SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3400
3401             //
3402             // Try and purge the cache map if this is a file
3403             //
3404
3405             if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
3406                 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
3407                 pTargetDirEntry->DirOpenReferenceCount > 1)
3408             {
3409
3410                 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
3411             }
3412
3413             ASSERT( pTargetDirEntry->DirOpenReferenceCount > 0);
3414
3415             lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount); // The count we added above
3416
3417             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3418                           AFS_TRACE_LEVEL_VERBOSE,
3419                           "AFSSetRenameInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3420                           &pTargetDirEntry->NameInformation.FileName,
3421                           pTargetDirEntry,
3422                           pSrcCcb,
3423                           lCount));
3424
3425             ASSERT( lCount >= 0);
3426
3427             if( lCount == 0 &&
3428                 pTargetDirEntry->NameArrayReferenceCount <= 0)
3429             {
3430
3431                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3432                               AFS_TRACE_LEVEL_VERBOSE,
3433                               "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
3434                               pTargetDirEntry,
3435                               &pTargetDirEntry->NameInformation.FileName));
3436
3437                 AFSDeleteDirEntry( pTargetParentObject,
3438                                    &pTargetDirEntry);
3439             }
3440
3441             pTargetDirEntry = NULL;
3442
3443             if ( pTargetFcb != NULL)
3444             {
3445
3446                 //
3447                 // Do not hold TreeLocks across the MmForceSectionClosed() call as
3448                 // it can deadlock with Trend Micro's TmPreFlt!TmpQueryFullName
3449                 //
3450
3451                 if( bReleaseTargetDirLock)
3452                 {
3453                     AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3454
3455                     bReleaseTargetDirLock = FALSE;
3456                 }
3457
3458                 if( bReleaseSourceDirLock)
3459                 {
3460
3461                     AFSReleaseResource( pSourceDirLock);
3462
3463                     bReleaseSourceDirLock = FALSE;
3464                 }
3465
3466                 //
3467                 // MmForceSectionClosed() can eventually call back into AFSCleanup
3468                 // which will need to acquire Fcb->Resource exclusively.  Failure
3469                 // to obtain it here before holding the SectionObjectResource will
3470                 // permit the locks to be obtained out of order risking a deadlock.
3471                 //
3472
3473                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3474                               AFS_TRACE_LEVEL_VERBOSE,
3475                               "AFSSetRenameInfo Acquiring Fcb lock %p EXCL %08lX\n",
3476                               &pTargetFcb->NPFcb->Resource,
3477                               PsGetCurrentThread()));
3478
3479                 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
3480                                 TRUE);
3481
3482                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3483                               AFS_TRACE_LEVEL_VERBOSE,
3484                               "AFSSetRenameInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3485                               &pTargetFcb->NPFcb->SectionObjectResource,
3486                               PsGetCurrentThread()));
3487
3488                 AFSAcquireExcl( &pTargetFcb->NPFcb->SectionObjectResource,
3489                                 TRUE);
3490
3491                 __try
3492                 {
3493
3494                     //
3495                     // Close the section in the event it was mapped
3496                     //
3497
3498                     if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
3499                                                TRUE))
3500                     {
3501
3502                         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3503                                       AFS_TRACE_LEVEL_ERROR,
3504                                       "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
3505                                       &uniTargetName));
3506                     }
3507                 }
3508                 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3509                 {
3510
3511                     ntStatus = GetExceptionCode();
3512
3513                     AFSDbgTrace(( 0,
3514                                   0,
3515                                   "EXCEPTION - AFSSetRenameInfo MmForceSectionClosed failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3516                                   pTargetFcb->ObjectInformation->FileId.Cell,
3517                                   pTargetFcb->ObjectInformation->FileId.Volume,
3518                                   pTargetFcb->ObjectInformation->FileId.Vnode,
3519                                   pTargetFcb->ObjectInformation->FileId.Unique,
3520                                   ntStatus));
3521                 }
3522
3523                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3524                               AFS_TRACE_LEVEL_VERBOSE,
3525                               "AFSSetRenameInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3526                               &pTargetFcb->NPFcb->SectionObjectResource,
3527                               PsGetCurrentThread()));
3528
3529                 AFSReleaseResource( &pTargetFcb->NPFcb->SectionObjectResource);
3530
3531                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3532                               AFS_TRACE_LEVEL_VERBOSE,
3533                               "AFSSetRenameInfo Releasing Fcb lock %p EXCL %08lX\n",
3534                               &pTargetFcb->NPFcb->Resource,
3535                               PsGetCurrentThread()));
3536
3537                 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
3538             }
3539         }
3540
3541 try_exit:
3542
3543         if( !NT_SUCCESS( ntStatus))
3544         {
3545
3546             if( bTargetEntryExists)
3547             {
3548
3549                 ASSERT( pTargetParentObject != NULL);
3550
3551                 AFSInsertDirectoryNode( pTargetParentObject,
3552                                         pTargetDirEntry,
3553                                         FALSE);
3554             }
3555         }
3556
3557         if( pTargetDirEntry != NULL)
3558         {
3559
3560             lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
3561
3562             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3563                           AFS_TRACE_LEVEL_VERBOSE,
3564                           "AFSSetRenameInfo Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
3565                           &pTargetDirEntry->NameInformation.FileName,
3566                           pTargetDirEntry,
3567                           pSrcCcb,
3568                           lCount));
3569
3570             ASSERT( lCount >= 0);
3571         }
3572
3573         if( bReleaseTargetDirLock)
3574         {
3575
3576             AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3577         }
3578
3579         if( bReleaseSourceDirLock)
3580         {
3581
3582             AFSReleaseResource( pSourceDirLock);
3583         }
3584
3585         if ( bDereferenceTargetParentObject)
3586         {
3587
3588             ObDereferenceObject( pTargetParentFileObj);
3589         }
3590
3591         if ( pSrcParentObject != NULL)
3592         {
3593
3594             AFSReleaseObjectInfo( &pSrcParentObject);
3595         }
3596
3597         //
3598         // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
3599         // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
3600         //
3601
3602         pTargetParentObject = NULL;
3603     }
3604
3605     return ntStatus;
3606 }
3607
3608 NTSTATUS
3609 AFSSetPositionInfo( IN PIRP Irp,
3610                     IN AFSDirectoryCB *DirectoryCB)
3611 {
3612     UNREFERENCED_PARAMETER(DirectoryCB);
3613     NTSTATUS ntStatus = STATUS_SUCCESS;
3614     PFILE_POSITION_INFORMATION pBuffer;
3615     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3616
3617     pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3618
3619     pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
3620
3621     return ntStatus;
3622 }
3623
3624 NTSTATUS
3625 AFSSetAllocationInfo( IN PIRP Irp,
3626                       IN AFSDirectoryCB *DirectoryCB)
3627 {
3628     UNREFERENCED_PARAMETER(DirectoryCB);
3629     NTSTATUS ntStatus = STATUS_SUCCESS;
3630     PFILE_ALLOCATION_INFORMATION pBuffer;
3631     BOOLEAN bReleasePaging = FALSE;
3632     BOOLEAN bTellCc = FALSE;
3633     BOOLEAN bTellService = FALSE;
3634     BOOLEAN bUserMapped = FALSE;
3635     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3636     PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3637     AFSFcb *pFcb = NULL;
3638     AFSCcb *pCcb = NULL;
3639     LARGE_INTEGER liSaveAlloc;
3640     LARGE_INTEGER liSaveFileSize;
3641     LARGE_INTEGER liSaveVDL;
3642
3643     pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3644
3645     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3646
3647     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3648
3649     //
3650     // save values to put back
3651     //
3652     liSaveAlloc = pFcb->Header.AllocationSize;
3653     liSaveFileSize = pFcb->Header.FileSize;
3654     liSaveVDL = pFcb->Header.ValidDataLength;
3655
3656     if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
3657         pIrpSp->Parameters.SetFile.AdvanceOnly)
3658     {
3659         return STATUS_SUCCESS ;
3660     }
3661
3662     if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3663     {
3664
3665         AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3666                       AFS_TRACE_LEVEL_VERBOSE,
3667                       "AFSSetAllocationInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3668                       &pFcb->NPFcb->SectionObjectResource,
3669                       PsGetCurrentThread()));
3670
3671         AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3672                         TRUE);
3673
3674         __try
3675         {
3676
3677             bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3678                                                  &pBuffer->AllocationSize);
3679         }
3680         __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3681         {
3682
3683             bUserMapped = FALSE;
3684
3685             ntStatus = GetExceptionCode();
3686
3687             AFSDbgTrace(( 0,
3688                           0,
3689                           "EXCEPTION - AFSSetAllocationInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3690                           pFcb->ObjectInformation->FileId.Cell,
3691                           pFcb->ObjectInformation->FileId.Volume,
3692                           pFcb->ObjectInformation->FileId.Vnode,
3693                           pFcb->ObjectInformation->FileId.Unique,
3694                           ntStatus));
3695         }
3696
3697         AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3698                       AFS_TRACE_LEVEL_VERBOSE,
3699                       "AFSSetAllocationInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3700                       &pFcb->NPFcb->SectionObjectResource,
3701                       PsGetCurrentThread()));
3702
3703         AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3704
3705         //
3706         // Truncating the file
3707         //
3708         if ( bUserMapped)
3709         {
3710
3711             ntStatus = STATUS_USER_MAPPED_FILE ;
3712         }
3713         else
3714         {
3715
3716             //
3717             // If this is a truncation we need to grab the paging IO resource.
3718             //
3719
3720             AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3721                           AFS_TRACE_LEVEL_VERBOSE,
3722                           "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3723                           &pFcb->NPFcb->PagingResource,
3724                           PsGetCurrentThread()));
3725
3726             AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3727                             TRUE);
3728
3729             bReleasePaging = TRUE;
3730
3731             //
3732             // Must drop the Fcb Resource.  When changing the file size
3733             // a deadlock can occur with Trend Micro's filter if the file
3734             // size is set to zero.
3735             //
3736
3737             AFSReleaseResource( &pFcb->NPFcb->Resource);
3738
3739             pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3740
3741             pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3742
3743             //
3744             // Tell Cc that Allocation is moved.
3745             //
3746             bTellCc = TRUE;
3747
3748             if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3749             {
3750                 //
3751                 // We are pulling the EOF back as well so we need to tell
3752                 // the service.
3753                 //
3754                 bTellService = TRUE;
3755
3756                 pFcb->Header.FileSize = pBuffer->AllocationSize;
3757
3758                 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
3759             }
3760
3761         }
3762     }
3763     else
3764     {
3765         //
3766         // Tell Cc if allocation is increased.
3767         //
3768
3769         AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3770                       AFS_TRACE_LEVEL_VERBOSE,
3771                       "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3772                       &pFcb->NPFcb->PagingResource,
3773                       PsGetCurrentThread()));
3774
3775         AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3776                         TRUE);
3777
3778         bReleasePaging = TRUE;
3779
3780         //
3781         // Must drop the Fcb Resource.  When changing the file size
3782         // a deadlock can occur with Trend Micro's filter if the file
3783         // size is set to zero.
3784         //
3785
3786         AFSReleaseResource( &pFcb->NPFcb->Resource);
3787
3788         bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
3789
3790         pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3791
3792         pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3793     }
3794
3795     //
3796     // Now Tell the server if we have to
3797     //
3798     if (bTellService)
3799     {
3800
3801         ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
3802
3803         ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
3804                                              pFcb->ObjectInformation,
3805                                              &pCcb->AuthGroup);
3806     }
3807
3808     if (NT_SUCCESS(ntStatus))
3809     {
3810         //
3811         // Trim extents if we told the service - the update has done an implicit
3812         // trim at the service.
3813         //
3814         if (bTellService)
3815         {
3816             AFSTrimExtents( pFcb,
3817                             &pFcb->Header.FileSize);
3818         }
3819
3820         KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3821
3822         SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3823
3824         if (bTellCc &&
3825             CcIsFileCached( pFileObject))
3826         {
3827             CcSetFileSizes( pFileObject,
3828                             (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3829         }
3830     }
3831     else
3832     {
3833         //
3834         // Put the saved values back
3835         //
3836         pFcb->Header.ValidDataLength = liSaveVDL;
3837         pFcb->Header.FileSize = liSaveFileSize;
3838         pFcb->Header.AllocationSize = liSaveAlloc;
3839         pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
3840         pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3841     }
3842
3843     if( bReleasePaging)
3844     {
3845
3846         AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3847
3848         AFSAcquireExcl( &pFcb->NPFcb->Resource,
3849                         TRUE);
3850     }
3851
3852     return ntStatus;
3853 }
3854
3855 NTSTATUS
3856 AFSSetEndOfFileInfo( IN PIRP Irp,
3857                      IN AFSDirectoryCB *DirectoryCB)
3858 {
3859     UNREFERENCED_PARAMETER(DirectoryCB);
3860     NTSTATUS ntStatus = STATUS_SUCCESS;
3861     PFILE_END_OF_FILE_INFORMATION pBuffer;
3862     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3863     PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3864     LARGE_INTEGER liSaveSize;
3865     LARGE_INTEGER liSaveVDL;
3866     LARGE_INTEGER liSaveAlloc;
3867     BOOLEAN bModified = FALSE;
3868     BOOLEAN bReleasePaging = FALSE;
3869     BOOLEAN bTruncated = FALSE;
3870     BOOLEAN bUserMapped = FALSE;
3871     AFSFcb *pFcb = NULL;
3872     AFSCcb *pCcb = NULL;
3873
3874     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3875
3876     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3877
3878     pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3879
3880     liSaveSize = pFcb->Header.FileSize;
3881     liSaveAlloc = pFcb->Header.AllocationSize;
3882     liSaveVDL = pFcb->Header.ValidDataLength;
3883
3884     if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
3885         !pIrpSp->Parameters.SetFile.AdvanceOnly)
3886     {
3887
3888         if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
3889         {
3890
3891             AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3892                           AFS_TRACE_LEVEL_VERBOSE,
3893                           "AFSSetEndOfFileInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3894                           &pFcb->NPFcb->SectionObjectResource,
3895                           PsGetCurrentThread()));
3896
3897             AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3898                             TRUE);
3899
3900             __try
3901             {
3902
3903                 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3904                                                      &pBuffer->EndOfFile);
3905             }
3906             __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3907             {
3908
3909                 bUserMapped = FALSE;
3910
3911                 ntStatus = GetExceptionCode();
3912
3913                 AFSDbgTrace(( 0,
3914                               0,
3915                               "EXCEPTION - AFSSetEndOfFileInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3916                               pFcb->ObjectInformation->FileId.Cell,
3917                               pFcb->ObjectInformation->FileId.Volume,
3918                               pFcb->ObjectInformation->FileId.Vnode,
3919                               pFcb->ObjectInformation->FileId.Unique,
3920                               ntStatus));
3921             }
3922
3923             AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3924                           AFS_TRACE_LEVEL_VERBOSE,
3925                           "AFSSetEndOfFileInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3926                           &pFcb->NPFcb->SectionObjectResource,
3927                           PsGetCurrentThread()));
3928
3929             AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3930
3931             // Truncating the file
3932             if ( bUserMapped)
3933             {
3934
3935                 ntStatus = STATUS_USER_MAPPED_FILE;
3936             }
3937             else
3938             {
3939
3940                 //
3941                 // If this is a truncation we need to grab the paging
3942                 // IO resource.
3943                 //
3944                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3945                               AFS_TRACE_LEVEL_VERBOSE,
3946                               "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3947                               &pFcb->NPFcb->PagingResource,
3948                               PsGetCurrentThread()));
3949
3950                 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3951                                 TRUE);
3952
3953                 bReleasePaging = TRUE;
3954
3955                 //
3956                 // Must drop the Fcb Resource.  When changing the file size
3957                 // a deadlock can occur with Trend Micro's filter if the file
3958                 // size is set to zero.
3959                 //
3960
3961                 AFSReleaseResource( &pFcb->NPFcb->Resource);
3962
3963                 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3964
3965                 pFcb->Header.FileSize = pBuffer->EndOfFile;
3966
3967                 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3968
3969                 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3970
3971                 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
3972                 {
3973
3974                     pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
3975                 }
3976
3977                 bTruncated = TRUE;
3978
3979                 bModified = TRUE;
3980             }
3981         }
3982         else
3983         {
3984
3985             //
3986             // extending the file, move EOF
3987             //
3988
3989             //
3990             // If this is a truncation we need to grab the paging
3991             // IO resource.
3992             //
3993             AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3994                           AFS_TRACE_LEVEL_VERBOSE,
3995                           "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3996                           &pFcb->NPFcb->PagingResource,
3997                           PsGetCurrentThread()));
3998
3999             AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
4000                             TRUE);
4001
4002             bReleasePaging = TRUE;
4003
4004             //
4005             // Must drop the Fcb Resource.  When changing the file size
4006             // a deadlock can occur with Trend Micro's filter if the file
4007             // size is set to zero.
4008             //
4009
4010             AFSReleaseResource( &pFcb->NPFcb->Resource);
4011
4012             pFcb->Header.FileSize = pBuffer->EndOfFile;
4013
4014             pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
4015
4016             if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
4017             {
4018                 //
4019                 // And Allocation as needed.
4020                 //
4021                 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
4022
4023                 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
4024             }
4025
4026             bModified = TRUE;
4027         }
4028     }
4029
4030     if (bModified)
4031     {
4032
4033         KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
4034
4035         SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
4036
4037         //
4038         // Tell the server
4039         //
4040
4041         ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
4042
4043         ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
4044                                              pFcb->ObjectInformation,
4045                                              &pCcb->AuthGroup);
4046
4047         if( NT_SUCCESS(ntStatus))
4048         {
4049             //
4050             // We are now good to go so tell CC.
4051             //
4052             CcSetFileSizes( pFileObject,
4053                             (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
4054
4055             //
4056             // And give up those extents
4057             //
4058             if( bTruncated)
4059             {
4060
4061                 AFSTrimExtents( pFcb,
4062                                 &pFcb->Header.FileSize);
4063             }
4064         }
4065         else
4066         {
4067             pFcb->Header.ValidDataLength = liSaveVDL;
4068             pFcb->Header.FileSize = liSaveSize;
4069             pFcb->Header.AllocationSize = liSaveAlloc;
4070             pFcb->ObjectInformation->EndOfFile = liSaveSize;
4071             pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
4072         }
4073     }
4074
4075     if( bReleasePaging)
4076     {
4077
4078         AFSReleaseResource( &pFcb->NPFcb->PagingResource);
4079
4080         AFSAcquireExcl( &pFcb->NPFcb->Resource,
4081                         TRUE);
4082     }
4083
4084     return ntStatus;
4085 }
4086
4087 NTSTATUS
4088 AFSProcessShareSetInfo( IN IRP *Irp,
4089                         IN AFSFcb *Fcb,
4090                         IN AFSCcb *Ccb)
4091 {
4092
4093     UNREFERENCED_PARAMETER(Fcb);
4094     NTSTATUS ntStatus = STATUS_SUCCESS;
4095     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4096     FILE_INFORMATION_CLASS ulFileInformationClass;
4097     void *pPipeInfo = NULL;
4098
4099     __Enter
4100     {
4101         ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
4102
4103         AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4104                       AFS_TRACE_LEVEL_VERBOSE,
4105                       "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
4106                       &Ccb->DirectoryCB->NameInformation.FileName,
4107                       ulFileInformationClass));
4108
4109         pPipeInfo = AFSLockSystemBuffer( Irp,
4110                                          pIrpSp->Parameters.SetFile.Length);
4111
4112         if( pPipeInfo == NULL)
4113         {
4114
4115             AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4116                           AFS_TRACE_LEVEL_ERROR,
4117                           "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
4118                           &Ccb->DirectoryCB->NameInformation.FileName));
4119
4120             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4121         }
4122
4123         //
4124         // Send the request to the service
4125         //
4126
4127         ntStatus = AFSNotifySetPipeInfo( Ccb,
4128                                          (ULONG)ulFileInformationClass,
4129                                          pIrpSp->Parameters.SetFile.Length,
4130                                          pPipeInfo);
4131
4132         if( !NT_SUCCESS( ntStatus))
4133         {
4134
4135             AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4136                           AFS_TRACE_LEVEL_ERROR,
4137                           "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4138                           &Ccb->DirectoryCB->NameInformation.FileName,
4139                           ntStatus));
4140
4141             try_return( ntStatus);
4142         }
4143
4144         AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4145                       AFS_TRACE_LEVEL_VERBOSE,
4146                       "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
4147                       &Ccb->DirectoryCB->NameInformation.FileName,
4148                       ulFileInformationClass));
4149
4150 try_exit:
4151
4152         NOTHING;
4153     }
4154
4155     return ntStatus;
4156 }
4157
4158 NTSTATUS
4159 AFSProcessShareQueryInfo( IN IRP *Irp,
4160                           IN AFSFcb *Fcb,
4161                           IN AFSCcb *Ccb)
4162 {
4163
4164     UNREFERENCED_PARAMETER(Fcb);
4165     NTSTATUS ntStatus = STATUS_SUCCESS;
4166     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4167     FILE_INFORMATION_CLASS ulFileInformationClass;
4168     void *pPipeInfo = NULL;
4169
4170     __Enter
4171     {
4172
4173         ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4174
4175         AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4176                       AFS_TRACE_LEVEL_VERBOSE,
4177                       "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
4178                       &Ccb->DirectoryCB->NameInformation.FileName,
4179                       ulFileInformationClass));
4180
4181         pPipeInfo = AFSLockSystemBuffer( Irp,
4182                                          pIrpSp->Parameters.QueryFile.Length);
4183
4184         if( pPipeInfo == NULL)
4185         {
4186
4187             AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4188                           AFS_TRACE_LEVEL_ERROR,
4189                           "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
4190                           &Ccb->DirectoryCB->NameInformation.FileName));
4191
4192             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4193         }
4194
4195         //
4196         // Send the request to the service
4197         //
4198
4199         ntStatus = AFSNotifyQueryPipeInfo( Ccb,
4200                                            (ULONG)ulFileInformationClass,
4201                                            pIrpSp->Parameters.QueryFile.Length,
4202                                            pPipeInfo,
4203                                            (ULONG *)&Irp->IoStatus.Information);
4204
4205         if( !NT_SUCCESS( ntStatus))
4206         {
4207
4208             AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4209                           AFS_TRACE_LEVEL_ERROR,
4210                           "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4211                           &Ccb->DirectoryCB->NameInformation.FileName,
4212                           ntStatus));
4213
4214             try_return( ntStatus);
4215         }
4216
4217         AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4218                       AFS_TRACE_LEVEL_VERBOSE,
4219                       "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
4220                       &Ccb->DirectoryCB->NameInformation.FileName,
4221                       ulFileInformationClass));
4222
4223 try_exit:
4224
4225         NOTHING;
4226     }
4227
4228     return ntStatus;
4229 }
4230
4231 NTSTATUS
4232 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
4233                            IN AFSFcb *Fcb,
4234                            IN AFSCcb *Ccb,
4235                            IN OUT LONG *Length)
4236 {
4237
4238     UNREFERENCED_PARAMETER(Fcb);
4239     UNREFERENCED_PARAMETER(Ccb);
4240     NTSTATUS ntStatus = STATUS_SUCCESS;
4241     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4242     FILE_INFORMATION_CLASS ulFileInformationClass;
4243
4244     __Enter
4245     {
4246
4247         ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4248
4249         switch( ulFileInformationClass)
4250         {
4251
4252             case FileBasicInformation:
4253             {
4254
4255                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4256                               AFS_TRACE_LEVEL_VERBOSE,
4257                               "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n"));
4258
4259                 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
4260                 {
4261                     PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4262
4263                     pBasic->CreationTime.QuadPart = 0;
4264                     pBasic->LastAccessTime.QuadPart = 0;
4265                     pBasic->ChangeTime.QuadPart = 0;
4266                     pBasic->LastWriteTime.QuadPart = 0;
4267                     pBasic->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
4268
4269                     *Length -= sizeof( FILE_BASIC_INFORMATION);
4270                 }
4271                 else
4272                 {
4273                     ntStatus = STATUS_BUFFER_TOO_SMALL;
4274                 }
4275
4276                 break;
4277             }
4278
4279             case FileStandardInformation:
4280             {
4281
4282                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4283                               AFS_TRACE_LEVEL_VERBOSE,
4284                               "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n"));
4285
4286                 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
4287                 {
4288                     PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4289
4290                     pStandard->NumberOfLinks = 1;
4291                     pStandard->DeletePending = 0;
4292                     pStandard->AllocationSize.QuadPart = 0;
4293                     pStandard->EndOfFile.QuadPart = 0;
4294                     pStandard->Directory = 0;
4295
4296                     *Length -= sizeof( FILE_STANDARD_INFORMATION);
4297                 }
4298                 else
4299                 {
4300                     ntStatus = STATUS_BUFFER_TOO_SMALL;
4301                 }
4302
4303                 break;
4304             }
4305
4306             case FileNormalizedNameInformation:
4307             case FileNameInformation:
4308             {
4309
4310                 ULONG ulCopyLength = 0;
4311                 AFSFcb *pFcb = NULL;
4312                 AFSCcb *pCcb = NULL;
4313                 USHORT usFullNameLength = 0;
4314                 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4315                 UNICODE_STRING uniName;
4316
4317                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4318                               AFS_TRACE_LEVEL_VERBOSE,
4319                               "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n"));
4320
4321                 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
4322                 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
4323
4324                 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
4325                 {
4326                     ntStatus = STATUS_BUFFER_TOO_SMALL;
4327                     break;
4328                 }
4329
4330                 RtlZeroMemory( pNameInfo,
4331                                *Length);
4332
4333                 usFullNameLength = sizeof( WCHAR) +
4334                                             AFSServerName.Length +
4335                                             pCcb->FullFileName.Length;
4336
4337                 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
4338                 {
4339                     ulCopyLength = (LONG)usFullNameLength;
4340                 }
4341                 else
4342                 {
4343                     ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4344                     ntStatus = STATUS_BUFFER_OVERFLOW;
4345                 }
4346
4347                 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
4348
4349                 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4350
4351                 if( ulCopyLength > 0)
4352                 {
4353
4354                     pNameInfo->FileName[ 0] = L'\\';
4355                     ulCopyLength -= sizeof( WCHAR);
4356
4357                     *Length -= sizeof( WCHAR);
4358
4359                     if( ulCopyLength >= AFSServerName.Length)
4360                     {
4361
4362                         RtlCopyMemory( &pNameInfo->FileName[ 1],
4363                                        AFSServerName.Buffer,
4364                                        AFSServerName.Length);
4365
4366                         ulCopyLength -= AFSServerName.Length;
4367                         *Length -= AFSServerName.Length;
4368
4369                         if( ulCopyLength >= pCcb->FullFileName.Length)
4370                         {
4371
4372                             RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4373                                            pCcb->FullFileName.Buffer,
4374                                            pCcb->FullFileName.Length);
4375
4376                             ulCopyLength -= pCcb->FullFileName.Length;
4377                             *Length -= pCcb->FullFileName.Length;
4378
4379                             uniName.Length = (USHORT)pNameInfo->FileNameLength;
4380                             uniName.MaximumLength = uniName.Length;
4381                             uniName.Buffer = pNameInfo->FileName;
4382                         }
4383                         else
4384                         {
4385
4386                             RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4387                                            pCcb->FullFileName.Buffer,
4388                                            ulCopyLength);
4389
4390                             *Length -= ulCopyLength;
4391
4392                             uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
4393                             uniName.MaximumLength = uniName.Length;
4394                             uniName.Buffer = pNameInfo->FileName;
4395                         }
4396
4397                         AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4398                                       AFS_TRACE_LEVEL_VERBOSE,
4399                                       "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
4400                                       &uniName));
4401                     }
4402                 }
4403
4404                 break;
4405             }
4406
4407             case FileInternalInformation:
4408             {
4409
4410                 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4411
4412                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4413                               AFS_TRACE_LEVEL_VERBOSE,
4414                               "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n"));
4415
4416                 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
4417                 {
4418
4419                     pInternalInfo->IndexNumber.HighPart = 0;
4420
4421                     pInternalInfo->IndexNumber.LowPart = 0;
4422
4423                     *Length -= sizeof( FILE_INTERNAL_INFORMATION);
4424                 }
4425                 else
4426                 {
4427
4428                     ntStatus = STATUS_BUFFER_TOO_SMALL;
4429                 }
4430
4431                 break;
4432             }
4433
4434             case FileAllInformation:
4435             {
4436                 ntStatus = STATUS_INVALID_PARAMETER;
4437
4438                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4439                               AFS_TRACE_LEVEL_WARNING,
4440                               "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n"));
4441
4442                 break;
4443             }
4444
4445             case FileEaInformation:
4446             {
4447                 ntStatus = STATUS_INVALID_PARAMETER;
4448
4449                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4450                               AFS_TRACE_LEVEL_WARNING,
4451                               "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n"));
4452
4453                 break;
4454             }
4455
4456             case FilePositionInformation:
4457             {
4458                 ntStatus = STATUS_INVALID_PARAMETER;
4459
4460                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4461                               AFS_TRACE_LEVEL_WARNING,
4462                               "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n"));
4463
4464                 break;
4465             }
4466
4467             case FileAlternateNameInformation:
4468             {
4469                 ntStatus = STATUS_INVALID_PARAMETER;
4470
4471                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4472                               AFS_TRACE_LEVEL_WARNING,
4473                               "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n"));
4474
4475                 break;
4476             }
4477
4478             case FileNetworkOpenInformation:
4479             {
4480                 ntStatus = STATUS_INVALID_PARAMETER;
4481
4482                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4483                               AFS_TRACE_LEVEL_WARNING,
4484                               "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n"));
4485
4486                 break;
4487             }
4488
4489             case FileStreamInformation:
4490             {
4491                 ntStatus = STATUS_INVALID_PARAMETER;
4492
4493                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4494                               AFS_TRACE_LEVEL_WARNING,
4495                               "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n"));
4496
4497                 break;
4498             }
4499
4500             case FileAttributeTagInformation:
4501             {
4502                 ntStatus = STATUS_INVALID_PARAMETER;
4503
4504                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4505                               AFS_TRACE_LEVEL_WARNING,
4506                               "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n"));
4507
4508                 break;
4509             }
4510
4511             case FileRemoteProtocolInformation:
4512             {
4513                 ntStatus = STATUS_INVALID_PARAMETER;
4514
4515                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4516                               AFS_TRACE_LEVEL_WARNING,
4517                               "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n"));
4518
4519                 break;
4520             }
4521
4522             case FileNetworkPhysicalNameInformation:
4523             {
4524                 ntStatus = STATUS_INVALID_PARAMETER;
4525
4526                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4527                               AFS_TRACE_LEVEL_WARNING,
4528                               "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n"));
4529
4530                 break;
4531             }
4532
4533             default:
4534             {
4535                 ntStatus = STATUS_INVALID_PARAMETER;
4536
4537                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4538                               AFS_TRACE_LEVEL_WARNING,
4539                               "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
4540                               ulFileInformationClass));
4541
4542                 break;
4543             }
4544         }
4545     }
4546
4547     AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4548                   AFS_TRACE_LEVEL_VERBOSE,
4549                   "AFSProcessPIOCtlQueryInfo ntStatus %08lX\n",
4550                   ntStatus));
4551
4552     return ntStatus;
4553 }
4554