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