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