//+---------------------------------------------------------------------------- // // File: DSDATA.C // // Contents: // This module declares the global data used by the Dsfs file system. // // Functions: // // History: 12 Nov 1991 AlanW Created from CDFS souce. //----------------------------------------------------------------------------- #include "dfsprocs.h" // // The debug trace level // #define Dbg (DEBUG_TRACE_CATCH_EXCEPTIONS) // DfsBugCheck // DfsExceptionFilter // DfsProcessException #ifdef ALLOC_PRAGMA #pragma alloc_text ( PAGE, DfsBugCheck ) #pragma alloc_text ( PAGE, DfsExceptionFilter ) #pragma alloc_text ( PAGE, DfsProcessException ) // // The following rountine cannot be paged because it raises the IRQL to // complete IRPs. // // // DfsCompleteRequest_Real // #endif // ALLOC_PRAGMA // // The global FSD data record // DFS_DATA DfsData; // // The global event logging level // ULONG DfsEventLog = 0; #if DBG //+--------------------------------------------------------------------------- // Function: DfsDebugTracePrint, public // // Synopsis: Produce a DFS debug trace printout // // Arguments: [x] -- DbgPrint format string // [y] -- optional argument to DbgPrint // // Returns: None // //---------------------------------------------------------------------------- LONG DfsDebugTraceLevel = 0x00000001; LONG DfsDebugTraceIndent = 0; VOID DfsDebugTracePrint(PCHAR x, PVOID y) { int i; DbgPrint("%08X:",PsGetCurrentThread()); if (DfsDebugTraceIndent < 0) DfsDebugTraceIndent = 0; for (i = 0; i+5 < DfsDebugTraceIndent; i += 5) { DbgPrint(" "); } for ( ; i < DfsDebugTraceIndent; i += 1) { DbgPrint(" "); } DbgPrint(x,y); } #endif // DBG //+--------------------------------------------------------------------------- // Function: DfsBugCheck, public // // Synopsis: Call KeBugCheck with DFS' constant // // Arguments: [pszmsg] -- message (DBG=1 only) // [pszfile] -- filename (DBG=1 only) // [line] -- line number (DBG=1 only) // // Returns: None // //---------------------------------------------------------------------------- #if DBG VOID DfsBugCheck(CHAR *pszmsg, CHAR *pszfile, ULONG line) { PVOID CallersAddress, CallersCaller; RtlGetCallersAddress(&CallersAddress, &CallersCaller); DbgPrint("\nDFS: BugCheck in %s, line %u (%s)\n", pszfile, line, pszmsg); KeBugCheckEx(DFS_FILE_SYSTEM, (ULONG_PTR)CallersAddress, (ULONG_PTR)pszmsg, (ULONG_PTR)pszfile, line); } #else // DBG VOID DfsBugCheck(VOID) { PVOID CallersAddress, CallersCaller; RtlGetCallersAddress(&CallersAddress, &CallersCaller); KeBugCheckEx(DFS_FILE_SYSTEM, (ULONG_PTR)CallersAddress, (ULONG_PTR)CallersCaller, 0, 0); } #endif // DBG //+---------------------------------------------------------------------------- // // Function: FillDebugException // // Synopsis: Captures the exception record into variables that we can // look at. // // Arguments: [pep] -- Pointer to exception record. // // Returns: Nothing // //----------------------------------------------------------------------------- #define CEXCEPTION_STACK 8 PEXCEPTION_RECORD DfsExceptionRecord; PCONTEXT DfsExceptionContext; ULONG DfsExceptionStack[CEXCEPTION_STACK]; VOID FillDebugException( PEXCEPTION_POINTERS pep) { if(pep != NULL) { DfsExceptionRecord = pep->ExceptionRecord; DfsExceptionContext = pep->ContextRecord; } } //+------------------------------------------------------------------- // // Function: DfsExceptionFilter // // Synopsis: Decide if we should or should not handle an exception status // that is being raised. // // Arguments: [ExceptionCode] -- Supplies the exception code to being checked. // [ExceptionPointers] -- Supplies the struct to fill with exception pointers // // Returns: ULONG - returns EXCEPTION_EXECUTE_HANDLER or BugChecks // //-------------------------------------------------------------------- LONG DfsExceptionFilter ( IN NTSTATUS ExceptionCode, IN PEXCEPTION_POINTERS ExceptionPointers OPTIONAL ) { DebugTrace( 0, DEBUG_TRACE_UNWIND, "DfsExceptionFilter %lx\n", ULongToPtr( ExceptionCode )); FillDebugException( ExceptionPointers ); ASSERT(ExceptionCode != STATUS_ACCESS_VIOLATION); ASSERTMSG( "DfsExceptionFilter entered\n", !(DfsDebugTraceLevel & DEBUG_TRACE_UNWIND)); if (!FsRtlIsNtstatusExpected( ExceptionCode )) { BugCheck( "DfsExceptionFilter: Unexpected exception" ); } return EXCEPTION_EXECUTE_HANDLER; } //+------------------------------------------------------------------- // // Function: DfsProcessException, public // // Synopsis: This routine processes an exception. It either completes // the request with the saved exception status or it sends // the request off to the Fsp. // // Arguments: [Irp] -- Supplies the IRP being processed // [ExceptionCode] -- normalized exception status being handled // // Returns: NTSTATUS - Returns the results of either posting the Irp or the // saved completion status. // //-------------------------------------------------------------------- NTSTATUS DfsProcessException ( IN PIRP Irp, IN NTSTATUS ExceptionCode ) { NTSTATUS Status; DebugTrace(0, Dbg, "DfsProcessException\n", 0); // // We got an error, so zero out the information field before // completing the request if this was an input operation. // Otherwise IopCompleteRequest will try to copy to the user's buffer. // if (FlagOn(Irp->Flags, IRP_INPUT_OPERATION)) { Irp->IoStatus.Information = 0; } Status = ExceptionCode; DfsCompleteRequest( Irp, Status ); return Status; } //+------------------------------------------------------------------- // // Function: DfsCompleteRequest, public // // Synopsis: This routine completes a Irp // // Arguments: [Irp] - Supplies the Irp being processed // [Status] - Supplies the status to complete the Irp with // // Returns: None. // //-------------------------------------------------------------------- VOID DfsCompleteRequest_Real ( IN PIRP Irp OPTIONAL, IN NTSTATUS Status ) { KIRQL PreviousIrql; // // If we have an Irp then complete the irp. // if (Irp != NULL) { Irp->IoStatus.Status = Status; IoCompleteRequest( Irp, IO_DISK_INCREMENT ); } return; }