Windows: FileNormalizedNameInformation take one
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSFileInfo.cpp
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3  * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * - Redistributions of source code must retain the above copyright notice,
11  *   this list of conditions and the following disclaimer.
12  * - Redistributions in binary form must reproduce the above copyright
13  *   notice,
14  *   this list of conditions and the following disclaimer in the
15  *   documentation
16  *   and/or other materials provided with the distribution.
17  * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18  *   nor the names of their contributors may be used to endorse or promote
19  *   products derived from this software without specific prior written
20  *   permission from Kernel Drivers, LLC and Your File System, Inc.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 //
36 // File: AFSFileInfo.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 //
42 // Function: AFSQueryFileInfo
43 //
44 // Description:
45 //
46 //      This function is the dispatch handler for the IRP_MJ_QUERY_FILE_INFORMATION request
47 //
48 // Return:
49 //
50 //      A status is returned for the function
51 //
52
53 NTSTATUS
54 AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
55                   IN PIRP Irp)
56 {
57
58     NTSTATUS ntStatus = STATUS_SUCCESS;
59     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
60     ULONG ulRequestType = 0;
61     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
62     AFSFcb *pFcb = NULL;
63     AFSCcb *pCcb = NULL;
64     PFILE_OBJECT pFileObject;
65     BOOLEAN bReleaseMain = FALSE;
66     LONG lLength;
67     FILE_INFORMATION_CLASS stFileInformationClass;
68     PVOID pBuffer;
69
70     __try
71     {
72
73         //
74         // Determine the type of request this request is
75         //
76
77         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
78
79         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
80
81         if( pFcb == NULL)
82         {
83
84             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
85                           AFS_TRACE_LEVEL_ERROR,
86                           "AFSQueryFileInfo Attempted access (%08lX) when pFcb == NULL\n",
87                           Irp);
88
89             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
90         }
91
92         lLength = (LONG)pIrpSp->Parameters.QueryFile.Length;
93         stFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
94         pBuffer = Irp->AssociatedIrp.SystemBuffer;
95
96         //
97         // Grab the main shared right off the bat
98         //
99
100         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
101                       AFS_TRACE_LEVEL_VERBOSE,
102                       "AFSQueryFileInfo Acquiring Fcb lock %08lX SHARED %08lX\n",
103                       &pFcb->NPFcb->Resource,
104                       PsGetCurrentThread());
105
106         AFSAcquireShared( &pFcb->NPFcb->Resource,
107                           TRUE);
108
109         bReleaseMain = TRUE;
110
111         //
112         // Don't allow requests against IOCtl nodes
113         //
114
115         if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
116         {
117
118             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
119                           AFS_TRACE_LEVEL_VERBOSE,
120                           "AFSQueryFileInfo Processing request against SpecialShare Fcb\n");
121
122             ntStatus = AFSProcessShareQueryInfo( Irp,
123                                                  pFcb,
124                                                  pCcb);
125
126             try_return( ntStatus);
127         }
128         else if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
129         {
130             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
131                           AFS_TRACE_LEVEL_VERBOSE,
132                           "AFSQueryFileInfo request against PIOCtl Fcb\n");
133
134             ntStatus = AFSProcessPIOCtlQueryInfo( Irp,
135                                                   pFcb,
136                                                   pCcb,
137                                                   &lLength);
138
139             try_return( ntStatus);
140         }
141
142         else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
143         {
144             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
145                           AFS_TRACE_LEVEL_VERBOSE,
146                           "AFSQueryFileInfo request against Invalid Fcb\n");
147
148             try_return( ntStatus = STATUS_ACCESS_DENIED);
149         }
150
151         //
152         // Process the request
153         //
154
155         switch( stFileInformationClass)
156         {
157
158             case FileAllInformation:
159             {
160
161                 PFILE_ALL_INFORMATION pAllInfo;
162
163                 //
164                 //  For the all information class we'll typecast a local
165                 //  pointer to the output buffer and then call the
166                 //  individual routines to fill in the buffer.
167                 //
168
169                 pAllInfo = (PFILE_ALL_INFORMATION)pBuffer;
170
171                 ntStatus = AFSQueryBasicInfo( Irp,
172                                               pCcb->DirectoryCB,
173                                               &pAllInfo->BasicInformation,
174                                               &lLength);
175
176                 if( !NT_SUCCESS( ntStatus))
177                 {
178
179                     try_return( ntStatus);
180                 }
181
182                 ntStatus = AFSQueryStandardInfo( Irp,
183                                                  pCcb->DirectoryCB,
184                                                  &pAllInfo->StandardInformation,
185                                                  &lLength);
186
187                 if( !NT_SUCCESS( ntStatus))
188                 {
189
190                     try_return( ntStatus);
191                 }
192
193                 ntStatus = AFSQueryInternalInfo( Irp,
194                                                  pFcb,
195                                                  &pAllInfo->InternalInformation,
196                                                  &lLength);
197
198                 if( !NT_SUCCESS( ntStatus))
199                 {
200
201                     try_return( ntStatus);
202                 }
203
204                 ntStatus = AFSQueryEaInfo( Irp,
205                                            pCcb->DirectoryCB,
206                                            &pAllInfo->EaInformation,
207                                            &lLength);
208
209                 if( !NT_SUCCESS( ntStatus))
210                 {
211
212                     try_return( ntStatus);
213                 }
214
215                 ntStatus = AFSQueryAccess( Irp,
216                                            pFcb,
217                                            &pAllInfo->AccessInformation,
218                                            &lLength);
219
220                 if( !NT_SUCCESS( ntStatus))
221                 {
222
223                     try_return( ntStatus);
224                 }
225
226                 ntStatus = AFSQueryPositionInfo( Irp,
227                                                  pFcb,
228                                                  &pAllInfo->PositionInformation,
229                                                  &lLength);
230
231                 if( !NT_SUCCESS( ntStatus))
232                 {
233
234                     try_return( ntStatus);
235                 }
236
237                 ntStatus = AFSQueryMode( Irp,
238                                          pFcb,
239                                          &pAllInfo->ModeInformation,
240                                          &lLength);
241
242                 if( !NT_SUCCESS( ntStatus))
243                 {
244
245                     try_return( ntStatus);
246                 }
247
248                 ntStatus = AFSQueryAlignment( Irp,
249                                               pFcb,
250                                               &pAllInfo->AlignmentInformation,
251                                               &lLength);
252
253                 if( !NT_SUCCESS( ntStatus))
254                 {
255
256                     try_return( ntStatus);
257                 }
258
259                 ntStatus = AFSQueryNameInfo( Irp,
260                                              pCcb->DirectoryCB,
261                                              &pAllInfo->NameInformation,
262                                              &lLength);
263
264                 if( !NT_SUCCESS( ntStatus))
265                 {
266
267                     try_return( ntStatus);
268                 }
269
270                 break;
271             }
272
273             case FileBasicInformation:
274             {
275
276                 ntStatus = AFSQueryBasicInfo( Irp,
277                                               pCcb->DirectoryCB,
278                                               (PFILE_BASIC_INFORMATION)pBuffer,
279                                               &lLength);
280
281                 break;
282             }
283
284             case FileStandardInformation:
285             {
286
287                 ntStatus = AFSQueryStandardInfo( Irp,
288                                                  pCcb->DirectoryCB,
289                                                  (PFILE_STANDARD_INFORMATION)pBuffer,
290                                                  &lLength);
291
292                 break;
293             }
294
295             case FileInternalInformation:
296             {
297
298                 ntStatus = AFSQueryInternalInfo( Irp,
299                                                  pFcb,
300                                                  (PFILE_INTERNAL_INFORMATION)pBuffer,
301                                                  &lLength);
302
303                 break;
304             }
305
306             case FileEaInformation:
307             {
308
309                 ntStatus = AFSQueryEaInfo( Irp,
310                                            pCcb->DirectoryCB,
311                                            (PFILE_EA_INFORMATION)pBuffer,
312                                            &lLength);
313
314                 break;
315             }
316
317             case FilePositionInformation:
318             {
319
320                 ntStatus = AFSQueryPositionInfo( Irp,
321                                       pFcb,
322                                       (PFILE_POSITION_INFORMATION)pBuffer,
323                                       &lLength);
324
325                 break;
326             }
327
328             case FileNormalizedNameInformation:
329             case FileNameInformation:
330             {
331
332                 ntStatus = AFSQueryNameInfo( Irp,
333                                   pCcb->DirectoryCB,
334                                   (PFILE_NAME_INFORMATION)pBuffer,
335                                   &lLength);
336
337                 break;
338             }
339
340             case FileAlternateNameInformation:
341             {
342
343                 ntStatus = AFSQueryShortNameInfo( Irp,
344                                        pCcb->DirectoryCB,
345                                        (PFILE_NAME_INFORMATION)pBuffer,
346                                        &lLength);
347
348                 break;
349             }
350
351             case FileNetworkOpenInformation:
352             {
353
354                 ntStatus = AFSQueryNetworkInfo( Irp,
355                                      pCcb->DirectoryCB,
356                                      (PFILE_NETWORK_OPEN_INFORMATION)pBuffer,
357                                      &lLength);
358
359                 break;
360             }
361
362             case FileStreamInformation:
363             {
364
365                 ntStatus = AFSQueryStreamInfo( Irp,
366                                                pCcb->DirectoryCB,
367                                                (FILE_STREAM_INFORMATION *)pBuffer,
368                                                &lLength);
369
370                 break;
371             }
372
373
374             case FileAttributeTagInformation:
375             {
376
377                 ntStatus = AFSQueryAttribTagInfo( Irp,
378                                                   pCcb->DirectoryCB,
379                                                   (FILE_ATTRIBUTE_TAG_INFORMATION *)pBuffer,
380                                                   &lLength);
381
382                 break;
383             }
384
385             case FileRemoteProtocolInformation:
386             {
387
388                     ntStatus = AFSQueryRemoteProtocolInfo( Irp,
389                                                            pCcb->DirectoryCB,
390                                                            (FILE_REMOTE_PROTOCOL_INFORMATION *)pBuffer,
391                                                            &lLength);
392
393                 break;
394             }
395
396             case FileNetworkPhysicalNameInformation:
397             {
398
399                 ntStatus = AFSQueryPhysicalNameInfo( Irp,
400                                                      pCcb->DirectoryCB,
401                                                      (FILE_NETWORK_PHYSICAL_NAME_INFORMATION *)pBuffer,
402                                                      &lLength);
403
404                 break;
405             }
406
407             default:
408             {
409                 ntStatus = STATUS_INVALID_PARAMETER;
410                 break;
411             }
412         }
413
414 try_exit:
415
416         Irp->IoStatus.Information = pIrpSp->Parameters.QueryFile.Length - lLength;
417
418         if( bReleaseMain)
419         {
420
421             AFSReleaseResource( &pFcb->NPFcb->Resource);
422         }
423
424         if( !NT_SUCCESS( ntStatus) &&
425             ntStatus != STATUS_INVALID_PARAMETER &&
426             ntStatus != STATUS_BUFFER_OVERFLOW)
427         {
428
429             if( pCcb != NULL &&
430                 pCcb->DirectoryCB != NULL)
431             {
432
433                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
434                               AFS_TRACE_LEVEL_ERROR,
435                               "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
436                               &pCcb->DirectoryCB->NameInformation.FileName,
437                               pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
438                               pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
439                               pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
440                               pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
441                               ntStatus);
442             }
443         }
444     }
445     __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
446     {
447
448         AFSDbgLogMsg( 0,
449                       0,
450                       "EXCEPTION - AFSQueryFileInfo\n");
451
452         AFSDumpTraceFilesFnc();
453
454         ntStatus = STATUS_UNSUCCESSFUL;
455
456         if( bReleaseMain)
457         {
458
459             AFSReleaseResource( &pFcb->NPFcb->Resource);
460         }
461     }
462
463     AFSCompleteRequest( Irp,
464                         ntStatus);
465
466     return ntStatus;
467 }
468
469 //
470 // Function: AFSSetFileInfo
471 //
472 // Description:
473 //
474 //      This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request
475 //
476 // Return:
477 //
478 //      A status is returned for the function
479 //
480
481 NTSTATUS
482 AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
483                 IN PIRP Irp)
484 {
485
486     NTSTATUS ntStatus = STATUS_SUCCESS;
487     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
488     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
489     AFSFcb *pFcb = NULL;
490     AFSCcb *pCcb = NULL;
491     BOOLEAN bCompleteRequest = TRUE;
492     FILE_INFORMATION_CLASS FileInformationClass;
493     BOOLEAN bCanQueueRequest = FALSE;
494     PFILE_OBJECT pFileObject = NULL;
495     BOOLEAN bReleaseMain = FALSE;
496     BOOLEAN bUpdateFileInfo = FALSE;
497     AFSFileID stParentFileId;
498
499     __try
500     {
501
502         pFileObject = pIrpSp->FileObject;
503
504         pFcb = (AFSFcb *)pFileObject->FsContext;
505         pCcb = (AFSCcb *)pFileObject->FsContext2;
506
507         if( pFcb == NULL)
508         {
509
510             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
511                           AFS_TRACE_LEVEL_ERROR,
512                           "AFSSetFileInfo Attempted access (%08lX) when pFcb == NULL\n",
513                           Irp);
514
515             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
516         }
517
518         bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
519         FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
520
521         //
522         // Grab the Fcb EXCL
523         //
524
525         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
526                       AFS_TRACE_LEVEL_VERBOSE,
527                       "AFSSetFileInfo Acquiring Fcb lock %08lX EXCL %08lX\n",
528                       &pFcb->NPFcb->Resource,
529                       PsGetCurrentThread());
530
531         AFSAcquireExcl( &pFcb->NPFcb->Resource,
532                         TRUE);
533
534         bReleaseMain = TRUE;
535
536         //
537         // Don't allow requests against IOCtl nodes
538         //
539
540         if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
541         {
542
543             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
544                           AFS_TRACE_LEVEL_ERROR,
545                           "AFSSetFileInfo Failing request against PIOCtl Fcb\n");
546
547             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
548         }
549         else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
550         {
551
552             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
553                           AFS_TRACE_LEVEL_VERBOSE,
554                           "AFSSetFileInfo Processing request against SpecialShare Fcb\n");
555
556             ntStatus = AFSProcessShareSetInfo( Irp,
557                                                pFcb,
558                                                pCcb);
559
560             try_return( ntStatus);
561         }
562
563         if( BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
564         {
565
566             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
567                           AFS_TRACE_LEVEL_ERROR,
568                           "AFSSetFileInfo Request failed due to read only volume\n",
569                           Irp);
570
571             try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
572         }
573
574         if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB &&
575             FileInformationClass != FileDispositionInformation)
576         {
577             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
578                           AFS_TRACE_LEVEL_VERBOSE,
579                           "AFSSetFileInfo request against Invalid Fcb\n");
580
581             try_return( ntStatus = STATUS_ACCESS_DENIED);
582         }
583
584         //
585         // Ensure rename operations are synchronous
586         //
587
588         if( FileInformationClass == FileRenameInformation)
589         {
590
591             bCanQueueRequest = FALSE;
592         }
593
594         //
595         // Store away the parent fid
596         //
597
598         RtlZeroMemory( &stParentFileId,
599                        sizeof( AFSFileID));
600
601         if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
602         {
603             stParentFileId = pFcb->ObjectInformation->ParentObjectInformation->FileId;
604         }
605
606         //
607         // Process the request
608         //
609
610         switch( FileInformationClass)
611         {
612
613             case FileBasicInformation:
614             {
615
616                 bUpdateFileInfo = TRUE;
617
618                 ntStatus = AFSSetBasicInfo( Irp,
619                                             pCcb->DirectoryCB);
620
621                 break;
622             }
623
624             case FileDispositionInformation:
625             {
626
627                 ntStatus = AFSSetDispositionInfo( Irp,
628                                                   pCcb->DirectoryCB);
629
630                 break;
631             }
632
633             case FileRenameInformation:
634             {
635
636                 ntStatus = AFSSetRenameInfo( Irp);
637
638                 break;
639             }
640
641             case FilePositionInformation:
642             {
643
644                 ntStatus = AFSSetPositionInfo( Irp,
645                                                pCcb->DirectoryCB);
646
647                 break;
648             }
649
650             case FileLinkInformation:
651             {
652
653                 ntStatus = STATUS_INVALID_DEVICE_REQUEST;
654
655                 break;
656             }
657
658             case FileAllocationInformation:
659             {
660
661                 ntStatus = AFSSetAllocationInfo( Irp,
662                                                  pCcb->DirectoryCB);
663
664                 break;
665             }
666
667             case FileEndOfFileInformation:
668             {
669
670                 ntStatus = AFSSetEndOfFileInfo( Irp,
671                                                 pCcb->DirectoryCB);
672
673                 break;
674             }
675
676             default:
677
678                 ntStatus = STATUS_INVALID_PARAMETER;
679
680                 break;
681         }
682
683 try_exit:
684
685         if( bReleaseMain)
686         {
687
688             AFSReleaseResource( &pFcb->NPFcb->Resource);
689         }
690
691         if( NT_SUCCESS( ntStatus) &&
692             bUpdateFileInfo)
693         {
694
695             ntStatus = AFSUpdateFileInformation( &stParentFileId,
696                                                  pFcb->ObjectInformation,
697                                                  &pCcb->AuthGroup);
698
699             if( !NT_SUCCESS( ntStatus))
700             {
701
702                 AFSAcquireExcl( &pFcb->NPFcb->Resource,
703                                 TRUE);
704
705                 //
706                 // Unwind the update and fail the request
707                 //
708
709                 AFSUnwindFileInfo( pFcb,
710                                    pCcb);
711
712                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
713                               AFS_TRACE_LEVEL_ERROR,
714                               "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
715                               &pCcb->DirectoryCB->NameInformation.FileName,
716                               pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
717                               pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
718                               pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
719                               pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
720                               ntStatus);
721
722                 AFSReleaseResource( &pFcb->NPFcb->Resource);
723             }
724         }
725
726         if( !NT_SUCCESS( ntStatus))
727         {
728
729             if( pCcb != NULL &&
730                 pCcb->DirectoryCB != NULL)
731             {
732
733                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
734                               AFS_TRACE_LEVEL_ERROR,
735                               "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
736                               &pCcb->DirectoryCB->NameInformation.FileName,
737                               pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
738                               pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
739                               pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
740                               pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
741                               ntStatus);
742             }
743         }
744     }
745     __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
746     {
747
748         AFSDbgLogMsg( 0,
749                       0,
750                       "EXCEPTION - AFSSetFileInfo\n");
751
752         AFSDumpTraceFilesFnc();
753
754         ntStatus = STATUS_UNSUCCESSFUL;
755
756         if( bReleaseMain)
757         {
758
759             AFSReleaseResource( &pFcb->NPFcb->Resource);
760         }
761     }
762
763     AFSCompleteRequest( Irp,
764                         ntStatus);
765
766     return ntStatus;
767 }
768
769 //
770 // Function: AFSQueryBasicInfo
771 //
772 // Description:
773 //
774 //      This function is the handler for the query basic information request
775 //
776 // Return:
777 //
778 //      A status is returned for the function
779 //
780
781 NTSTATUS
782 AFSQueryBasicInfo( IN PIRP Irp,
783                    IN AFSDirectoryCB *DirectoryCB,
784                    IN OUT PFILE_BASIC_INFORMATION Buffer,
785                    IN OUT PLONG Length)
786 {
787     NTSTATUS ntStatus = STATUS_SUCCESS;
788     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
789     ULONG ulFileAttribs = 0;
790     AFSFcb *pFcb = NULL;
791     AFSCcb *pCcb = NULL;
792     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
793     AFSFileInfoCB stFileInfo;
794     AFSDirectoryCB *pParentDirectoryCB = NULL;
795     UNICODE_STRING uniParentPath;
796
797     if( *Length >= sizeof( FILE_BASIC_INFORMATION))
798     {
799
800         RtlZeroMemory( Buffer,
801                        *Length);
802
803         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
804
805         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
806         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
807
808         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
809         {
810
811             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
812
813             AFSRetrieveParentPath( &pCcb->FullFileName,
814                                    &uniParentPath);
815
816             RtlZeroMemory( &stFileInfo,
817                            sizeof( AFSFileInfoCB));
818
819             //
820             // Can't hold the Fcb while evaluating the path, leads to lock inversion
821             //
822
823             AFSReleaseResource( &pFcb->NPFcb->Resource);
824
825             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
826                                                        DirectoryCB,
827                                                        &uniParentPath,
828                                                        pCcb->NameArray,
829                                                        &pCcb->AuthGroup,
830                                                        &stFileInfo)))
831             {
832                 ulFileAttribs = stFileInfo.FileAttributes;
833
834                 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
835             }
836
837             AFSAcquireShared( &pFcb->NPFcb->Resource,
838                               TRUE);
839         }
840
841
842         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
843                       AFS_TRACE_LEVEL_VERBOSE_2,
844                       "AFSQueryBasicInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
845                       &pCcb->DirectoryCB->NameInformation.FileName,
846                       pCcb->DirectoryCB->ObjectInformation->FileType,
847                       pCcb->DirectoryCB->ObjectInformation->FileAttributes,
848                       ulFileAttribs);
849
850         Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
851         Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
852         Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
853         Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
854         Buffer->FileAttributes = ulFileAttribs;
855
856         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
857             BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
858         {
859
860             if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
861             {
862                 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
863             }
864             else
865             {
866                 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
867             }
868         }
869
870         *Length -= sizeof( FILE_BASIC_INFORMATION);
871     }
872     else
873     {
874
875         ntStatus = STATUS_BUFFER_TOO_SMALL;
876     }
877
878     return ntStatus;
879 }
880
881 NTSTATUS
882 AFSQueryStandardInfo( IN PIRP Irp,
883                       IN AFSDirectoryCB *DirectoryCB,
884                       IN OUT PFILE_STANDARD_INFORMATION Buffer,
885                       IN OUT PLONG Length)
886 {
887
888     NTSTATUS ntStatus = STATUS_SUCCESS;
889     AFSFcb *pFcb = NULL;
890     AFSCcb *pCcb = NULL;
891     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
892     AFSFileInfoCB stFileInfo;
893     AFSDirectoryCB *pParentDirectoryCB = NULL;
894     UNICODE_STRING uniParentPath;
895     ULONG ulFileAttribs = 0;
896
897     if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
898     {
899
900         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
901         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
902
903         RtlZeroMemory( Buffer,
904                        *Length);
905
906         Buffer->NumberOfLinks = 1;
907         Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
908
909         Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
910
911         Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
912
913         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
914
915         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
916         {
917
918             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
919
920             AFSRetrieveParentPath( &pCcb->FullFileName,
921                                    &uniParentPath);
922
923             RtlZeroMemory( &stFileInfo,
924                            sizeof( AFSFileInfoCB));
925
926             //
927             // Can't hold the Fcb while evaluating the path, leads to lock inversion
928             //
929
930             AFSReleaseResource( &pFcb->NPFcb->Resource);
931
932             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
933                                                        DirectoryCB,
934                                                        &uniParentPath,
935                                                        pCcb->NameArray,
936                                                        &pCcb->AuthGroup,
937                                                        &stFileInfo)))
938             {
939                 ulFileAttribs = stFileInfo.FileAttributes;
940             }
941
942             AFSAcquireShared( &pFcb->NPFcb->Resource,
943                               TRUE);
944         }
945
946         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
947                       AFS_TRACE_LEVEL_VERBOSE_2,
948                       "AFSQueryStandardInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
949                       &pCcb->DirectoryCB->NameInformation.FileName,
950                       pCcb->DirectoryCB->ObjectInformation->FileType,
951                       pCcb->DirectoryCB->ObjectInformation->FileAttributes,
952                       ulFileAttribs);
953
954         Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
955
956         *Length -= sizeof( FILE_STANDARD_INFORMATION);
957     }
958     else
959     {
960
961         ntStatus = STATUS_BUFFER_TOO_SMALL;
962     }
963
964     return ntStatus;
965 }
966
967 NTSTATUS
968 AFSQueryInternalInfo( IN PIRP Irp,
969                       IN AFSFcb *Fcb,
970                       IN OUT PFILE_INTERNAL_INFORMATION Buffer,
971                       IN OUT PLONG Length)
972 {
973
974     NTSTATUS ntStatus = STATUS_SUCCESS;
975
976     if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
977     {
978
979         Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Volume;
980
981         Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Vnode;
982
983         *Length -= sizeof( FILE_INTERNAL_INFORMATION);
984     }
985     else
986     {
987
988         ntStatus = STATUS_BUFFER_TOO_SMALL;
989     }
990
991     return ntStatus;
992 }
993
994 NTSTATUS
995 AFSQueryEaInfo( IN PIRP Irp,
996                 IN AFSDirectoryCB *DirectoryCB,
997                 IN OUT PFILE_EA_INFORMATION Buffer,
998                 IN OUT PLONG Length)
999 {
1000
1001     NTSTATUS ntStatus = STATUS_SUCCESS;
1002
1003     RtlZeroMemory( Buffer,
1004                    *Length);
1005
1006     if( *Length >= sizeof( FILE_EA_INFORMATION))
1007     {
1008
1009         Buffer->EaSize = 0;
1010
1011         *Length -= sizeof( FILE_EA_INFORMATION);
1012     }
1013     else
1014     {
1015
1016         ntStatus = STATUS_BUFFER_TOO_SMALL;
1017     }
1018
1019     return ntStatus;
1020 }
1021
1022 NTSTATUS
1023 AFSQueryPositionInfo( IN PIRP Irp,
1024                       IN AFSFcb *Fcb,
1025                       IN OUT PFILE_POSITION_INFORMATION Buffer,
1026                       IN OUT PLONG Length)
1027 {
1028
1029     NTSTATUS ntStatus = STATUS_SUCCESS;
1030     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1031
1032     if( *Length >= sizeof( FILE_POSITION_INFORMATION))
1033     {
1034
1035         RtlZeroMemory( Buffer,
1036                        *Length);
1037
1038         Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
1039
1040         *Length -= sizeof( FILE_POSITION_INFORMATION);
1041     }
1042     else
1043     {
1044
1045         ntStatus = STATUS_BUFFER_TOO_SMALL;
1046     }
1047
1048     return ntStatus;
1049 }
1050
1051 NTSTATUS
1052 AFSQueryAccess( IN PIRP Irp,
1053                 IN AFSFcb *Fcb,
1054                 IN OUT PFILE_ACCESS_INFORMATION Buffer,
1055                 IN OUT PLONG Length)
1056 {
1057
1058     NTSTATUS ntStatus = STATUS_SUCCESS;
1059
1060     if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
1061     {
1062
1063         RtlZeroMemory( Buffer,
1064                        *Length);
1065
1066         Buffer->AccessFlags = 0;
1067
1068         *Length -= sizeof( FILE_ACCESS_INFORMATION);
1069     }
1070     else
1071     {
1072
1073         ntStatus = STATUS_BUFFER_TOO_SMALL;
1074     }
1075
1076     return ntStatus;
1077 }
1078
1079 NTSTATUS
1080 AFSQueryMode( IN PIRP Irp,
1081               IN AFSFcb *Fcb,
1082               IN OUT PFILE_MODE_INFORMATION Buffer,
1083               IN OUT PLONG Length)
1084 {
1085
1086     NTSTATUS ntStatus = STATUS_SUCCESS;
1087
1088     if( *Length >= sizeof( FILE_MODE_INFORMATION))
1089     {
1090
1091         RtlZeroMemory( Buffer,
1092                        *Length);
1093
1094         Buffer->Mode = 0;
1095
1096         *Length -= sizeof( FILE_MODE_INFORMATION);
1097     }
1098     else
1099     {
1100
1101         ntStatus = STATUS_BUFFER_TOO_SMALL;
1102     }
1103
1104     return ntStatus;
1105 }
1106
1107 NTSTATUS
1108 AFSQueryAlignment( IN PIRP Irp,
1109                    IN AFSFcb *Fcb,
1110                    IN OUT PFILE_ALIGNMENT_INFORMATION Buffer,
1111                    IN OUT PLONG Length)
1112 {
1113
1114     NTSTATUS ntStatus = STATUS_SUCCESS;
1115
1116     if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
1117     {
1118
1119         RtlZeroMemory( Buffer,
1120                        *Length);
1121
1122         Buffer->AlignmentRequirement = 1;
1123
1124         *Length -= sizeof( FILE_ALIGNMENT_INFORMATION);
1125     }
1126     else
1127     {
1128
1129         ntStatus = STATUS_BUFFER_TOO_SMALL;
1130     }
1131
1132     return ntStatus;
1133 }
1134
1135 NTSTATUS
1136 AFSQueryNameInfo( IN PIRP Irp,
1137                   IN AFSDirectoryCB *DirectoryCB,
1138                   IN OUT PFILE_NAME_INFORMATION Buffer,
1139                   IN OUT PLONG Length)
1140 {
1141
1142     NTSTATUS ntStatus = STATUS_SUCCESS;
1143     ULONG ulCopyLength = 0;
1144     ULONG cchCopied = 0;
1145     AFSFcb *pFcb = NULL;
1146     AFSCcb *pCcb = NULL;
1147     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1148     BOOLEAN bAddLeadingSlash = FALSE;
1149     BOOLEAN bAddTrailingSlash = FALSE;
1150     USHORT usFullNameLength = 0;
1151
1152     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1153
1154     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1155
1156     if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1157     {
1158
1159         RtlZeroMemory( Buffer,
1160                        *Length);
1161
1162         if( pCcb->FullFileName.Length == 0 ||
1163             pCcb->FullFileName.Buffer[ 0] != L'\\')
1164         {
1165             bAddLeadingSlash = TRUE;
1166         }
1167
1168         if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1169             pCcb->FullFileName.Length > 0 &&
1170             pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
1171         {
1172             bAddTrailingSlash = TRUE;
1173         }
1174
1175         usFullNameLength = sizeof( WCHAR) +
1176                                     AFSServerName.Length +
1177                                     pCcb->FullFileName.Length;
1178
1179         if( bAddLeadingSlash)
1180         {
1181             usFullNameLength += sizeof( WCHAR);
1182         }
1183
1184         if( bAddTrailingSlash)
1185         {
1186             usFullNameLength += sizeof( WCHAR);
1187         }
1188
1189         if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1190         {
1191
1192             ulCopyLength = (LONG)usFullNameLength;
1193         }
1194         else
1195         {
1196
1197             ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1198
1199             ntStatus = STATUS_BUFFER_OVERFLOW;
1200         }
1201
1202         Buffer->FileNameLength = (ULONG)usFullNameLength;
1203
1204         *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1205
1206         if( ulCopyLength > 0)
1207         {
1208
1209             Buffer->FileName[ 0] = L'\\';
1210             ulCopyLength -= sizeof( WCHAR);
1211
1212             *Length -= sizeof( WCHAR);
1213             cchCopied += 1;
1214
1215             if( ulCopyLength >= AFSServerName.Length)
1216             {
1217
1218                 RtlCopyMemory( &Buffer->FileName[ 1],
1219                                AFSServerName.Buffer,
1220                                AFSServerName.Length);
1221
1222                 ulCopyLength -= AFSServerName.Length;
1223                 *Length -= AFSServerName.Length;
1224                 cchCopied += AFSServerName.Length/sizeof( WCHAR);
1225
1226                 if ( ulCopyLength > 0 &&
1227                      bAddLeadingSlash)
1228                 {
1229
1230                     Buffer->FileName[ cchCopied] = L'\\';
1231
1232                     ulCopyLength -= sizeof( WCHAR);
1233                     *Length -= sizeof( WCHAR);
1234                     cchCopied++;
1235                 }
1236
1237                 if( ulCopyLength >= pCcb->FullFileName.Length)
1238                 {
1239
1240                     RtlCopyMemory( &Buffer->FileName[ cchCopied],
1241                                    pCcb->FullFileName.Buffer,
1242                                    pCcb->FullFileName.Length);
1243
1244                     ulCopyLength -= pCcb->FullFileName.Length;
1245                     *Length -= pCcb->FullFileName.Length;
1246                     cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1247
1248                     if( ulCopyLength > 0 &&
1249                         bAddTrailingSlash)
1250                     {
1251                         Buffer->FileName[ cchCopied] = L'\\';
1252
1253                         *Length -= sizeof( WCHAR);
1254                     }
1255                 }
1256                 else
1257                 {
1258
1259                     RtlCopyMemory( &Buffer->FileName[ cchCopied],
1260                                    pCcb->FullFileName.Buffer,
1261                                    ulCopyLength);
1262
1263                     *Length -= ulCopyLength;
1264                 }
1265             }
1266         }
1267     }
1268     else
1269     {
1270
1271         ntStatus = STATUS_BUFFER_TOO_SMALL;
1272     }
1273
1274     return ntStatus;
1275 }
1276
1277 NTSTATUS
1278 AFSQueryShortNameInfo( IN PIRP Irp,
1279                        IN AFSDirectoryCB *DirectoryCB,
1280                        IN OUT PFILE_NAME_INFORMATION Buffer,
1281                        IN OUT PLONG Length)
1282 {
1283
1284     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1285     ULONG ulCopyLength = 0;
1286
1287     RtlZeroMemory( Buffer,
1288                    *Length);
1289
1290     if( DirectoryCB->NameInformation.ShortNameLength == 0)
1291     {
1292
1293         //
1294         // The short name IS the long name
1295         //
1296
1297         if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1298         {
1299
1300             if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1301             {
1302
1303                 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1304
1305                 ntStatus = STATUS_SUCCESS;
1306             }
1307             else
1308             {
1309
1310                 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1311
1312                 ntStatus = STATUS_BUFFER_OVERFLOW;
1313             }
1314
1315             Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1316
1317             *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1318
1319             if( ulCopyLength > 0)
1320             {
1321
1322                 RtlCopyMemory( Buffer->FileName,
1323                                DirectoryCB->NameInformation.FileName.Buffer,
1324                                ulCopyLength);
1325
1326                 *Length -= ulCopyLength;
1327             }
1328         }
1329     }
1330     else
1331     {
1332
1333         if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1334         {
1335
1336             if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1337             {
1338
1339                 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1340
1341                 ntStatus = STATUS_SUCCESS;
1342             }
1343             else
1344             {
1345
1346                 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1347
1348                 ntStatus = STATUS_BUFFER_OVERFLOW;
1349             }
1350
1351             Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1352
1353             *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1354
1355             if( ulCopyLength > 0)
1356             {
1357
1358                 RtlCopyMemory( Buffer->FileName,
1359                                DirectoryCB->NameInformation.ShortName,
1360                                Buffer->FileNameLength);
1361
1362                 *Length -= ulCopyLength;
1363             }
1364         }
1365     }
1366
1367     return ntStatus;
1368 }
1369
1370 NTSTATUS
1371 AFSQueryNetworkInfo( IN PIRP Irp,
1372                      IN AFSDirectoryCB *DirectoryCB,
1373                      IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1374                      IN OUT PLONG Length)
1375 {
1376
1377     NTSTATUS ntStatus = STATUS_SUCCESS;
1378     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1379     AFSFcb *pFcb = NULL;
1380     AFSCcb *pCcb = NULL;
1381     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1382     AFSFileInfoCB stFileInfo;
1383     AFSDirectoryCB *pParentDirectoryCB = NULL;
1384     UNICODE_STRING uniParentPath;
1385     ULONG ulFileAttribs = 0;
1386
1387     RtlZeroMemory( Buffer,
1388                    *Length);
1389
1390     if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
1391     {
1392
1393         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1394
1395         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1396         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1397
1398         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1399         {
1400
1401             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1402
1403             AFSRetrieveParentPath( &pCcb->FullFileName,
1404                                    &uniParentPath);
1405
1406             RtlZeroMemory( &stFileInfo,
1407                            sizeof( AFSFileInfoCB));
1408
1409             //
1410             // Can't hold the Fcb while evaluating the path, leads to lock inversion
1411             //
1412
1413             AFSReleaseResource( &pFcb->NPFcb->Resource);
1414
1415             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1416                                                        DirectoryCB,
1417                                                        &uniParentPath,
1418                                                        pCcb->NameArray,
1419                                                        &pCcb->AuthGroup,
1420                                                        &stFileInfo)))
1421             {
1422                 ulFileAttribs = stFileInfo.FileAttributes;
1423
1424                 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1425             }
1426
1427             AFSAcquireShared( &pFcb->NPFcb->Resource,
1428                               TRUE);
1429         }
1430
1431         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1432                       AFS_TRACE_LEVEL_VERBOSE_2,
1433                       "AFSQueryNetworkInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1434                       &pCcb->DirectoryCB->NameInformation.FileName,
1435                       pCcb->DirectoryCB->ObjectInformation->FileType,
1436                       pCcb->DirectoryCB->ObjectInformation->FileAttributes,
1437                       ulFileAttribs);
1438
1439         Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1440         Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1441         Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1442         Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1443
1444         Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1445         Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1446
1447         Buffer->FileAttributes = ulFileAttribs;
1448
1449         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1450             BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1451         {
1452
1453             if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1454             {
1455
1456                 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1457             }
1458             else
1459             {
1460
1461                 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1462             }
1463         }
1464
1465         *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1466     }
1467     else
1468     {
1469
1470         ntStatus = STATUS_BUFFER_TOO_SMALL;
1471     }
1472
1473     return ntStatus;
1474 }
1475
1476 NTSTATUS
1477 AFSQueryStreamInfo( IN PIRP Irp,
1478                     IN AFSDirectoryCB *DirectoryCB,
1479                     IN OUT FILE_STREAM_INFORMATION *Buffer,
1480                     IN OUT PLONG Length)
1481 {
1482
1483     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1484     ULONG ulCopyLength = 0;
1485     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1486
1487     if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1488     {
1489
1490         RtlZeroMemory( Buffer,
1491                        *Length);
1492
1493         Buffer->NextEntryOffset = 0;
1494
1495
1496         if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1497         {
1498
1499             if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14))  // ::$DATA
1500             {
1501
1502                 ulCopyLength = 14;
1503
1504                 ntStatus = STATUS_SUCCESS;
1505             }
1506             else
1507             {
1508
1509                 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1510
1511                 ntStatus = STATUS_BUFFER_OVERFLOW;
1512             }
1513
1514             Buffer->StreamNameLength = 14; // ::$DATA
1515
1516             Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1517
1518             Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1519
1520             *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1521
1522             if( ulCopyLength > 0)
1523             {
1524
1525                 RtlCopyMemory( Buffer->StreamName,
1526                                L"::$DATA",
1527                                ulCopyLength);
1528
1529                 *Length -= ulCopyLength;
1530             }
1531         }
1532         else
1533         {
1534
1535             Buffer->StreamNameLength = 0;       // No stream for a directory
1536
1537             // The response size is zero
1538
1539             ntStatus = STATUS_SUCCESS;
1540         }
1541     }
1542
1543     return ntStatus;
1544 }
1545
1546 NTSTATUS
1547 AFSQueryAttribTagInfo( IN PIRP Irp,
1548                        IN AFSDirectoryCB *DirectoryCB,
1549                        IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1550                        IN OUT PLONG Length)
1551 {
1552
1553     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1554     ULONG ulCopyLength = 0;
1555     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1556     AFSFcb *pFcb = NULL;
1557     AFSCcb *pCcb = NULL;
1558     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1559     AFSFileInfoCB stFileInfo;
1560     AFSDirectoryCB *pParentDirectoryCB = NULL;
1561     UNICODE_STRING uniParentPath;
1562     ULONG ulFileAttribs = 0;
1563
1564     if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1565     {
1566
1567         RtlZeroMemory( Buffer,
1568                        *Length);
1569
1570         ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1571
1572         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1573         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1574
1575         if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1576         {
1577
1578             pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1579
1580             AFSRetrieveParentPath( &pCcb->FullFileName,
1581                                    &uniParentPath);
1582
1583             RtlZeroMemory( &stFileInfo,
1584                            sizeof( AFSFileInfoCB));
1585
1586             //
1587             // Can't hold the Fcb while evaluating the path, leads to lock inversion
1588             //
1589
1590             AFSReleaseResource( &pFcb->NPFcb->Resource);
1591
1592             if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1593                                                        DirectoryCB,
1594                                                        &uniParentPath,
1595                                                        pCcb->NameArray,
1596                                                        &pCcb->AuthGroup,
1597                                                        &stFileInfo)))
1598             {
1599                 ulFileAttribs = stFileInfo.FileAttributes;
1600
1601                 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1602             }
1603
1604             AFSAcquireShared( &pFcb->NPFcb->Resource,
1605                               TRUE);
1606         }
1607
1608         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1609                       AFS_TRACE_LEVEL_VERBOSE_2,
1610                       "AFSAttribTagInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1611                       &pCcb->DirectoryCB->NameInformation.FileName,
1612                       pCcb->DirectoryCB->ObjectInformation->FileType,
1613                       pCcb->DirectoryCB->ObjectInformation->FileAttributes,
1614                       ulFileAttribs);
1615
1616         Buffer->FileAttributes = ulFileAttribs;
1617
1618         if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1619             BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1620         {
1621
1622             if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1623             {
1624
1625                 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1626             }
1627             else
1628             {
1629
1630                 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1631             }
1632         }
1633
1634         if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1635         {
1636             Buffer->ReparseTag = IO_REPARSE_TAG_SURROGATE|IO_REPARSE_TAG_OPENAFS_DFS;
1637         }
1638
1639         *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1640
1641         ntStatus = STATUS_SUCCESS;
1642     }
1643
1644     return ntStatus;
1645 }
1646
1647 NTSTATUS
1648 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1649                             IN AFSDirectoryCB *DirectoryCB,
1650                             IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1651                             IN OUT PLONG Length)
1652 {
1653
1654     NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1655     ULONG ulCopyLength = 0;
1656     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1657
1658     if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1659     {
1660
1661         RtlZeroMemory( Buffer,
1662                        *Length);
1663
1664         Buffer->StructureVersion = 1;
1665
1666         Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1667
1668         Buffer->Protocol = WNNC_NET_OPENAFS;
1669
1670         Buffer->ProtocolMajorVersion = 3;
1671
1672         Buffer->ProtocolMinorVersion = 0;
1673
1674         Buffer->ProtocolRevision = 0;
1675
1676         *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1677
1678         ntStatus = STATUS_SUCCESS;
1679     }
1680
1681     return ntStatus;
1682 }
1683
1684 NTSTATUS
1685 AFSQueryPhysicalNameInfo( IN PIRP Irp,
1686                           IN AFSDirectoryCB *DirectoryCB,
1687                           IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
1688                           IN OUT PLONG Length)
1689 {
1690
1691     NTSTATUS ntStatus = STATUS_SUCCESS;
1692     ULONG ulCopyLength = 0;
1693     ULONG cchCopied = 0;
1694     AFSFcb *pFcb = NULL;
1695     AFSCcb *pCcb = NULL;
1696     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1697     BOOLEAN bAddLeadingSlash = FALSE;
1698     USHORT usFullNameLength = 0;
1699
1700     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1701
1702     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1703
1704     if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
1705     {
1706
1707         RtlZeroMemory( Buffer,
1708                        *Length);
1709
1710         if( pCcb->FullFileName.Length == 0 ||
1711             pCcb->FullFileName.Buffer[ 0] != L'\\')
1712         {
1713             bAddLeadingSlash = TRUE;
1714         }
1715
1716         usFullNameLength = pCcb->FullFileName.Length;
1717
1718         if( bAddLeadingSlash)
1719         {
1720             usFullNameLength += sizeof( WCHAR);
1721         }
1722
1723         if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1724         {
1725             ulCopyLength = (LONG)usFullNameLength;
1726         }
1727         else
1728         {
1729
1730             ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1731
1732             ntStatus = STATUS_BUFFER_OVERFLOW;
1733         }
1734
1735         Buffer->FileNameLength = (ULONG)usFullNameLength;
1736
1737         *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1738
1739         if( ulCopyLength > 0)
1740         {
1741
1742             if( bAddLeadingSlash)
1743             {
1744
1745                 Buffer->FileName[ cchCopied] = L'\\';
1746
1747                 ulCopyLength -= sizeof( WCHAR);
1748                 *Length -= sizeof( WCHAR);
1749                 cchCopied++;
1750             }
1751
1752             if( ulCopyLength >= pCcb->FullFileName.Length)
1753             {
1754
1755                 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1756                                pCcb->FullFileName.Buffer,
1757                                pCcb->FullFileName.Length);
1758
1759                 ulCopyLength -= pCcb->FullFileName.Length;
1760                 *Length -= pCcb->FullFileName.Length;
1761                 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1762             }
1763             else
1764             {
1765
1766                 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1767                                pCcb->FullFileName.Buffer,
1768                                ulCopyLength);
1769
1770                 *Length -= ulCopyLength;
1771             }
1772         }
1773     }
1774     else
1775     {
1776
1777         ntStatus = STATUS_BUFFER_TOO_SMALL;
1778     }
1779
1780     return ntStatus;
1781 }
1782
1783 NTSTATUS
1784 AFSSetBasicInfo( IN PIRP Irp,
1785                  IN AFSDirectoryCB *DirectoryCB)
1786 {
1787     NTSTATUS ntStatus = STATUS_SUCCESS;
1788     PFILE_BASIC_INFORMATION pBuffer;
1789     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1790     ULONG ulNotifyFilter = 0;
1791     AFSCcb *pCcb = NULL;
1792
1793     __Enter
1794     {
1795
1796         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1797
1798         pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1799
1800         pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1801
1802         if( pBuffer->FileAttributes != (ULONGLONG)0)
1803         {
1804
1805             if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
1806                 BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1807             {
1808
1809                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1810             }
1811
1812             if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1813             {
1814
1815                 pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1816             }
1817
1818             pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1819
1820             DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
1821
1822             ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1823
1824             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1825         }
1826
1827         pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
1828
1829         if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
1830             pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
1831         {
1832
1833             pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1834
1835             DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
1836
1837             ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
1838
1839             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
1840         }
1841
1842         pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
1843
1844         if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
1845             pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
1846         {
1847
1848             pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1849
1850             DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
1851
1852             ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1853
1854             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
1855         }
1856
1857         pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
1858
1859         if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
1860             pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
1861         {
1862
1863             pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1864
1865             DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
1866
1867             ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
1868
1869             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
1870         }
1871
1872         pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
1873
1874         if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
1875             pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
1876         {
1877
1878             pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1879
1880             DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
1881
1882             ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1883
1884             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
1885         }
1886
1887         if( ulNotifyFilter > 0)
1888         {
1889
1890             if( DirectoryCB->ObjectInformation->ParentObjectInformation != NULL)
1891             {
1892
1893                 AFSFsRtlNotifyFullReportChange( DirectoryCB->ObjectInformation->ParentObjectInformation,
1894                                                 pCcb,
1895                                                 (ULONG)ulNotifyFilter,
1896                                                 (ULONG)FILE_ACTION_MODIFIED);
1897             }
1898         }
1899
1900 try_exit:
1901
1902         NOTHING;
1903     }
1904
1905     return ntStatus;
1906 }
1907
1908 NTSTATUS
1909 AFSSetDispositionInfo( IN PIRP Irp,
1910                        IN AFSDirectoryCB *DirectoryCB)
1911 {
1912     NTSTATUS ntStatus = STATUS_SUCCESS;
1913     PFILE_DISPOSITION_INFORMATION pBuffer;
1914     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1915     AFSFcb *pFcb = NULL;
1916     AFSCcb *pCcb = NULL;
1917
1918     __Enter
1919     {
1920
1921         pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1922
1923         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1924
1925         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1926
1927         //
1928         // Can't delete the root
1929         //
1930
1931         if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
1932         {
1933
1934             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1935                           AFS_TRACE_LEVEL_ERROR,
1936                           "AFSSetDispositionInfo Attempt to delete root entry\n");
1937
1938             try_return( ntStatus = STATUS_CANNOT_DELETE);
1939         }
1940
1941         //
1942         // If the file is read only then do not allow the delete
1943         //
1944
1945         if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
1946         {
1947
1948             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1949                           AFS_TRACE_LEVEL_ERROR,
1950                           "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
1951                           &DirectoryCB->NameInformation.FileName);
1952
1953             try_return( ntStatus = STATUS_CANNOT_DELETE);
1954         }
1955
1956         if( pBuffer->DeleteFile)
1957         {
1958
1959             //
1960             // Check if the caller can delete the file
1961             //
1962
1963             ntStatus = AFSNotifyDelete( DirectoryCB,
1964                                         &pCcb->AuthGroup,
1965                                         TRUE);
1966
1967             if( !NT_SUCCESS( ntStatus))
1968             {
1969
1970                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1971                               AFS_TRACE_LEVEL_ERROR,
1972                               "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
1973                               &DirectoryCB->NameInformation.FileName,
1974                               ntStatus);
1975
1976                 try_return( ntStatus);
1977             }
1978
1979             if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1980             {
1981
1982                 //
1983                 // Check if this is a directory that there are not currently other opens
1984                 //
1985
1986                 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
1987                 {
1988
1989                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1990                                   AFS_TRACE_LEVEL_ERROR,
1991                                   "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
1992                                   &DirectoryCB->NameInformation.FileName,
1993                                   pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount);
1994
1995                     try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
1996                 }
1997
1998                 if( !AFSIsDirectoryEmptyForDelete( pFcb))
1999                 {
2000
2001                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2002                                   AFS_TRACE_LEVEL_ERROR,
2003                                   "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
2004                                   &DirectoryCB->NameInformation.FileName);
2005
2006                     try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2007                 }
2008
2009                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2010                               AFS_TRACE_LEVEL_VERBOSE,
2011                               "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry  %p Name %wZ\n",
2012                               DirectoryCB,
2013                               &DirectoryCB->NameInformation.FileName);
2014
2015                 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2016             }
2017             else if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2018             {
2019
2020                 //
2021                 // Attempt to flush any outstanding data
2022                 //
2023
2024                 if( !MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
2025                                           MmFlushForDelete))
2026                 {
2027
2028                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2029                                   AFS_TRACE_LEVEL_ERROR,
2030                                   "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
2031                                   &DirectoryCB->NameInformation.FileName);
2032
2033                     try_return( ntStatus = STATUS_CANNOT_DELETE);
2034                 }
2035
2036                 //
2037                 // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
2038                 // deadlock with Trend Micro's Enterprise anti-virus product
2039                 // which attempts to open the file which is being deleted.
2040                 //
2041
2042                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2043                               AFS_TRACE_LEVEL_VERBOSE,
2044                               "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2045                               DirectoryCB,
2046                               &DirectoryCB->NameInformation.FileName);
2047
2048                 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2049
2050                 //
2051                 // Purge the cache as well
2052                 //
2053
2054                 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2055                 {
2056
2057                     if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
2058                                                NULL,
2059                                                0,
2060                                                TRUE))
2061                     {
2062
2063                         SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2064                     }
2065                 }
2066             }
2067         }
2068         else
2069         {
2070
2071             ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2072         }
2073
2074         //
2075         // OK, should be good to go, set the flag in the file object
2076         //
2077
2078         pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2079
2080 try_exit:
2081
2082         NOTHING;
2083     }
2084
2085     return ntStatus;
2086 }
2087
2088 NTSTATUS
2089 AFSSetRenameInfo( IN PIRP Irp)
2090 {
2091
2092     NTSTATUS ntStatus = STATUS_SUCCESS;
2093     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2094     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2095     IO_STATUS_BLOCK stIoSb = {0,0};
2096     AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2097     AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2098     PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2099     PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2100     PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2101     UNICODE_STRING uniTargetName, uniSourceName;
2102     BOOLEAN bReplaceIfExists = FALSE;
2103     UNICODE_STRING uniShortName;
2104     AFSDirectoryCB *pTargetDirEntry = NULL;
2105     ULONG ulTargetCRC = 0;
2106     BOOLEAN bTargetEntryExists = FALSE;
2107     AFSObjectInfoCB *pSrcObject = NULL, *pTargetObject = NULL;
2108     AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2109     AFSFileID stNewFid, stTmpTargetFid;
2110     ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2111     UNICODE_STRING uniFullTargetPath;
2112     BOOLEAN bCommonParent = FALSE;
2113     BOOLEAN bReleaseTargetDirLock = FALSE;
2114     BOOLEAN bReleaseSourceDirLock = FALSE;
2115     PERESOURCE  pSourceDirLock = NULL;
2116     LONG lCount;
2117
2118     __Enter
2119     {
2120
2121         bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2122
2123         pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2124         pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2125
2126         pSrcObject = pSrcFcb->ObjectInformation;
2127         pSrcParentObject = pSrcFcb->ObjectInformation->ParentObjectInformation;
2128
2129         //
2130         // Perform some basic checks to ensure FS integrity
2131         //
2132
2133         if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2134         {
2135
2136             //
2137             // Can't rename the root directory
2138             //
2139
2140             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2141                           AFS_TRACE_LEVEL_ERROR,
2142                           "AFSSetRenameInfo Attempt to rename root entry\n");
2143
2144             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2145         }
2146
2147         if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2148         {
2149
2150             //
2151             // If there are any open children then fail the rename
2152             //
2153
2154             if( pSrcFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2155             {
2156
2157                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2158                               AFS_TRACE_LEVEL_ERROR,
2159                               "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2160                               &pSrcCcb->DirectoryCB->NameInformation.FileName);
2161
2162                 try_return( ntStatus = STATUS_ACCESS_DENIED);
2163             }
2164         }
2165
2166         //
2167         // Extract off the final component name from the Fcb
2168         //
2169
2170         uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2171         uniSourceName.MaximumLength = uniSourceName.Length;
2172
2173         uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2174
2175         //
2176         // Resolve the target fileobject
2177         //
2178
2179         if( pTargetFileObj == NULL)
2180         {
2181
2182             //
2183             // This is a simple rename. Here the target directory is the same as the source parent directory
2184             // and the name is retrieved from the system buffer information
2185             //
2186
2187             pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2188
2189             pTargetParentObject = pSrcParentObject;
2190
2191             pTargetDcb = pTargetParentObject->Fcb;
2192
2193             uniTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2194             uniTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2195         }
2196         else
2197         {
2198
2199             //
2200             // So here we have the target directory taken from the targetfile object
2201             //
2202
2203             pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2204
2205             pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2206
2207             pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2208
2209             //
2210             // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2211             // it is only the target component of the rename operation
2212             //
2213
2214             uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2215         }
2216
2217         //
2218         // The quick check to see if they are not really performing a rename
2219         // Do the names match? Only do this where the parent directories are
2220         // the same
2221         //
2222
2223         if( pTargetParentObject == pSrcParentObject)
2224         {
2225
2226             if( FsRtlAreNamesEqual( &uniTargetName,
2227                                     &uniSourceName,
2228                                     FALSE,
2229                                     NULL))
2230             {
2231                 try_return( ntStatus = STATUS_SUCCESS);
2232             }
2233
2234             bCommonParent = TRUE;
2235         }
2236         else
2237         {
2238
2239             bCommonParent = FALSE;
2240         }
2241
2242         //
2243         // We do not allow cross-volume renames to occur
2244         //
2245
2246         if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2247         {
2248
2249             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2250                           AFS_TRACE_LEVEL_ERROR,
2251                           "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2252                           &pSrcCcb->DirectoryCB->NameInformation.FileName);
2253
2254             try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2255         }
2256
2257         ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2258                                       FALSE);
2259
2260         AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2261                         TRUE);
2262
2263         bReleaseTargetDirLock = TRUE;
2264
2265         if( pTargetParentObject != pSrcParentObject)
2266         {
2267             AFSAcquireExcl( pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2268                             TRUE);
2269
2270             bReleaseSourceDirLock = TRUE;
2271
2272             pSourceDirLock = pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock;
2273         }
2274
2275         AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2276                                         ulTargetCRC,
2277                                         &pTargetDirEntry);
2278
2279         if( pTargetDirEntry == NULL)
2280         {
2281
2282             //
2283             // Missed so perform a case insensitive lookup
2284             //
2285
2286             ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2287                                           TRUE);
2288
2289             AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2290                                               ulTargetCRC,
2291                                               &pTargetDirEntry);
2292         }
2293
2294         if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2295              pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2296                                                                NULL,
2297                                                                NULL))
2298         {
2299             //
2300             // Try the short name
2301             //
2302             AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2303                                         ulTargetCRC,
2304                                         &pTargetDirEntry);
2305         }
2306
2307         //
2308         // Increment our ref count on the dir entry
2309         //
2310
2311         if( pTargetDirEntry != NULL)
2312         {
2313
2314             ASSERT( pTargetParentObject == pTargetDirEntry->ObjectInformation->ParentObjectInformation);
2315
2316             lCount = InterlockedIncrement( &pTargetDirEntry->OpenReferenceCount);
2317
2318             if( !bReplaceIfExists)
2319             {
2320
2321                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2322                               AFS_TRACE_LEVEL_ERROR,
2323                               "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
2324                               &pSrcCcb->DirectoryCB->NameInformation.FileName,
2325                               &pTargetDirEntry->NameInformation.FileName);
2326
2327                 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2328             }
2329
2330             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2331                           AFS_TRACE_LEVEL_ERROR,
2332                           "AFSSetRenameInfo Target %wZ exists DE %p Count %08lX, performing delete of target\n",
2333                           &pTargetDirEntry->NameInformation.FileName,
2334                           pTargetDirEntry,
2335                           pTargetDirEntry->OpenReferenceCount);
2336
2337             //
2338             // Pull the directory entry from the parent
2339             //
2340
2341             AFSRemoveDirNodeFromParent( pTargetParentObject,
2342                                         pTargetDirEntry,
2343                                         FALSE);
2344
2345             bTargetEntryExists = TRUE;
2346         }
2347         else
2348         {
2349             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2350                           AFS_TRACE_LEVEL_VERBOSE,
2351                           "AFSSetRenameInfo Target does NOT exist, normal rename\n");
2352         }
2353
2354         //
2355         // We need to remove the DirEntry from the parent node, update the index
2356         // and reinsert it into the parent tree. Note that for entries with the
2357         // same parent we do not pull the node from the enumeration list
2358         //
2359
2360         AFSRemoveDirNodeFromParent( pSrcFcb->ObjectInformation->ParentObjectInformation,
2361                                     pSrcCcb->DirectoryCB,
2362                                     !bCommonParent);
2363
2364         //
2365         // OK, this is a simple rename. Issue the rename
2366         // request to the service.
2367         //
2368
2369         ntStatus = AFSNotifyRename( pSrcFcb->ObjectInformation,
2370                                     &pSrcCcb->AuthGroup,
2371                                     pSrcFcb->ObjectInformation->ParentObjectInformation,
2372                                     pTargetDcb->ObjectInformation,
2373                                     pSrcCcb->DirectoryCB,
2374                                     &uniTargetName,
2375                                     &stNewFid);
2376
2377         if( !NT_SUCCESS( ntStatus))
2378         {
2379
2380             //
2381             // Attempt to re-insert the directory entry
2382             //
2383
2384             AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2385                                     pSrcCcb->DirectoryCB,
2386                                     !bCommonParent);
2387
2388             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2389                           AFS_TRACE_LEVEL_ERROR,
2390                           "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
2391                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
2392                           &uniTargetName,
2393                           ntStatus);
2394
2395             try_return( ntStatus);
2396         }
2397
2398         //
2399         // Set the notification up for the source file
2400         //
2401
2402         if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation == pTargetParentObject &&
2403             !bTargetEntryExists)
2404         {
2405
2406             ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
2407         }
2408         else
2409         {
2410
2411             ulNotificationAction = FILE_ACTION_REMOVED;
2412         }
2413
2414         if( pSrcCcb->DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
2415         {
2416
2417             ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2418         }
2419         else
2420         {
2421
2422             ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2423         }
2424
2425         AFSFsRtlNotifyFullReportChange( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation,
2426                                         pSrcCcb,
2427                                         (ULONG)ulNotifyFilter,
2428                                         (ULONG)ulNotificationAction);
2429
2430         //
2431         // Update the name in the dir entry.
2432         //
2433
2434         ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
2435                                           &uniTargetName);
2436
2437         if( !NT_SUCCESS( ntStatus))
2438         {
2439
2440             //
2441             // Attempt to re-insert the directory entry
2442             //
2443
2444             AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2445                                     pSrcCcb->DirectoryCB,
2446                                     !bCommonParent);
2447
2448             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2449                           AFS_TRACE_LEVEL_ERROR,
2450                           "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
2451                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
2452                           &uniTargetName,
2453                           ntStatus);
2454
2455             try_return( ntStatus);
2456         }
2457
2458         //
2459         // Update the object information block, if needed
2460         //
2461
2462         if( !AFSIsEqualFID( &pSrcObject->FileId,
2463                             &stNewFid))
2464         {
2465
2466             AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
2467                             TRUE);
2468
2469             //
2470             // Remove the old information entry
2471             //
2472
2473             AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2474                                 &pSrcObject->TreeEntry);
2475
2476             RtlCopyMemory( &pSrcObject->FileId,
2477                            &stNewFid,
2478                            sizeof( AFSFileID));
2479
2480             //
2481             // Insert the entry into the new object table.
2482             //
2483
2484             pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
2485
2486             if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
2487             {
2488
2489                 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
2490             }
2491             else
2492             {
2493
2494                 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2495                                                      &pSrcObject->TreeEntry)))
2496                 {
2497
2498                     //
2499                     // Lost a race, an ObjectInfo object already exists for this FID.
2500                     // Let this copy be garbage collected.
2501                     //
2502
2503                     ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
2504                 }
2505             }
2506
2507             AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
2508         }
2509
2510         //
2511         // Update the hash values for the name trees.
2512         //
2513
2514         pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2515                                                                                  FALSE);
2516
2517         pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2518                                                                                    TRUE);
2519
2520         if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2521             pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
2522             !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2523                                      NULL,
2524                                      NULL))
2525         {
2526
2527             uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
2528             uniShortName.MaximumLength = uniShortName.Length;
2529             uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
2530
2531             pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
2532                                                                                            TRUE);
2533
2534             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2535                           AFS_TRACE_LEVEL_VERBOSE,
2536                           "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
2537                           &uniShortName,
2538                           &pSrcCcb->DirectoryCB->NameInformation.FileName);
2539         }
2540         else
2541         {
2542
2543             pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
2544         }
2545
2546         if( !bCommonParent)
2547         {
2548
2549             //
2550             // Update the file index for the object in the new parent
2551             //
2552
2553             pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
2554         }
2555
2556         //
2557         // Re-insert the directory entry
2558         //
2559
2560         AFSInsertDirectoryNode( pTargetParentObject,
2561                                 pSrcCcb->DirectoryCB,
2562                                 !bCommonParent);
2563
2564         //
2565         // Update the parent pointer in the source object if they are different
2566         //
2567
2568         if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation != pTargetParentObject)
2569         {
2570
2571             lCount = InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2572
2573             lCount = InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2574
2575             lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
2576
2577             lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
2578
2579             pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation = pTargetParentObject;
2580
2581             ulNotificationAction = FILE_ACTION_ADDED;
2582         }
2583         else
2584         {
2585
2586             ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
2587         }
2588
2589         //
2590         // Now update the notification for the target file
2591         //
2592
2593         AFSFsRtlNotifyFullReportChange( pTargetParentObject->ParentObjectInformation,
2594                                         pSrcCcb,
2595                                         (ULONG)ulNotifyFilter,
2596                                         (ULONG)ulNotificationAction);
2597
2598         //
2599         // If we performed the rename of the target because it existed, we now need to
2600         // delete the tmp target we created above
2601         //
2602
2603         if( bTargetEntryExists)
2604         {
2605
2606             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2607                           AFS_TRACE_LEVEL_VERBOSE,
2608                           "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
2609                           pTargetDirEntry,
2610                           &pTargetDirEntry->NameInformation.FileName);
2611
2612             SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2613
2614             //
2615             // Try and purge the cache map if this is a file
2616             //
2617
2618             if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
2619                 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
2620                 pTargetDirEntry->OpenReferenceCount > 1)
2621             {
2622
2623                 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
2624
2625                 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
2626                                 TRUE);
2627
2628                 //
2629                 // Close the section in the event it was mapped
2630                 //
2631
2632                 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
2633                                            TRUE))
2634                 {
2635
2636                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2637                                   AFS_TRACE_LEVEL_ERROR,
2638                                   "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
2639                                   &pTargetDirEntry->NameInformation.FileName);
2640                 }
2641
2642                 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
2643             }
2644
2645             ASSERT( pTargetDirEntry->OpenReferenceCount > 0);
2646
2647             lCount = InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount); // The count we added above
2648
2649             if( lCount == 0)
2650             {
2651
2652                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2653                               AFS_TRACE_LEVEL_VERBOSE,
2654                               "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
2655                               pTargetDirEntry,
2656                               &pTargetDirEntry->NameInformation.FileName);
2657
2658                 AFSDeleteDirEntry( pTargetParentObject,
2659                                    pTargetDirEntry);
2660             }
2661
2662             pTargetDirEntry = NULL;
2663         }
2664
2665 try_exit:
2666
2667
2668         if( !NT_SUCCESS( ntStatus))
2669         {
2670
2671             if( bTargetEntryExists)
2672             {
2673                 AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
2674                                         pTargetDirEntry,
2675                                         FALSE);
2676             }
2677         }
2678
2679         if( pTargetDirEntry != NULL)
2680         {
2681
2682             lCount = InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
2683         }
2684
2685         if( bReleaseTargetDirLock)
2686         {
2687             AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2688         }
2689
2690         if( bReleaseSourceDirLock)
2691         {
2692             AFSReleaseResource( pSourceDirLock);
2693         }
2694     }
2695
2696     return ntStatus;
2697 }
2698
2699 NTSTATUS
2700 AFSSetPositionInfo( IN PIRP Irp,
2701                     IN AFSDirectoryCB *DirectoryCB)
2702 {
2703     NTSTATUS ntStatus = STATUS_SUCCESS;
2704     PFILE_POSITION_INFORMATION pBuffer;
2705     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2706
2707     pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2708
2709     pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
2710
2711     return ntStatus;
2712 }
2713
2714 NTSTATUS
2715 AFSSetAllocationInfo( IN PIRP Irp,
2716                       IN AFSDirectoryCB *DirectoryCB)
2717 {
2718     NTSTATUS ntStatus = STATUS_SUCCESS;
2719     PFILE_ALLOCATION_INFORMATION pBuffer;
2720     BOOLEAN bReleasePaging = FALSE;
2721     BOOLEAN bTellCc = FALSE;
2722     BOOLEAN bTellService = FALSE;
2723     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2724     PFILE_OBJECT pFileObject = pIrpSp->FileObject;
2725     AFSFcb *pFcb = NULL;
2726     AFSCcb *pCcb = NULL;
2727     LARGE_INTEGER liSaveAlloc;
2728     LARGE_INTEGER liSaveFileSize;
2729     LARGE_INTEGER liSaveVDL;
2730
2731     pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2732
2733     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2734
2735     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2736
2737     //
2738     // save values to put back
2739     //
2740     liSaveAlloc = pFcb->Header.AllocationSize;
2741     liSaveFileSize = pFcb->Header.FileSize;
2742     liSaveVDL = pFcb->Header.ValidDataLength;
2743
2744     if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
2745         pIrpSp->Parameters.SetFile.AdvanceOnly)
2746     {
2747         return STATUS_SUCCESS ;
2748     }
2749
2750     if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
2751     {
2752         //
2753         // Truncating the file
2754         //
2755         if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
2756                                    &pBuffer->AllocationSize))
2757         {
2758
2759             ntStatus = STATUS_USER_MAPPED_FILE ;
2760         }
2761         else
2762         {
2763             //
2764             // If this is a truncation we need to grab the paging IO resource.
2765             //
2766
2767             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2768                           AFS_TRACE_LEVEL_VERBOSE,
2769                           "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2770                           &pFcb->NPFcb->PagingResource,
2771                           PsGetCurrentThread());
2772
2773             AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2774                             TRUE);
2775
2776             bReleasePaging = TRUE;
2777
2778             //
2779             // Must drop the Fcb Resource.  When changing the file size
2780             // a deadlock can occur with Trend Micro's filter if the file
2781             // size is set to zero.
2782             //
2783
2784             AFSReleaseResource( &pFcb->NPFcb->Resource);
2785
2786             pFcb->Header.AllocationSize = pBuffer->AllocationSize;
2787
2788             pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
2789
2790             //
2791             // Tell Cc that Allocation is moved.
2792             //
2793             bTellCc = TRUE;
2794
2795             if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
2796             {
2797                 //
2798                 // We are pulling the EOF back as well so we need to tell
2799                 // the service.
2800                 //
2801                 bTellService = TRUE;
2802
2803                 pFcb->Header.FileSize = pBuffer->AllocationSize;
2804
2805                 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
2806             }
2807
2808         }
2809     }
2810     else
2811     {
2812         //
2813         // Tell Cc if allocation is increased.
2814         //
2815
2816         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2817                       AFS_TRACE_LEVEL_VERBOSE,
2818                       "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2819                       &pFcb->NPFcb->PagingResource,
2820                       PsGetCurrentThread());
2821
2822         AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2823                         TRUE);
2824
2825         bReleasePaging = TRUE;
2826
2827         //
2828         // Must drop the Fcb Resource.  When changing the file size
2829         // a deadlock can occur with Trend Micro's filter if the file
2830         // size is set to zero.
2831         //
2832
2833         AFSReleaseResource( &pFcb->NPFcb->Resource);
2834
2835         bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
2836
2837         pFcb->Header.AllocationSize = pBuffer->AllocationSize;
2838
2839         pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
2840     }
2841
2842     //
2843     // Now Tell the server if we have to
2844     //
2845     if (bTellService)
2846     {
2847         ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
2848                                              pFcb->ObjectInformation,
2849                                              &pCcb->AuthGroup);
2850     }
2851
2852     if (NT_SUCCESS(ntStatus))
2853     {
2854         //
2855         // Trim extents if we told the service - the update has done an implicit
2856         // trim at the service.
2857         //
2858         if (bTellService)
2859         {
2860             AFSTrimExtents( pFcb,
2861                             &pFcb->Header.FileSize);
2862         }
2863
2864         KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
2865
2866         SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2867
2868         if (bTellCc &&
2869             CcIsFileCached( pFileObject))
2870         {
2871             CcSetFileSizes( pFileObject,
2872                             (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
2873         }
2874     }
2875     else
2876     {
2877         //
2878         // Put the saved values back
2879         //
2880         pFcb->Header.ValidDataLength = liSaveVDL;
2881         pFcb->Header.FileSize = liSaveFileSize;
2882         pFcb->Header.AllocationSize = liSaveAlloc;
2883         pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
2884         pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
2885     }
2886
2887     if( bReleasePaging)
2888     {
2889
2890         AFSReleaseResource( &pFcb->NPFcb->PagingResource);
2891
2892         AFSAcquireExcl( &pFcb->NPFcb->Resource,
2893                         TRUE);
2894     }
2895
2896     return ntStatus;
2897 }
2898
2899 NTSTATUS
2900 AFSSetEndOfFileInfo( IN PIRP Irp,
2901                      IN AFSDirectoryCB *DirectoryCB)
2902 {
2903     NTSTATUS ntStatus = STATUS_SUCCESS;
2904     PFILE_END_OF_FILE_INFORMATION pBuffer;
2905     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2906     PFILE_OBJECT pFileObject = pIrpSp->FileObject;
2907     LARGE_INTEGER liSaveSize;
2908     LARGE_INTEGER liSaveVDL;
2909     LARGE_INTEGER liSaveAlloc;
2910     BOOLEAN bModified = FALSE;
2911     BOOLEAN bReleasePaging = FALSE;
2912     BOOLEAN bTruncated = FALSE;
2913     AFSFcb *pFcb = NULL;
2914     AFSCcb *pCcb = NULL;
2915
2916     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2917
2918     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2919
2920     pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2921
2922     liSaveSize = pFcb->Header.FileSize;
2923     liSaveAlloc = pFcb->Header.AllocationSize;
2924     liSaveVDL = pFcb->Header.ValidDataLength;
2925
2926     if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
2927         !pIrpSp->Parameters.SetFile.AdvanceOnly)
2928     {
2929
2930         if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
2931         {
2932
2933             // Truncating the file
2934             if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
2935                                        &pBuffer->EndOfFile))
2936             {
2937
2938                 ntStatus = STATUS_USER_MAPPED_FILE;
2939             }
2940             else
2941             {
2942
2943                 //
2944                 // If this is a truncation we need to grab the paging
2945                 // IO resource.
2946                 //
2947                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2948                               AFS_TRACE_LEVEL_VERBOSE,
2949                               "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2950                               &pFcb->NPFcb->PagingResource,
2951                               PsGetCurrentThread());
2952
2953                 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2954                                 TRUE);
2955
2956                 bReleasePaging = TRUE;
2957
2958                 //
2959                 // Must drop the Fcb Resource.  When changing the file size
2960                 // a deadlock can occur with Trend Micro's filter if the file
2961                 // size is set to zero.
2962                 //
2963
2964                 AFSReleaseResource( &pFcb->NPFcb->Resource);
2965
2966                 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
2967
2968                 pFcb->Header.FileSize = pBuffer->EndOfFile;
2969
2970                 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
2971
2972                 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
2973
2974                 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
2975                 {
2976
2977                     pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
2978                 }
2979
2980                 bTruncated = TRUE;
2981
2982                 bModified = TRUE;
2983             }
2984         }
2985         else
2986         {
2987
2988             //
2989             // extending the file, move EOF
2990             //
2991
2992             //
2993             // If this is a truncation we need to grab the paging
2994             // IO resource.
2995             //
2996             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2997                           AFS_TRACE_LEVEL_VERBOSE,
2998                           "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2999                           &pFcb->NPFcb->PagingResource,
3000                           PsGetCurrentThread());
3001
3002             AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3003                             TRUE);
3004
3005             bReleasePaging = TRUE;
3006
3007             //
3008             // Must drop the Fcb Resource.  When changing the file size
3009             // a deadlock can occur with Trend Micro's filter if the file
3010             // size is set to zero.
3011             //
3012
3013             AFSReleaseResource( &pFcb->NPFcb->Resource);
3014
3015             pFcb->Header.FileSize = pBuffer->EndOfFile;
3016
3017             pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3018
3019             if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
3020             {
3021                 //
3022                 // And Allocation as needed.
3023                 //
3024                 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3025
3026                 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3027             }
3028
3029             bModified = TRUE;
3030         }
3031     }
3032
3033     if (bModified)
3034     {
3035
3036         KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3037
3038         SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3039
3040         //
3041         // Tell the server
3042         //
3043
3044         ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
3045                                              pFcb->ObjectInformation,
3046                                              &pCcb->AuthGroup);
3047
3048         if( NT_SUCCESS(ntStatus))
3049         {
3050             //
3051             // We are now good to go so tell CC.
3052             //
3053             CcSetFileSizes( pFileObject,
3054                             (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3055
3056             //
3057             // And give up those extents
3058             //
3059             if( bTruncated)
3060             {
3061
3062                 AFSTrimExtents( pFcb,
3063                                 &pFcb->Header.FileSize);
3064             }
3065         }
3066         else
3067         {
3068             pFcb->Header.ValidDataLength = liSaveVDL;
3069             pFcb->Header.FileSize = liSaveSize;
3070             pFcb->Header.AllocationSize = liSaveAlloc;
3071             pFcb->ObjectInformation->EndOfFile = liSaveSize;
3072             pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3073         }
3074     }
3075
3076     if( bReleasePaging)
3077     {
3078
3079         AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3080
3081         AFSAcquireExcl( &pFcb->NPFcb->Resource,
3082                         TRUE);
3083     }
3084
3085     return ntStatus;
3086 }
3087
3088 NTSTATUS
3089 AFSProcessShareSetInfo( IN IRP *Irp,
3090                         IN AFSFcb *Fcb,
3091                         IN AFSCcb *Ccb)
3092 {
3093
3094     NTSTATUS ntStatus = STATUS_SUCCESS;
3095     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3096     ULONG ulOutputBufferLen = 0, ulInputBufferLen;
3097     FILE_INFORMATION_CLASS ulFileInformationClass;
3098     void *pPipeInfo = NULL;
3099
3100     __Enter
3101     {
3102         ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
3103
3104         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3105                       AFS_TRACE_LEVEL_VERBOSE,
3106                       "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
3107                       &Ccb->DirectoryCB->NameInformation.FileName,
3108                       ulFileInformationClass);
3109
3110         pPipeInfo = AFSLockSystemBuffer( Irp,
3111                                          pIrpSp->Parameters.SetFile.Length);
3112
3113         if( pPipeInfo == NULL)
3114         {
3115
3116             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3117                           AFS_TRACE_LEVEL_ERROR,
3118                           "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
3119                           &Ccb->DirectoryCB->NameInformation.FileName);
3120
3121             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3122         }
3123
3124         //
3125         // Send the request to the service
3126         //
3127
3128         ntStatus = AFSNotifySetPipeInfo( Ccb,
3129                                          (ULONG)ulFileInformationClass,
3130                                          pIrpSp->Parameters.SetFile.Length,
3131                                          pPipeInfo);
3132
3133         if( !NT_SUCCESS( ntStatus))
3134         {
3135
3136             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3137                           AFS_TRACE_LEVEL_ERROR,
3138                           "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3139                           &Ccb->DirectoryCB->NameInformation.FileName,
3140                           ntStatus);
3141
3142             try_return( ntStatus);
3143         }
3144
3145         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3146                       AFS_TRACE_LEVEL_VERBOSE,
3147                       "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
3148                       &Ccb->DirectoryCB->NameInformation.FileName,
3149                       ulFileInformationClass);
3150
3151 try_exit:
3152
3153         NOTHING;
3154     }
3155
3156     return ntStatus;
3157 }
3158
3159 NTSTATUS
3160 AFSProcessShareQueryInfo( IN IRP *Irp,
3161                           IN AFSFcb *Fcb,
3162                           IN AFSCcb *Ccb)
3163 {
3164
3165     NTSTATUS ntStatus = STATUS_SUCCESS;
3166     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3167     ULONG ulOutputBufferLen = 0, ulInputBufferLen;
3168     FILE_INFORMATION_CLASS ulFileInformationClass;
3169     void *pPipeInfo = NULL;
3170
3171     __Enter
3172     {
3173
3174         ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3175
3176         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3177                       AFS_TRACE_LEVEL_VERBOSE,
3178                       "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
3179                       &Ccb->DirectoryCB->NameInformation.FileName,
3180                       ulFileInformationClass);
3181
3182         pPipeInfo = AFSLockSystemBuffer( Irp,
3183                                          pIrpSp->Parameters.QueryFile.Length);
3184
3185         if( pPipeInfo == NULL)
3186         {
3187
3188             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3189                           AFS_TRACE_LEVEL_ERROR,
3190                           "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
3191                           &Ccb->DirectoryCB->NameInformation.FileName);
3192
3193             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3194         }
3195
3196         //
3197         // Send the request to the service
3198         //
3199
3200         ntStatus = AFSNotifyQueryPipeInfo( Ccb,
3201                                            (ULONG)ulFileInformationClass,
3202                                            pIrpSp->Parameters.QueryFile.Length,
3203                                            pPipeInfo,
3204                                            (ULONG *)&Irp->IoStatus.Information);
3205
3206         if( !NT_SUCCESS( ntStatus))
3207         {
3208
3209             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3210                           AFS_TRACE_LEVEL_ERROR,
3211                           "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3212                           &Ccb->DirectoryCB->NameInformation.FileName,
3213                           ntStatus);
3214
3215             try_return( ntStatus);
3216         }
3217
3218         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3219                       AFS_TRACE_LEVEL_VERBOSE,
3220                       "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
3221                       &Ccb->DirectoryCB->NameInformation.FileName,
3222                       ulFileInformationClass);
3223
3224 try_exit:
3225
3226         NOTHING;
3227     }
3228
3229     return ntStatus;
3230 }
3231
3232 NTSTATUS
3233 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
3234                            IN AFSFcb *Fcb,
3235                            IN AFSCcb *Ccb,
3236                            IN OUT LONG *Length)
3237 {
3238
3239     NTSTATUS ntStatus = STATUS_SUCCESS;
3240     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3241     FILE_INFORMATION_CLASS ulFileInformationClass;
3242
3243     __Enter
3244     {
3245
3246         ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3247
3248         switch( ulFileInformationClass)
3249         {
3250
3251             case FileBasicInformation:
3252             {
3253
3254                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3255                               AFS_TRACE_LEVEL_VERBOSE,
3256                               "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n");
3257
3258                 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
3259                 {
3260                     PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3261
3262                     pBasic->CreationTime.QuadPart = 0;
3263                     pBasic->LastAccessTime.QuadPart = 0;
3264                     pBasic->ChangeTime.QuadPart = 0;
3265                     pBasic->LastWriteTime.QuadPart = 0;
3266                     pBasic->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;