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