Windows: Call AFSExeceptionFilter for all exceptions
[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 SectionObject lock %p EXCL %08lX\n",
2207                               &pFcb->NPFcb->SectionObjectResource,
2208                               PsGetCurrentThread()));
2209
2210                 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
2211                                 TRUE);
2212
2213                 __try
2214                 {
2215
2216                     //
2217                     // Attempt to flush any outstanding data
2218                     //
2219
2220                     bMmFlushed = MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
2221                                                       MmFlushForDelete);
2222
2223                     if ( bMmFlushed)
2224                     {
2225
2226                         //
2227                         // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
2228                         // deadlock with Trend Micro's Enterprise anti-virus product
2229                         // which attempts to open the file which is being deleted.
2230                         //
2231
2232                         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2233                                       AFS_TRACE_LEVEL_VERBOSE,
2234                                       "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2235                                       DirectoryCB,
2236                                       &DirectoryCB->NameInformation.FileName));
2237
2238                         SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2239
2240                         //
2241                         // Purge the cache as well
2242                         //
2243
2244                         if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2245                         {
2246
2247                             if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
2248                                                        NULL,
2249                                                        0,
2250                                                        TRUE))
2251                             {
2252
2253                                 SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2254                             }
2255                         }
2256                     }
2257                 }
2258                 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
2259                 {
2260
2261                     bMmFlushed = FALSE;
2262
2263                     ntStatus = GetExceptionCode();
2264
2265                     AFSDbgTrace(( 0,
2266                                   0,
2267                                   "EXCEPTION - AFSSetDispositionInfo MmFlushImageSection failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2268                                   pFcb->ObjectInformation->FileId.Cell,
2269                                   pFcb->ObjectInformation->FileId.Volume,
2270                                   pFcb->ObjectInformation->FileId.Vnode,
2271                                   pFcb->ObjectInformation->FileId.Unique,
2272                                   ntStatus));
2273                 }
2274
2275                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2276                               AFS_TRACE_LEVEL_VERBOSE,
2277                               "AFSSetDispositionInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2278                               &pFcb->NPFcb->SectionObjectResource,
2279                               PsGetCurrentThread()));
2280
2281                 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
2282
2283                 if ( !bMmFlushed)
2284                 {
2285
2286                     AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2287                                   AFS_TRACE_LEVEL_ERROR,
2288                                   "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
2289                                   &DirectoryCB->NameInformation.FileName));
2290
2291                     try_return( ntStatus = STATUS_CANNOT_DELETE);
2292                 }
2293             }
2294             else if( pFcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2295                      pFcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2296                      pFcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2297                      pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2298             {
2299
2300                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2301                               AFS_TRACE_LEVEL_VERBOSE,
2302                               "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2303                               DirectoryCB,
2304                               &DirectoryCB->NameInformation.FileName));
2305
2306                 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2307             }
2308         }
2309         else
2310         {
2311
2312             ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2313         }
2314
2315         //
2316         // OK, should be good to go, set the flag in the file object
2317         //
2318
2319         pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2320
2321 try_exit:
2322
2323         NOTHING;
2324     }
2325
2326     return ntStatus;
2327 }
2328
2329 NTSTATUS
2330 AFSSetFileLinkInfo( IN PIRP Irp)
2331 {
2332
2333     NTSTATUS ntStatus = STATUS_SUCCESS;
2334     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2335     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2336     PFILE_LINK_INFORMATION pFileLinkInfo = NULL;
2337     PFILE_OBJECT pSrcFileObj = NULL;
2338     PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2339     AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL;
2340     AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2341     AFSObjectInfoCB *pSrcObject = NULL;
2342     AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2343     UNICODE_STRING uniSourceName, uniTargetName;
2344     UNICODE_STRING uniFullTargetName, uniTargetParentName;
2345     BOOLEAN bCommonParent = FALSE;
2346     AFSDirectoryCB *pTargetDirEntry = NULL;
2347     AFSDirectoryCB *pNewTargetDirEntry = NULL;
2348     ULONG ulTargetCRC;
2349     BOOLEAN bTargetEntryExists = FALSE;
2350     LONG lCount;
2351     BOOLEAN bReleaseTargetDirLock = FALSE;
2352     ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2353
2354     __Enter
2355     {
2356
2357         pSrcFileObj = pIrpSp->FileObject;
2358
2359         pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2360         pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2361
2362         pSrcObject = pSrcFcb->ObjectInformation;
2363
2364         if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2365         {
2366
2367             pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2368                                                   &pSrcObject->ParentFileId,
2369                                                   TRUE);
2370         }
2371
2372         if( pSrcParentObject == NULL)
2373         {
2374
2375             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2376                           AFS_TRACE_LEVEL_ERROR,
2377                           "AFSSetFileLinkInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2378
2379             ASSERT( FALSE);
2380
2381             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2382         }
2383
2384         pFileLinkInfo = (PFILE_LINK_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2385
2386         //
2387         // Perform some basic checks to ensure FS integrity
2388         //
2389
2390         if( pSrcFcb->Header.NodeTypeCode != AFS_FILE_FCB)
2391         {
2392
2393             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2394                           AFS_TRACE_LEVEL_ERROR,
2395                           "AFSSetFileLinkInfo Attempt to non-file (INVALID_PARAMETER)\n"));
2396
2397             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2398         }
2399
2400         if( pTargetFileObj == NULL)
2401         {
2402
2403             if ( pFileLinkInfo->RootDirectory)
2404             {
2405
2406                 //
2407                 // The target directory is provided by HANDLE
2408                 // RootDirectory is only set when the target directory is not the same
2409                 // as the source directory.
2410                 //
2411                 // AFS only supports hard links within a single directory.
2412                 //
2413                 // The IOManager should translate any Handle to a FileObject for us.
2414                 // However, the failure to receive a FileObject is treated as a fatal
2415                 // error.
2416                 //
2417
2418                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2419                               AFS_TRACE_LEVEL_ERROR,
2420                               "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory by handle INVALID_PARAMETER\n",
2421                               &pSrcCcb->DirectoryCB->NameInformation.FileName));
2422
2423                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2424             }
2425             else
2426             {
2427
2428                 uniFullTargetName.Length = (USHORT)pFileLinkInfo->FileNameLength;
2429
2430                 uniFullTargetName.Buffer = (PWSTR)&pFileLinkInfo->FileName;
2431
2432                 AFSRetrieveFinalComponent( &uniFullTargetName,
2433                                            &uniTargetName);
2434
2435                 AFSRetrieveParentPath( &uniFullTargetName,
2436                                        &uniTargetParentName);
2437
2438                 if ( uniTargetParentName.Length == 0)
2439                 {
2440
2441                     //
2442                     // This is a simple rename. Here the target directory is the same as the source parent directory
2443                     // and the name is retrieved from the system buffer information
2444                     //
2445
2446                     pTargetParentObject = pSrcParentObject;
2447                 }
2448                 else
2449                 {
2450                     //
2451                     // uniTargetParentName contains the directory the renamed object
2452                     // will be moved to.  Must obtain the TargetParentObject.
2453                     //
2454
2455                     AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2456                                   AFS_TRACE_LEVEL_ERROR,
2457                                   "AFSSetFileLinkInfo Attempt to link  %wZ to alternate directory %wZ (NOT_SAME_DEVICE)\n",
2458                                   &pSrcCcb->DirectoryCB->NameInformation.FileName,
2459                                   &uniFullTargetName));
2460
2461                     try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2462                 }
2463             }
2464
2465             pTargetDcb = pTargetParentObject->Fcb;
2466         }
2467         else
2468         {
2469
2470             //
2471             // So here we have the target directory taken from the targetfile object
2472             //
2473
2474             pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2475
2476             pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2477
2478             pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2479
2480             //
2481             // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2482             // it is only the target component of the rename operation
2483             //
2484
2485             uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2486         }
2487
2488         //
2489         // The quick check to see if they are self linking.
2490         // Do the names match? Only do this where the parent directories are
2491         // the same
2492         //
2493
2494         if( pTargetParentObject == pSrcParentObject)
2495         {
2496
2497             if( FsRtlAreNamesEqual( &uniTargetName,
2498                                     &uniSourceName,
2499                                     FALSE,
2500                                     NULL))
2501             {
2502                 try_return( ntStatus = STATUS_SUCCESS);
2503             }
2504
2505             bCommonParent = TRUE;
2506         }
2507         else
2508         {
2509
2510             //
2511             // We do not allow cross-volume hard links
2512             //
2513
2514             if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2515             {
2516
2517                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2518                               AFS_TRACE_LEVEL_ERROR,
2519                               "AFSSetFileLinkInfo Attempt to link to different volume %wZ\n",
2520                               &pSrcCcb->DirectoryCB->NameInformation.FileName));
2521
2522                 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2523             }
2524         }
2525
2526         ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2527                                       FALSE);
2528
2529         AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2530                         TRUE);
2531
2532         bReleaseTargetDirLock = TRUE;
2533
2534         AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2535                                         ulTargetCRC,
2536                                         &pTargetDirEntry);
2537
2538         if( pTargetDirEntry == NULL)
2539         {
2540
2541             //
2542             // Missed so perform a case insensitive lookup
2543             //
2544
2545             ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2546                                           TRUE);
2547
2548             AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2549                                               ulTargetCRC,
2550                                               &pTargetDirEntry);
2551         }
2552
2553         if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2554              pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2555                                                                 NULL,
2556                                                                 NULL))
2557         {
2558             //
2559             // Try the short name
2560             //
2561             AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2562                                         ulTargetCRC,
2563                                         &pTargetDirEntry);
2564         }
2565
2566         //
2567         // Increment our ref count on the dir entry
2568         //
2569
2570         if( pTargetDirEntry != NULL)
2571         {
2572
2573             ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2574                     AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
2575
2576             lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
2577
2578             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2579                           AFS_TRACE_LEVEL_VERBOSE,
2580                           "AFSSetFileLinkInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
2581                           &pTargetDirEntry->NameInformation.FileName,
2582                           pTargetDirEntry,
2583                           pSrcCcb,
2584                           lCount));
2585
2586             ASSERT( lCount >= 0);
2587
2588             if( !pFileLinkInfo->ReplaceIfExists)
2589             {
2590
2591                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2592                               AFS_TRACE_LEVEL_ERROR,
2593                               "AFSSetFileLinkInfo Attempt to link with target collision %wZ Target %wZ\n",
2594                               &pSrcCcb->DirectoryCB->NameInformation.FileName,
2595                               &pTargetDirEntry->NameInformation.FileName));
2596
2597                 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2598             }
2599
2600             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2601                           AFS_TRACE_LEVEL_ERROR,
2602                           "AFSSetFileLinkInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
2603                           &pTargetDirEntry->NameInformation.FileName,
2604                           pTargetDirEntry,
2605                           lCount));
2606
2607             //
2608             // Pull the directory entry from the parent
2609             //
2610
2611             AFSRemoveDirNodeFromParent( pTargetParentObject,
2612                                         pTargetDirEntry,
2613                                         FALSE);
2614
2615             bTargetEntryExists = TRUE;
2616         }
2617         else
2618         {
2619             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2620                           AFS_TRACE_LEVEL_VERBOSE,
2621                           "AFSSetFileLinkInfo Target does NOT exist, normal linking\n"));
2622         }
2623
2624         //
2625         // OK, this is a simple rename. Issue the rename
2626         // request to the service.
2627         //
2628
2629         ntStatus = AFSNotifyHardLink( pSrcObject,
2630                                       &pSrcCcb->AuthGroup,
2631                                       pSrcParentObject,
2632                                       pTargetDcb->ObjectInformation,
2633                                       pSrcCcb->DirectoryCB,
2634                                       &uniTargetName,
2635                                       pFileLinkInfo->ReplaceIfExists,
2636                                       &pNewTargetDirEntry);
2637
2638         if( ntStatus != STATUS_REPARSE &&
2639             !NT_SUCCESS( ntStatus))
2640         {
2641
2642             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2643                           AFS_TRACE_LEVEL_ERROR,
2644                           "AFSSetFileLinkInfo Failed link of %wZ to target %wZ Status %08lX\n",
2645                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
2646                           &uniTargetName,
2647                           ntStatus));
2648
2649             try_return( ntStatus);
2650         }
2651
2652         if ( ntStatus != STATUS_REPARSE)
2653         {
2654
2655             AFSInsertDirectoryNode( pTargetDcb->ObjectInformation,
2656                                     pNewTargetDirEntry,
2657                                     TRUE);
2658         }
2659
2660         //
2661         // Send notification for the target link file
2662         //
2663
2664         if( bTargetEntryExists || pNewTargetDirEntry)
2665         {
2666
2667             ulNotificationAction = FILE_ACTION_MODIFIED;
2668         }
2669         else
2670         {
2671
2672             ulNotificationAction = FILE_ACTION_ADDED;
2673         }
2674
2675         AFSFsRtlNotifyFullReportChange( pTargetParentObject,
2676                                         pSrcCcb,
2677                                         (ULONG)ulNotifyFilter,
2678                                         (ULONG)ulNotificationAction);
2679
2680       try_exit:
2681
2682         if( !NT_SUCCESS( ntStatus))
2683         {
2684
2685             if( bTargetEntryExists)
2686             {
2687
2688                 AFSInsertDirectoryNode( pTargetParentObject,
2689                                         pTargetDirEntry,
2690                                         FALSE);
2691             }
2692         }
2693
2694         if( pTargetDirEntry != NULL)
2695         {
2696
2697             //
2698             // Release DirOpenReferenceCount obtained above
2699             //
2700
2701             lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
2702
2703             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2704                           AFS_TRACE_LEVEL_VERBOSE,
2705                           "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2706                           &pTargetDirEntry->NameInformation.FileName,
2707                           pTargetDirEntry,
2708                           pSrcCcb,
2709                           lCount));
2710
2711             ASSERT( lCount >= 0);
2712         }
2713
2714         if( pNewTargetDirEntry != NULL)
2715         {
2716
2717             //
2718             // Release DirOpenReferenceCount obtained from AFSNotifyHardLink
2719             //
2720
2721             lCount = InterlockedDecrement( &pNewTargetDirEntry->DirOpenReferenceCount);
2722
2723             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2724                           AFS_TRACE_LEVEL_VERBOSE,
2725                           "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2726                           &pNewTargetDirEntry->NameInformation.FileName,
2727                           pNewTargetDirEntry,
2728                           pSrcCcb,
2729                           lCount));
2730
2731             ASSERT( lCount >= 0);
2732         }
2733
2734         if( bReleaseTargetDirLock)
2735         {
2736
2737             AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2738         }
2739
2740         if ( pSrcParentObject != NULL)
2741         {
2742
2743             AFSReleaseObjectInfo( &pSrcParentObject);
2744         }
2745
2746         //
2747         // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
2748         // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
2749         //
2750
2751         pTargetParentObject = NULL;
2752     }
2753
2754     return ntStatus;
2755 }
2756
2757 NTSTATUS
2758 AFSSetRenameInfo( IN PIRP Irp)
2759 {
2760
2761     NTSTATUS ntStatus = STATUS_SUCCESS;
2762     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2763     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2764     AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2765     AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2766     PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2767     PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2768     PFILE_OBJECT pTargetParentFileObj = NULL;
2769     PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2770     UNICODE_STRING uniTargetName, uniSourceName, uniTargetParentName;
2771     BOOLEAN bReplaceIfExists = FALSE;
2772     UNICODE_STRING uniShortName;
2773     AFSDirectoryCB *pTargetDirEntry = NULL;
2774     ULONG ulTargetCRC = 0;
2775     BOOLEAN bTargetEntryExists = FALSE;
2776     AFSObjectInfoCB *pSrcObject = NULL;
2777     AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2778     AFSFileID stNewFid;
2779     ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2780     UNICODE_STRING uniFullTargetName;
2781     BOOLEAN bCommonParent = FALSE;
2782     BOOLEAN bReleaseTargetDirLock = FALSE;
2783     BOOLEAN bReleaseSourceDirLock = FALSE;
2784     BOOLEAN bDereferenceTargetParentObject = FALSE;
2785     PERESOURCE  pSourceDirLock = NULL;
2786     LONG lCount;
2787
2788     __Enter
2789     {
2790
2791         bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2792
2793         pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2794
2795         pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2796         pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2797
2798         pSrcObject = pSrcFcb->ObjectInformation;
2799
2800         if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2801         {
2802
2803             pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2804                                                   &pSrcObject->ParentFileId,
2805                                                   TRUE);
2806         }
2807
2808         if( pSrcParentObject == NULL)
2809         {
2810
2811             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2812                           AFS_TRACE_LEVEL_ERROR,
2813                           "AFSSetRenameInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2814
2815             ASSERT( FALSE);
2816
2817             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2818         }
2819
2820         //
2821         // Perform some basic checks to ensure FS integrity
2822         //
2823
2824         if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2825         {
2826
2827             //
2828             // Can't rename the root directory
2829             //
2830
2831             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2832                           AFS_TRACE_LEVEL_ERROR,
2833                           "AFSSetRenameInfo Attempt to rename root entry\n"));
2834
2835             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2836         }
2837
2838         if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2839         {
2840
2841             //
2842             // If there are any open children then fail the rename
2843             //
2844
2845             if( pSrcObject->Specific.Directory.ChildOpenHandleCount > 0)
2846             {
2847
2848                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2849                               AFS_TRACE_LEVEL_ERROR,
2850                               "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2851                               &pSrcCcb->DirectoryCB->NameInformation.FileName));
2852
2853                 try_return( ntStatus = STATUS_ACCESS_DENIED);
2854             }
2855         }
2856
2857
2858         //
2859         // Extract off the final component name from the Fcb
2860         //
2861
2862         uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2863         uniSourceName.MaximumLength = uniSourceName.Length;
2864
2865         uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2866
2867         //
2868         // Resolve the target fileobject
2869         //
2870
2871         if( pTargetFileObj == NULL)
2872         {
2873
2874             if ( pRenameInfo->RootDirectory)
2875             {
2876
2877                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2878                               AFS_TRACE_LEVEL_ERROR,
2879                               "AFSSetRenameInfo Handle provided but no FileObject ntStatus INVALID_PARAMETER\n"));
2880
2881                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2882             }
2883             else
2884             {
2885
2886                 uniFullTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2887
2888                 uniFullTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2889
2890                 AFSRetrieveFinalComponent( &uniFullTargetName,
2891                                            &uniTargetName);
2892
2893                 AFSRetrieveParentPath( &uniFullTargetName,
2894                                        &uniTargetParentName);
2895
2896                 if ( uniTargetParentName.Length == 0)
2897                 {
2898
2899                     //
2900                     // This is a simple rename. Here the target directory is the same as the source parent directory
2901                     // and the name is retrieved from the system buffer information
2902                     //
2903
2904                     pTargetParentObject = pSrcParentObject;
2905                 }
2906                 else
2907                 {
2908                     //
2909                     // uniTargetParentName contains the directory the renamed object
2910                     // will be moved to.  Must obtain the TargetParentObject.
2911                     //
2912
2913                     AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2914                                   AFS_TRACE_LEVEL_ERROR,
2915                                   "AFSSetRenameInfo Attempt to move %wZ to %wZ -- not yet supported (NOT_SAME_DEVICE)\n",
2916                                   &pSrcCcb->DirectoryCB->NameInformation.FileName,
2917                                   &uniFullTargetName));
2918
2919                     try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2920                 }
2921             }
2922
2923             pTargetDcb = pTargetParentObject->Fcb;
2924         }
2925         else
2926         {
2927
2928             //
2929             // So here we have the target directory taken from the targetfile object
2930             //
2931
2932             pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2933
2934             pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2935
2936             pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2937
2938             //
2939             // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2940             // it is only the target component of the rename operation
2941             //
2942
2943             uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2944         }
2945
2946         //
2947         // The quick check to see if they are not really performing a rename
2948         // Do the names match? Only do this where the parent directories are
2949         // the same
2950         //
2951
2952         if( pTargetParentObject == pSrcParentObject)
2953         {
2954
2955             if( FsRtlAreNamesEqual( &uniTargetName,
2956                                     &uniSourceName,
2957                                     FALSE,
2958                                     NULL))
2959             {
2960                 try_return( ntStatus = STATUS_SUCCESS);
2961             }
2962
2963             bCommonParent = TRUE;
2964         }
2965         else
2966         {
2967
2968             bCommonParent = FALSE;
2969         }
2970
2971         //
2972         // We do not allow cross-volume renames to occur
2973         //
2974
2975         if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2976         {
2977
2978             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2979                           AFS_TRACE_LEVEL_ERROR,
2980                           "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2981                           &pSrcCcb->DirectoryCB->NameInformation.FileName));
2982
2983             try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2984         }
2985
2986         ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2987                                       FALSE);
2988
2989         AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2990                         TRUE);
2991
2992         bReleaseTargetDirLock = TRUE;
2993
2994         if( pTargetParentObject != pSrcParentObject)
2995         {
2996             AFSAcquireExcl( pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2997                             TRUE);
2998
2999             bReleaseSourceDirLock = TRUE;
3000
3001             pSourceDirLock = pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock;
3002         }
3003
3004         AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3005                                         ulTargetCRC,
3006                                         &pTargetDirEntry);
3007
3008         if( pTargetDirEntry == NULL)
3009         {
3010
3011             //
3012             // Missed so perform a case insensitive lookup
3013             //
3014
3015             ulTargetCRC = AFSGenerateCRC( &uniTargetName,
3016                                           TRUE);
3017
3018             AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3019                                               ulTargetCRC,
3020                                               &pTargetDirEntry);
3021         }
3022
3023         if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3024              pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
3025                                                                NULL,
3026                                                                NULL))
3027         {
3028             //
3029             // Try the short name
3030             //
3031             AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
3032                                         ulTargetCRC,
3033                                         &pTargetDirEntry);
3034         }
3035
3036         //
3037         // Increment our ref count on the dir entry
3038         //
3039
3040         if( pTargetDirEntry != NULL)
3041         {
3042
3043             ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
3044                     AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
3045
3046             lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
3047
3048             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3049                           AFS_TRACE_LEVEL_VERBOSE,
3050                           "AFSSetRenameInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
3051                           &pTargetDirEntry->NameInformation.FileName,
3052                           pTargetDirEntry,
3053                           pSrcCcb,
3054                           lCount));
3055
3056             ASSERT( lCount >= 0);
3057
3058             if( !bReplaceIfExists)
3059             {
3060
3061                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3062                               AFS_TRACE_LEVEL_ERROR,
3063                               "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
3064                               &pSrcCcb->DirectoryCB->NameInformation.FileName,
3065                               &pTargetDirEntry->NameInformation.FileName));
3066
3067                 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
3068             }
3069
3070             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3071                           AFS_TRACE_LEVEL_ERROR,
3072                           "AFSSetRenameInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
3073                           &pTargetDirEntry->NameInformation.FileName,
3074                           pTargetDirEntry,
3075                           lCount));
3076
3077             //
3078             // Pull the directory entry from the parent
3079             //
3080
3081             AFSRemoveDirNodeFromParent( pTargetParentObject,
3082                                         pTargetDirEntry,
3083                                         FALSE);
3084
3085             bTargetEntryExists = TRUE;
3086         }
3087         else
3088         {
3089             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3090                           AFS_TRACE_LEVEL_VERBOSE,
3091                           "AFSSetRenameInfo Target does NOT exist, normal rename\n"));
3092         }
3093
3094         //
3095         // We need to remove the DirEntry from the parent node, update the index
3096         // and reinsert it into the parent tree. Note that for entries with the
3097         // same parent we do not pull the node from the enumeration list
3098         //
3099
3100         AFSRemoveDirNodeFromParent( pSrcParentObject,
3101                                     pSrcCcb->DirectoryCB,
3102                                     !bCommonParent);
3103
3104         //
3105         // OK, this is a simple rename. Issue the rename
3106         // request to the service.
3107         //
3108
3109         ntStatus = AFSNotifyRename( pSrcObject,
3110                                     &pSrcCcb->AuthGroup,
3111                                     pSrcParentObject,
3112                                     pTargetDcb->ObjectInformation,
3113                                     pSrcCcb->DirectoryCB,
3114                                     &uniTargetName,
3115                                     &stNewFid);
3116
3117         if( !NT_SUCCESS( ntStatus))
3118         {
3119
3120             //
3121             // Attempt to re-insert the directory entry
3122             //
3123
3124             AFSInsertDirectoryNode( pSrcParentObject,
3125                                     pSrcCcb->DirectoryCB,
3126                                     !bCommonParent);
3127
3128             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3129                           AFS_TRACE_LEVEL_ERROR,
3130                           "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
3131                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
3132                           &uniTargetName,
3133                           ntStatus));
3134
3135             try_return( ntStatus);
3136         }
3137
3138         //
3139         // Set the notification up for the source file
3140         //
3141
3142         if( pSrcParentObject == pTargetParentObject &&
3143             !bTargetEntryExists)
3144         {
3145
3146             ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
3147         }
3148         else
3149         {
3150
3151             ulNotificationAction = FILE_ACTION_REMOVED;
3152         }
3153
3154         if( pSrcObject->FileType == AFS_FILE_TYPE_DIRECTORY)
3155         {
3156
3157             ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
3158         }
3159         else
3160         {
3161
3162             ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
3163         }
3164
3165         AFSFsRtlNotifyFullReportChange( pSrcParentObject,
3166                                         pSrcCcb,
3167                                         (ULONG)ulNotifyFilter,
3168                                         (ULONG)ulNotificationAction);
3169
3170         //
3171         // Update the name in the dir entry.
3172         //
3173
3174         ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
3175                                           &uniTargetName);
3176
3177         if( !NT_SUCCESS( ntStatus))
3178         {
3179
3180             //
3181             // Attempt to re-insert the directory entry
3182             //
3183
3184             AFSInsertDirectoryNode( pSrcParentObject,
3185                                     pSrcCcb->DirectoryCB,
3186                                     !bCommonParent);
3187
3188             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3189                           AFS_TRACE_LEVEL_ERROR,
3190                           "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
3191                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
3192                           &uniTargetName,
3193                           ntStatus));
3194
3195             try_return( ntStatus);
3196         }
3197
3198         //
3199         // Update the object information block, if needed
3200         //
3201
3202         if( !AFSIsEqualFID( &pSrcObject->FileId,
3203                             &stNewFid))
3204         {
3205
3206             AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
3207                             TRUE);
3208
3209             //
3210             // Remove the old information entry
3211             //
3212
3213             AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3214                                 &pSrcObject->TreeEntry);
3215
3216             RtlCopyMemory( &pSrcObject->FileId,
3217                            &stNewFid,
3218                            sizeof( AFSFileID));
3219
3220             //
3221             // Insert the entry into the new object table.
3222             //
3223
3224             pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
3225
3226             if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
3227             {
3228
3229                 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
3230             }
3231             else
3232             {
3233
3234                 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3235                                                      &pSrcObject->TreeEntry)))
3236                 {
3237
3238                     //
3239                     // Lost a race, an ObjectInfo object already exists for this FID.
3240                     // Let this copy be garbage collected.
3241                     //
3242
3243                     ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
3244                 }
3245             }
3246
3247             AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
3248         }
3249
3250         //
3251         // Update the hash values for the name trees.
3252         //
3253
3254         pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3255                                                                                  FALSE);
3256
3257         pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3258                                                                                    TRUE);
3259
3260         if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3261             pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
3262             !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3263                                      NULL,
3264                                      NULL))
3265         {
3266
3267             uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
3268             uniShortName.MaximumLength = uniShortName.Length;
3269             uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
3270
3271             pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
3272                                                                                            TRUE);
3273
3274             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3275                           AFS_TRACE_LEVEL_VERBOSE,
3276                           "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
3277                           &uniShortName,
3278                           &pSrcCcb->DirectoryCB->NameInformation.FileName));
3279         }
3280         else
3281         {
3282
3283             pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
3284         }
3285
3286         if( !bCommonParent)
3287         {
3288
3289             //
3290             // Update the file index for the object in the new parent
3291             //
3292
3293             pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
3294         }
3295
3296         //
3297         // Re-insert the directory entry
3298         //
3299
3300         AFSInsertDirectoryNode( pTargetParentObject,
3301                                 pSrcCcb->DirectoryCB,
3302                                 !bCommonParent);
3303
3304         //
3305         // Update the parent pointer in the source object if they are different
3306         //
3307
3308         if( pSrcParentObject != pTargetParentObject)
3309         {
3310
3311             lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenHandleCount);
3312
3313             lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenReferenceCount);
3314
3315             lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
3316
3317             lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
3318
3319
3320             //
3321             // Guaranteed to be in the same volume
3322             //
3323
3324             AFSAcquireExcl( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock,
3325                             TRUE);
3326
3327             lCount = AFSObjectInfoIncrement( pTargetParentObject,
3328                                              AFS_OBJECT_REFERENCE_CHILD);
3329
3330             AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3331                           AFS_TRACE_LEVEL_VERBOSE,
3332                           "AFSSetRenameInfo Increment count on parent object %p Cnt %d\n",
3333                           pTargetParentObject,
3334                           lCount));
3335
3336             lCount = AFSObjectInfoDecrement( pSrcParentObject,
3337                                              AFS_OBJECT_REFERENCE_CHILD);
3338
3339             AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3340                           AFS_TRACE_LEVEL_VERBOSE,
3341                           "AFSSetRenameInfo Decrement count on parent object %p Cnt %d\n",
3342                           pSrcParentObject,
3343                           lCount));
3344
3345             pSrcObject->ParentFileId = pTargetParentObject->FileId;
3346
3347             SetFlag( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
3348
3349             AFSReleaseResource( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock);
3350
3351             ulNotificationAction = FILE_ACTION_ADDED;
3352         }
3353         else
3354         {
3355
3356             ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
3357         }
3358
3359         //
3360         // Now update the notification for the target file
3361         //
3362
3363         AFSFsRtlNotifyFullReportChange( pTargetParentObject,
3364                                         pSrcCcb,
3365                                         (ULONG)ulNotifyFilter,
3366                                         (ULONG)ulNotificationAction);
3367
3368         //
3369         // If we performed the rename of the target because it existed, we now need to
3370         // delete the tmp target we created above
3371         //
3372
3373         if( bTargetEntryExists)
3374         {
3375
3376             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3377                           AFS_TRACE_LEVEL_VERBOSE,
3378                           "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
3379                           pTargetDirEntry,
3380                           &pTargetDirEntry->NameInformation.FileName));
3381
3382             SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3383
3384             //
3385             // Try and purge the cache map if this is a file
3386             //
3387
3388             if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
3389                 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
3390                 pTargetDirEntry->DirOpenReferenceCount > 1)
3391             {
3392
3393                 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
3394             }
3395
3396             ASSERT( pTargetDirEntry->DirOpenReferenceCount > 0);
3397
3398             lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount); // The count we added above
3399
3400             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3401                           AFS_TRACE_LEVEL_VERBOSE,
3402                           "AFSSetRenameInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3403                           &pTargetDirEntry->NameInformation.FileName,
3404                           pTargetDirEntry,
3405                           pSrcCcb,
3406                           lCount));
3407
3408             ASSERT( lCount >= 0);
3409
3410             if( lCount == 0 &&
3411                 pTargetDirEntry->NameArrayReferenceCount <= 0)
3412             {
3413
3414                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3415                               AFS_TRACE_LEVEL_VERBOSE,
3416                               "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
3417                               pTargetDirEntry,
3418                               &pTargetDirEntry->NameInformation.FileName));
3419
3420                 AFSDeleteDirEntry( pTargetParentObject,
3421                                    &pTargetDirEntry);
3422             }
3423
3424             pTargetDirEntry = NULL;
3425
3426             if ( pTargetFcb != NULL)
3427             {
3428
3429                 //
3430                 // Do not hold TreeLocks across the MmForceSectionClosed() call as
3431                 // it can deadlock with Trend Micro's TmPreFlt!TmpQueryFullName
3432                 //
3433
3434                 if( bReleaseTargetDirLock)
3435                 {
3436                     AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3437
3438                     bReleaseTargetDirLock = FALSE;
3439                 }
3440
3441                 if( bReleaseSourceDirLock)
3442                 {
3443
3444                     AFSReleaseResource( pSourceDirLock);
3445
3446                     bReleaseSourceDirLock = FALSE;
3447                 }
3448
3449                 //
3450                 // MmForceSectionClosed() can eventually call back into AFSCleanup
3451                 // which will need to acquire Fcb->Resource exclusively.  Failure
3452                 // to obtain it here before holding the SectionObjectResource will
3453                 // permit the locks to be obtained out of order risking a deadlock.
3454                 //
3455
3456                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3457                               AFS_TRACE_LEVEL_VERBOSE,
3458                               "AFSSetRenameInfo Acquiring Fcb lock %p EXCL %08lX\n",
3459                               &pTargetFcb->NPFcb->Resource,
3460                               PsGetCurrentThread()));
3461
3462                 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
3463                                 TRUE);
3464
3465                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3466                               AFS_TRACE_LEVEL_VERBOSE,
3467                               "AFSSetRenameInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3468                               &pTargetFcb->NPFcb->SectionObjectResource,
3469                               PsGetCurrentThread()));
3470
3471                 AFSAcquireExcl( &pTargetFcb->NPFcb->SectionObjectResource,
3472                                 TRUE);
3473
3474                 __try
3475                 {
3476
3477                     //
3478                     // Close the section in the event it was mapped
3479                     //
3480
3481                     if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
3482                                                TRUE))
3483                     {
3484
3485                         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3486                                       AFS_TRACE_LEVEL_ERROR,
3487                                       "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
3488                                       &uniTargetName));
3489                     }
3490                 }
3491                 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3492                 {
3493
3494                     ntStatus = GetExceptionCode();
3495
3496                     AFSDbgTrace(( 0,
3497                                   0,
3498                                   "EXCEPTION - AFSSetRenameInfo MmForceSectionClosed failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3499                                   pTargetFcb->ObjectInformation->FileId.Cell,
3500                                   pTargetFcb->ObjectInformation->FileId.Volume,
3501                                   pTargetFcb->ObjectInformation->FileId.Vnode,
3502                                   pTargetFcb->ObjectInformation->FileId.Unique,
3503                                   ntStatus));
3504                 }
3505
3506                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3507                               AFS_TRACE_LEVEL_VERBOSE,
3508                               "AFSSetRenameInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3509                               &pTargetFcb->NPFcb->SectionObjectResource,
3510                               PsGetCurrentThread()));
3511
3512                 AFSReleaseResource( &pTargetFcb->NPFcb->SectionObjectResource);
3513
3514                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3515                               AFS_TRACE_LEVEL_VERBOSE,
3516                               "AFSSetRenameInfo Releasing Fcb lock %p EXCL %08lX\n",
3517                               &pTargetFcb->NPFcb->Resource,
3518                               PsGetCurrentThread()));
3519
3520                 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
3521             }
3522         }
3523
3524 try_exit:
3525
3526         if( !NT_SUCCESS( ntStatus))
3527         {
3528
3529             if( bTargetEntryExists)
3530             {
3531
3532                 ASSERT( pTargetParentObject != NULL);
3533
3534                 AFSInsertDirectoryNode( pTargetParentObject,
3535                                         pTargetDirEntry,
3536                                         FALSE);
3537             }
3538         }
3539
3540         if( pTargetDirEntry != NULL)
3541         {
3542
3543             lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
3544
3545             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3546                           AFS_TRACE_LEVEL_VERBOSE,
3547                           "AFSSetRenameInfo Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
3548                           &pTargetDirEntry->NameInformation.FileName,
3549                           pTargetDirEntry,
3550                           pSrcCcb,
3551                           lCount));
3552
3553             ASSERT( lCount >= 0);
3554         }
3555
3556         if( bReleaseTargetDirLock)
3557         {
3558
3559             AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3560         }
3561
3562         if( bReleaseSourceDirLock)
3563         {
3564
3565             AFSReleaseResource( pSourceDirLock);
3566         }
3567
3568         if ( bDereferenceTargetParentObject)
3569         {
3570
3571             ObDereferenceObject( pTargetParentFileObj);
3572         }
3573
3574         if ( pSrcParentObject != NULL)
3575         {
3576
3577             AFSReleaseObjectInfo( &pSrcParentObject);
3578         }
3579
3580         //
3581         // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
3582         // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
3583         //
3584
3585         pTargetParentObject = NULL;
3586     }
3587
3588     return ntStatus;
3589 }
3590
3591 NTSTATUS
3592 AFSSetPositionInfo( IN PIRP Irp,
3593                     IN AFSDirectoryCB *DirectoryCB)
3594 {
3595     UNREFERENCED_PARAMETER(DirectoryCB);
3596     NTSTATUS ntStatus = STATUS_SUCCESS;
3597     PFILE_POSITION_INFORMATION pBuffer;
3598     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3599
3600     pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3601
3602     pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
3603
3604     return ntStatus;
3605 }
3606
3607 NTSTATUS
3608 AFSSetAllocationInfo( IN PIRP Irp,
3609                       IN AFSDirectoryCB *DirectoryCB)
3610 {
3611     UNREFERENCED_PARAMETER(DirectoryCB);
3612     NTSTATUS ntStatus = STATUS_SUCCESS;
3613     PFILE_ALLOCATION_INFORMATION pBuffer;
3614     BOOLEAN bReleasePaging = FALSE;
3615     BOOLEAN bTellCc = FALSE;
3616     BOOLEAN bTellService = FALSE;
3617     BOOLEAN bUserMapped = FALSE;
3618     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3619     PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3620     AFSFcb *pFcb = NULL;
3621     AFSCcb *pCcb = NULL;
3622     LARGE_INTEGER liSaveAlloc;
3623     LARGE_INTEGER liSaveFileSize;
3624     LARGE_INTEGER liSaveVDL;
3625
3626     pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3627
3628     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3629
3630     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3631
3632     //
3633     // save values to put back
3634     //
3635     liSaveAlloc = pFcb->Header.AllocationSize;
3636     liSaveFileSize = pFcb->Header.FileSize;
3637     liSaveVDL = pFcb->Header.ValidDataLength;
3638
3639     if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
3640         pIrpSp->Parameters.SetFile.AdvanceOnly)
3641     {
3642         return STATUS_SUCCESS ;
3643     }
3644
3645     if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3646     {
3647
3648         AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3649                       AFS_TRACE_LEVEL_VERBOSE,
3650                       "AFSSetAllocationInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3651                       &pFcb->NPFcb->SectionObjectResource,
3652                       PsGetCurrentThread()));
3653
3654         AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3655                         TRUE);
3656
3657         __try
3658         {
3659
3660             bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3661                                                  &pBuffer->AllocationSize);
3662         }
3663         __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3664         {
3665
3666             bUserMapped = FALSE;
3667
3668             ntStatus = GetExceptionCode();
3669
3670             AFSDbgTrace(( 0,
3671                           0,
3672                           "EXCEPTION - AFSSetAllocationInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3673                           pFcb->ObjectInformation->FileId.Cell,
3674                           pFcb->ObjectInformation->FileId.Volume,
3675                           pFcb->ObjectInformation->FileId.Vnode,
3676                           pFcb->ObjectInformation->FileId.Unique,
3677                           ntStatus));
3678         }
3679
3680         AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3681                       AFS_TRACE_LEVEL_VERBOSE,
3682                       "AFSSetAllocationInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3683                       &pFcb->NPFcb->SectionObjectResource,
3684                       PsGetCurrentThread()));
3685
3686         AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3687
3688         //
3689         // Truncating the file
3690         //
3691         if ( bUserMapped)
3692         {
3693
3694             ntStatus = STATUS_USER_MAPPED_FILE ;
3695         }
3696         else
3697         {
3698
3699             //
3700             // If this is a truncation we need to grab the paging IO resource.
3701             //
3702
3703             AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3704                           AFS_TRACE_LEVEL_VERBOSE,
3705                           "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3706                           &pFcb->NPFcb->PagingResource,
3707                           PsGetCurrentThread()));
3708
3709             AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3710                             TRUE);
3711
3712             bReleasePaging = TRUE;
3713
3714             //
3715             // Must drop the Fcb Resource.  When changing the file size
3716             // a deadlock can occur with Trend Micro's filter if the file
3717             // size is set to zero.
3718             //
3719
3720             AFSReleaseResource( &pFcb->NPFcb->Resource);
3721
3722             pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3723
3724             pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3725
3726             //
3727             // Tell Cc that Allocation is moved.
3728             //
3729             bTellCc = TRUE;
3730
3731             if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3732             {
3733                 //
3734                 // We are pulling the EOF back as well so we need to tell
3735                 // the service.
3736                 //
3737                 bTellService = TRUE;
3738
3739                 pFcb->Header.FileSize = pBuffer->AllocationSize;
3740
3741                 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
3742             }
3743
3744         }
3745     }
3746     else
3747     {
3748         //
3749         // Tell Cc if allocation is increased.
3750         //
3751
3752         AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3753                       AFS_TRACE_LEVEL_VERBOSE,
3754                       "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3755                       &pFcb->NPFcb->PagingResource,
3756                       PsGetCurrentThread()));
3757
3758         AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3759                         TRUE);
3760
3761         bReleasePaging = TRUE;
3762
3763         //
3764         // Must drop the Fcb Resource.  When changing the file size
3765         // a deadlock can occur with Trend Micro's filter if the file
3766         // size is set to zero.
3767         //
3768
3769         AFSReleaseResource( &pFcb->NPFcb->Resource);
3770
3771         bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
3772
3773         pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3774
3775         pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3776     }
3777
3778     //
3779     // Now Tell the server if we have to
3780     //
3781     if (bTellService)
3782     {
3783
3784         ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
3785
3786         ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
3787                                              pFcb->ObjectInformation,
3788                                              &pCcb->AuthGroup);
3789     }
3790
3791     if (NT_SUCCESS(ntStatus))
3792     {
3793         //
3794         // Trim extents if we told the service - the update has done an implicit
3795         // trim at the service.
3796         //
3797         if (bTellService)
3798         {
3799             AFSTrimExtents( pFcb,
3800                             &pFcb->Header.FileSize);
3801         }
3802
3803         KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3804
3805         SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3806
3807         if (bTellCc &&
3808             CcIsFileCached( pFileObject))
3809         {
3810             CcSetFileSizes( pFileObject,
3811                             (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3812         }
3813     }
3814     else
3815     {
3816         //
3817         // Put the saved values back
3818         //
3819         pFcb->Header.ValidDataLength = liSaveVDL;
3820         pFcb->Header.FileSize = liSaveFileSize;
3821         pFcb->Header.AllocationSize = liSaveAlloc;
3822         pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
3823         pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3824     }
3825
3826     if( bReleasePaging)
3827     {
3828
3829         AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3830
3831         AFSAcquireExcl( &pFcb->NPFcb->Resource,
3832                         TRUE);
3833     }
3834
3835     return ntStatus;
3836 }
3837
3838 NTSTATUS
3839 AFSSetEndOfFileInfo( IN PIRP Irp,
3840                      IN AFSDirectoryCB *DirectoryCB)
3841 {
3842     UNREFERENCED_PARAMETER(DirectoryCB);
3843     NTSTATUS ntStatus = STATUS_SUCCESS;
3844     PFILE_END_OF_FILE_INFORMATION pBuffer;
3845     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3846     PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3847     LARGE_INTEGER liSaveSize;
3848     LARGE_INTEGER liSaveVDL;
3849     LARGE_INTEGER liSaveAlloc;
3850     BOOLEAN bModified = FALSE;
3851     BOOLEAN bReleasePaging = FALSE;
3852     BOOLEAN bTruncated = FALSE;
3853     BOOLEAN bUserMapped = FALSE;
3854     AFSFcb *pFcb = NULL;
3855     AFSCcb *pCcb = NULL;
3856
3857     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3858
3859     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3860
3861     pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3862
3863     liSaveSize = pFcb->Header.FileSize;
3864     liSaveAlloc = pFcb->Header.AllocationSize;
3865     liSaveVDL = pFcb->Header.ValidDataLength;
3866
3867     if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
3868         !pIrpSp->Parameters.SetFile.AdvanceOnly)
3869     {
3870
3871         if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
3872         {
3873
3874             AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3875                           AFS_TRACE_LEVEL_VERBOSE,
3876                           "AFSSetEndOfFileInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3877                           &pFcb->NPFcb->SectionObjectResource,
3878                           PsGetCurrentThread()));
3879
3880             AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3881                             TRUE);
3882
3883             __try
3884             {
3885
3886                 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3887                                                      &pBuffer->EndOfFile);
3888             }
3889             __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3890             {
3891
3892                 bUserMapped = FALSE;
3893
3894                 ntStatus = GetExceptionCode();
3895
3896                 AFSDbgTrace(( 0,
3897                               0,
3898                               "EXCEPTION - AFSSetEndOfFileInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3899                               pFcb->ObjectInformation->FileId.Cell,
3900                               pFcb->ObjectInformation->FileId.Volume,
3901                               pFcb->ObjectInformation->FileId.Vnode,
3902                               pFcb->ObjectInformation->FileId.Unique,
3903                               ntStatus));
3904             }
3905
3906             AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3907                           AFS_TRACE_LEVEL_VERBOSE,
3908                           "AFSSetEndOfFileInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3909                           &pFcb->NPFcb->SectionObjectResource,
3910                           PsGetCurrentThread()));
3911
3912             AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3913
3914             // Truncating the file
3915             if ( bUserMapped)
3916             {
3917
3918                 ntStatus = STATUS_USER_MAPPED_FILE;
3919             }
3920             else
3921             {
3922
3923                 //
3924                 // If this is a truncation we need to grab the paging
3925                 // IO resource.
3926                 //
3927                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3928                               AFS_TRACE_LEVEL_VERBOSE,
3929                               "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3930                               &pFcb->NPFcb->PagingResource,
3931                               PsGetCurrentThread()));
3932
3933                 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3934                                 TRUE);
3935
3936                 bReleasePaging = TRUE;
3937
3938                 //
3939                 // Must drop the Fcb Resource.  When changing the file size
3940                 // a deadlock can occur with Trend Micro's filter if the file
3941                 // size is set to zero.
3942                 //
3943
3944                 AFSReleaseResource( &pFcb->NPFcb->Resource);
3945
3946                 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3947
3948                 pFcb->Header.FileSize = pBuffer->EndOfFile;
3949
3950                 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3951
3952                 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3953
3954                 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
3955                 {
3956
3957                     pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
3958                 }
3959
3960                 bTruncated = TRUE;
3961
3962                 bModified = TRUE;
3963             }
3964         }
3965         else
3966         {
3967
3968             //
3969             // extending the file, move EOF
3970             //
3971
3972             //
3973             // If this is a truncation we need to grab the paging
3974             // IO resource.
3975             //
3976             AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3977                           AFS_TRACE_LEVEL_VERBOSE,
3978                           "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3979                           &pFcb->NPFcb->PagingResource,
3980                           PsGetCurrentThread()));
3981
3982             AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3983                             TRUE);
3984
3985             bReleasePaging = TRUE;
3986
3987             //
3988             // Must drop the Fcb Resource.  When changing the file size
3989             // a deadlock can occur with Trend Micro's filter if the file
3990             // size is set to zero.
3991             //
3992
3993             AFSReleaseResource( &pFcb->NPFcb->Resource);
3994
3995             pFcb->Header.FileSize = pBuffer->EndOfFile;
3996
3997             pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3998
3999             if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
4000             {
4001                 //
4002                 // And Allocation as needed.
4003                 //
4004                 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
4005
4006                 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
4007             }
4008
4009             bModified = TRUE;
4010         }
4011     }
4012
4013     if (bModified)
4014     {
4015
4016         KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
4017
4018         SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
4019
4020         //
4021         // Tell the server
4022         //
4023
4024         ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
4025
4026         ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
4027                                              pFcb->ObjectInformation,
4028                                              &pCcb->AuthGroup);
4029
4030         if( NT_SUCCESS(ntStatus))
4031         {
4032             //
4033             // We are now good to go so tell CC.
4034             //
4035             CcSetFileSizes( pFileObject,
4036                             (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
4037
4038             //
4039             // And give up those extents
4040             //
4041             if( bTruncated)
4042             {
4043
4044                 AFSTrimExtents( pFcb,
4045                                 &pFcb->Header.FileSize);
4046             }
4047         }
4048         else
4049         {
4050             pFcb->Header.ValidDataLength = liSaveVDL;
4051             pFcb->Header.FileSize = liSaveSize;
4052             pFcb->Header.AllocationSize = liSaveAlloc;
4053             pFcb->ObjectInformation->EndOfFile = liSaveSize;
4054             pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
4055         }
4056     }
4057
4058     if( bReleasePaging)
4059     {
4060
4061         AFSReleaseResource( &pFcb->NPFcb->PagingResource);
4062
4063         AFSAcquireExcl( &pFcb->NPFcb->Resource,
4064                         TRUE);
4065     }
4066
4067     return ntStatus;
4068 }
4069
4070 NTSTATUS
4071 AFSProcessShareSetInfo( IN IRP *Irp,
4072                         IN AFSFcb *Fcb,
4073                         IN AFSCcb *Ccb)
4074 {
4075
4076     UNREFERENCED_PARAMETER(Fcb);
4077     NTSTATUS ntStatus = STATUS_SUCCESS;
4078     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4079     FILE_INFORMATION_CLASS ulFileInformationClass;
4080     void *pPipeInfo = NULL;
4081
4082     __Enter
4083     {
4084         ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
4085
4086         AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4087                       AFS_TRACE_LEVEL_VERBOSE,
4088                       "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
4089                       &Ccb->DirectoryCB->NameInformation.FileName,
4090                       ulFileInformationClass));
4091
4092         pPipeInfo = AFSLockSystemBuffer( Irp,
4093                                          pIrpSp->Parameters.SetFile.Length);
4094
4095         if( pPipeInfo == NULL)
4096         {
4097
4098             AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4099                           AFS_TRACE_LEVEL_ERROR,
4100                           "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
4101                           &Ccb->DirectoryCB->NameInformation.FileName));
4102
4103             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4104         }
4105
4106         //
4107         // Send the request to the service
4108         //
4109
4110         ntStatus = AFSNotifySetPipeInfo( Ccb,
4111                                          (ULONG)ulFileInformationClass,
4112                                          pIrpSp->Parameters.SetFile.Length,
4113                                          pPipeInfo);
4114
4115         if( !NT_SUCCESS( ntStatus))
4116         {
4117
4118             AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4119                           AFS_TRACE_LEVEL_ERROR,
4120                           "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4121                           &Ccb->DirectoryCB->NameInformation.FileName,
4122                           ntStatus));
4123
4124             try_return( ntStatus);
4125         }
4126
4127         AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4128                       AFS_TRACE_LEVEL_VERBOSE,
4129                       "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
4130                       &Ccb->DirectoryCB->NameInformation.FileName,
4131                       ulFileInformationClass));
4132
4133 try_exit:
4134
4135         NOTHING;
4136     }
4137
4138     return ntStatus;
4139 }
4140
4141 NTSTATUS
4142 AFSProcessShareQueryInfo( IN IRP *Irp,
4143                           IN AFSFcb *Fcb,
4144                           IN AFSCcb *Ccb)
4145 {
4146
4147     UNREFERENCED_PARAMETER(Fcb);
4148     NTSTATUS ntStatus = STATUS_SUCCESS;
4149     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4150     FILE_INFORMATION_CLASS ulFileInformationClass;
4151     void *pPipeInfo = NULL;
4152
4153     __Enter
4154     {
4155
4156         ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4157
4158         AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4159                       AFS_TRACE_LEVEL_VERBOSE,
4160                       "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
4161                       &Ccb->DirectoryCB->NameInformation.FileName,
4162                       ulFileInformationClass));
4163
4164         pPipeInfo = AFSLockSystemBuffer( Irp,
4165                                          pIrpSp->Parameters.QueryFile.Length);
4166
4167         if( pPipeInfo == NULL)
4168         {
4169
4170             AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4171                           AFS_TRACE_LEVEL_ERROR,
4172                           "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
4173                           &Ccb->DirectoryCB->NameInformation.FileName));
4174
4175             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4176         }
4177
4178         //
4179         // Send the request to the service
4180         //
4181
4182         ntStatus = AFSNotifyQueryPipeInfo( Ccb,
4183                                            (ULONG)ulFileInformationClass,
4184                                            pIrpSp->Parameters.QueryFile.Length,
4185                                            pPipeInfo,
4186                                            (ULONG *)&Irp->IoStatus.Information);
4187
4188         if( !NT_SUCCESS( ntStatus))
4189         {
4190
4191             AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4192                           AFS_TRACE_LEVEL_ERROR,
4193                           "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4194                           &Ccb->DirectoryCB->NameInformation.FileName,
4195                           ntStatus));
4196
4197             try_return( ntStatus);
4198         }
4199
4200         AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4201                       AFS_TRACE_LEVEL_VERBOSE,
4202                       "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
4203                       &Ccb->DirectoryCB->NameInformation.FileName,
4204                       ulFileInformationClass));
4205
4206 try_exit:
4207
4208         NOTHING;
4209     }
4210
4211     return ntStatus;
4212 }
4213
4214 NTSTATUS
4215 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
4216                            IN AFSFcb *Fcb,
4217                            IN AFSCcb *Ccb,
4218                            IN OUT LONG *Length)
4219 {
4220
4221     UNREFERENCED_PARAMETER(Fcb);
4222     UNREFERENCED_PARAMETER(Ccb);
4223     NTSTATUS ntStatus = STATUS_SUCCESS;
4224     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4225     FILE_INFORMATION_CLASS ulFileInformationClass;
4226
4227     __Enter
4228     {
4229
4230         ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4231
4232         switch( ulFileInformationClass)
4233         {
4234
4235             case FileBasicInformation:
4236             {
4237
4238                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4239                               AFS_TRACE_LEVEL_VERBOSE,
4240                               "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n"));
4241
4242                 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
4243                 {
4244                     PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4245
4246                     pBasic->CreationTime.QuadPart = 0;
4247                     pBasic->LastAccessTime.QuadPart = 0;
4248                     pBasic->ChangeTime.QuadPart = 0;
4249                     pBasic->LastWriteTime.QuadPart = 0;
4250                     pBasic->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
4251
4252                     *Length -= sizeof( FILE_BASIC_INFORMATION);
4253                 }
4254                 else
4255                 {
4256                     ntStatus = STATUS_BUFFER_TOO_SMALL;
4257                 }
4258
4259                 break;
4260             }
4261
4262             case FileStandardInformation:
4263             {
4264
4265                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4266                               AFS_TRACE_LEVEL_VERBOSE,
4267                               "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n"));
4268
4269                 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
4270                 {
4271                     PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4272
4273                     pStandard->NumberOfLinks = 1;
4274                     pStandard->DeletePending = 0;
4275                     pStandard->AllocationSize.QuadPart = 0;
4276                     pStandard->EndOfFile.QuadPart = 0;
4277                     pStandard->Directory = 0;
4278
4279                     *Length -= sizeof( FILE_STANDARD_INFORMATION);
4280                 }
4281                 else
4282                 {
4283                     ntStatus = STATUS_BUFFER_TOO_SMALL;
4284                 }
4285
4286                 break;
4287             }
4288
4289             case FileNormalizedNameInformation:
4290             case FileNameInformation:
4291             {
4292
4293                 ULONG ulCopyLength = 0;
4294                 AFSFcb *pFcb = NULL;
4295                 AFSCcb *pCcb = NULL;
4296                 USHORT usFullNameLength = 0;
4297                 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4298                 UNICODE_STRING uniName;
4299
4300                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4301                               AFS_TRACE_LEVEL_VERBOSE,
4302                               "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n"));
4303
4304                 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
4305                 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
4306
4307                 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
4308                 {
4309                     ntStatus = STATUS_BUFFER_TOO_SMALL;
4310                     break;
4311                 }
4312
4313                 RtlZeroMemory( pNameInfo,
4314                                *Length);
4315
4316                 usFullNameLength = sizeof( WCHAR) +
4317                                             AFSServerName.Length +
4318                                             pCcb->FullFileName.Length;
4319
4320                 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
4321                 {
4322                     ulCopyLength = (LONG)usFullNameLength;
4323                 }
4324                 else
4325                 {
4326                     ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4327                     ntStatus = STATUS_BUFFER_OVERFLOW;
4328                 }
4329
4330                 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
4331
4332                 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4333
4334                 if( ulCopyLength > 0)
4335                 {
4336
4337                     pNameInfo->FileName[ 0] = L'\\';
4338                     ulCopyLength -= sizeof( WCHAR);
4339
4340                     *Length -= sizeof( WCHAR);
4341
4342                     if( ulCopyLength >= AFSServerName.Length)
4343                     {
4344
4345                         RtlCopyMemory( &pNameInfo->FileName[ 1],
4346                                        AFSServerName.Buffer,
4347                                        AFSServerName.Length);
4348
4349                         ulCopyLength -= AFSServerName.Length;
4350                         *Length -= AFSServerName.Length;
4351
4352                         if( ulCopyLength >= pCcb->FullFileName.Length)
4353                         {
4354
4355                             RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4356                                            pCcb->FullFileName.Buffer,
4357                                            pCcb->FullFileName.Length);
4358
4359                             ulCopyLength -= pCcb->FullFileName.Length;
4360                             *Length -= pCcb->FullFileName.Length;
4361
4362                             uniName.Length = (USHORT)pNameInfo->FileNameLength;
4363                             uniName.MaximumLength = uniName.Length;
4364                             uniName.Buffer = pNameInfo->FileName;
4365                         }
4366                         else
4367                         {
4368
4369                             RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4370                                            pCcb->FullFileName.Buffer,
4371                                            ulCopyLength);
4372
4373                             *Length -= ulCopyLength;
4374
4375                             uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
4376                             uniName.MaximumLength = uniName.Length;
4377                             uniName.Buffer = pNameInfo->FileName;
4378                         }
4379
4380                         AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4381                                       AFS_TRACE_LEVEL_VERBOSE,
4382                                       "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
4383                                       &uniName));
4384                     }
4385                 }
4386
4387                 break;
4388             }
4389
4390             case FileInternalInformation:
4391             {
4392
4393                 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4394
4395                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4396                               AFS_TRACE_LEVEL_VERBOSE,
4397                               "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n"));
4398
4399                 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
4400                 {
4401
4402                     pInternalInfo->IndexNumber.HighPart = 0;
4403
4404                     pInternalInfo->IndexNumber.LowPart = 0;
4405
4406                     *Length -= sizeof( FILE_INTERNAL_INFORMATION);
4407                 }
4408                 else
4409                 {
4410
4411                     ntStatus = STATUS_BUFFER_TOO_SMALL;
4412                 }
4413
4414                 break;
4415             }
4416
4417             case FileAllInformation:
4418             {
4419                 ntStatus = STATUS_INVALID_PARAMETER;
4420
4421                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4422                               AFS_TRACE_LEVEL_WARNING,
4423                               "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n"));
4424
4425                 break;
4426             }
4427
4428             case FileEaInformation:
4429             {
4430                 ntStatus = STATUS_INVALID_PARAMETER;
4431
4432                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4433                               AFS_TRACE_LEVEL_WARNING,
4434                               "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n"));
4435
4436                 break;
4437             }
4438
4439             case FilePositionInformation:
4440             {
4441                 ntStatus = STATUS_INVALID_PARAMETER;
4442
4443                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4444                               AFS_TRACE_LEVEL_WARNING,
4445                               "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n"));
4446
4447                 break;
4448             }
4449
4450             case FileAlternateNameInformation:
4451             {
4452                 ntStatus = STATUS_INVALID_PARAMETER;
4453
4454                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4455                               AFS_TRACE_LEVEL_WARNING,
4456                               "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n"));
4457
4458                 break;
4459             }
4460
4461             case FileNetworkOpenInformation:
4462             {
4463                 ntStatus = STATUS_INVALID_PARAMETER;
4464
4465                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4466                               AFS_TRACE_LEVEL_WARNING,
4467                               "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n"));
4468
4469                 break;
4470             }
4471
4472             case FileStreamInformation:
4473             {
4474                 ntStatus = STATUS_INVALID_PARAMETER;
4475
4476                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4477                               AFS_TRACE_LEVEL_WARNING,
4478                               "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n"));
4479
4480                 break;
4481             }
4482
4483             case FileAttributeTagInformation:
4484             {
4485                 ntStatus = STATUS_INVALID_PARAMETER;
4486
4487                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4488                               AFS_TRACE_LEVEL_WARNING,
4489                               "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n"));
4490
4491                 break;
4492             }
4493
4494             case FileRemoteProtocolInformation:
4495             {
4496                 ntStatus = STATUS_INVALID_PARAMETER;
4497
4498                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4499                               AFS_TRACE_LEVEL_WARNING,
4500                               "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n"));
4501
4502                 break;
4503             }
4504
4505             case FileNetworkPhysicalNameInformation:
4506             {
4507                 ntStatus = STATUS_INVALID_PARAMETER;
4508
4509                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4510                               AFS_TRACE_LEVEL_WARNING,
4511                               "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n"));
4512
4513                 break;
4514             }
4515
4516             default:
4517             {
4518                 ntStatus = STATUS_INVALID_PARAMETER;
4519
4520                 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4521                               AFS_TRACE_LEVEL_WARNING,
4522                               "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
4523                               ulFileInformationClass));
4524
4525                 break;
4526             }
4527         }
4528     }
4529
4530     AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4531                   AFS_TRACE_LEVEL_VERBOSE,
4532                   "AFSProcessPIOCtlQueryInfo ntStatus %08lX\n",
4533                   ntStatus));
4534
4535     return ntStatus;
4536 }
4537