Windows: Categorize ObjectInformationCB RefCnts
[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 (%p) 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 %p 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 (%p) 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 %p 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 %p 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 %p 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 %d, performing delete of target\n",
2466                           &pTargetDirEntry->NameInformation.FileName,
2467                           pTargetDirEntry,
2468                           lCount);
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( ntStatus != STATUS_REPARSE &&
2502             !NT_SUCCESS( ntStatus))
2503         {
2504
2505             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2506                           AFS_TRACE_LEVEL_ERROR,
2507                           "AFSSetFileLinkInfo Failed link of %wZ to target %wZ Status %08lX\n",
2508                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
2509                           &uniTargetName,
2510                           ntStatus);
2511
2512             try_return( ntStatus);
2513         }
2514
2515         if ( ntStatus != STATUS_REPARSE)
2516         {
2517
2518             AFSInsertDirectoryNode( pTargetDcb->ObjectInformation,
2519                                     pNewTargetDirEntry,
2520                                     TRUE);
2521         }
2522
2523         //
2524         // Send notification for the target link file
2525         //
2526
2527         if( bTargetEntryExists || pNewTargetDirEntry)
2528         {
2529
2530             ulNotificationAction = FILE_ACTION_MODIFIED;
2531         }
2532         else
2533         {
2534
2535             ulNotificationAction = FILE_ACTION_ADDED;
2536         }
2537
2538         AFSFsRtlNotifyFullReportChange( pTargetParentObject->ParentObjectInformation,
2539                                         pSrcCcb,
2540                                         (ULONG)ulNotifyFilter,
2541                                         (ULONG)ulNotificationAction);
2542
2543       try_exit:
2544
2545         if( !NT_SUCCESS( ntStatus))
2546         {
2547
2548             if( bTargetEntryExists)
2549             {
2550
2551                 AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
2552                                         pTargetDirEntry,
2553                                         FALSE);
2554             }
2555         }
2556
2557         if( pTargetDirEntry != NULL)
2558         {
2559
2560             //
2561             // Release DirOpenReferenceCount obtained above
2562             //
2563
2564             lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
2565
2566             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2567                           AFS_TRACE_LEVEL_VERBOSE,
2568                           "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2569                           &pTargetDirEntry->NameInformation.FileName,
2570                           pTargetDirEntry,
2571                           pSrcCcb,
2572                           lCount);
2573
2574             ASSERT( lCount >= 0);
2575         }
2576
2577         if( pNewTargetDirEntry != NULL)
2578         {
2579
2580             //
2581             // Release DirOpenReferenceCount obtained from AFSNotifyHardLink
2582             //
2583
2584             lCount = InterlockedDecrement( &pNewTargetDirEntry->DirOpenReferenceCount);
2585
2586             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2587                           AFS_TRACE_LEVEL_VERBOSE,
2588                           "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2589                           &pNewTargetDirEntry->NameInformation.FileName,
2590                           pNewTargetDirEntry,
2591                           pSrcCcb,
2592                           lCount);
2593
2594             ASSERT( lCount >= 0);
2595         }
2596
2597         if( bReleaseTargetDirLock)
2598         {
2599
2600             AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2601         }
2602     }
2603
2604     return ntStatus;
2605 }
2606
2607 NTSTATUS
2608 AFSSetRenameInfo( IN PIRP Irp)
2609 {
2610
2611     NTSTATUS ntStatus = STATUS_SUCCESS;
2612     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2613     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2614     AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2615     AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2616     PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2617     PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2618     PFILE_OBJECT pTargetParentFileObj = NULL;
2619     PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2620     UNICODE_STRING uniTargetName, uniSourceName, uniTargetParentName;
2621     BOOLEAN bReplaceIfExists = FALSE;
2622     UNICODE_STRING uniShortName;
2623     AFSDirectoryCB *pTargetDirEntry = NULL;
2624     ULONG ulTargetCRC = 0;
2625     BOOLEAN bTargetEntryExists = FALSE;
2626     AFSObjectInfoCB *pSrcObject = NULL;
2627     AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2628     AFSFileID stNewFid;
2629     ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2630     UNICODE_STRING uniFullTargetName;
2631     BOOLEAN bCommonParent = FALSE;
2632     BOOLEAN bReleaseTargetDirLock = FALSE;
2633     BOOLEAN bReleaseSourceDirLock = FALSE;
2634     BOOLEAN bDereferenceTargetParentObject = FALSE;
2635     PERESOURCE  pSourceDirLock = NULL;
2636     LONG lCount;
2637
2638     __Enter
2639     {
2640
2641         bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2642
2643         pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2644
2645         pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2646         pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2647
2648         pSrcObject = pSrcFcb->ObjectInformation;
2649         pSrcParentObject = pSrcFcb->ObjectInformation->ParentObjectInformation;
2650
2651         //
2652         // Perform some basic checks to ensure FS integrity
2653         //
2654
2655         if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2656         {
2657
2658             //
2659             // Can't rename the root directory
2660             //
2661
2662             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2663                           AFS_TRACE_LEVEL_ERROR,
2664                           "AFSSetRenameInfo Attempt to rename root entry\n");
2665
2666             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2667         }
2668
2669         if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2670         {
2671
2672             //
2673             // If there are any open children then fail the rename
2674             //
2675
2676             if( pSrcFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2677             {
2678
2679                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2680                               AFS_TRACE_LEVEL_ERROR,
2681                               "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2682                               &pSrcCcb->DirectoryCB->NameInformation.FileName);
2683
2684                 try_return( ntStatus = STATUS_ACCESS_DENIED);
2685             }
2686         }
2687
2688
2689         //
2690         // Extract off the final component name from the Fcb
2691         //
2692
2693         uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2694         uniSourceName.MaximumLength = uniSourceName.Length;
2695
2696         uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2697
2698         //
2699         // Resolve the target fileobject
2700         //
2701
2702         if( pTargetFileObj == NULL)
2703         {
2704
2705             if ( pRenameInfo->RootDirectory)
2706             {
2707
2708                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2709                               AFS_TRACE_LEVEL_ERROR,
2710                               "AFSSetRenameInfo Handle provided but no FileObject ntStatus INVALID_PARAMETER\n");
2711
2712                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2713             }
2714             else
2715             {
2716
2717                 uniFullTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2718
2719                 uniFullTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2720
2721                 AFSRetrieveFinalComponent( &uniFullTargetName,
2722                                            &uniTargetName);
2723
2724                 AFSRetrieveParentPath( &uniFullTargetName,
2725                                        &uniTargetParentName);
2726
2727                 if ( uniTargetParentName.Length == 0)
2728                 {
2729
2730                     //
2731                     // This is a simple rename. Here the target directory is the same as the source parent directory
2732                     // and the name is retrieved from the system buffer information
2733                     //
2734
2735                     pTargetParentObject = pSrcParentObject;
2736                 }
2737                 else
2738                 {
2739                     //
2740                     // uniTargetParentName contains the directory the renamed object
2741                     // will be moved to.  Must obtain the TargetParentObject.
2742                     //
2743
2744                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2745                                   AFS_TRACE_LEVEL_ERROR,
2746                                   "AFSSetRenameInfo Attempt to move %wZ to %wZ -- not yet supported (NOT_SAME_DEVICE)\n",
2747                                   &pSrcCcb->DirectoryCB->NameInformation.FileName,
2748                                   &uniFullTargetName);
2749
2750                     try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2751                 }
2752             }
2753
2754             pTargetDcb = pTargetParentObject->Fcb;
2755         }
2756         else
2757         {
2758
2759             //
2760             // So here we have the target directory taken from the targetfile object
2761             //
2762
2763             pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2764
2765             pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2766
2767             pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2768
2769             //
2770             // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2771             // it is only the target component of the rename operation
2772             //
2773
2774             uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2775         }
2776
2777         //
2778         // The quick check to see if they are not really performing a rename
2779         // Do the names match? Only do this where the parent directories are
2780         // the same
2781         //
2782
2783         if( pTargetParentObject == pSrcParentObject)
2784         {
2785
2786             if( FsRtlAreNamesEqual( &uniTargetName,
2787                                     &uniSourceName,
2788                                     FALSE,
2789                                     NULL))
2790             {
2791                 try_return( ntStatus = STATUS_SUCCESS);
2792             }
2793
2794             bCommonParent = TRUE;
2795         }
2796         else
2797         {
2798
2799             bCommonParent = FALSE;
2800         }
2801
2802         //
2803         // We do not allow cross-volume renames to occur
2804         //
2805
2806         if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2807         {
2808
2809             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2810                           AFS_TRACE_LEVEL_ERROR,
2811                           "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2812                           &pSrcCcb->DirectoryCB->NameInformation.FileName);
2813
2814             try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2815         }
2816
2817         ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2818                                       FALSE);
2819
2820         AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2821                         TRUE);
2822
2823         bReleaseTargetDirLock = TRUE;
2824
2825         if( pTargetParentObject != pSrcParentObject)
2826         {
2827             AFSAcquireExcl( pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2828                             TRUE);
2829
2830             bReleaseSourceDirLock = TRUE;
2831
2832             pSourceDirLock = pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock;
2833         }
2834
2835         AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2836                                         ulTargetCRC,
2837                                         &pTargetDirEntry);
2838
2839         if( pTargetDirEntry == NULL)
2840         {
2841
2842             //
2843             // Missed so perform a case insensitive lookup
2844             //
2845
2846             ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2847                                           TRUE);
2848
2849             AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2850                                               ulTargetCRC,
2851                                               &pTargetDirEntry);
2852         }
2853
2854         if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2855              pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2856                                                                NULL,
2857                                                                NULL))
2858         {
2859             //
2860             // Try the short name
2861             //
2862             AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2863                                         ulTargetCRC,
2864                                         &pTargetDirEntry);
2865         }
2866
2867         //
2868         // Increment our ref count on the dir entry
2869         //
2870
2871         if( pTargetDirEntry != NULL)
2872         {
2873
2874             ASSERT( pTargetParentObject == pTargetDirEntry->ObjectInformation->ParentObjectInformation);
2875
2876             lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
2877
2878             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2879                           AFS_TRACE_LEVEL_VERBOSE,
2880                           "AFSSetRenameInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
2881                           &pTargetDirEntry->NameInformation.FileName,
2882                           pTargetDirEntry,
2883                           pSrcCcb,
2884                           lCount);
2885
2886             ASSERT( lCount >= 0);
2887
2888             if( !bReplaceIfExists)
2889             {
2890
2891                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2892                               AFS_TRACE_LEVEL_ERROR,
2893                               "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
2894                               &pSrcCcb->DirectoryCB->NameInformation.FileName,
2895                               &pTargetDirEntry->NameInformation.FileName);
2896
2897                 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2898             }
2899
2900             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2901                           AFS_TRACE_LEVEL_ERROR,
2902                           "AFSSetRenameInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
2903                           &pTargetDirEntry->NameInformation.FileName,
2904                           pTargetDirEntry,
2905                           lCount);
2906
2907             //
2908             // Pull the directory entry from the parent
2909             //
2910
2911             AFSRemoveDirNodeFromParent( pTargetParentObject,
2912                                         pTargetDirEntry,
2913                                         FALSE);
2914
2915             bTargetEntryExists = TRUE;
2916         }
2917         else
2918         {
2919             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2920                           AFS_TRACE_LEVEL_VERBOSE,
2921                           "AFSSetRenameInfo Target does NOT exist, normal rename\n");
2922         }
2923
2924         //
2925         // We need to remove the DirEntry from the parent node, update the index
2926         // and reinsert it into the parent tree. Note that for entries with the
2927         // same parent we do not pull the node from the enumeration list
2928         //
2929
2930         AFSRemoveDirNodeFromParent( pSrcFcb->ObjectInformation->ParentObjectInformation,
2931                                     pSrcCcb->DirectoryCB,
2932                                     !bCommonParent);
2933
2934         //
2935         // OK, this is a simple rename. Issue the rename
2936         // request to the service.
2937         //
2938
2939         ntStatus = AFSNotifyRename( pSrcFcb->ObjectInformation,
2940                                     &pSrcCcb->AuthGroup,
2941                                     pSrcFcb->ObjectInformation->ParentObjectInformation,
2942                                     pTargetDcb->ObjectInformation,
2943                                     pSrcCcb->DirectoryCB,
2944                                     &uniTargetName,
2945                                     &stNewFid);
2946
2947         if( !NT_SUCCESS( ntStatus))
2948         {
2949
2950             //
2951             // Attempt to re-insert the directory entry
2952             //
2953
2954             AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2955                                     pSrcCcb->DirectoryCB,
2956                                     !bCommonParent);
2957
2958             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2959                           AFS_TRACE_LEVEL_ERROR,
2960                           "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
2961                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
2962                           &uniTargetName,
2963                           ntStatus);
2964
2965             try_return( ntStatus);
2966         }
2967
2968         //
2969         // Set the notification up for the source file
2970         //
2971
2972         if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation == pTargetParentObject &&
2973             !bTargetEntryExists)
2974         {
2975
2976             ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
2977         }
2978         else
2979         {
2980
2981             ulNotificationAction = FILE_ACTION_REMOVED;
2982         }
2983
2984         if( pSrcCcb->DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
2985         {
2986
2987             ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2988         }
2989         else
2990         {
2991
2992             ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2993         }
2994
2995         AFSFsRtlNotifyFullReportChange( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation,
2996                                         pSrcCcb,
2997                                         (ULONG)ulNotifyFilter,
2998                                         (ULONG)ulNotificationAction);
2999
3000         //
3001         // Update the name in the dir entry.
3002         //
3003
3004         ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
3005                                           &uniTargetName);
3006
3007         if( !NT_SUCCESS( ntStatus))
3008         {
3009
3010             //
3011             // Attempt to re-insert the directory entry
3012             //
3013
3014             AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
3015                                     pSrcCcb->DirectoryCB,
3016                                     !bCommonParent);
3017
3018             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3019                           AFS_TRACE_LEVEL_ERROR,
3020                           "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
3021                           &pSrcCcb->DirectoryCB->NameInformation.FileName,
3022                           &uniTargetName,
3023                           ntStatus);
3024
3025             try_return( ntStatus);
3026         }
3027
3028         //
3029         // Update the object information block, if needed
3030         //
3031
3032         if( !AFSIsEqualFID( &pSrcObject->FileId,
3033                             &stNewFid))
3034         {
3035
3036             AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
3037                             TRUE);
3038
3039             //
3040             // Remove the old information entry
3041             //
3042
3043             AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3044                                 &pSrcObject->TreeEntry);
3045
3046             RtlCopyMemory( &pSrcObject->FileId,
3047                            &stNewFid,
3048                            sizeof( AFSFileID));
3049
3050             //
3051             // Insert the entry into the new object table.
3052             //
3053
3054             pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
3055
3056             if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
3057             {
3058
3059                 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
3060             }
3061             else
3062             {
3063
3064                 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3065                                                      &pSrcObject->TreeEntry)))
3066                 {
3067
3068                     //
3069                     // Lost a race, an ObjectInfo object already exists for this FID.
3070                     // Let this copy be garbage collected.
3071                     //
3072
3073                     ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
3074                 }
3075             }
3076
3077             AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
3078         }
3079
3080         //
3081         // Update the hash values for the name trees.
3082         //
3083
3084         pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3085                                                                                  FALSE);
3086
3087         pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3088                                                                                    TRUE);
3089
3090         if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3091             pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
3092             !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3093                                      NULL,
3094                                      NULL))
3095         {
3096
3097             uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
3098             uniShortName.MaximumLength = uniShortName.Length;
3099             uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
3100
3101             pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
3102                                                                                            TRUE);
3103
3104             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3105                           AFS_TRACE_LEVEL_VERBOSE,
3106                           "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
3107                           &uniShortName,
3108                           &pSrcCcb->DirectoryCB->NameInformation.FileName);
3109         }
3110         else
3111         {
3112
3113             pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
3114         }
3115
3116         if( !bCommonParent)
3117         {
3118
3119             //
3120             // Update the file index for the object in the new parent
3121             //
3122
3123             pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
3124         }
3125
3126         //
3127         // Re-insert the directory entry
3128         //
3129
3130         AFSInsertDirectoryNode( pTargetParentObject,
3131                                 pSrcCcb->DirectoryCB,
3132                                 !bCommonParent);
3133
3134         //
3135         // Update the parent pointer in the source object if they are different
3136         //
3137
3138         if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation != pTargetParentObject)
3139         {
3140
3141             lCount = InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
3142
3143             lCount = InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
3144
3145             lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
3146
3147             lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
3148
3149             lCount = AFSObjectInfoIncrement( pTargetParentObject,
3150                                              AFS_OBJECT_REFERENCE_CHILD);
3151
3152             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3153                           AFS_TRACE_LEVEL_VERBOSE,
3154                           "AFSSetRenameInfo Increment count on parent object %p Cnt %d\n",
3155                           pTargetParentObject,
3156                           lCount);
3157
3158             lCount = AFSObjectInfoDecrement( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation,
3159                                              AFS_OBJECT_REFERENCE_CHILD);
3160
3161             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3162                           AFS_TRACE_LEVEL_VERBOSE,
3163                           "AFSSetRenameInfo Decrement count on parent object %p Cnt %d\n",
3164                           pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation,
3165                           lCount);
3166
3167             pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation = pTargetParentObject;
3168
3169             ulNotificationAction = FILE_ACTION_ADDED;
3170         }
3171         else
3172         {
3173
3174             ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
3175         }
3176
3177         //
3178         // Now update the notification for the target file
3179         //
3180
3181         AFSFsRtlNotifyFullReportChange( pTargetParentObject->ParentObjectInformation,
3182                                         pSrcCcb,
3183                                         (ULONG)ulNotifyFilter,
3184                                         (ULONG)ulNotificationAction);
3185
3186         //
3187         // If we performed the rename of the target because it existed, we now need to
3188         // delete the tmp target we created above
3189         //
3190
3191         if( bTargetEntryExists)
3192         {
3193
3194             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3195                           AFS_TRACE_LEVEL_VERBOSE,
3196                           "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
3197                           pTargetDirEntry,
3198                           &pTargetDirEntry->NameInformation.FileName);
3199
3200             SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3201
3202             //
3203             // Try and purge the cache map if this is a file
3204             //
3205
3206             if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
3207                 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
3208                 pTargetDirEntry->DirOpenReferenceCount > 1)
3209             {
3210
3211                 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
3212             }
3213
3214             ASSERT( pTargetDirEntry->DirOpenReferenceCount > 0);
3215
3216             lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount); // The count we added above
3217
3218             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3219                           AFS_TRACE_LEVEL_VERBOSE,
3220                           "AFSSetRenameInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3221                           &pTargetDirEntry->NameInformation.FileName,
3222                           pTargetDirEntry,
3223                           pSrcCcb,
3224                           lCount);
3225
3226             ASSERT( lCount >= 0);
3227
3228             if( lCount == 0)
3229             {
3230
3231                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3232                               AFS_TRACE_LEVEL_VERBOSE,
3233                               "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
3234                               pTargetDirEntry,
3235                               &pTargetDirEntry->NameInformation.FileName);
3236
3237                 AFSDeleteDirEntry( pTargetParentObject,
3238                                    pTargetDirEntry);
3239             }
3240
3241             pTargetDirEntry = NULL;
3242
3243             if ( pTargetFcb != NULL)
3244             {
3245
3246                 //
3247                 // Do not hold TreeLocks across the MmForceSectionClosed() call as
3248                 // it can deadlock with Trend Micro's TmPreFlt!TmpQueryFullName
3249                 //
3250
3251                 if( bReleaseTargetDirLock)
3252                 {
3253                     AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3254
3255                     bReleaseTargetDirLock = FALSE;
3256                 }
3257
3258                 if( bReleaseSourceDirLock)
3259                 {
3260
3261                     AFSReleaseResource( pSourceDirLock);
3262
3263                     bReleaseSourceDirLock = FALSE;
3264                 }
3265
3266                 //
3267                 // MmForceSectionClosed() can eventually call back into AFSCleanup
3268                 // which will need to acquire Fcb->Resource exclusively.  Failure
3269                 // to obtain it here before holding the SectionObjectResource will
3270                 // permit the locks to be obtained out of order risking a deadlock.
3271                 //
3272
3273                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3274                               AFS_TRACE_LEVEL_VERBOSE,
3275                               "AFSSetRenameInfo Acquiring Fcb lock %p EXCL %08lX\n",
3276                               &pTargetFcb->NPFcb->Resource,
3277                               PsGetCurrentThread());
3278
3279                 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
3280                                 TRUE);
3281
3282                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3283                               AFS_TRACE_LEVEL_VERBOSE,
3284                               "AFSSetRenameInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3285                               &pTargetFcb->NPFcb->SectionObjectResource,
3286                               PsGetCurrentThread());
3287
3288                 AFSAcquireExcl( &pTargetFcb->NPFcb->SectionObjectResource,
3289                                 TRUE);
3290
3291                 //
3292                 // Close the section in the event it was mapped
3293                 //
3294
3295                 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
3296                                            TRUE))
3297                 {
3298
3299                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3300                                   AFS_TRACE_LEVEL_ERROR,
3301                                   "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
3302                                   &uniTargetName);
3303                 }
3304
3305                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3306                               AFS_TRACE_LEVEL_VERBOSE,
3307                               "AFSSetRenameInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3308                               &pTargetFcb->NPFcb->SectionObjectResource,
3309                               PsGetCurrentThread());
3310
3311                 AFSReleaseResource( &pTargetFcb->NPFcb->SectionObjectResource);
3312
3313                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3314                               AFS_TRACE_LEVEL_VERBOSE,
3315                               "AFSSetRenameInfo Releasing Fcb lock %p EXCL %08lX\n",
3316                               &pTargetFcb->NPFcb->Resource,
3317                               PsGetCurrentThread());
3318
3319                 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
3320             }
3321         }
3322
3323 try_exit:
3324
3325         if( !NT_SUCCESS( ntStatus))
3326         {
3327
3328             if( bTargetEntryExists)
3329             {
3330                 AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
3331                                         pTargetDirEntry,
3332                                         FALSE);
3333             }
3334         }
3335
3336         if( pTargetDirEntry != NULL)
3337         {
3338
3339             lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
3340
3341             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3342                           AFS_TRACE_LEVEL_VERBOSE,
3343                           "AFSSetRenameInfo Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
3344                           &pTargetDirEntry->NameInformation.FileName,
3345                           pTargetDirEntry,
3346                           pSrcCcb,
3347                           lCount);
3348
3349             ASSERT( lCount >= 0);
3350         }
3351
3352         if( bReleaseTargetDirLock)
3353         {
3354
3355             AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3356         }
3357
3358         if( bReleaseSourceDirLock)
3359         {
3360
3361             AFSReleaseResource( pSourceDirLock);
3362         }
3363     }
3364
3365     if ( bDereferenceTargetParentObject)
3366     {
3367
3368         ObDereferenceObject( pTargetParentFileObj);
3369     }
3370
3371     return ntStatus;
3372 }
3373
3374 NTSTATUS
3375 AFSSetPositionInfo( IN PIRP Irp,
3376                     IN AFSDirectoryCB *DirectoryCB)
3377 {
3378     UNREFERENCED_PARAMETER(DirectoryCB);
3379     NTSTATUS ntStatus = STATUS_SUCCESS;
3380     PFILE_POSITION_INFORMATION pBuffer;
3381     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3382
3383     pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3384
3385     pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
3386
3387     return ntStatus;
3388 }
3389
3390 NTSTATUS
3391 AFSSetAllocationInfo( IN PIRP Irp,
3392                       IN AFSDirectoryCB *DirectoryCB)
3393 {
3394     UNREFERENCED_PARAMETER(DirectoryCB);
3395     NTSTATUS ntStatus = STATUS_SUCCESS;
3396     PFILE_ALLOCATION_INFORMATION pBuffer;
3397     BOOLEAN bReleasePaging = FALSE;
3398     BOOLEAN bTellCc = FALSE;
3399     BOOLEAN bTellService = FALSE;
3400     BOOLEAN bUserMapped = FALSE;
3401     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3402     PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3403     AFSFcb *pFcb = NULL;
3404     AFSCcb *pCcb = NULL;
3405     LARGE_INTEGER liSaveAlloc;
3406     LARGE_INTEGER liSaveFileSize;
3407     LARGE_INTEGER liSaveVDL;
3408
3409     pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3410
3411     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3412
3413     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3414
3415     //
3416     // save values to put back
3417     //
3418     liSaveAlloc = pFcb->Header.AllocationSize;
3419     liSaveFileSize = pFcb->Header.FileSize;
3420     liSaveVDL = pFcb->Header.ValidDataLength;
3421
3422     if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
3423         pIrpSp->Parameters.SetFile.AdvanceOnly)
3424     {
3425         return STATUS_SUCCESS ;
3426     }
3427
3428     if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3429     {
3430
3431         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3432                       AFS_TRACE_LEVEL_VERBOSE,
3433                       "AFSSetAllocationInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3434                       &pFcb->NPFcb->SectionObjectResource,
3435                       PsGetCurrentThread());
3436
3437         AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3438                         TRUE);
3439
3440         bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3441                                              &pBuffer->AllocationSize);
3442
3443         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3444                       AFS_TRACE_LEVEL_VERBOSE,
3445                       "AFSSetAllocationInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3446                       &pFcb->NPFcb->SectionObjectResource,
3447                       PsGetCurrentThread());
3448
3449         AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3450
3451         //
3452         // Truncating the file
3453         //
3454         if ( bUserMapped)
3455         {
3456
3457             ntStatus = STATUS_USER_MAPPED_FILE ;
3458         }
3459         else
3460         {
3461
3462             //
3463             // If this is a truncation we need to grab the paging IO resource.
3464             //
3465
3466             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3467                           AFS_TRACE_LEVEL_VERBOSE,
3468                           "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3469                           &pFcb->NPFcb->PagingResource,
3470                           PsGetCurrentThread());
3471
3472             AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3473                             TRUE);
3474
3475             bReleasePaging = TRUE;
3476
3477             //
3478             // Must drop the Fcb Resource.  When changing the file size
3479             // a deadlock can occur with Trend Micro's filter if the file
3480             // size is set to zero.
3481             //
3482
3483             AFSReleaseResource( &pFcb->NPFcb->Resource);
3484
3485             pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3486
3487             pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3488
3489             //
3490             // Tell Cc that Allocation is moved.
3491             //
3492             bTellCc = TRUE;
3493
3494             if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3495             {
3496                 //
3497                 // We are pulling the EOF back as well so we need to tell
3498                 // the service.
3499                 //
3500                 bTellService = TRUE;
3501
3502                 pFcb->Header.FileSize = pBuffer->AllocationSize;
3503
3504                 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
3505             }
3506
3507         }
3508     }
3509     else
3510     {
3511         //
3512         // Tell Cc if allocation is increased.
3513         //
3514
3515         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3516                       AFS_TRACE_LEVEL_VERBOSE,
3517                       "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3518                       &pFcb->NPFcb->PagingResource,
3519                       PsGetCurrentThread());
3520
3521         AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3522                         TRUE);
3523
3524         bReleasePaging = TRUE;
3525
3526         //
3527         // Must drop the Fcb Resource.  When changing the file size
3528         // a deadlock can occur with Trend Micro's filter if the file
3529         // size is set to zero.
3530         //
3531
3532         AFSReleaseResource( &pFcb->NPFcb->Resource);
3533
3534         bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
3535
3536         pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3537
3538         pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3539     }
3540
3541     //
3542     // Now Tell the server if we have to
3543     //
3544     if (bTellService)
3545     {
3546         ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
3547                                              pFcb->ObjectInformation,
3548                                              &pCcb->AuthGroup);
3549     }
3550
3551     if (NT_SUCCESS(ntStatus))
3552     {
3553         //
3554         // Trim extents if we told the service - the update has done an implicit
3555         // trim at the service.
3556         //
3557         if (bTellService)
3558         {
3559             AFSTrimExtents( pFcb,
3560                             &pFcb->Header.FileSize);
3561         }
3562
3563         KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3564
3565         SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3566
3567         if (bTellCc &&
3568             CcIsFileCached( pFileObject))
3569         {
3570             CcSetFileSizes( pFileObject,
3571                             (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3572         }
3573     }
3574     else
3575     {
3576         //
3577         // Put the saved values back
3578         //
3579         pFcb->Header.ValidDataLength = liSaveVDL;
3580         pFcb->Header.FileSize = liSaveFileSize;
3581         pFcb->Header.AllocationSize = liSaveAlloc;
3582         pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
3583         pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3584     }
3585
3586     if( bReleasePaging)
3587     {
3588
3589         AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3590
3591         AFSAcquireExcl( &pFcb->NPFcb->Resource,
3592                         TRUE);
3593     }
3594
3595     return ntStatus;
3596 }
3597
3598 NTSTATUS
3599 AFSSetEndOfFileInfo( IN PIRP Irp,
3600                      IN AFSDirectoryCB *DirectoryCB)
3601 {
3602     UNREFERENCED_PARAMETER(DirectoryCB);
3603     NTSTATUS ntStatus = STATUS_SUCCESS;
3604     PFILE_END_OF_FILE_INFORMATION pBuffer;
3605     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3606     PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3607     LARGE_INTEGER liSaveSize;
3608     LARGE_INTEGER liSaveVDL;
3609     LARGE_INTEGER liSaveAlloc;
3610     BOOLEAN bModified = FALSE;
3611     BOOLEAN bReleasePaging = FALSE;
3612     BOOLEAN bTruncated = FALSE;
3613     BOOLEAN bUserMapped = FALSE;
3614     AFSFcb *pFcb = NULL;
3615     AFSCcb *pCcb = NULL;
3616
3617     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3618
3619     pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3620
3621     pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3622
3623     liSaveSize = pFcb->Header.FileSize;
3624     liSaveAlloc = pFcb->Header.AllocationSize;
3625     liSaveVDL = pFcb->Header.ValidDataLength;
3626
3627     if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
3628         !pIrpSp->Parameters.SetFile.AdvanceOnly)
3629     {
3630
3631         if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
3632         {
3633
3634             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3635                           AFS_TRACE_LEVEL_VERBOSE,
3636                           "AFSSetEndOfFileInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3637                           &pFcb->NPFcb->SectionObjectResource,
3638                           PsGetCurrentThread());
3639
3640             AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3641                             TRUE);
3642
3643             bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3644                                                  &pBuffer->EndOfFile);
3645
3646             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3647                           AFS_TRACE_LEVEL_VERBOSE,
3648                           "AFSSetEndOfFileInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3649                           &pFcb->NPFcb->SectionObjectResource,
3650                           PsGetCurrentThread());
3651
3652             AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3653
3654             // Truncating the file
3655             if ( bUserMapped)
3656             {
3657
3658                 ntStatus = STATUS_USER_MAPPED_FILE;
3659             }
3660             else
3661             {
3662
3663                 //
3664                 // If this is a truncation we need to grab the paging
3665                 // IO resource.
3666                 //
3667                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3668                               AFS_TRACE_LEVEL_VERBOSE,
3669                               "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3670                               &pFcb->NPFcb->PagingResource,
3671                               PsGetCurrentThread());
3672
3673                 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3674                                 TRUE);
3675
3676                 bReleasePaging = TRUE;
3677
3678                 //
3679                 // Must drop the Fcb Resource.  When changing the file size
3680                 // a deadlock can occur with Trend Micro's filter if the file
3681                 // size is set to zero.
3682                 //
3683
3684                 AFSReleaseResource( &pFcb->NPFcb->Resource);
3685
3686                 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3687
3688                 pFcb->Header.FileSize = pBuffer->EndOfFile;
3689
3690                 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3691
3692                 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3693
3694                 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
3695                 {
3696
3697                     pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
3698                 }
3699
3700                 bTruncated = TRUE;
3701
3702                 bModified = TRUE;
3703             }
3704         }
3705         else
3706         {
3707
3708             //
3709             // extending the file, move EOF
3710             //
3711
3712             //
3713             // If this is a truncation we need to grab the paging
3714             // IO resource.
3715             //
3716             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3717                           AFS_TRACE_LEVEL_VERBOSE,
3718                           "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3719                           &pFcb->NPFcb->PagingResource,
3720                           PsGetCurrentThread());
3721
3722             AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3723                             TRUE);
3724
3725             bReleasePaging = TRUE;
3726
3727             //
3728             // Must drop the Fcb Resource.  When changing the file size
3729             // a deadlock can occur with Trend Micro's filter if the file
3730             // size is set to zero.
3731             //
3732
3733             AFSReleaseResource( &pFcb->NPFcb->Resource);
3734
3735             pFcb->Header.FileSize = pBuffer->EndOfFile;
3736
3737             pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3738
3739             if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
3740             {
3741                 //
3742                 // And Allocation as needed.
3743                 //
3744                 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3745
3746                 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3747             }
3748
3749             bModified = TRUE;
3750         }
3751     }
3752
3753     if (bModified)
3754     {
3755
3756         KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3757
3758         SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3759
3760         //
3761         // Tell the server
3762         //
3763
3764         ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
3765                                              pFcb->ObjectInformation,
3766                                              &pCcb->AuthGroup);
3767
3768         if( NT_SUCCESS(ntStatus))
3769         {
3770             //
3771             // We are now good to go so tell CC.
3772             //
3773             CcSetFileSizes( pFileObject,
3774                             (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3775
3776             //
3777             // And give up those extents
3778             //
3779             if( bTruncated)
3780             {
3781
3782                 AFSTrimExtents( pFcb,
3783                                 &pFcb->Header.FileSize);
3784             }
3785         }
3786         else
3787         {
3788             pFcb->Header.ValidDataLength = liSaveVDL;
3789             pFcb->Header.FileSize = liSaveSize;
3790             pFcb->Header.AllocationSize = liSaveAlloc;
3791             pFcb->ObjectInformation->EndOfFile = liSaveSize;
3792             pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3793         }
3794     }
3795
3796     if( bReleasePaging)
3797     {
3798
3799         AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3800
3801         AFSAcquireExcl( &pFcb->NPFcb->Resource,
3802                         TRUE);
3803     }
3804
3805     return ntStatus;
3806 }
3807
3808 NTSTATUS
3809 AFSProcessShareSetInfo( IN IRP *Irp,
3810                         IN AFSFcb *Fcb,
3811                         IN AFSCcb *Ccb)
3812 {
3813
3814     UNREFERENCED_PARAMETER(Fcb);
3815     NTSTATUS ntStatus = STATUS_SUCCESS;
3816     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3817     FILE_INFORMATION_CLASS ulFileInformationClass;
3818     void *pPipeInfo = NULL;
3819
3820     __Enter
3821     {
3822         ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
3823
3824         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3825                       AFS_TRACE_LEVEL_VERBOSE,
3826                       "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
3827                       &Ccb->DirectoryCB->NameInformation.FileName,
3828                       ulFileInformationClass);
3829
3830         pPipeInfo = AFSLockSystemBuffer( Irp,
3831                                          pIrpSp->Parameters.SetFile.Length);
3832
3833         if( pPipeInfo == NULL)
3834         {
3835
3836             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3837                           AFS_TRACE_LEVEL_ERROR,
3838                           "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
3839                           &Ccb->DirectoryCB->NameInformation.FileName);
3840
3841             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3842         }
3843
3844         //
3845         // Send the request to the service
3846         //
3847
3848         ntStatus = AFSNotifySetPipeInfo( Ccb,
3849                                          (ULONG)ulFileInformationClass,
3850                                          pIrpSp->Parameters.SetFile.Length,
3851                                          pPipeInfo);
3852
3853         if( !NT_SUCCESS( ntStatus))
3854         {
3855
3856             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3857                           AFS_TRACE_LEVEL_ERROR,
3858                           "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3859                           &Ccb->DirectoryCB->NameInformation.FileName,
3860                           ntStatus);
3861
3862             try_return( ntStatus);
3863         }
3864
3865         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3866                       AFS_TRACE_LEVEL_VERBOSE,
3867                       "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
3868                       &Ccb->DirectoryCB->NameInformation.FileName,
3869                       ulFileInformationClass);
3870
3871 try_exit:
3872
3873         NOTHING;
3874     }
3875
3876     return ntStatus;
3877 }
3878
3879 NTSTATUS
3880 AFSProcessShareQueryInfo( IN IRP *Irp,
3881                           IN AFSFcb *Fcb,
3882                           IN AFSCcb *Ccb)
3883 {
3884
3885     UNREFERENCED_PARAMETER(Fcb);
3886     NTSTATUS ntStatus = STATUS_SUCCESS;
3887     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3888     FILE_INFORMATION_CLASS ulFileInformationClass;
3889     void *pPipeInfo = NULL;
3890
3891     __Enter
3892     {
3893
3894         ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3895
3896         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3897                       AFS_TRACE_LEVEL_VERBOSE,
3898                       "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
3899                       &Ccb->DirectoryCB->NameInformation.FileName,
3900                       ulFileInformationClass);
3901
3902         pPipeInfo = AFSLockSystemBuffer( Irp,
3903                                          pIrpSp->Parameters.QueryFile.Length);
3904
3905         if( pPipeInfo == NULL)
3906         {
3907
3908             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3909                           AFS_TRACE_LEVEL_ERROR,
3910                           "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
3911                           &Ccb->DirectoryCB->NameInformation.FileName);
3912
3913             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3914         }
3915
3916         //
3917         // Send the request to the service
3918         //
3919
3920         ntStatus = AFSNotifyQueryPipeInfo( Ccb,
3921                                            (ULONG)ulFileInformationClass,
3922                                            pIrpSp->Parameters.QueryFile.Length,
3923                                            pPipeInfo,
3924                                            (ULONG *)&Irp->IoStatus.Information);
3925
3926         if( !NT_SUCCESS( ntStatus))
3927         {
3928
3929             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3930                           AFS_TRACE_LEVEL_ERROR,
3931                           "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3932                           &Ccb->DirectoryCB->NameInformation.FileName,
3933                           ntStatus);
3934
3935             try_return( ntStatus);
3936         }
3937
3938         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3939                       AFS_TRACE_LEVEL_VERBOSE,
3940                       "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
3941                       &Ccb->DirectoryCB->NameInformation.FileName,
3942                       ulFileInformationClass);
3943
3944 try_exit:
3945
3946         NOTHING;
3947     }
3948
3949     return ntStatus;
3950 }
3951
3952 NTSTATUS
3953 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
3954                            IN AFSFcb *Fcb,
3955                            IN AFSCcb *Ccb,
3956                            IN OUT LONG *Length)
3957 {
3958
3959     UNREFERENCED_PARAMETER(Fcb);
3960     UNREFERENCED_PARAMETER(Ccb);
3961     NTSTATUS ntStatus = STATUS_SUCCESS;
3962     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3963     FILE_INFORMATION_CLASS ulFileInformationClass;
3964
3965     __Enter
3966     {
3967
3968         ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3969
3970         switch( ulFileInformationClass)
3971         {
3972
3973             case FileBasicInformation:
3974             {
3975
3976                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3977                               AFS_TRACE_LEVEL_VERBOSE,
3978                               "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n");
3979
3980                 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
3981                 {
3982                     PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3983
3984                     pBasic->CreationTime.QuadPart = 0;
3985                     pBasic->LastAccessTime.QuadPart = 0;
3986                     pBasic->ChangeTime.QuadPart = 0;
3987                     pBasic->LastWriteTime.QuadPart = 0;
3988                     pBasic->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
3989
3990                     *Length -= sizeof( FILE_BASIC_INFORMATION);
3991                 }
3992                 else
3993                 {
3994                     ntStatus = STATUS_BUFFER_TOO_SMALL;
3995                 }
3996
3997                 break;
3998             }
3999
4000             case FileStandardInformation:
4001             {
4002
4003                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4004                               AFS_TRACE_LEVEL_VERBOSE,
4005                               "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n");
4006
4007                 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
4008                 {
4009                     PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4010
4011                     pStandard->NumberOfLinks = 1;
4012                     pStandard->DeletePending = 0;
4013                     pStandard->AllocationSize.QuadPart = 0;
4014                     pStandard->EndOfFile.QuadPart = 0;
4015                     pStandard->Directory = 0;
4016
4017                     *Length -= sizeof( FILE_STANDARD_INFORMATION);
4018                 }
4019                 else
4020                 {
4021                     ntStatus = STATUS_BUFFER_TOO_SMALL;
4022                 }
4023
4024                 break;
4025             }
4026
4027             case FileNormalizedNameInformation:
4028             case FileNameInformation:
4029             {
4030
4031                 ULONG ulCopyLength = 0;
4032                 AFSFcb *pFcb = NULL;
4033                 AFSCcb *pCcb = NULL;
4034                 USHORT usFullNameLength = 0;
4035                 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4036                 UNICODE_STRING uniName;
4037
4038                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4039                               AFS_TRACE_LEVEL_VERBOSE,
4040                               "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n");
4041
4042                 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
4043                 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
4044
4045                 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
4046                 {
4047                     ntStatus = STATUS_BUFFER_TOO_SMALL;
4048                     break;
4049                 }
4050
4051                 RtlZeroMemory( pNameInfo,
4052                                *Length);
4053
4054                 usFullNameLength = sizeof( WCHAR) +
4055                                             AFSServerName.Length +
4056                                             pCcb->FullFileName.Length;
4057
4058                 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
4059                 {
4060                     ulCopyLength = (LONG)usFullNameLength;
4061                 }
4062                 else
4063                 {
4064                     ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4065                     ntStatus = STATUS_BUFFER_OVERFLOW;
4066                 }
4067
4068                 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
4069
4070                 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4071
4072                 if( ulCopyLength > 0)
4073                 {
4074
4075                     pNameInfo->FileName[ 0] = L'\\';
4076                     ulCopyLength -= sizeof( WCHAR);
4077
4078                     *Length -= sizeof( WCHAR);
4079
4080                     if( ulCopyLength >= AFSServerName.Length)
4081                     {
4082
4083                         RtlCopyMemory( &pNameInfo->FileName[ 1],
4084                                        AFSServerName.Buffer,
4085                                        AFSServerName.Length);
4086
4087                         ulCopyLength -= AFSServerName.Length;
4088                         *Length -= AFSServerName.Length;
4089
4090                         if( ulCopyLength >= pCcb->FullFileName.Length)
4091                         {
4092
4093                             RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4094                                            pCcb->FullFileName.Buffer,
4095                                            pCcb->FullFileName.Length);
4096
4097                             ulCopyLength -= pCcb->FullFileName.Length;
4098                             *Length -= pCcb->FullFileName.Length;
4099
4100                             uniName.Length = (USHORT)pNameInfo->FileNameLength;
4101                             uniName.MaximumLength = uniName.Length;
4102                             uniName.Buffer = pNameInfo->FileName;
4103                         }
4104                         else
4105                         {
4106
4107                             RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4108                                            pCcb->FullFileName.Buffer,
4109                                            ulCopyLength);
4110
4111                             *Length -= ulCopyLength;
4112
4113                             uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
4114                             uniName.MaximumLength = uniName.Length;
4115                             uniName.Buffer = pNameInfo->FileName;
4116                         }
4117
4118                         AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4119                                       AFS_TRACE_LEVEL_VERBOSE,
4120                                       "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
4121                                       &uniName);
4122                     }
4123                 }
4124
4125                 break;
4126             }
4127
4128             case FileInternalInformation:
4129             {
4130
4131                 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4132
4133                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4134                               AFS_TRACE_LEVEL_VERBOSE,
4135                               "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n");
4136
4137                 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
4138                 {
4139
4140                     pInternalInfo->IndexNumber.HighPart = 0;
4141
4142                     pInternalInfo->IndexNumber.LowPart = 0;
4143
4144                     *Length -= sizeof( FILE_INTERNAL_INFORMATION);
4145                 }
4146                 else
4147                 {
4148
4149                     ntStatus = STATUS_BUFFER_TOO_SMALL;
4150                 }
4151
4152                 break;
4153             }
4154
4155             case FileAllInformation:
4156             {
4157                 ntStatus = STATUS_INVALID_PARAMETER;
4158
4159                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4160                               AFS_TRACE_LEVEL_WARNING,
4161                               "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n");
4162
4163                 break;
4164             }
4165
4166             case FileEaInformation:
4167             {
4168                 ntStatus = STATUS_INVALID_PARAMETER;
4169
4170                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4171                               AFS_TRACE_LEVEL_WARNING,
4172                               "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n");
4173
4174                 break;
4175             }
4176
4177             case FilePositionInformation:
4178             {
4179                 ntStatus = STATUS_INVALID_PARAMETER;
4180
4181                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4182                               AFS_TRACE_LEVEL_WARNING,
4183                               "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n");
4184
4185                 break;
4186             }
4187
4188             case FileAlternateNameInformation:
4189             {
4190                 ntStatus = STATUS_INVALID_PARAMETER;
4191
4192                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4193                               AFS_TRACE_LEVEL_WARNING,
4194                               "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n");
4195
4196                 break;
4197             }
4198
4199             case FileNetworkOpenInformation:
4200             {
4201                 ntStatus = STATUS_INVALID_PARAMETER;
4202
4203                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4204                               AFS_TRACE_LEVEL_WARNING,
4205                               "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n");
4206
4207                 break;
4208             }
4209
4210             case FileStreamInformation:
4211             {
4212                 ntStatus = STATUS_INVALID_PARAMETER;
4213
4214                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4215                               AFS_TRACE_LEVEL_WARNING,
4216                               "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n");
4217
4218                 break;
4219             }
4220
4221             case FileAttributeTagInformation:
4222             {
4223                 ntStatus = STATUS_INVALID_PARAMETER;
4224
4225                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4226                               AFS_TRACE_LEVEL_WARNING,
4227                               "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n");
4228
4229                 break;
4230             }
4231
4232             case FileRemoteProtocolInformation:
4233             {
4234                 ntStatus = STATUS_INVALID_PARAMETER;
4235
4236                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4237                               AFS_TRACE_LEVEL_WARNING,
4238                               "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n");
4239
4240                 break;
4241             }
4242
4243             case FileNetworkPhysicalNameInformation:
4244             {
4245                 ntStatus = STATUS_INVALID_PARAMETER;
4246
4247                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4248                               AFS_TRACE_LEVEL_WARNING,
4249                               "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n");
4250
4251                 break;
4252             }
4253
4254             default:
4255             {
4256                 ntStatus = STATUS_INVALID_PARAMETER;
4257
4258                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4259                               AFS_TRACE_LEVEL_WARNING,
4260                               "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
4261                               ulFileInformationClass);
4262
4263                 break;
4264             }
4265         }
4266     }
4267
4268     AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4269                   AFS_TRACE_LEVEL_VERBOSE,
4270                   "AFSProcessPIOCtlQueryInfo ntStatus %08lX\n",
4271                   ntStatus);
4272
4273     return ntStatus;
4274 }
4275