Windows: Deny writes/truncation to files w RO attr
[openafs.git] / src / WINNT / afsrdr / kernel / fs / AFSLogSupport.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 #include "AFSCommon.h"
36
37 NTSTATUS
38 AFSDbgLogMsg( IN ULONG Subsystem,
39               IN ULONG Level,
40               IN PCCH Format,
41               ...)
42 {
43
44     NTSTATUS ntStatus = STATUS_SUCCESS;
45     va_list va_args;
46     ULONG ulBytesWritten = 0;
47     BOOLEAN bReleaseLock = FALSE;
48     char    *pCurrentTrace = NULL;
49
50     __Enter
51     {
52
53         if( AFSDbgBuffer == NULL)
54         {
55
56             try_return( ntStatus = STATUS_DEVICE_NOT_READY);
57         }
58
59         if( Subsystem > 0 &&
60             (Subsystem & AFSTraceComponent) == 0)
61         {
62
63             //
64             // Not tracing this subsystem
65             //
66
67             try_return( ntStatus);
68         }
69
70         if( Level > 0 &&
71             Level > AFSTraceLevel)
72         {
73
74             //
75             // Not tracing this level
76             //
77
78             try_return( ntStatus);
79         }
80
81         AFSAcquireExcl( &AFSDbgLogLock,
82                         TRUE);
83
84         bReleaseLock = TRUE;
85
86         //
87         // Check again under lock
88         //
89
90         if( AFSDbgBuffer == NULL)
91         {
92
93             try_return( ntStatus = STATUS_DEVICE_NOT_READY);
94         }
95
96         if( AFSDbgLogRemainingLength < 255)
97         {
98
99             AFSDbgLogRemainingLength = AFSDbgBufferLength;
100
101             AFSDbgCurrentBuffer = AFSDbgBuffer;
102
103             SetFlag( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED);
104         }
105
106         pCurrentTrace = AFSDbgCurrentBuffer;
107
108         RtlStringCchPrintfA( AFSDbgCurrentBuffer,
109                              10,
110                              "%08lX:",
111                              AFSDbgLogCounter++);
112
113         AFSDbgCurrentBuffer += 9;
114
115         AFSDbgLogRemainingLength -= 9;
116
117         va_start( va_args, Format);
118
119         ntStatus = RtlStringCbVPrintfA( AFSDbgCurrentBuffer,
120                                         AFSDbgLogRemainingLength,
121                                         Format,
122                                         va_args);
123
124         if( ntStatus == STATUS_BUFFER_OVERFLOW)
125         {
126
127             RtlZeroMemory( AFSDbgCurrentBuffer,
128                            AFSDbgLogRemainingLength);
129
130             AFSDbgLogRemainingLength = AFSDbgBufferLength;
131
132             AFSDbgCurrentBuffer = AFSDbgBuffer;
133
134             SetFlag( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED);
135
136             pCurrentTrace = AFSDbgCurrentBuffer;
137
138             RtlStringCchPrintfA( AFSDbgCurrentBuffer,
139                                  10,
140                                  "%08lX:",
141                                  AFSDbgLogCounter++);
142
143             AFSDbgCurrentBuffer += 9;
144
145             AFSDbgLogRemainingLength -= 9;
146
147             ntStatus = RtlStringCbVPrintfA( AFSDbgCurrentBuffer,
148                                             AFSDbgLogRemainingLength,
149                                             Format,
150                                             va_args);
151         }
152
153         if( NT_SUCCESS( ntStatus))
154         {
155
156             RtlStringCbLengthA( AFSDbgCurrentBuffer,
157                                 AFSDbgLogRemainingLength,
158                                 (size_t *)&ulBytesWritten);
159
160             AFSDbgCurrentBuffer += ulBytesWritten;
161
162             AFSDbgLogRemainingLength -= ulBytesWritten;
163         }
164
165         va_end( va_args);
166
167         if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_TRACE_TO_DEBUGGER) &&
168             pCurrentTrace != NULL)
169         {
170
171             DbgPrint( pCurrentTrace);
172         }
173
174 try_exit:
175
176         if( bReleaseLock)
177         {
178
179             AFSReleaseResource( &AFSDbgLogLock);
180         }
181     }
182
183     return ntStatus;
184 }
185
186 NTSTATUS
187 AFSInitializeDbgLog()
188 {
189
190     NTSTATUS ntStatus = STATUS_INSUFFICIENT_RESOURCES;
191
192     AFSAcquireExcl( &AFSDbgLogLock,
193                     TRUE);
194
195     if( AFSDbgBufferLength > 0)
196     {
197
198         AFSDbgBuffer = (char *)AFSExAllocatePoolWithTag( NonPagedPool,
199                                                          AFSDbgBufferLength,
200                                                          AFS_GENERIC_MEMORY_19_TAG);
201
202         if( AFSDbgBuffer != NULL)
203         {
204
205             AFSDbgCurrentBuffer = AFSDbgBuffer;
206
207             AFSDbgLogRemainingLength = AFSDbgBufferLength;
208
209             ntStatus = STATUS_SUCCESS;
210
211             InterlockedCompareExchangePointer( (PVOID *)&AFSDebugTraceFnc,
212                                                (void *)AFSDbgLogMsg,
213                                                NULL);
214         }
215     }
216
217     AFSReleaseResource( &AFSDbgLogLock);
218
219     if( NT_SUCCESS( ntStatus))
220     {
221         AFSTagInitialLogEntry();
222     }
223
224     return ntStatus;
225 }
226
227 NTSTATUS
228 AFSTearDownDbgLog()
229 {
230
231     NTSTATUS ntStatus = STATUS_SUCCESS;
232
233     AFSAcquireExcl( &AFSDbgLogLock,
234                     TRUE);
235
236     if( AFSDbgBuffer != NULL)
237     {
238
239         ExFreePool( AFSDbgBuffer);
240     }
241
242     AFSDbgBuffer = NULL;
243
244     AFSDbgCurrentBuffer = NULL;
245
246     AFSDbgLogRemainingLength = 0;
247
248     AFSReleaseResource( &AFSDbgLogLock);
249
250     return ntStatus;
251 }
252
253 NTSTATUS
254 AFSConfigureTrace( IN AFSTraceConfigCB *TraceInfo)
255 {
256
257     NTSTATUS ntStatus = STATUS_SUCCESS;
258     UNICODE_STRING uniString;
259
260     __Enter
261     {
262
263         AFSAcquireExcl( &AFSDbgLogLock,
264                         TRUE);
265
266         if( TraceInfo->TraceLevel == AFSTraceLevel &&
267             TraceInfo->TraceBufferLength == AFSDbgBufferLength &&
268             TraceInfo->Subsystem == AFSTraceComponent &&
269             TraceInfo->DebugFlags == AFSDebugFlags)
270         {
271
272             //
273             // Nothing to do
274             //
275
276             try_return( ntStatus);
277         }
278
279         //
280         // Go update the registry with the new entries
281         //
282
283         if( TraceInfo->TraceLevel != (ULONG)-1 &&
284             TraceInfo->TraceLevel != AFSTraceLevel)
285         {
286
287             AFSTraceLevel = TraceInfo->TraceLevel;
288
289             RtlInitUnicodeString( &uniString,
290                                   AFS_REG_TRACE_LEVEL);
291
292             ntStatus = AFSUpdateRegistryParameter( &uniString,
293                                                    REG_DWORD,
294                                                    &TraceInfo->TraceLevel,
295                                                    sizeof( ULONG));
296
297             if( !NT_SUCCESS( ntStatus))
298             {
299
300                 DbgPrint("AFSConfigureTrace Failed to set debug level in registry Status %08lX\n", ntStatus);
301             }
302         }
303
304         if( TraceInfo->Subsystem != (ULONG)-1 &&
305             TraceInfo->Subsystem != AFSTraceComponent)
306         {
307
308             AFSTraceComponent = TraceInfo->Subsystem;
309
310             RtlInitUnicodeString( &uniString,
311                                   AFS_REG_TRACE_SUBSYSTEM);
312
313             ntStatus = AFSUpdateRegistryParameter( &uniString,
314                                                    REG_DWORD,
315                                                    &TraceInfo->Subsystem,
316                                                    sizeof( ULONG));
317
318             if( !NT_SUCCESS( ntStatus))
319             {
320
321                 DbgPrint("AFSConfigureTrace Failed to set debug subsystem in registry Status %08lX\n", ntStatus);
322             }
323         }
324
325         if( TraceInfo->DebugFlags != (ULONG)-1 &&
326             TraceInfo->DebugFlags != AFSDebugFlags)
327         {
328
329             AFSDebugFlags = TraceInfo->DebugFlags;
330
331             RtlInitUnicodeString( &uniString,
332                                   AFS_REG_DEBUG_FLAGS);
333
334             ntStatus = AFSUpdateRegistryParameter( &uniString,
335                                                    REG_DWORD,
336                                                    &TraceInfo->DebugFlags,
337                                                    sizeof( ULONG));
338
339             if( !NT_SUCCESS( ntStatus))
340             {
341
342                 DbgPrint("AFSConfigureTrace Failed to set debug flags in registry Status %08lX\n", ntStatus);
343             }
344         }
345
346         if( TraceInfo->TraceBufferLength != (ULONG)-1 &&
347             TraceInfo->TraceBufferLength != AFSDbgBufferLength)
348         {
349
350             RtlInitUnicodeString( &uniString,
351                                   AFS_REG_TRACE_BUFFER_LENGTH);
352
353             ntStatus = AFSUpdateRegistryParameter( &uniString,
354                                                    REG_DWORD,
355                                                    &TraceInfo->TraceBufferLength,
356                                                    sizeof( ULONG));
357
358             if( !NT_SUCCESS( ntStatus))
359             {
360
361                 DbgPrint("AFSConfigureTrace Failed to set debug buffer length in registry Status %08lX\n", ntStatus);
362             }
363
364             AFSDbgBufferLength = TraceInfo->TraceBufferLength * 1024;
365
366             ClearFlag( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED);
367
368             if( AFSDbgBuffer != NULL)
369             {
370
371                 ExFreePool( AFSDbgBuffer);
372
373                 AFSDbgBuffer = NULL;
374
375                 AFSDbgCurrentBuffer = NULL;
376
377                 AFSDbgLogRemainingLength = 0;
378             }
379
380             if( AFSDbgBufferLength > 0)
381             {
382
383                 AFSDbgBuffer = (char *)AFSExAllocatePoolWithTag( NonPagedPool,
384                                                                  AFSDbgBufferLength,
385                                                                  AFS_GENERIC_MEMORY_20_TAG);
386
387                 if( AFSDbgBuffer == NULL)
388                 {
389
390                     AFSDbgBufferLength = 0;
391
392                     try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
393                 }
394
395                 InterlockedCompareExchangePointer( (PVOID *)&AFSDebugTraceFnc,
396                                                    (void *)AFSDbgLogMsg,
397                                                    NULL);
398
399                 AFSDbgCurrentBuffer = AFSDbgBuffer;
400
401                 AFSDbgLogRemainingLength = AFSDbgBufferLength;
402
403                 AFSTagInitialLogEntry();
404             }
405             else
406             {
407                 InterlockedCompareExchangePointer( (PVOID *)&AFSDebugTraceFnc,
408                                                    NULL,
409                                                    (void *)AFSDbgLogMsg);
410             }
411
412             AFSConfigLibraryDebug();
413         }
414
415 try_exit:
416
417         AFSReleaseResource( &AFSDbgLogLock);
418     }
419
420     return ntStatus;
421 }
422
423 NTSTATUS
424 AFSGetTraceConfig( OUT AFSTraceConfigCB *TraceInfo)
425 {
426     NTSTATUS ntStatus = STATUS_SUCCESS;
427
428     __Enter
429     {
430
431         AFSAcquireExcl( &AFSDbgLogLock,
432                         TRUE);
433
434         TraceInfo->TraceLevel = AFSTraceLevel;
435
436         TraceInfo->TraceBufferLength = AFSDbgBufferLength;
437
438         TraceInfo->Subsystem = AFSTraceComponent;
439
440         TraceInfo->DebugFlags = AFSDebugFlags;
441
442         AFSReleaseResource( &AFSDbgLogLock);
443     }
444
445     return ntStatus;
446 }
447
448 NTSTATUS
449 AFSGetTraceBuffer( IN ULONG TraceBufferLength,
450                    OUT void *TraceBuffer,
451                    OUT ULONG_PTR *CopiedLength)
452 {
453
454     NTSTATUS ntStatus = STATUS_SUCCESS;
455     ULONG ulCopyLength = 0;
456     char *pCurrentLocation = NULL;
457
458     __Enter
459     {
460
461         AFSAcquireShared( &AFSDbgLogLock,
462                           TRUE);
463
464         if( TraceBufferLength < AFSDbgBufferLength)
465         {
466
467             try_return( ntStatus = STATUS_INVALID_PARAMETER);
468         }
469
470         //
471         // If we have wrapped then copy in the remaining portion
472         //
473
474         pCurrentLocation = (char *)TraceBuffer;
475
476         *CopiedLength = 0;
477
478         if( BooleanFlagOn( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED))
479         {
480
481             ulCopyLength = AFSDbgLogRemainingLength;
482
483             RtlCopyMemory( pCurrentLocation,
484                            AFSDbgCurrentBuffer,
485                            ulCopyLength);
486
487             pCurrentLocation[ 0] = '0'; // The buffer is NULL terminated ...
488
489             pCurrentLocation += ulCopyLength;
490
491             *CopiedLength = ulCopyLength;
492         }
493
494         ulCopyLength = AFSDbgBufferLength - AFSDbgLogRemainingLength;
495
496         if( ulCopyLength > 0)
497         {
498
499             RtlCopyMemory( pCurrentLocation,
500                            AFSDbgBuffer,
501                            ulCopyLength);
502
503             *CopiedLength += ulCopyLength;
504         }
505
506 try_exit:
507
508         AFSReleaseResource( &AFSDbgLogLock);
509     }
510
511     return ntStatus;
512 }
513
514 void
515 AFSTagInitialLogEntry()
516 {
517
518     LARGE_INTEGER liTime, liLocalTime;
519     TIME_FIELDS timeFields;
520
521     KeQuerySystemTime( &liTime);
522
523     ExSystemTimeToLocalTime( &liTime,
524                              &liLocalTime);
525
526     RtlTimeToTimeFields( &liLocalTime,
527                          &timeFields);
528
529     AFSDbgTrace(( 0,
530                   0,
531                   "AFS Log Initialized %d-%d-%d %d:%d Level %d Subsystems %08lX\n",
532                   timeFields.Month,
533                   timeFields.Day,
534                   timeFields.Year,
535                   timeFields.Hour,
536                   timeFields.Minute,
537                   AFSTraceLevel,
538                   AFSTraceComponent));
539
540     return;
541 }
542
543 void
544 AFSDumpTraceFiles()
545 {
546
547     NTSTATUS ntStatus = STATUS_SUCCESS;
548     HANDLE hDirectory = NULL;
549     OBJECT_ATTRIBUTES   stObjectAttribs;
550     IO_STATUS_BLOCK stIoStatus;
551     LARGE_INTEGER liTime, liLocalTime;
552     TIME_FIELDS timeFields;
553     ULONG ulBytesWritten = 0;
554     HANDLE hDumpFile = NULL;
555     ULONG ulBytesProcessed, ulCopyLength;
556     LARGE_INTEGER liOffset;
557     ULONG ulDumpLength = 0;
558     BOOLEAN bSetEvent = FALSE;
559
560     __Enter
561     {
562
563         AFSAcquireShared( &AFSDbgLogLock,
564                           TRUE);
565
566         ulDumpLength = AFSDbgBufferLength - AFSDbgLogRemainingLength;
567
568         AFSReleaseResource( &AFSDbgLogLock);
569
570         if( AFSDumpFileLocation.Length == 0 ||
571             AFSDumpFileLocation.Buffer == NULL ||
572             AFSDbgBufferLength == 0 ||
573             ulDumpLength == 0 ||
574             AFSDumpFileName.MaximumLength == 0 ||
575             AFSDumpFileName.Buffer == NULL ||
576             AFSDumpBuffer == NULL)
577         {
578             try_return( ntStatus);
579         }
580
581         //
582         // Go open the cache file
583         //
584
585         InitializeObjectAttributes( &stObjectAttribs,
586                                     &AFSDumpFileLocation,
587                                     OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
588                                     NULL,
589                                     NULL);
590
591         ntStatus = ZwCreateFile( &hDirectory,
592                                  GENERIC_READ | GENERIC_WRITE,
593                                  &stObjectAttribs,
594                                  &stIoStatus,
595                                  NULL,
596                                  0,
597                                  FILE_SHARE_READ | FILE_SHARE_WRITE,
598                                  FILE_OPEN,
599                                  FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
600                                  NULL,
601                                  0);
602
603         if( !NT_SUCCESS( ntStatus))
604         {
605
606             try_return( ntStatus);
607         }
608
609         ntStatus = KeWaitForSingleObject( &AFSDumpFileEvent,
610                                           Executive,
611                                           KernelMode,
612                                           FALSE,
613                                           NULL);
614
615         if( !NT_SUCCESS( ntStatus))
616         {
617
618             try_return( ntStatus);
619         }
620
621         bSetEvent = TRUE;
622
623         AFSDumpFileName.Length = 0;
624
625         RtlZeroMemory( AFSDumpFileName.Buffer,
626                        AFSDumpFileName.MaximumLength);
627
628         KeQuerySystemTime( &liTime);
629
630         ExSystemTimeToLocalTime( &liTime,
631                                  &liLocalTime);
632
633         RtlTimeToTimeFields( &liLocalTime,
634                              &timeFields);
635
636         ntStatus = RtlStringCchPrintfW( AFSDumpFileName.Buffer,
637                                         AFSDumpFileName.MaximumLength/sizeof( WCHAR),
638                                         L"AFSDumpFile %d.%d.%d %d.%d.%d.log",
639                                                   timeFields.Month,
640                                                   timeFields.Day,
641                                                   timeFields.Year,
642                                                   timeFields.Hour,
643                                                   timeFields.Minute,
644                                                   timeFields.Second);
645
646         if( !NT_SUCCESS( ntStatus))
647         {
648             try_return( ntStatus);
649         }
650
651         RtlStringCbLengthW( AFSDumpFileName.Buffer,
652                             AFSDumpFileName.MaximumLength,
653                             (size_t *)&ulBytesWritten);
654
655         AFSDumpFileName.Length = (USHORT)ulBytesWritten;
656
657         InitializeObjectAttributes( &stObjectAttribs,
658                                     &AFSDumpFileName,
659                                     OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
660                                     hDirectory,
661                                     NULL);
662
663         ntStatus = ZwCreateFile( &hDumpFile,
664                                  GENERIC_READ | GENERIC_WRITE,
665                                  &stObjectAttribs,
666                                  &stIoStatus,
667                                  NULL,
668                                  0,
669                                  FILE_SHARE_READ | FILE_SHARE_WRITE,
670                                  FILE_CREATE,
671                                  FILE_SYNCHRONOUS_IO_NONALERT,
672                                  NULL,
673                                  0);
674
675         if( !NT_SUCCESS( ntStatus))
676         {
677             try_return( ntStatus);
678         }
679
680         //
681         // Write out the trace buffer
682         //
683
684         liOffset.QuadPart = 0;
685
686         ulBytesProcessed = 0;
687
688         while( ulBytesProcessed < ulDumpLength)
689         {
690
691             ulCopyLength = AFSDumpBufferLength;
692
693             if( ulCopyLength > ulDumpLength - ulBytesProcessed)
694             {
695                 ulCopyLength = ulDumpLength - ulBytesProcessed;
696             }
697
698             RtlCopyMemory( AFSDumpBuffer,
699                            (void *)((char *)AFSDbgBuffer + ulBytesProcessed),
700                            ulCopyLength);
701
702             ntStatus = ZwWriteFile( hDumpFile,
703                                     NULL,
704                                     NULL,
705                                     NULL,
706                                     &stIoStatus,
707                                     AFSDumpBuffer,
708                                     ulCopyLength,
709                                     &liOffset,
710                                     NULL);
711
712             if( !NT_SUCCESS( ntStatus))
713             {
714                 break;
715             }
716
717             liOffset.QuadPart += ulCopyLength;
718
719             ulBytesProcessed += ulCopyLength;
720         }
721
722 try_exit:
723
724         if( hDumpFile != NULL)
725         {
726             ZwClose( hDumpFile);
727         }
728
729         if( hDirectory != NULL)
730         {
731             ZwClose( hDirectory);
732         }
733
734         if( bSetEvent)
735         {
736             KeSetEvent( &AFSDumpFileEvent,
737                         0,
738                         FALSE);
739         }
740     }
741
742     return;
743 }
744
745 NTSTATUS
746 AFSInitializeDumpFile()
747 {
748
749     NTSTATUS ntStatus = STATUS_SUCCESS;
750
751     __Enter
752     {
753
754         KeInitializeEvent( &AFSDumpFileEvent,
755                            SynchronizationEvent,
756                            TRUE);
757
758         AFSDumpFileName.Length = 0;
759         AFSDumpFileName.Buffer = NULL;
760         AFSDumpFileName.MaximumLength = PAGE_SIZE;
761
762         AFSDumpFileName.Buffer = (WCHAR *)ExAllocatePoolWithTag( PagedPool,
763                                                                  AFSDumpFileName.MaximumLength,
764                                                                  AFS_GENERIC_MEMORY_28_TAG);
765
766         if( AFSDumpFileName.Buffer == NULL)
767         {
768             AFSDumpFileName.MaximumLength = 0;
769
770             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
771         }
772
773         AFSDumpBufferLength = 64 * 1024;
774
775         AFSDumpBuffer = ExAllocatePoolWithTag( PagedPool,
776                                                AFSDumpBufferLength,
777                                                AFS_GENERIC_MEMORY_28_TAG);
778
779         if( AFSDumpBuffer == NULL)
780         {
781
782             ExFreePool( AFSDumpFileName.Buffer);
783
784             AFSDumpFileName.Buffer = NULL;
785             AFSDumpFileName.MaximumLength = 0;
786
787             AFSDumpBufferLength = 0;
788
789             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
790         }
791
792 try_exit:
793
794         NOTHING;
795     }
796
797     return ntStatus;
798 }