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