2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
14 * this list of conditions and the following disclaimer in the
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.
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.
35 #include "AFSCommon.h"
38 AFSDbgLogMsg( IN ULONG Subsystem,
44 NTSTATUS ntStatus = STATUS_SUCCESS;
46 ULONG ulBytesWritten = 0;
47 BOOLEAN bReleaseLock = FALSE;
48 char *pCurrentTrace = NULL;
53 if( AFSDbgBuffer == NULL)
56 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
60 (Subsystem & AFSTraceComponent) == 0)
64 // Not tracing this subsystem
67 try_return( ntStatus);
71 Level > AFSTraceLevel)
75 // Not tracing this level
78 try_return( ntStatus);
81 AFSAcquireExcl( &AFSDbgLogLock,
87 // Check again under lock
90 if( AFSDbgBuffer == NULL)
93 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
96 if( AFSDbgLogRemainingLength < 255)
99 AFSDbgLogRemainingLength = AFSDbgBufferLength;
101 AFSDbgCurrentBuffer = AFSDbgBuffer;
103 SetFlag( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED);
106 pCurrentTrace = AFSDbgCurrentBuffer;
108 RtlStringCchPrintfA( AFSDbgCurrentBuffer,
113 AFSDbgCurrentBuffer += 9;
115 AFSDbgLogRemainingLength -= 9;
117 va_start( va_args, Format);
119 ntStatus = RtlStringCbVPrintfA( AFSDbgCurrentBuffer,
120 AFSDbgLogRemainingLength,
124 if( ntStatus == STATUS_BUFFER_OVERFLOW)
127 RtlZeroMemory( AFSDbgCurrentBuffer,
128 AFSDbgLogRemainingLength);
130 AFSDbgLogRemainingLength = AFSDbgBufferLength;
132 AFSDbgCurrentBuffer = AFSDbgBuffer;
134 SetFlag( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED);
136 pCurrentTrace = AFSDbgCurrentBuffer;
138 RtlStringCchPrintfA( AFSDbgCurrentBuffer,
143 AFSDbgCurrentBuffer += 9;
145 AFSDbgLogRemainingLength -= 9;
147 ntStatus = RtlStringCbVPrintfA( AFSDbgCurrentBuffer,
148 AFSDbgLogRemainingLength,
153 if( NT_SUCCESS( ntStatus))
156 RtlStringCbLengthA( AFSDbgCurrentBuffer,
157 AFSDbgLogRemainingLength,
158 (size_t *)&ulBytesWritten);
160 AFSDbgCurrentBuffer += ulBytesWritten;
162 AFSDbgLogRemainingLength -= ulBytesWritten;
167 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_TRACE_TO_DEBUGGER) &&
168 pCurrentTrace != NULL)
171 DbgPrint( pCurrentTrace);
179 AFSReleaseResource( &AFSDbgLogLock);
187 AFSInitializeDbgLog()
190 NTSTATUS ntStatus = STATUS_INSUFFICIENT_RESOURCES;
192 AFSAcquireExcl( &AFSDbgLogLock,
195 if( AFSDbgBufferLength > 0)
198 AFSDbgBuffer = (char *)AFSExAllocatePoolWithTag( NonPagedPool,
200 AFS_GENERIC_MEMORY_19_TAG);
202 if( AFSDbgBuffer != NULL)
205 AFSDbgCurrentBuffer = AFSDbgBuffer;
207 AFSDbgLogRemainingLength = AFSDbgBufferLength;
209 ntStatus = STATUS_SUCCESS;
213 AFSReleaseResource( &AFSDbgLogLock);
215 if( NT_SUCCESS( ntStatus))
217 AFSTagInitialLogEntry();
227 NTSTATUS ntStatus = STATUS_SUCCESS;
229 AFSAcquireExcl( &AFSDbgLogLock,
232 if( AFSDbgBuffer != NULL)
235 ExFreePool( AFSDbgBuffer);
240 AFSDbgCurrentBuffer = NULL;
242 AFSDbgLogRemainingLength = 0;
244 AFSReleaseResource( &AFSDbgLogLock);
250 AFSConfigureTrace( IN AFSTraceConfigCB *TraceInfo)
253 NTSTATUS ntStatus = STATUS_SUCCESS;
254 UNICODE_STRING uniString;
259 AFSAcquireExcl( &AFSDbgLogLock,
262 if( TraceInfo->TraceLevel == AFSTraceLevel &&
263 TraceInfo->TraceBufferLength == AFSDbgBufferLength &&
264 TraceInfo->Subsystem == AFSTraceComponent)
271 try_return( ntStatus);
275 // Go update the registry with the new entries
278 if( TraceInfo->TraceLevel != (ULONG)-1 &&
279 TraceInfo->TraceLevel != AFSTraceLevel)
282 AFSTraceLevel = TraceInfo->TraceLevel;
284 RtlInitUnicodeString( &uniString,
285 AFS_REG_TRACE_LEVEL);
287 ntStatus = AFSUpdateRegistryParameter( &uniString,
289 &TraceInfo->TraceLevel,
292 if( !NT_SUCCESS( ntStatus))
295 DbgPrint("AFSConfigureTrace Failed to set debug level in registry Status %08lX\n", ntStatus);
299 if( TraceInfo->Subsystem != (ULONG)-1 &&
300 TraceInfo->Subsystem != AFSTraceComponent)
303 AFSTraceComponent = TraceInfo->Subsystem;
305 RtlInitUnicodeString( &uniString,
306 AFS_REG_TRACE_SUBSYSTEM);
308 ntStatus = AFSUpdateRegistryParameter( &uniString,
310 &TraceInfo->Subsystem,
313 if( !NT_SUCCESS( ntStatus))
316 DbgPrint("AFSConfigureTrace Failed to set debug subsystem in registry Status %08lX\n", ntStatus);
320 if( TraceInfo->DebugFlags != (ULONG)-1 &&
321 TraceInfo->DebugFlags != AFSDebugFlags)
324 AFSDebugFlags = TraceInfo->DebugFlags;
326 RtlInitUnicodeString( &uniString,
327 AFS_REG_DEBUG_FLAGS);
329 ntStatus = AFSUpdateRegistryParameter( &uniString,
331 &TraceInfo->DebugFlags,
334 if( !NT_SUCCESS( ntStatus))
337 DbgPrint("AFSConfigureTrace Failed to set debug flags in registry Status %08lX\n", ntStatus);
341 if( TraceInfo->TraceBufferLength != (ULONG)-1 &&
342 TraceInfo->TraceBufferLength != AFSDbgBufferLength)
345 RtlInitUnicodeString( &uniString,
346 AFS_REG_TRACE_BUFFER_LENGTH);
348 ntStatus = AFSUpdateRegistryParameter( &uniString,
350 &TraceInfo->TraceBufferLength,
353 if( !NT_SUCCESS( ntStatus))
356 DbgPrint("AFSConfigureTrace Failed to set debug buffer length in registry Status %08lX\n", ntStatus);
359 AFSDbgBufferLength = TraceInfo->TraceBufferLength * 1024;
361 ClearFlag( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED);
363 if( AFSDbgBuffer != NULL)
366 ExFreePool( AFSDbgBuffer);
370 AFSDbgCurrentBuffer = NULL;
372 AFSDbgLogRemainingLength = 0;
375 if( AFSDbgBufferLength > 0)
378 AFSDbgBuffer = (char *)AFSExAllocatePoolWithTag( NonPagedPool,
380 AFS_GENERIC_MEMORY_20_TAG);
382 if( AFSDbgBuffer == NULL)
385 AFSDbgBufferLength = 0;
387 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
390 AFSDbgCurrentBuffer = AFSDbgBuffer;
392 AFSDbgLogRemainingLength = AFSDbgBufferLength;
394 AFSTagInitialLogEntry();
400 AFSReleaseResource( &AFSDbgLogLock);
407 AFSGetTraceBuffer( IN ULONG TraceBufferLength,
408 OUT void *TraceBuffer,
409 OUT ULONG_PTR *CopiedLength)
412 NTSTATUS ntStatus = STATUS_SUCCESS;
413 ULONG ulCopyLength = 0;
414 char *pCurrentLocation = NULL;
419 AFSAcquireShared( &AFSDbgLogLock,
422 if( TraceBufferLength < AFSDbgBufferLength)
425 try_return( ntStatus = STATUS_INVALID_PARAMETER);
429 // If we have wrapped then copy in the remaining portion
432 pCurrentLocation = (char *)TraceBuffer;
436 if( BooleanFlagOn( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED))
439 ulCopyLength = AFSDbgLogRemainingLength;
441 RtlCopyMemory( pCurrentLocation,
445 pCurrentLocation[ 0] = '0'; // The buffer is NULL terminated ...
447 pCurrentLocation += ulCopyLength;
449 *CopiedLength = ulCopyLength;
452 ulCopyLength = AFSDbgBufferLength - AFSDbgLogRemainingLength;
454 if( ulCopyLength > 0)
457 RtlCopyMemory( pCurrentLocation,
461 *CopiedLength += ulCopyLength;
466 AFSReleaseResource( &AFSDbgLogLock);
473 AFSTagInitialLogEntry()
476 LARGE_INTEGER liTime, liLocalTime;
477 TIME_FIELDS timeFields;
479 KeQuerySystemTime( &liTime);
481 ExSystemTimeToLocalTime( &liTime,
484 RtlTimeToTimeFields( &liLocalTime,
489 "AFS Log Initialized %d-%d-%d %d:%d Level %d Subsystems %08lX\n",
505 NTSTATUS ntStatus = STATUS_SUCCESS;
506 HANDLE hDirectory = NULL;
507 OBJECT_ATTRIBUTES stObjectAttribs;
508 IO_STATUS_BLOCK stIoStatus;
509 LARGE_INTEGER liTime, liLocalTime;
510 TIME_FIELDS timeFields;
511 ULONG ulBytesWritten = 0;
512 HANDLE hDumpFile = NULL;
513 ULONG ulBytesProcessed, ulCopyLength;
514 LARGE_INTEGER liOffset;
515 ULONG ulDumpLength = 0;
516 BOOLEAN bSetEvent = FALSE;
521 AFSAcquireShared( &AFSDbgLogLock,
524 ulDumpLength = AFSDbgBufferLength - AFSDbgLogRemainingLength;
526 AFSReleaseResource( &AFSDbgLogLock);
528 if( AFSDumpFileLocation.Length == 0 ||
529 AFSDumpFileLocation.Buffer == NULL ||
530 AFSDbgBufferLength == 0 ||
532 AFSDumpFileName.MaximumLength == 0 ||
533 AFSDumpFileName.Buffer == NULL ||
534 AFSDumpBuffer == NULL)
536 try_return( ntStatus);
540 // Go open the cache file
543 InitializeObjectAttributes( &stObjectAttribs,
544 &AFSDumpFileLocation,
545 OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
549 ntStatus = ZwCreateFile( &hDirectory,
550 GENERIC_READ | GENERIC_WRITE,
555 FILE_SHARE_READ | FILE_SHARE_WRITE,
557 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
561 if( !NT_SUCCESS( ntStatus))
564 try_return( ntStatus);
567 ntStatus = KeWaitForSingleObject( &AFSDumpFileEvent,
573 if( !NT_SUCCESS( ntStatus))
576 try_return( ntStatus);
581 AFSDumpFileName.Length = 0;
583 RtlZeroMemory( AFSDumpFileName.Buffer,
584 AFSDumpFileName.MaximumLength);
586 KeQuerySystemTime( &liTime);
588 ExSystemTimeToLocalTime( &liTime,
591 RtlTimeToTimeFields( &liLocalTime,
594 ntStatus = RtlStringCchPrintfW( AFSDumpFileName.Buffer,
595 AFSDumpFileName.MaximumLength/sizeof( WCHAR),
596 L"AFSDumpFile %d.%d.%d %d.%d.%d.log",
604 if( !NT_SUCCESS( ntStatus))
606 try_return( ntStatus);
609 RtlStringCbLengthW( AFSDumpFileName.Buffer,
610 AFSDumpFileName.MaximumLength,
611 (size_t *)&ulBytesWritten);
613 AFSDumpFileName.Length = (USHORT)ulBytesWritten;
615 InitializeObjectAttributes( &stObjectAttribs,
617 OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
621 ntStatus = ZwCreateFile( &hDumpFile,
622 GENERIC_READ | GENERIC_WRITE,
627 FILE_SHARE_READ | FILE_SHARE_WRITE,
629 FILE_SYNCHRONOUS_IO_NONALERT,
633 if( !NT_SUCCESS( ntStatus))
635 try_return( ntStatus);
639 // Write out the trace buffer
642 liOffset.QuadPart = 0;
644 ulBytesProcessed = 0;
646 while( ulBytesProcessed < ulDumpLength)
649 ulCopyLength = AFSDumpBufferLength;
651 if( ulCopyLength > ulDumpLength - ulBytesProcessed)
653 ulCopyLength = ulDumpLength - ulBytesProcessed;
656 RtlCopyMemory( AFSDumpBuffer,
657 (void *)((char *)AFSDbgBuffer + ulBytesProcessed),
660 ntStatus = ZwWriteFile( hDumpFile,
670 if( !NT_SUCCESS( ntStatus))
675 liOffset.QuadPart += ulCopyLength;
677 ulBytesProcessed += ulCopyLength;
682 if( hDumpFile != NULL)
687 if( hDirectory != NULL)
689 ZwClose( hDirectory);
694 KeSetEvent( &AFSDumpFileEvent,
704 AFSInitializeDumpFile()
707 NTSTATUS ntStatus = STATUS_SUCCESS;
712 KeInitializeEvent( &AFSDumpFileEvent,
713 SynchronizationEvent,
716 AFSDumpFileName.Length = 0;
717 AFSDumpFileName.Buffer = NULL;
718 AFSDumpFileName.MaximumLength = PAGE_SIZE;
720 AFSDumpFileName.Buffer = (WCHAR *)ExAllocatePoolWithTag( PagedPool,
721 AFSDumpFileName.MaximumLength,
722 AFS_GENERIC_MEMORY_28_TAG);
724 if( AFSDumpFileName.Buffer == NULL)
726 AFSDumpFileName.MaximumLength = 0;
728 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
731 AFSDumpBufferLength = 64 * 1024;
733 AFSDumpBuffer = ExAllocatePoolWithTag( PagedPool,
735 AFS_GENERIC_MEMORY_28_TAG);
737 if( AFSDumpBuffer == NULL)
740 ExFreePool( AFSDumpFileName.Buffer);
742 AFSDumpFileName.Buffer = NULL;
743 AFSDumpFileName.MaximumLength = 0;
745 AFSDumpBufferLength = 0;
747 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);