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