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