Windows: New Trace for DirEntry tracking problem
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSCommSupport.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: AFSCommSupport.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 NTSTATUS
42 AFSEnumerateDirectory( IN GUID *AuthGroup,
43                        IN AFSObjectInfoCB *ObjectInfoCB,
44                        IN BOOLEAN   FastQuery)
45 {
46
47     NTSTATUS ntStatus = STATUS_SUCCESS;
48     void *pBuffer = NULL;
49     ULONG ulResultLen = 0;
50     AFSDirQueryCB *pDirQueryCB;
51     AFSDirEnumEntry *pCurrentDirEntry = NULL;
52     AFSDirectoryCB *pDirNode = NULL;
53     ULONG  ulEntryLength = 0;
54     AFSDirEnumResp *pDirEnumResponse = NULL;
55     UNICODE_STRING uniDirName, uniTargetName;
56     ULONG   ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
57     ULONG ulCRC = 0;
58     UNICODE_STRING uniGUID;
59
60     __Enter
61     {
62
63         uniGUID.Length = 0;
64         uniGUID.MaximumLength = 0;
65         uniGUID.Buffer = NULL;
66
67         if( AuthGroup != NULL)
68         {
69             RtlStringFromGUID( *AuthGroup,
70                                &uniGUID);
71         }
72
73         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
74                       AFS_TRACE_LEVEL_VERBOSE,
75                       "AFSEnumerateDirectory Enumerating FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ\n",
76                       ObjectInfoCB->FileId.Cell,
77                       ObjectInfoCB->FileId.Volume,
78                       ObjectInfoCB->FileId.Vnode,
79                       ObjectInfoCB->FileId.Unique,
80                       &uniGUID);
81
82         if( AuthGroup != NULL)
83         {
84             RtlFreeUnicodeString( &uniGUID);
85         }
86
87         //
88         // Initialize the directory enumeration buffer for the directory
89         //
90
91         pBuffer = AFSExAllocatePoolWithTag( PagedPool,
92                                             AFS_DIR_ENUM_BUFFER_LEN,
93                                             AFS_DIR_BUFFER_TAG);
94
95         if( pBuffer == NULL)
96         {
97
98             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
99         }
100
101         RtlZeroMemory( pBuffer,
102                        AFS_DIR_ENUM_BUFFER_LEN);
103
104         ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
105
106         //
107         // Use the payload buffer for information we will pass to the service
108         //
109
110         pDirQueryCB = (AFSDirQueryCB *)pBuffer;
111
112         pDirQueryCB->EnumHandle = 0;
113
114         if( FastQuery)
115         {
116
117             ulRequestFlags |= AFS_REQUEST_FLAG_FAST_REQUEST;
118         }
119
120         //
121         // Loop on the information
122         //
123
124         while( TRUE)
125         {
126
127             //
128             // Go and retrieve the directory contents
129             //
130
131             ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
132                                           ulRequestFlags,
133                                           AuthGroup,
134                                           NULL,
135                                           &ObjectInfoCB->FileId,
136                                           (void *)pDirQueryCB,
137                                           sizeof( AFSDirQueryCB),
138                                           pBuffer,
139                                           &ulResultLen);
140
141             if( ntStatus != STATUS_SUCCESS ||
142                 ulResultLen == 0)
143             {
144
145                 if( ntStatus == STATUS_NO_MORE_FILES ||
146                     ntStatus == STATUS_NO_MORE_ENTRIES)
147                 {
148
149                     ntStatus = STATUS_SUCCESS;
150                 }
151                 else
152                 {
153
154                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
155                                   AFS_TRACE_LEVEL_ERROR,
156                                   "AFSEnumerateDirectory Failed to enumerate directory Status %08lX\n",
157                                   ntStatus);
158                 }
159
160                 break;
161             }
162
163             pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
164
165             pCurrentDirEntry = (AFSDirEnumEntry *)pDirEnumResponse->Entry;
166
167             //
168             // Remove the leading header from the processed length
169             //
170
171             ulResultLen -= FIELD_OFFSET( AFSDirEnumResp, Entry);
172
173             while( ulResultLen > 0)
174             {
175
176                 uniDirName.Length = (USHORT)pCurrentDirEntry->FileNameLength;
177
178                 uniDirName.MaximumLength = uniDirName.Length;
179
180                 uniDirName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->FileNameOffset);
181
182                 uniTargetName.Length = (USHORT)pCurrentDirEntry->TargetNameLength;
183
184                 uniTargetName.MaximumLength = uniTargetName.Length;
185
186                 uniTargetName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->TargetNameOffset);
187
188                 //
189                 // Be sure we don't have this entry in the case sensitive tree
190                 //
191
192                 ulCRC = AFSGenerateCRC( &uniDirName,
193                                         FALSE);
194
195                 AFSLocateCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
196                                                 ulCRC,
197                                                 &pDirNode);
198
199                 if( pDirNode != NULL)
200                 {
201
202                     //
203                     // Duplicate entry, skip it
204                     //
205
206                     ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
207                                                     uniDirName.Length +
208                                                     uniTargetName.Length);
209
210                     pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
211
212                     if( ulResultLen >= ulEntryLength)
213                     {
214                         ulResultLen -= ulEntryLength;
215                     }
216                     else
217                     {
218                         ulResultLen = 0;
219                     }
220
221                     continue;
222                 }
223
224                 pDirNode = AFSInitDirEntry( ObjectInfoCB,
225                                             &uniDirName,
226                                             &uniTargetName,
227                                             pCurrentDirEntry,
228                                             (ULONG)InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.ContentIndex));
229
230                 if( pDirNode == NULL)
231                 {
232
233                     ntStatus = STATUS_INSUFFICIENT_RESOURCES;
234
235                     break;
236                 }
237
238                 //
239                 // Set up the entry length
240                 //
241
242                 ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
243                                                     pCurrentDirEntry->FileNameLength +
244                                                     pCurrentDirEntry->TargetNameLength);
245
246                 //
247                 // Init the short name if we have one
248                 //
249
250                 if( pCurrentDirEntry->ShortNameLength > 0)
251                 {
252
253                     UNICODE_STRING uniShortName;
254
255                     pDirNode->NameInformation.ShortNameLength = pCurrentDirEntry->ShortNameLength;
256
257                     RtlCopyMemory( pDirNode->NameInformation.ShortName,
258                                    pCurrentDirEntry->ShortName,
259                                    pDirNode->NameInformation.ShortNameLength);
260
261                     //
262                     // Generate the short name index
263                     //
264
265                     uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
266                     uniShortName.Buffer = pDirNode->NameInformation.ShortName;
267
268                     pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
269                                                                                        TRUE);
270
271                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
272                                   AFS_TRACE_LEVEL_VERBOSE,
273                                   "AFSEnumerateDirectory Initialized short name %wZ for DE %p for %wZ\n",
274                                   &uniShortName,
275                                   pDirNode,
276                                   &pDirNode->NameInformation.FileName);
277                 }
278
279                 //
280                 // Insert the node into the name tree
281                 //
282
283                 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
284
285                 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
286                 {
287
288                     ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = pDirNode;
289
290                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
291                                   AFS_TRACE_LEVEL_VERBOSE,
292                                   "AFSEnumerateDirectory Insert DE %p to head of case sensitive tree for %wZ\n",
293                                   pDirNode,
294                                   &pDirNode->NameInformation.FileName);
295                 }
296                 else
297                 {
298
299                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
300                                   AFS_TRACE_LEVEL_VERBOSE,
301                                   "AFSEnumerateDirectory Insert DE %p to case sensitive tree for %wZ\n",
302                                   pDirNode,
303                                   &pDirNode->NameInformation.FileName);
304
305                     AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
306                                                     pDirNode);
307                 }
308
309                 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
310                 {
311
312                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
313                                   AFS_TRACE_LEVEL_VERBOSE,
314                                   "AFSEnumerateDirectory Insert DE %p to head of case insensitive tree for %wZ\n",
315                                   pDirNode,
316                                   &pDirNode->NameInformation.FileName);
317
318                     ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = pDirNode;
319
320                     SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
321                 }
322                 else
323                 {
324
325                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
326                                   AFS_TRACE_LEVEL_VERBOSE,
327                                   "AFSEnumerateDirectory Insert DE %p to case insensitive tree for %wZ\n",
328                                   pDirNode,
329                                   &pDirNode->NameInformation.FileName);
330
331                     AFSInsertCaseInsensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
332                                                       pDirNode);
333                 }
334
335                 if( ObjectInfoCB->Specific.Directory.DirectoryNodeListHead == NULL)
336                 {
337
338                     ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = pDirNode;
339                 }
340                 else
341                 {
342
343                     ObjectInfoCB->Specific.Directory.DirectoryNodeListTail->ListEntry.fLink = pDirNode;
344
345                     pDirNode->ListEntry.bLink = ObjectInfoCB->Specific.Directory.DirectoryNodeListTail;
346                 }
347
348                 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = pDirNode;
349
350                 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
351
352                 InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeCount);
353
354                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
355                               AFS_TRACE_LEVEL_VERBOSE,
356                               "AFSEnumerateDirectory Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
357                               &pDirNode->NameInformation.FileName,
358                               ObjectInfoCB->Specific.Directory.DirectoryNodeCount,
359                               ObjectInfoCB->FileId.Cell,
360                               ObjectInfoCB->FileId.Volume,
361                               ObjectInfoCB->FileId.Vnode,
362                               ObjectInfoCB->FileId.Unique);
363
364                 if( pDirNode->Type.Data.ShortNameTreeEntry.HashIndex != 0)
365                 {
366
367                     //
368                     // Insert the short name entry if we have a valid short name
369                     //
370
371                     if( ObjectInfoCB->Specific.Directory.ShortNameTree == NULL)
372                     {
373
374                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
375                                       AFS_TRACE_LEVEL_VERBOSE,
376                                       "AFSEnumerateDirectory Insert DE %p to head of shortname tree for %wZ\n",
377                                       pDirNode,
378                                       &pDirNode->NameInformation.FileName);
379
380                         ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
381                     }
382                     else
383                     {
384
385                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
386                                       AFS_TRACE_LEVEL_VERBOSE,
387                                       "AFSEnumerateDirectory Insert DE %p to shortname tree for %wZ\n",
388                                       pDirNode,
389                                       &pDirNode->NameInformation.FileName);
390
391                         AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
392                                                     pDirNode);
393                     }
394                 }
395
396                 //
397                 // Next dir entry
398                 //
399
400                 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
401
402                 if( ulResultLen >= ulEntryLength)
403                 {
404                     ulResultLen -= ulEntryLength;
405                 }
406                 else
407                 {
408                     ulResultLen = 0;
409                 }
410             }
411
412             ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
413
414             //
415             // Reset the information in the request buffer since it got trampled
416             // above
417             //
418
419             pDirQueryCB->EnumHandle = pDirEnumResponse->EnumHandle;
420
421             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
422                           AFS_TRACE_LEVEL_VERBOSE,
423                           "AFSEnumerateDirectory EnumHandle %08lX\n",
424                           pDirQueryCB->EnumHandle);
425
426             //
427             // If the enumeration handle is -1 then we are done
428             //
429
430             if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
431             {
432
433                 break;
434             }
435         }
436
437 try_exit:
438
439         //
440         // Cleanup
441         //
442
443         if( pBuffer != NULL)
444         {
445
446             AFSExFreePool( pBuffer);
447         }
448
449         //
450         // If the processing failed then we should reset the directory content in the event
451         // it is re-enumerated
452         //
453
454         if( !NT_SUCCESS( ntStatus))
455         {
456
457             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
458                           AFS_TRACE_LEVEL_ERROR,
459                           "AFSEnumerateDirectory Resetting content for FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
460                           ObjectInfoCB->FileId.Cell,
461                           ObjectInfoCB->FileId.Volume,
462                           ObjectInfoCB->FileId.Vnode,
463                           ObjectInfoCB->FileId.Unique,
464                           ntStatus);
465
466             AFSResetDirectoryContent( ObjectInfoCB);
467         }
468     }
469
470     return ntStatus;
471 }
472
473 NTSTATUS
474 AFSEnumerateDirectoryNoResponse( IN GUID *AuthGroup,
475                                  IN AFSFileID *FileId)
476 {
477
478     NTSTATUS ntStatus = STATUS_SUCCESS;
479     AFSDirQueryCB stDirQueryCB;
480     ULONG   ulRequestFlags = 0;
481
482     __Enter
483     {
484
485         //
486         // Use the payload buffer for information we will pass to the service
487         //
488
489         stDirQueryCB.EnumHandle = 0;
490
491         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
492                                       ulRequestFlags,
493                                       AuthGroup,
494                                       NULL,
495                                       FileId,
496                                       (void *)&stDirQueryCB,
497                                       sizeof( AFSDirQueryCB),
498                                       NULL,
499                                       NULL);
500
501         if( ntStatus != STATUS_SUCCESS)
502         {
503
504             if( ntStatus == STATUS_NO_MORE_FILES ||
505                 ntStatus == STATUS_NO_MORE_ENTRIES)
506             {
507
508                 ntStatus = STATUS_SUCCESS;
509             }
510             else
511             {
512
513                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
514                               AFS_TRACE_LEVEL_ERROR,
515                               "AFSEnumerateDirectoryNoResponse Failed to enumerate directory Status %08lX\n",
516                               ntStatus);
517             }
518         }
519     }
520
521     return ntStatus;
522 }
523
524 NTSTATUS
525 AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
526                            IN GUID *AuthGroup)
527 {
528
529     NTSTATUS ntStatus = STATUS_SUCCESS;
530     void *pBuffer = NULL;
531     ULONG ulResultLen = 0;
532     AFSDirQueryCB *pDirQueryCB;
533     AFSDirEnumEntry *pCurrentDirEntry = NULL;
534     AFSDirectoryCB *pDirNode = NULL;
535     ULONG  ulEntryLength = 0;
536     AFSDirEnumResp *pDirEnumResponse = NULL;
537     UNICODE_STRING uniDirName, uniTargetName;
538     ULONG   ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_FAST_REQUEST;
539     ULONG ulCRC = 0;
540     AFSObjectInfoCB *pObjectInfo = NULL;
541     ULONGLONG ullIndex = 0;
542     UNICODE_STRING uniGUID;
543
544     __Enter
545     {
546
547         uniGUID.Length = 0;
548         uniGUID.MaximumLength = 0;
549         uniGUID.Buffer = NULL;
550
551         if( AuthGroup != NULL)
552         {
553             RtlStringFromGUID( *AuthGroup,
554                                &uniGUID);
555         }
556
557         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
558                       AFS_TRACE_LEVEL_VERBOSE,
559                       "AFSVerifyDirectoryContent Verifying content for FID %08lX-%08lX-%08lX-%08lX AuthGroup %wZ\n",
560                       ObjectInfoCB->FileId.Cell,
561                       ObjectInfoCB->FileId.Volume,
562                       ObjectInfoCB->FileId.Vnode,
563                       ObjectInfoCB->FileId.Unique,
564                       &uniGUID);
565
566         if( AuthGroup != NULL)
567         {
568             RtlFreeUnicodeString( &uniGUID);
569         }
570
571         //
572         // Initialize the directory enumeration buffer for the directory
573         //
574
575         pBuffer = AFSExAllocatePoolWithTag( PagedPool,
576                                             AFS_DIR_ENUM_BUFFER_LEN,
577                                             AFS_DIR_BUFFER_TAG);
578
579         if( pBuffer == NULL)
580         {
581
582             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
583         }
584
585         RtlZeroMemory( pBuffer,
586                        AFS_DIR_ENUM_BUFFER_LEN);
587
588         ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
589
590         //
591         // Use the payload buffer for information we will pass to the service
592         //
593
594         pDirQueryCB = (AFSDirQueryCB *)pBuffer;
595
596         pDirQueryCB->EnumHandle = 0;
597
598         //
599         // Loop on the information
600         //
601
602         while( TRUE)
603         {
604
605             //
606             // Go and retrieve the directory contents
607             //
608
609             ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DIR_ENUM,
610                                           ulRequestFlags,
611                                           AuthGroup,
612                                           NULL,
613                                           &ObjectInfoCB->FileId,
614                                           (void *)pDirQueryCB,
615                                           sizeof( AFSDirQueryCB),
616                                           pBuffer,
617                                           &ulResultLen);
618
619             if( ntStatus != STATUS_SUCCESS ||
620                 ulResultLen == 0)
621             {
622
623                 if( ntStatus == STATUS_NO_MORE_FILES ||
624                     ntStatus == STATUS_NO_MORE_ENTRIES)
625                 {
626
627                     ntStatus = STATUS_SUCCESS;
628                 }
629                 else
630                 {
631
632                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
633                                   AFS_TRACE_LEVEL_ERROR,
634                                   "AFSVerifyDirectoryContent Failed to enumerate directory Status %08lX\n",
635                                   ntStatus);
636                 }
637
638                 break;
639             }
640
641             pDirEnumResponse = (AFSDirEnumResp *)pBuffer;
642
643             pCurrentDirEntry = (AFSDirEnumEntry *)pDirEnumResponse->Entry;
644
645             //
646             // Remove the leading header from the processed length
647             //
648
649             ulResultLen -= FIELD_OFFSET( AFSDirEnumResp, Entry);
650
651             while( ulResultLen > 0)
652             {
653
654                 uniDirName.Length = (USHORT)pCurrentDirEntry->FileNameLength;
655
656                 uniDirName.MaximumLength = uniDirName.Length;
657
658                 uniDirName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->FileNameOffset);
659
660                 uniTargetName.Length = (USHORT)pCurrentDirEntry->TargetNameLength;
661
662                 uniTargetName.MaximumLength = uniTargetName.Length;
663
664                 uniTargetName.Buffer = (WCHAR *)((char *)pCurrentDirEntry + pCurrentDirEntry->TargetNameOffset);
665
666                 //
667                 // Does this entry already exist in the directory?
668                 //
669
670                 ulCRC = AFSGenerateCRC( &uniDirName,
671                                         FALSE);
672
673                 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
674
675                 AFSLocateCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
676                                                 ulCRC,
677                                                 &pDirNode);
678
679                 //
680                 //
681                 // Set up the entry length
682                 //
683
684                 ulEntryLength = QuadAlign( sizeof( AFSDirEnumEntry) +
685                                            pCurrentDirEntry->FileNameLength +
686                                            pCurrentDirEntry->TargetNameLength);
687
688                 if( pDirNode != NULL)
689                 {
690
691                     //
692                     // Check that the FIDs are the same
693                     //
694
695                     if( AFSIsEqualFID( &pCurrentDirEntry->FileId,
696                                        &pDirNode->ObjectInformation->FileId))
697                     {
698
699                         AFSAcquireShared( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
700                                           TRUE);
701
702                         ullIndex = AFSCreateLowIndex( &pCurrentDirEntry->FileId);
703
704                         ntStatus = AFSLocateHashEntry( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeHead,
705                                                        ullIndex,
706                                                        (AFSBTreeEntry **)&pObjectInfo);
707
708                         AFSReleaseResource( ObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
709
710                         if( NT_SUCCESS( ntStatus) &&
711                             pObjectInfo != NULL)
712                         {
713
714                             //
715                             // Indicate this is a valid entry
716                             //
717
718                             SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
719
720                             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
721                                           AFS_TRACE_LEVEL_VERBOSE,
722                                           "AFSVerifyDirectoryContent Verified entry %wZ for parent FID %08lX-%08lX-%08lX-%08lX\n",
723                                           &uniDirName,
724                                           ObjectInfoCB->FileId.Cell,
725                                           ObjectInfoCB->FileId.Volume,
726                                           ObjectInfoCB->FileId.Vnode,
727                                           ObjectInfoCB->FileId.Unique);
728
729
730                             //
731                             // Update the metadata for the entry
732                             //
733
734                             if( pObjectInfo->DataVersion.QuadPart == 0 ||
735                                 pObjectInfo->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
736                             {
737
738                                 AFSUpdateMetaData( pDirNode,
739                                                    pCurrentDirEntry);
740
741                                 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
742                                 {
743
744                                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
745                                                   AFS_TRACE_LEVEL_VERBOSE,
746                                                   "AFSVerifyDirectoryContent Setting VERIFY on entry %wZ for FID %08lX-%08lX-%08lX-%08lX\n",
747                                                   &uniDirName,
748                                                   ObjectInfoCB->FileId.Cell,
749                                                   ObjectInfoCB->FileId.Volume,
750                                                   ObjectInfoCB->FileId.Vnode,
751                                                   ObjectInfoCB->FileId.Unique);
752
753                                     SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
754                                     pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
755                                     pObjectInfo->Expiration.QuadPart = 0;
756                                 }
757                             }
758
759                             //
760                             // Next dir entry
761                             //
762
763                             pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
764
765                             if( ulResultLen >= ulEntryLength)
766                             {
767                                 ulResultLen -= ulEntryLength;
768                             }
769                             else
770                             {
771                                 ulResultLen = 0;
772                             }
773
774                             continue;
775                         }
776                     }
777
778                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
779                                   AFS_TRACE_LEVEL_VERBOSE,
780                                   "AFSVerifyDirectoryContent Processing dir entry %wZ with different FID, same name in parent FID %08lX-%08lX-%08lX-%08lX\n",
781                                   &pDirNode->NameInformation.FileName,
782                                   ObjectInfoCB->FileId.Cell,
783                                   ObjectInfoCB->FileId.Volume,
784                                   ObjectInfoCB->FileId.Vnode,
785                                   ObjectInfoCB->FileId.Unique);
786
787                     //
788                     // Need to tear down this entry and rebuild it below
789                     //
790
791                     if( pDirNode->OpenReferenceCount == 0)
792                     {
793
794                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
795                                       AFS_TRACE_LEVEL_VERBOSE,
796                                       "AFSVerifyDirectoryContent Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
797                                       &pDirNode->NameInformation.FileName,
798                                       ObjectInfoCB->FileId.Cell,
799                                       ObjectInfoCB->FileId.Volume,
800                                       ObjectInfoCB->FileId.Vnode,
801                                       ObjectInfoCB->FileId.Unique);
802
803                         AFSDeleteDirEntry( ObjectInfoCB,
804                                            pDirNode);
805                     }
806                     else
807                     {
808
809                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
810                                       AFS_TRACE_LEVEL_VERBOSE,
811                                       "AFSVerifyDirectoryContent Setting dir entry %p name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
812                                       pDirNode,
813                                       &pDirNode->NameInformation.FileName,
814                                       ObjectInfoCB->FileId.Cell,
815                                       ObjectInfoCB->FileId.Volume,
816                                       ObjectInfoCB->FileId.Vnode,
817                                       ObjectInfoCB->FileId.Unique);
818
819                         SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_DELETED);
820
821                         AFSRemoveNameEntry( ObjectInfoCB,
822                                             pDirNode);
823                     }
824                 }
825
826                 pDirNode = AFSInitDirEntry( ObjectInfoCB,
827                                             &uniDirName,
828                                             &uniTargetName,
829                                             pCurrentDirEntry,
830                                             (ULONG)InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.ContentIndex));
831
832                 if( pDirNode == NULL)
833                 {
834
835                     ntStatus = STATUS_INSUFFICIENT_RESOURCES;
836
837                     break;
838                 }
839
840                 //
841                 // Init the short name if we have one
842                 //
843
844                 if( pCurrentDirEntry->ShortNameLength > 0)
845                 {
846
847                     UNICODE_STRING uniShortName;
848
849                     pDirNode->NameInformation.ShortNameLength = pCurrentDirEntry->ShortNameLength;
850
851                     RtlCopyMemory( pDirNode->NameInformation.ShortName,
852                                    pCurrentDirEntry->ShortName,
853                                    pDirNode->NameInformation.ShortNameLength);
854
855                     //
856                     // Generate the short name index
857                     //
858
859                     uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
860                     uniShortName.Buffer = pDirNode->NameInformation.ShortName;
861
862                     pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
863                                                                                        TRUE);
864
865                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
866                                   AFS_TRACE_LEVEL_VERBOSE,
867                                   "AFSVerifyDirectoryContent Initialized short name %wZ for DE %p for %wZ\n",
868                                   &uniShortName,
869                                   pDirNode,
870                                   &pDirNode->NameInformation.FileName);
871                 }
872
873                 //
874                 // Insert the node into the name tree
875                 //
876
877                 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
878
879                 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead == NULL)
880                 {
881
882                     ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = pDirNode;
883
884                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
885                                   AFS_TRACE_LEVEL_VERBOSE,
886                                   "AFSVerifyDirectoryContent Insert DE %p to head of case sensitive tree for %wZ\n",
887                                   pDirNode,
888                                   &pDirNode->NameInformation.FileName);
889                 }
890                 else
891                 {
892
893                     AFSInsertCaseSensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
894                                                     pDirNode);
895
896                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
897                                   AFS_TRACE_LEVEL_VERBOSE,
898                                   "AFSVerifyDirectoryContent Insert DE %p to case sensitive tree for %wZ\n",
899                                   pDirNode,
900                                   &pDirNode->NameInformation.FileName);
901                 }
902
903                 if( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead == NULL)
904                 {
905
906                     ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = pDirNode;
907
908                     SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
909
910                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
911                                   AFS_TRACE_LEVEL_VERBOSE,
912                                   "AFSVerifyDirectoryContent Insert DE %p to head of case insensitive tree for %wZ\n",
913                                   pDirNode,
914                                   &pDirNode->NameInformation.FileName);
915                 }
916                 else
917                 {
918
919                     AFSInsertCaseInsensitiveDirEntry( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
920                                                       pDirNode);
921
922                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
923                                   AFS_TRACE_LEVEL_VERBOSE,
924                                   "AFSVerifyDirectoryContent Insert DE %p to case insensitive tree for %wZ\n",
925                                   pDirNode,
926                                   &pDirNode->NameInformation.FileName);
927                 }
928
929                 if( ObjectInfoCB->Specific.Directory.DirectoryNodeListHead == NULL)
930                 {
931
932                     ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = pDirNode;
933                 }
934                 else
935                 {
936
937                     (ObjectInfoCB->Specific.Directory.DirectoryNodeListTail)->ListEntry.fLink = pDirNode;
938
939                     pDirNode->ListEntry.bLink = ObjectInfoCB->Specific.Directory.DirectoryNodeListTail;
940                 }
941
942                 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = pDirNode;
943
944                 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_INSERTED_ENUM_LIST);
945
946                 InterlockedIncrement( &ObjectInfoCB->Specific.Directory.DirectoryNodeCount);
947
948                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
949                               AFS_TRACE_LEVEL_VERBOSE,
950                               "AFSVerifyDirectoryContent Adding entry %wZ Inc Count %d to parent FID %08lX-%08lX-%08lX-%08lX\n",
951                               &pDirNode->NameInformation.FileName,
952                               ObjectInfoCB->Specific.Directory.DirectoryNodeCount,
953                               ObjectInfoCB->FileId.Cell,
954                               ObjectInfoCB->FileId.Volume,
955                               ObjectInfoCB->FileId.Vnode,
956                               ObjectInfoCB->FileId.Unique);
957
958                 if( pDirNode->Type.Data.ShortNameTreeEntry.HashIndex != 0)
959                 {
960
961                     //
962                     // Insert the short name entry if we have a valid short name
963                     //
964
965                     if( ObjectInfoCB->Specific.Directory.ShortNameTree == NULL)
966                     {
967
968                         ObjectInfoCB->Specific.Directory.ShortNameTree = pDirNode;
969
970                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
971                                       AFS_TRACE_LEVEL_VERBOSE,
972                                       "AFSVerifyDirectoryContent Insert DE %p to head of shortname tree for %wZ\n",
973                                       pDirNode,
974                                       &pDirNode->NameInformation.FileName);
975                     }
976                     else
977                     {
978
979                         AFSInsertShortNameDirEntry( ObjectInfoCB->Specific.Directory.ShortNameTree,
980                                                     pDirNode);
981
982                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
983                                       AFS_TRACE_LEVEL_VERBOSE,
984                                       "AFSVerifyDirectoryContent Insert DE %p to shortname tree for %wZ\n",
985                                       pDirNode,
986                                       &pDirNode->NameInformation.FileName);
987                     }
988                 }
989
990                 //
991                 // Next dir entry
992                 //
993
994                 pCurrentDirEntry = (AFSDirEnumEntry *)((char *)pCurrentDirEntry + ulEntryLength);
995
996                 if( ulResultLen >= ulEntryLength)
997                 {
998                     ulResultLen -= ulEntryLength;
999                 }
1000                 else
1001                 {
1002                     ulResultLen = 0;
1003                 }
1004             }
1005
1006             ulResultLen = AFS_DIR_ENUM_BUFFER_LEN;
1007
1008             //
1009             // Reset the information in the request buffer since it got trampled
1010             // above
1011             //
1012
1013             pDirQueryCB->EnumHandle = pDirEnumResponse->EnumHandle;
1014
1015             //
1016             // If the enumeration handle is -1 then we are done
1017             //
1018
1019             if( ((ULONG)-1) == pDirQueryCB->EnumHandle )
1020             {
1021
1022                 break;
1023             }
1024         }
1025
1026 try_exit:
1027
1028         //
1029         // Cleanup
1030         //
1031
1032         if( pBuffer != NULL)
1033         {
1034
1035             AFSExFreePool( pBuffer);
1036         }
1037     }
1038
1039     return ntStatus;
1040 }
1041
1042 NTSTATUS
1043 AFSNotifyFileCreate( IN GUID            *AuthGroup,
1044                      IN AFSObjectInfoCB *ParentObjectInfo,
1045                      IN PLARGE_INTEGER FileSize,
1046                      IN ULONG FileAttributes,
1047                      IN UNICODE_STRING *FileName,
1048                      OUT AFSDirectoryCB **DirNode)
1049 {
1050
1051     NTSTATUS ntStatus = STATUS_SUCCESS;
1052     AFSFileCreateCB stCreateCB;
1053     AFSFileCreateResultCB *pResultCB = NULL;
1054     ULONG ulResultLen = 0;
1055     UNICODE_STRING uniTargetName;
1056     AFSDirectoryCB *pDirNode = NULL;
1057     ULONG     ulCRC = 0;
1058     LARGE_INTEGER liOldDataVersion;
1059
1060     __Enter
1061     {
1062
1063         //
1064         // Init the control block for the request
1065         //
1066
1067         RtlZeroMemory( &stCreateCB,
1068                        sizeof( AFSFileCreateCB));
1069
1070         stCreateCB.ParentId = ParentObjectInfo->FileId;
1071
1072         stCreateCB.AllocationSize = *FileSize;
1073
1074         stCreateCB.FileAttributes = FileAttributes;
1075
1076         stCreateCB.EaSize = 0;
1077
1078         liOldDataVersion = ParentObjectInfo->DataVersion;
1079
1080         //
1081         // Allocate our return buffer
1082         //
1083
1084         pResultCB = (AFSFileCreateResultCB *)AFSExAllocatePoolWithTag( PagedPool,
1085                                                                        PAGE_SIZE,
1086                                                                        AFS_GENERIC_MEMORY_1_TAG);
1087
1088         if( pResultCB == NULL)
1089         {
1090
1091             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1092         }
1093
1094         RtlZeroMemory( pResultCB,
1095                        PAGE_SIZE);
1096
1097         ulResultLen = PAGE_SIZE;
1098
1099         //
1100         // Send the call to the service
1101         //
1102
1103         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CREATE_FILE,
1104                                       AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1105                                       AuthGroup,
1106                                       FileName,
1107                                       NULL,
1108                                       &stCreateCB,
1109                                       sizeof( AFSFileCreateCB),
1110                                       pResultCB,
1111                                       &ulResultLen);
1112
1113         if( ntStatus != STATUS_SUCCESS)
1114         {
1115
1116             if( NT_SUCCESS( ntStatus))
1117             {
1118
1119                 ntStatus = STATUS_DEVICE_NOT_READY;
1120             }
1121
1122             try_return( ntStatus);
1123         }
1124
1125         //
1126         // We may have raced with an invalidation call and a subsequent re-enumeration of this parent
1127         // and though we created the node, it is already in our list. If this is the case then
1128         // look up the entry rather than create a new entry
1129         // The check is to ensure the DV has been modified
1130         //
1131
1132         if( liOldDataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1 ||
1133             liOldDataVersion.QuadPart != ParentObjectInfo->DataVersion.QuadPart)
1134         {
1135
1136             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1137                           AFS_TRACE_LEVEL_VERBOSE,
1138                           "AFSNotifyFileCreate Raced with an invalidate call and a re-enumeration for entry %wZ\n",
1139                           FileName);
1140
1141             //
1142             // We raced so go and lookup the directory entry in the parent
1143             //
1144
1145             ulCRC = AFSGenerateCRC( FileName,
1146                                     FALSE);
1147
1148             AFSAcquireShared( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
1149                               TRUE);
1150
1151             AFSLocateCaseSensitiveDirEntry( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1152                                             ulCRC,
1153                                             &pDirNode);
1154
1155             AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
1156
1157             if( pDirNode != NULL)
1158             {
1159
1160                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1161                               AFS_TRACE_LEVEL_VERBOSE,
1162                               "AFSNotifyFileCreate Located dir entry for file %wZ\n",
1163                               FileName);
1164
1165                 *DirNode = pDirNode;
1166
1167                 try_return( ntStatus = STATUS_REPARSE);
1168             }
1169
1170             //
1171             // We are unsure of our current data so set the verify flag. It may already be set
1172             // but no big deal to reset it
1173             //
1174
1175             SetFlag( ParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1176
1177             ParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1178         }
1179         else
1180         {
1181
1182             //
1183             // Update the parent data version
1184             //
1185
1186             ParentObjectInfo->DataVersion = pResultCB->ParentDataVersion;
1187         }
1188
1189         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1190                       AFS_TRACE_LEVEL_VERBOSE,
1191                       "AFSNotifyFileCreate Creating new entry %wZ\n",
1192                       FileName);
1193
1194         //
1195         // Initialize the directory entry
1196         //
1197
1198         uniTargetName.Length = (USHORT)pResultCB->DirEnum.TargetNameLength;
1199
1200         uniTargetName.MaximumLength = uniTargetName.Length;
1201
1202         uniTargetName.Buffer = (WCHAR *)((char *)&pResultCB->DirEnum + pResultCB->DirEnum.TargetNameOffset);
1203
1204         pDirNode = AFSInitDirEntry( ParentObjectInfo,
1205                                     FileName,
1206                                     &uniTargetName,
1207                                     &pResultCB->DirEnum,
1208                                     (ULONG)InterlockedIncrement( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.ContentIndex));
1209
1210         if( pDirNode == NULL)
1211         {
1212
1213             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1214         }
1215
1216         //
1217         // Init the short name if we have one
1218         //
1219
1220         if( pResultCB->DirEnum.ShortNameLength > 0)
1221         {
1222
1223             UNICODE_STRING uniShortName;
1224
1225             pDirNode->NameInformation.ShortNameLength = pResultCB->DirEnum.ShortNameLength;
1226
1227             RtlCopyMemory( pDirNode->NameInformation.ShortName,
1228                            pResultCB->DirEnum.ShortName,
1229                            pDirNode->NameInformation.ShortNameLength);
1230
1231             //
1232             // Generate the short name index
1233             //
1234
1235             uniShortName.Length = pDirNode->NameInformation.ShortNameLength;
1236             uniShortName.Buffer = pDirNode->NameInformation.ShortName;
1237
1238             pDirNode->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
1239                                                                                TRUE);
1240
1241             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1242                           AFS_TRACE_LEVEL_VERBOSE,
1243                           "AFSNotifyFileCreate Initialized short name %wZ for DE %p for %wZ\n",
1244                           &uniShortName,
1245                           pDirNode,
1246                           &pDirNode->NameInformation.FileName);
1247         }
1248
1249         //
1250         // Return the directory node
1251         //
1252
1253         *DirNode = pDirNode;
1254
1255 try_exit:
1256
1257         if( pResultCB != NULL)
1258         {
1259
1260             AFSExFreePool( pResultCB);
1261         }
1262     }
1263
1264     return ntStatus;
1265 }
1266
1267 NTSTATUS
1268 AFSUpdateFileInformation( IN AFSFileID *ParentFid,
1269                           IN AFSObjectInfoCB *ObjectInfo,
1270                           IN GUID *AuthGroup)
1271 {
1272
1273     NTSTATUS ntStatus = STATUS_SUCCESS;
1274     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1275     AFSFileUpdateCB stUpdateCB;
1276     ULONG ulResultLen = 0;
1277     AFSFileUpdateResultCB *pUpdateResultCB = NULL;
1278
1279     __Enter
1280     {
1281
1282         //
1283         // Init the control block for the request
1284         //
1285
1286         RtlZeroMemory( &stUpdateCB,
1287                        sizeof( AFSFileUpdateCB));
1288
1289         stUpdateCB.AllocationSize = ObjectInfo->EndOfFile;
1290
1291         stUpdateCB.FileAttributes = ObjectInfo->FileAttributes;
1292
1293         stUpdateCB.EaSize = ObjectInfo->EaSize;
1294
1295         stUpdateCB.ParentId = *ParentFid;
1296
1297         stUpdateCB.LastAccessTime = ObjectInfo->LastAccessTime;
1298
1299         stUpdateCB.CreateTime = ObjectInfo->CreationTime;
1300
1301         stUpdateCB.ChangeTime = ObjectInfo->ChangeTime;
1302
1303         stUpdateCB.LastWriteTime = ObjectInfo->LastWriteTime;
1304
1305         pUpdateResultCB = (AFSFileUpdateResultCB *)AFSExAllocatePoolWithTag( PagedPool,
1306                                                                              PAGE_SIZE,
1307                                                                              AFS_UPDATE_RESULT_TAG);
1308
1309         if( pUpdateResultCB == NULL)
1310         {
1311
1312             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1313         }
1314
1315         ulResultLen = PAGE_SIZE;
1316
1317         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_UPDATE_FILE,
1318                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
1319                                       AuthGroup,
1320                                       NULL,
1321                                       &ObjectInfo->FileId,
1322                                       &stUpdateCB,
1323                                       sizeof( AFSFileUpdateCB),
1324                                       pUpdateResultCB,
1325                                       &ulResultLen);
1326
1327         if( ntStatus != STATUS_SUCCESS)
1328         {
1329
1330             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1331                           AFS_TRACE_LEVEL_ERROR,
1332                           "AFSUpdateFileInformation failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1333                           ObjectInfo->FileId.Cell,
1334                           ObjectInfo->FileId.Volume,
1335                           ObjectInfo->FileId.Vnode,
1336                           ObjectInfo->FileId.Unique,
1337                           ntStatus);
1338
1339             try_return( ntStatus);
1340         }
1341
1342         //
1343         // Update the data version
1344         //
1345
1346         ObjectInfo->DataVersion = pUpdateResultCB->DirEnum.DataVersion;
1347
1348 try_exit:
1349
1350         if( pUpdateResultCB != NULL)
1351         {
1352
1353             AFSExFreePool( pUpdateResultCB);
1354         }
1355     }
1356
1357     return ntStatus;
1358 }
1359
1360 NTSTATUS
1361 AFSNotifyDelete( IN AFSDirectoryCB *DirectoryCB,
1362                  IN BOOLEAN CheckOnly)
1363 {
1364     NTSTATUS ntStatus = STATUS_SUCCESS;
1365     ULONG ulResultLen = 0;
1366     AFSFileDeleteCB stDelete;
1367     AFSFileDeleteResultCB stDeleteResult;
1368     ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
1369     GUID *pAuthGroup = NULL;
1370
1371     __Enter
1372     {
1373
1374         stDelete.ParentId = DirectoryCB->ObjectInformation->ParentObjectInformation->FileId;
1375
1376         stDelete.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
1377
1378         ulResultLen = sizeof( AFSFileDeleteResultCB);
1379
1380         if( CheckOnly)
1381         {
1382             ulRequestFlags |= AFS_REQUEST_FLAG_CHECK_ONLY;
1383         }
1384
1385         if( DirectoryCB->ObjectInformation->Fcb != NULL)
1386         {
1387             pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
1388         }
1389
1390         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DELETE_FILE,
1391                                       ulRequestFlags,
1392                                       pAuthGroup,
1393                                       &DirectoryCB->NameInformation.FileName,
1394                                       &DirectoryCB->ObjectInformation->FileId,
1395                                       &stDelete,
1396                                       sizeof( AFSFileDeleteCB),
1397                                       &stDeleteResult,
1398                                       &ulResultLen);
1399
1400         if( ntStatus != STATUS_SUCCESS)
1401         {
1402
1403             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1404                           AFS_TRACE_LEVEL_ERROR,
1405                           "AFSNotifyDelete failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1406                           &DirectoryCB->ObjectInformation->FileId.Cell,
1407                           &DirectoryCB->ObjectInformation->FileId.Volume,
1408                           &DirectoryCB->ObjectInformation->FileId.Vnode,
1409                           &DirectoryCB->ObjectInformation->FileId.Unique,
1410                           ntStatus);
1411
1412             try_return( ntStatus);
1413         }
1414
1415         if( !CheckOnly)
1416         {
1417
1418             //
1419             // Update the parent data version
1420             //
1421
1422             if( DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart != stDeleteResult.ParentDataVersion.QuadPart)
1423             {
1424
1425                 SetFlag( DirectoryCB->ObjectInformation->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1426
1427                 DirectoryCB->ObjectInformation->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1428             }
1429         }
1430
1431 try_exit:
1432
1433         NOTHING;
1434     }
1435
1436     return ntStatus;
1437 }
1438
1439 NTSTATUS
1440 AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo,
1441                  IN AFSObjectInfoCB *ParentObjectInfo,
1442                  IN AFSObjectInfoCB *TargetParentObjectInfo,
1443                  IN AFSDirectoryCB *DirectoryCB,
1444                  IN UNICODE_STRING *TargetName,
1445                  OUT AFSFileID  *UpdatedFID)
1446 {
1447
1448     NTSTATUS ntStatus = STATUS_SUCCESS;
1449     AFSFileRenameCB *pRenameCB = NULL;
1450     AFSFileRenameResultCB *pRenameResultCB = NULL;
1451     ULONG ulResultLen = 0;
1452     GUID *pAuthGroup = NULL;
1453
1454     __Enter
1455     {
1456
1457         //
1458         // Init the control block for the request
1459         //
1460
1461         pRenameCB = (AFSFileRenameCB *)AFSExAllocatePoolWithTag( PagedPool,
1462                                                                  PAGE_SIZE,
1463                                                                  AFS_RENAME_REQUEST_TAG);
1464
1465         if( pRenameCB == NULL)
1466         {
1467
1468             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1469         }
1470
1471         RtlZeroMemory( pRenameCB,
1472                        PAGE_SIZE);
1473
1474         pRenameCB->SourceParentId = ParentObjectInfo->FileId;
1475
1476         pRenameCB->TargetParentId = TargetParentObjectInfo->FileId;
1477
1478         pRenameCB->TargetNameLength = TargetName->Length;
1479
1480         RtlCopyMemory( pRenameCB->TargetName,
1481                        TargetName->Buffer,
1482                        TargetName->Length);
1483
1484         if( ObjectInfo->Fcb != NULL)
1485         {
1486             pAuthGroup = &ObjectInfo->Fcb->AuthGroup;
1487         }
1488
1489         //
1490         // Use the same buffer for the result control block
1491         //
1492
1493         pRenameResultCB = (AFSFileRenameResultCB *)pRenameCB;
1494
1495         ulResultLen = PAGE_SIZE;
1496
1497         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RENAME_FILE,
1498                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
1499                                       pAuthGroup,
1500                                       &DirectoryCB->NameInformation.FileName,
1501                                       &ObjectInfo->FileId,
1502                                       pRenameCB,
1503                                       sizeof( AFSFileRenameCB) + TargetName->Length,
1504                                       pRenameResultCB,
1505                                       &ulResultLen);
1506
1507         if( ntStatus != STATUS_SUCCESS)
1508         {
1509
1510             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1511                           AFS_TRACE_LEVEL_ERROR,
1512                           "AFSNotifyRename failed FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1513                           ObjectInfo->FileId.Cell,
1514                           ObjectInfo->FileId.Volume,
1515                           ObjectInfo->FileId.Vnode,
1516                           ObjectInfo->FileId.Unique,
1517                           ntStatus);
1518
1519             try_return( ntStatus);
1520         }
1521
1522         //
1523         // Update the information from the returned data
1524         //
1525
1526         ParentObjectInfo->DataVersion = pRenameResultCB->SourceParentDataVersion;
1527
1528         TargetParentObjectInfo->DataVersion = pRenameResultCB->TargetParentDataVersion;
1529
1530         //
1531         // Move over the short name
1532         //
1533
1534         DirectoryCB->NameInformation.ShortNameLength = pRenameResultCB->DirEnum.ShortNameLength;
1535
1536         if( DirectoryCB->NameInformation.ShortNameLength > 0)
1537         {
1538
1539             RtlCopyMemory( DirectoryCB->NameInformation.ShortName,
1540                            pRenameResultCB->DirEnum.ShortName,
1541                            DirectoryCB->NameInformation.ShortNameLength);
1542         }
1543
1544         if( UpdatedFID != NULL)
1545         {
1546
1547             *UpdatedFID = pRenameResultCB->DirEnum.FileId;
1548         }
1549
1550 try_exit:
1551
1552         if( pRenameCB != NULL)
1553         {
1554
1555             AFSExFreePool( pRenameCB);
1556         }
1557     }
1558
1559     return ntStatus;
1560 }
1561
1562 NTSTATUS
1563 AFSEvaluateTargetByID( IN AFSObjectInfoCB *ObjectInfo,
1564                        IN GUID *AuthGroup,
1565                        IN BOOLEAN FastCall,
1566                        OUT AFSDirEnumEntry **DirEnumEntry)
1567 {
1568
1569     NTSTATUS ntStatus = STATUS_SUCCESS;
1570     AFSEvalTargetCB stTargetID;
1571     ULONG ulResultBufferLength;
1572     AFSDirEnumEntry *pDirEnumCB = NULL;
1573     ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
1574
1575     __Enter
1576     {
1577
1578         RtlZeroMemory( &stTargetID,
1579                        sizeof( AFSEvalTargetCB));
1580
1581         if( ObjectInfo->ParentObjectInformation != NULL)
1582         {
1583
1584             stTargetID.ParentId = ObjectInfo->ParentObjectInformation->FileId;
1585         }
1586
1587         //
1588         // Allocate our response buffer
1589         //
1590
1591         pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
1592                                                                   PAGE_SIZE,
1593                                                                   AFS_GENERIC_MEMORY_2_TAG);
1594
1595         if( pDirEnumCB == NULL)
1596         {
1597
1598             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1599         }
1600
1601         //
1602         // Call to the service to evaluate the fid
1603         //
1604
1605         ulResultBufferLength = PAGE_SIZE;
1606
1607         if( FastCall)
1608         {
1609
1610             ulRequestFlags |= AFS_REQUEST_FLAG_FAST_REQUEST;
1611         }
1612
1613         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_EVAL_TARGET_BY_ID,
1614                                       ulRequestFlags,
1615                                       AuthGroup,
1616                                       NULL,
1617                                       &ObjectInfo->FileId,
1618                                       &stTargetID,
1619                                       sizeof( AFSEvalTargetCB),
1620                                       pDirEnumCB,
1621                                       &ulResultBufferLength);
1622
1623         if( ntStatus != STATUS_SUCCESS)
1624         {
1625
1626             //
1627             // If we received back a STATUS_INVALID_HANDLE then mark the parent as requiring
1628             // verification
1629             //
1630
1631             if( ntStatus == STATUS_INVALID_HANDLE)
1632             {
1633
1634                 if( ObjectInfo->ParentObjectInformation != NULL)
1635                 {
1636
1637                     SetFlag( ObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1638                 }
1639             }
1640
1641             try_return( ntStatus);
1642         }
1643
1644         //
1645         // Pass back the dir enum entry
1646         //
1647
1648         if( DirEnumEntry != NULL)
1649         {
1650
1651             *DirEnumEntry = pDirEnumCB;
1652         }
1653         else
1654         {
1655
1656             AFSExFreePool( pDirEnumCB);
1657         }
1658
1659 try_exit:
1660
1661         if( !NT_SUCCESS( ntStatus))
1662         {
1663
1664             if( pDirEnumCB != NULL)
1665             {
1666
1667                 AFSExFreePool( pDirEnumCB);
1668             }
1669
1670             *DirEnumEntry = NULL;
1671         }
1672     }
1673
1674     return ntStatus;
1675 }
1676
1677 NTSTATUS
1678 AFSEvaluateTargetByName( IN GUID *AuthGroup,
1679                          IN AFSFileID *ParentFileId,
1680                          IN PUNICODE_STRING SourceName,
1681                          OUT AFSDirEnumEntry **DirEnumEntry)
1682 {
1683
1684     NTSTATUS ntStatus = STATUS_SUCCESS;
1685     AFSEvalTargetCB stTargetID;
1686     ULONG ulResultBufferLength;
1687     AFSDirEnumEntry *pDirEnumCB = NULL;
1688
1689     __Enter
1690     {
1691
1692         stTargetID.ParentId = *ParentFileId;
1693
1694         //
1695         // Allocate our response buffer
1696         //
1697
1698         pDirEnumCB = (AFSDirEnumEntry *)AFSExAllocatePoolWithTag( PagedPool,
1699                                                                   PAGE_SIZE,
1700                                                                   AFS_GENERIC_MEMORY_3_TAG);
1701
1702         if( pDirEnumCB == NULL)
1703         {
1704
1705             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1706         }
1707
1708         //
1709         // Call to the service to evaluate the fid
1710         //
1711
1712         ulResultBufferLength = PAGE_SIZE;
1713
1714         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_EVAL_TARGET_BY_NAME,
1715                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
1716                                       AuthGroup,
1717                                       SourceName,
1718                                       NULL,
1719                                       &stTargetID,
1720                                       sizeof( AFSEvalTargetCB),
1721                                       pDirEnumCB,
1722                                       &ulResultBufferLength);
1723
1724         if( ntStatus != STATUS_SUCCESS)
1725         {
1726
1727             try_return( ntStatus);
1728         }
1729
1730         //
1731         // Pass back the dir enum entry
1732         //
1733
1734         if( DirEnumEntry != NULL)
1735         {
1736
1737             *DirEnumEntry = pDirEnumCB;
1738         }
1739         else
1740         {
1741
1742             AFSExFreePool( pDirEnumCB);
1743         }
1744
1745 try_exit:
1746
1747         if( !NT_SUCCESS( ntStatus))
1748         {
1749
1750             if( pDirEnumCB != NULL)
1751             {
1752
1753                 AFSExFreePool( pDirEnumCB);
1754             }
1755
1756             *DirEnumEntry = NULL;
1757         }
1758     }
1759
1760     return ntStatus;
1761 }
1762
1763 NTSTATUS
1764 AFSRetrieveVolumeInformation( IN GUID *AuthGroup,
1765                               IN AFSFileID *FileID,
1766                               OUT AFSVolumeInfoCB *VolumeInformation)
1767 {
1768
1769     NTSTATUS ntStatus = STATUS_SUCCESS;
1770     ULONG ulResultLen = 0;
1771
1772     __Enter
1773     {
1774
1775         ulResultLen = sizeof( AFSVolumeInfoCB);
1776
1777         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_GET_VOLUME_INFO,
1778                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
1779                                       AuthGroup,
1780                                       NULL,
1781                                       FileID,
1782                                       NULL,
1783                                       0,
1784                                       VolumeInformation,
1785                                       &ulResultLen);
1786
1787         if( ntStatus != STATUS_SUCCESS)
1788         {
1789
1790             try_return( ntStatus);
1791         }
1792
1793 try_exit:
1794
1795         NOTHING;
1796     }
1797
1798     return ntStatus;
1799 }
1800
1801 NTSTATUS
1802 AFSNotifyPipeTransceive( IN AFSCcb *Ccb,
1803                          IN ULONG InputLength,
1804                          IN ULONG OutputLength,
1805                          IN void *InputDataBuffer,
1806                          OUT void *OutputDataBuffer,
1807                          OUT ULONG *BytesReturned)
1808 {
1809
1810     NTSTATUS ntStatus = STATUS_SUCCESS;
1811     ULONG ulResultLen = 0;
1812     MDL *pInputMdl = NULL, *pOutputMdl = NULL;
1813     void *pInputSystemBuffer = NULL, *pOutputSystemBuffer = NULL;
1814     ULONG ulBufferLength = OutputLength;
1815     AFSPipeIORequestCB *pIoRequest = NULL;
1816     GUID *pAuthGroup = NULL;
1817
1818     __Enter
1819     {
1820
1821         //
1822         // Map the user buffer to a system address
1823         //
1824
1825         pInputSystemBuffer = AFSLockUserBuffer( InputDataBuffer,
1826                                                 InputLength,
1827                                                 &pInputMdl);
1828
1829         if( pInputSystemBuffer == NULL)
1830         {
1831
1832             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1833         }
1834
1835         pIoRequest = (AFSPipeIORequestCB *)AFSExAllocatePoolWithTag( PagedPool,
1836                                                                      sizeof( AFSPipeIORequestCB) +
1837                                                                                 InputLength,
1838                                                                      AFS_GENERIC_MEMORY_4_TAG);
1839
1840         if( pIoRequest == NULL)
1841         {
1842
1843             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1844         }
1845
1846         RtlZeroMemory( pIoRequest,
1847                        sizeof( AFSPipeIORequestCB) + InputLength);
1848
1849         pIoRequest->RequestId = Ccb->RequestID;
1850
1851         pIoRequest->RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1852
1853         pIoRequest->BufferLength = InputLength;
1854
1855         RtlCopyMemory( (void *)((char *)pIoRequest + sizeof( AFSPipeIORequestCB)),
1856                        pInputSystemBuffer,
1857                        InputLength);
1858
1859         pOutputSystemBuffer = AFSLockUserBuffer( OutputDataBuffer,
1860                                                  OutputLength,
1861                                                  &pOutputMdl);
1862
1863         if( pOutputSystemBuffer == NULL)
1864         {
1865
1866             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1867         }
1868
1869         if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
1870         {
1871             pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
1872         }
1873
1874         //
1875         // Send the call to the service
1876         //
1877
1878         ulResultLen = OutputLength;
1879
1880         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_TRANSCEIVE,
1881                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
1882                                       pAuthGroup,
1883                                       &Ccb->DirectoryCB->NameInformation.FileName,
1884                                       NULL,
1885                                       pIoRequest,
1886                                       sizeof( AFSPipeIORequestCB) + InputLength,
1887                                       pOutputSystemBuffer,
1888                                       &ulResultLen);
1889
1890         if( ntStatus != STATUS_SUCCESS &&
1891             ntStatus != STATUS_BUFFER_OVERFLOW)
1892         {
1893
1894             if( NT_SUCCESS( ntStatus))
1895             {
1896
1897                 ntStatus = STATUS_DEVICE_NOT_READY;
1898             }
1899
1900             try_return( ntStatus);
1901         }
1902
1903         //
1904         // Return the bytes processed
1905         //
1906
1907         *BytesReturned = ulResultLen;
1908
1909 try_exit:
1910
1911         if( pInputMdl != NULL)
1912         {
1913
1914             MmUnlockPages( pInputMdl);
1915
1916             IoFreeMdl( pInputMdl);
1917         }
1918
1919         if( pOutputMdl != NULL)
1920         {
1921
1922             MmUnlockPages( pOutputMdl);
1923
1924             IoFreeMdl( pOutputMdl);
1925         }
1926
1927         if( pIoRequest != NULL)
1928         {
1929
1930             AFSExFreePool( pIoRequest);
1931         }
1932     }
1933
1934     return ntStatus;
1935 }
1936
1937 NTSTATUS
1938 AFSNotifySetPipeInfo( IN AFSCcb *Ccb,
1939                       IN ULONG InformationClass,
1940                       IN ULONG InputLength,
1941                       IN void *DataBuffer)
1942 {
1943
1944     NTSTATUS ntStatus = STATUS_SUCCESS;
1945     AFSPipeInfoRequestCB *pInfoRequest = NULL;
1946     GUID *pAuthGroup = NULL;
1947
1948     __Enter
1949     {
1950
1951         pInfoRequest = (AFSPipeInfoRequestCB *)AFSExAllocatePoolWithTag( PagedPool,
1952                                                                          sizeof( AFSPipeInfoRequestCB) +
1953                                                                                 InputLength,
1954                                                                          AFS_GENERIC_MEMORY_5_TAG);
1955
1956         if( pInfoRequest == NULL)
1957         {
1958
1959             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1960         }
1961
1962         RtlZeroMemory( pInfoRequest,
1963                        sizeof( AFSPipeInfoRequestCB) + InputLength);
1964
1965         pInfoRequest->RequestId = Ccb->RequestID;
1966
1967         pInfoRequest->RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
1968
1969         pInfoRequest->BufferLength = InputLength;
1970
1971         pInfoRequest->InformationClass = InformationClass;
1972
1973         RtlCopyMemory( (void *)((char *)pInfoRequest + sizeof( AFSPipeInfoRequestCB)),
1974                        DataBuffer,
1975                        InputLength);
1976
1977         if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
1978         {
1979             pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
1980         }
1981
1982         //
1983         // Send the call to the service
1984         //
1985
1986         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_SET_INFO,
1987                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
1988                                       pAuthGroup,
1989                                       &Ccb->DirectoryCB->NameInformation.FileName,
1990                                       NULL,
1991                                       pInfoRequest,
1992                                       sizeof( AFSPipeInfoRequestCB) + InputLength,
1993                                       NULL,
1994                                       NULL);
1995
1996         if( ntStatus != STATUS_SUCCESS)
1997         {
1998
1999             if( NT_SUCCESS( ntStatus))
2000             {
2001
2002                 ntStatus = STATUS_DEVICE_NOT_READY;
2003             }
2004
2005             try_return( ntStatus);
2006         }
2007
2008 try_exit:
2009
2010         if( pInfoRequest != NULL)
2011         {
2012
2013             AFSExFreePool( pInfoRequest);
2014         }
2015     }
2016
2017     return ntStatus;
2018 }
2019
2020 NTSTATUS
2021 AFSNotifyQueryPipeInfo( IN AFSCcb *Ccb,
2022                         IN ULONG InformationClass,
2023                         IN ULONG OutputLength,
2024                         IN void *DataBuffer,
2025                         OUT ULONG *BytesReturned)
2026 {
2027
2028     NTSTATUS ntStatus = STATUS_SUCCESS;
2029     AFSPipeInfoRequestCB stInfoRequest;
2030     ULONG ulBytesProcessed = 0;
2031     GUID *pAuthGroup = NULL;
2032
2033     __Enter
2034     {
2035
2036         RtlZeroMemory( &stInfoRequest,
2037                        sizeof( AFSPipeInfoRequestCB));
2038
2039         stInfoRequest.RequestId = Ccb->RequestID;
2040
2041         stInfoRequest.RootId = Ccb->DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
2042
2043         stInfoRequest.BufferLength = OutputLength;
2044
2045         stInfoRequest.InformationClass = InformationClass;
2046
2047         ulBytesProcessed = OutputLength;
2048
2049         if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL)
2050         {
2051             pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup;
2052         }
2053
2054         //
2055         // Send the call to the service
2056         //
2057
2058         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_QUERY_INFO,
2059                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
2060                                       pAuthGroup,
2061                                       &Ccb->DirectoryCB->NameInformation.FileName,
2062                                       NULL,
2063                                       &stInfoRequest,
2064                                       sizeof( AFSPipeInfoRequestCB),
2065                                       DataBuffer,
2066                                       &ulBytesProcessed);
2067
2068         if( ntStatus != STATUS_SUCCESS)
2069         {
2070
2071             if( NT_SUCCESS( ntStatus))
2072             {
2073
2074                 ntStatus = STATUS_DEVICE_NOT_READY;
2075             }
2076
2077             try_return( ntStatus);
2078         }
2079
2080         *BytesReturned = ulBytesProcessed;
2081
2082 try_exit:
2083
2084         NOTHING;
2085     }
2086
2087     return ntStatus;
2088 }
2089
2090 NTSTATUS
2091 AFSReleaseFid( IN AFSFileID *FileId)
2092 {
2093
2094     NTSTATUS ntStatus = STATUS_SUCCESS;
2095
2096     __Enter
2097     {
2098
2099         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FID,
2100                                       0,
2101                                       NULL,
2102                                       NULL,
2103                                       FileId,
2104                                       NULL,
2105                                       0,
2106                                       NULL,
2107                                       NULL);
2108     }
2109
2110     return ntStatus;
2111 }
2112
2113 BOOLEAN
2114 AFSIsExtentRequestQueued( IN AFSFileID *FileID,
2115                           IN LARGE_INTEGER *ExtentOffset,
2116                           IN ULONG Length)
2117 {
2118
2119     BOOLEAN bRequestQueued = FALSE;
2120     NTSTATUS ntStatus = STATUS_SUCCESS;
2121     AFSDeviceExt    *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2122     AFSCommSrvcCB   *pCommSrvc = NULL;
2123     AFSPoolEntry    *pPoolEntry = NULL;
2124     AFSRequestExtentsCB *pRequestExtents = NULL;
2125
2126     __Enter
2127     {
2128
2129
2130         pCommSrvc = &pControlDevExt->Specific.Control.CommServiceCB;
2131
2132         AFSAcquireShared( &pCommSrvc->IrpPoolLock,
2133                           TRUE);
2134
2135         pPoolEntry = pCommSrvc->RequestPoolHead;
2136
2137         while( pPoolEntry != NULL)
2138         {
2139
2140             if( pPoolEntry->RequestType == AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS)
2141             {
2142
2143                 if( AFSIsEqualFID( &pPoolEntry->FileId, FileID))
2144                 {
2145
2146                     pRequestExtents = (AFSRequestExtentsCB *)pPoolEntry->Data;
2147
2148                     if( pRequestExtents->ByteOffset.QuadPart == ExtentOffset->QuadPart &&
2149                         pRequestExtents->Length == Length)
2150                     {
2151
2152                         bRequestQueued = TRUE;
2153                     }
2154                 }
2155             }
2156
2157             pPoolEntry = pPoolEntry->fLink;
2158         }
2159
2160         AFSReleaseResource( &pCommSrvc->IrpPoolLock);
2161     }
2162
2163     return bRequestQueued;
2164 }