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