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