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