Windows: Restrict redir trace buffer to 10240KB
[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             if ( TraceInfo->TraceBufferLength > AFS_DBG_LOG_MAXLENGTH)
365             {
366
367                 AFSDbgBufferLength = AFS_DBG_LOG_MAXLENGTH * 1024;
368             }
369             else
370             {
371
372                 AFSDbgBufferLength = TraceInfo->TraceBufferLength * 1024;
373             }
374
375             ClearFlag( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED);
376
377             if( AFSDbgBuffer != NULL)
378             {
379
380                 ExFreePool( AFSDbgBuffer);
381
382                 AFSDbgBuffer = NULL;
383
384                 AFSDbgCurrentBuffer = NULL;
385
386                 AFSDbgLogRemainingLength = 0;
387             }
388
389             if( AFSDbgBufferLength > 0)
390             {
391
392                 AFSDbgBuffer = (char *)AFSExAllocatePoolWithTag( NonPagedPool,
393                                                                  AFSDbgBufferLength,
394                                                                  AFS_GENERIC_MEMORY_20_TAG);
395
396                 if( AFSDbgBuffer == NULL)
397                 {
398
399                     AFSDbgBufferLength = 0;
400
401                     try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
402                 }
403
404                 InterlockedCompareExchangePointer( (PVOID *)&AFSDebugTraceFnc,
405                                                    (void *)AFSDbgLogMsg,
406                                                    NULL);
407
408                 AFSDbgCurrentBuffer = AFSDbgBuffer;
409
410                 AFSDbgLogRemainingLength = AFSDbgBufferLength;
411
412                 AFSTagInitialLogEntry();
413             }
414             else
415             {
416                 InterlockedCompareExchangePointer( (PVOID *)&AFSDebugTraceFnc,
417                                                    NULL,
418                                                    (void *)AFSDbgLogMsg);
419             }
420
421             AFSConfigLibraryDebug();
422         }
423
424 try_exit:
425
426         AFSReleaseResource( &AFSDbgLogLock);
427     }
428
429     return ntStatus;
430 }
431
432 NTSTATUS
433 AFSGetTraceConfig( OUT AFSTraceConfigCB *TraceInfo)
434 {
435     NTSTATUS ntStatus = STATUS_SUCCESS;
436
437     __Enter
438     {
439
440         AFSAcquireExcl( &AFSDbgLogLock,
441                         TRUE);
442
443         TraceInfo->TraceLevel = AFSTraceLevel;
444
445         TraceInfo->TraceBufferLength = AFSDbgBufferLength;
446
447         TraceInfo->Subsystem = AFSTraceComponent;
448
449         TraceInfo->DebugFlags = AFSDebugFlags;
450
451         AFSReleaseResource( &AFSDbgLogLock);
452     }
453
454     return ntStatus;
455 }
456
457 NTSTATUS
458 AFSGetTraceBuffer( IN ULONG TraceBufferLength,
459                    OUT void *TraceBuffer,
460                    OUT ULONG_PTR *CopiedLength)
461 {
462
463     NTSTATUS ntStatus = STATUS_SUCCESS;
464     ULONG ulCopyLength = 0;
465     char *pCurrentLocation = NULL;
466
467     __Enter
468     {
469
470         AFSAcquireShared( &AFSDbgLogLock,
471                           TRUE);
472
473         if( TraceBufferLength < AFSDbgBufferLength)
474         {
475
476             try_return( ntStatus = STATUS_INVALID_PARAMETER);
477         }
478
479         //
480         // If we have wrapped then copy in the remaining portion
481         //
482
483         pCurrentLocation = (char *)TraceBuffer;
484
485         *CopiedLength = 0;
486
487         if( BooleanFlagOn( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED))
488         {
489
490             ulCopyLength = AFSDbgLogRemainingLength;
491
492             RtlCopyMemory( pCurrentLocation,
493                            AFSDbgCurrentBuffer,
494                            ulCopyLength);
495
496             pCurrentLocation[ 0] = '0'; // The buffer is NULL terminated ...
497
498             pCurrentLocation += ulCopyLength;
499
500             *CopiedLength = ulCopyLength;
501         }
502
503         ulCopyLength = AFSDbgBufferLength - AFSDbgLogRemainingLength;
504
505         if( ulCopyLength > 0)
506         {
507
508             RtlCopyMemory( pCurrentLocation,
509                            AFSDbgBuffer,
510                            ulCopyLength);
511
512             *CopiedLength += ulCopyLength;
513         }
514
515 try_exit:
516
517         AFSReleaseResource( &AFSDbgLogLock);
518     }
519
520     return ntStatus;
521 }
522
523 void
524 AFSTagInitialLogEntry()
525 {
526
527     LARGE_INTEGER liTime, liLocalTime;
528     TIME_FIELDS timeFields;
529
530     KeQuerySystemTime( &liTime);
531
532     ExSystemTimeToLocalTime( &liTime,
533                              &liLocalTime);
534
535     RtlTimeToTimeFields( &liLocalTime,
536                          &timeFields);
537
538     AFSDbgTrace(( 0,
539                   0,
540                   "AFS Log Initialized %d-%d-%d %d:%d Level %d Subsystems %08lX\n",
541                   timeFields.Month,
542                   timeFields.Day,
543                   timeFields.Year,
544                   timeFields.Hour,
545                   timeFields.Minute,
546                   AFSTraceLevel,
547                   AFSTraceComponent));
548
549     return;
550 }
551
552 void
553 AFSDumpTraceFiles()
554 {
555
556     NTSTATUS ntStatus = STATUS_SUCCESS;
557     HANDLE hDirectory = NULL;
558     OBJECT_ATTRIBUTES   stObjectAttribs;
559     IO_STATUS_BLOCK stIoStatus;
560     LARGE_INTEGER liTime, liLocalTime;
561     TIME_FIELDS timeFields;
562     ULONG ulBytesWritten = 0;
563     HANDLE hDumpFile = NULL;
564     ULONG ulBytesProcessed, ulCopyLength;
565     LARGE_INTEGER liOffset;
566     ULONG ulDumpLength = 0;
567     BOOLEAN bSetEvent = FALSE;
568
569     __Enter
570     {
571
572         AFSAcquireShared( &AFSDbgLogLock,
573                           TRUE);
574
575         ulDumpLength = AFSDbgBufferLength - AFSDbgLogRemainingLength;
576
577         AFSReleaseResource( &AFSDbgLogLock);
578
579         if( AFSDumpFileLocation.Length == 0 ||
580             AFSDumpFileLocation.Buffer == NULL ||
581             AFSDbgBufferLength == 0 ||
582             ulDumpLength == 0 ||
583             AFSDumpFileName.MaximumLength == 0 ||
584             AFSDumpFileName.Buffer == NULL ||
585             AFSDumpBuffer == NULL)
586         {
587             try_return( ntStatus);
588         }
589
590         //
591         // Go open the cache file
592         //
593
594         InitializeObjectAttributes( &stObjectAttribs,
595                                     &AFSDumpFileLocation,
596                                     OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
597                                     NULL,
598                                     NULL);
599
600         ntStatus = ZwCreateFile( &hDirectory,
601                                  GENERIC_READ | GENERIC_WRITE,
602                                  &stObjectAttribs,
603                                  &stIoStatus,
604                                  NULL,
605                                  0,
606                                  FILE_SHARE_READ | FILE_SHARE_WRITE,
607                                  FILE_OPEN,
608                                  FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
609                                  NULL,
610                                  0);
611
612         if( !NT_SUCCESS( ntStatus))
613         {
614
615             try_return( ntStatus);
616         }
617
618         ntStatus = KeWaitForSingleObject( &AFSDumpFileEvent,
619                                           Executive,
620                                           KernelMode,
621                                           FALSE,
622                                           NULL);
623
624         if( !NT_SUCCESS( ntStatus))
625         {
626
627             try_return( ntStatus);
628         }
629
630         bSetEvent = TRUE;
631
632         AFSDumpFileName.Length = 0;
633
634         RtlZeroMemory( AFSDumpFileName.Buffer,
635                        AFSDumpFileName.MaximumLength);
636
637         KeQuerySystemTime( &liTime);
638
639         ExSystemTimeToLocalTime( &liTime,
640                                  &liLocalTime);
641
642         RtlTimeToTimeFields( &liLocalTime,
643                              &timeFields);
644
645         ntStatus = RtlStringCchPrintfW( AFSDumpFileName.Buffer,
646                                         AFSDumpFileName.MaximumLength/sizeof( WCHAR),
647                                         L"AFSDumpFile %d.%d.%d %d.%d.%d.log",
648                                                   timeFields.Month,
649                                                   timeFields.Day,
650                                                   timeFields.Year,
651                                                   timeFields.Hour,
652                                                   timeFields.Minute,
653                                                   timeFields.Second);
654
655         if( !NT_SUCCESS( ntStatus))
656         {
657             try_return( ntStatus);
658         }
659
660         RtlStringCbLengthW( AFSDumpFileName.Buffer,
661                             AFSDumpFileName.MaximumLength,
662                             (size_t *)&ulBytesWritten);
663
664         AFSDumpFileName.Length = (USHORT)ulBytesWritten;
665
666         InitializeObjectAttributes( &stObjectAttribs,
667                                     &AFSDumpFileName,
668                                     OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
669                                     hDirectory,
670                                     NULL);
671
672         ntStatus = ZwCreateFile( &hDumpFile,
673                                  GENERIC_READ | GENERIC_WRITE,
674                                  &stObjectAttribs,
675                                  &stIoStatus,
676                                  NULL,
677                                  0,
678                                  FILE_SHARE_READ | FILE_SHARE_WRITE,
679                                  FILE_CREATE,
680                                  FILE_SYNCHRONOUS_IO_NONALERT,
681                                  NULL,
682                                  0);
683
684         if( !NT_SUCCESS( ntStatus))
685         {
686             try_return( ntStatus);
687         }
688
689         //
690         // Write out the trace buffer
691         //
692
693         liOffset.QuadPart = 0;
694
695         ulBytesProcessed = 0;
696
697         while( ulBytesProcessed < ulDumpLength)
698         {
699
700             ulCopyLength = AFSDumpBufferLength;
701
702             if( ulCopyLength > ulDumpLength - ulBytesProcessed)
703             {
704                 ulCopyLength = ulDumpLength - ulBytesProcessed;
705             }
706
707             RtlCopyMemory( AFSDumpBuffer,
708                            (void *)((char *)AFSDbgBuffer + ulBytesProcessed),
709                            ulCopyLength);
710
711             ntStatus = ZwWriteFile( hDumpFile,
712                                     NULL,
713                                     NULL,
714                                     NULL,
715                                     &stIoStatus,
716                                     AFSDumpBuffer,
717                                     ulCopyLength,
718                                     &liOffset,
719                                     NULL);
720
721             if( !NT_SUCCESS( ntStatus))
722             {
723                 break;
724             }
725
726             liOffset.QuadPart += ulCopyLength;
727
728             ulBytesProcessed += ulCopyLength;
729         }
730
731 try_exit:
732
733         if( hDumpFile != NULL)
734         {
735             ZwClose( hDumpFile);
736         }
737
738         if( hDirectory != NULL)
739         {
740             ZwClose( hDirectory);
741         }
742
743         if( bSetEvent)
744         {
745             KeSetEvent( &AFSDumpFileEvent,
746                         0,
747                         FALSE);
748         }
749     }
750
751     return;
752 }
753
754 NTSTATUS
755 AFSInitializeDumpFile()
756 {
757
758     NTSTATUS ntStatus = STATUS_SUCCESS;
759
760     __Enter
761     {
762
763         KeInitializeEvent( &AFSDumpFileEvent,
764                            SynchronizationEvent,
765                            TRUE);
766
767         AFSDumpFileName.Length = 0;
768         AFSDumpFileName.Buffer = NULL;
769         AFSDumpFileName.MaximumLength = PAGE_SIZE;
770
771         AFSDumpFileName.Buffer = (WCHAR *)ExAllocatePoolWithTag( PagedPool,
772                                                                  AFSDumpFileName.MaximumLength,
773                                                                  AFS_GENERIC_MEMORY_28_TAG);
774
775         if( AFSDumpFileName.Buffer == NULL)
776         {
777             AFSDumpFileName.MaximumLength = 0;
778
779             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
780         }
781
782         AFSDumpBufferLength = 64 * 1024;
783
784         AFSDumpBuffer = ExAllocatePoolWithTag( PagedPool,
785                                                AFSDumpBufferLength,
786                                                AFS_GENERIC_MEMORY_28_TAG);
787
788         if( AFSDumpBuffer == NULL)
789         {
790
791             ExFreePool( AFSDumpFileName.Buffer);
792
793             AFSDumpFileName.Buffer = NULL;
794             AFSDumpFileName.MaximumLength = 0;
795
796             AFSDumpBufferLength = 0;
797
798             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
799         }
800
801 try_exit:
802
803         NOTHING;
804     }
805
806     return ntStatus;
807 }