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