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