typedef struct _OC_CR_SECTION_VIEW{ // // the start and end adress in the system process // ULONG_PTR BaseAddress; ULONG_PTR EndAddress; // // where the mapped view starts in a file // ULARGE_INTEGER ViewStartInFile; // // where the mapped view ends in a file // ULARGE_INTEGER ViewEndInFile; // // the current pointer // ULONG_PTR CurrentPointer; // // a referenced section object // POC_CR_MAPPED_FILE_SECTION FileSectionObject; } //-------------------------------------------------- NTSTATUS OcCrCreateShadowFile( IN PUNICODE_STRING FileName, IN PULARGE_INTEGER ThresholdFileSize, IN PKEVENT ReferencedServiceEvent OPTIONAL, IN PKEVENT ReferencedEventToSetWhenReleasingFile OPTIONAL, IN PULARGE_INTEGER MaximumSizeDueToQuota OPTIONAL ) { NTSTATUS RC = STATUS_SUCCESS; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatus; HANDLE FileHandle = NULL; PFILE_OBJECT FileObject = NULL; USHORT usCompressionFormat = COMPRESSION_FORMAT_NONE; HANDLE EventHandle; PKEVENT EventObject; BOOLEAN UseCache = FALSE; ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); // // align the maximum size to the page boundary, this restriction // is imposed by our proprietary cache // if( NULL != MaximumSizeDueToQuota ){ MaximumSizeDueToQuota->LowPart = MaximumSizeDueToQuota->LowPart & ~( PAGE_SIZE - 0x1 ); } // // always use fast write! // UseCache = TRUE;//!( g_ShadowLevel > ShadowLevelBase ); //RtlInitUnicodeString( &uFileName, L"\\DosDevices\\C:\\shadow_pio.dat" ); InitializeObjectAttributes( &ObjectAttributes, FileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL ); // // TO DO - Protect file from changing attributes and other file information. // RC = ZwCreateFile( &FileHandle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL, 0x0,// sharing is disabled FILE_SUPERSEDE,// replace the file if exist, because we must be the first and the last file owner FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS | FILE_NO_COMPRESSION | ( UseCache ? 0x0 : FILE_NO_INTERMEDIATE_BUFFERING ), NULL, 0 ); ASSERT( RC != STATUS_PENDING ); if( !NT_SUCCESS( RC ) ) goto __exit; EventObject = IoCreateSynchronizationEvent( NULL, &EventHandle ); if( NULL != EventObject ){ // // Event is created in the signal state // KeResetEvent( EventObject ); // // disable the compression // RC = ZwFsControlFile( FileHandle, EventHandle,//Event NULL,//Apc NULL,//Apc Context &IoStatus, FSCTL_SET_COMPRESSION, &usCompressionFormat, sizeof( usCompressionFormat ), NULL, 0 ); if( STATUS_PENDING == RC ){ KeWaitForSingleObject( EventObject, Executive, KernelMode, FALSE, NULL ); }//if( STATUS_PENDING == RC ) ZwClose( EventHandle ); }//if( NULL != EventObject ){ // // the FSD may not support the compression set request // or the event creation failed, in any case I set // FILE_NO_COMPRESSION attribute, hope this is enough. // RC = STATUS_SUCCESS; RC = ObReferenceObjectByHandle( FileHandle, FILE_ANY_ACCESS, *IoFileObjectType, KernelMode, //to avoid a security check set mode to Kernel (PVOID *)&FileObject, NULL ); ASSERT( NT_SUCCESS( RC ) ); if( !NT_SUCCESS( RC ) ) goto __exit; RC = DldSetNewBuffersFile( FileHandle, FileObject, ThresholdFileSize, ReferencedServiceEvent, ReferencedEventToSetWhenReleasingFile, MaximumSizeDueToQuota ); // // Set file handle to NULL, because it has been grabed by // the DldSetNewBuffersFile and will be closed // when it is no longer needed. // FileHandle = NULL; if( !NT_SUCCESS( RC ) ) goto __exit; __exit: ASSERT( NT_SUCCESS( RC ) ); if( !NT_SUCCESS( RC ) ){ if( NULL != FileObject ){ ObDereferenceObject( FileObject ); } if( NULL != FileHandle ){ ZwClose( FileHandle ); } } else { ASSERT( NULL == FileHandle ); ASSERT( FileObject ); ObDereferenceObject( FileObject ); } return RC; }
BOOLEAN NTAPI InitializeGlobalData(IN PUNICODE_STRING RegistryPath, IN PDRIVER_OBJECT DriverObject) { NTSTATUS Status; UNICODE_STRING LinkName; UNICODE_STRING DeviceName; UNICODE_STRING EventName; PAGED_CODE(); SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n"); /* If we already did this, bail out */ if (GlobalDataInitialized) goto SuccessExit; /* Setup the symbolic link for Win32 support */ RtlInitUnicodeString(&LinkName, L"\\DosDevices\\SAC"); RtlInitUnicodeString(&DeviceName, L"\\Device\\SAC"); Status = IoCreateSymbolicLink(&LinkName, &DeviceName); if (!NT_SUCCESS(Status)) return FALSE; /* Initialize the internal heap manager */ if (!InitializeMemoryManagement()) { IoDeleteSymbolicLink(&LinkName); SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status FALSE\n"); return FALSE; } /* Preload the messages in memory */ Status = PreloadGlobalMessageTable(DriverObject->DriverStart); if (!NT_SUCCESS(Status)) { IoDeleteSymbolicLink(&LinkName); SAC_DBG(SAC_DBG_INIT, "unable to pre-load message table: %X\n", Status); return FALSE; } /* Check if the administrator enabled this */ Status = GetCommandConsoleLaunchingPermission(&CommandConsoleLaunchingEnabled); if (!NT_SUCCESS(Status)) { /* Is it enabled? */ if (CommandConsoleLaunchingEnabled) { /* Set the service start type to the correct value */ Status = ImposeSacCmdServiceStartTypePolicy(); if (!NT_SUCCESS(Status)) { SAC_DBG(SAC_DBG_INIT, "failed ImposeSacCmdServiceStartTypePolicy: %X\n", Status); } } /* We're going to keep going with the default */ SAC_DBG(SAC_DBG_INIT, "failed GetCommandConsoleLaunchingPermission: %X\n", Status); } /* Allocate the UTF-8 Conversion Buffer */ Utf8ConversionBuffer = SacAllocatePool(Utf8ConversionBufferSize, GLOBAL_BLOCK_TAG); if (!Utf8ConversionBuffer) { /* Handle failure case */ TearDownGlobalMessageTable(); IoDeleteSymbolicLink(&LinkName); SAC_DBG(SAC_DBG_INIT, "unable to allocate memory for UTF8 translation\n"); return FALSE; } /* Initialize the channel manager */ Status = ChanMgrInitialize(); if (!NT_SUCCESS(Status)) { /* Handle failure case */ SacFreePool(Utf8ConversionBuffer); TearDownGlobalMessageTable(); IoDeleteSymbolicLink(&LinkName); SAC_DBG(SAC_DBG_INIT, "Failed to create SAC Channel\n"); return FALSE; } /* Allocate the serial port buffer */ SerialPortBuffer = SacAllocatePool(SAC_SERIAL_PORT_BUFFER_SIZE, GLOBAL_BLOCK_TAG); if (!SerialPortBuffer) { /* Handle failure case */ SacFreePool(Utf8ConversionBuffer); TearDownGlobalMessageTable(); IoDeleteSymbolicLink(&LinkName); SAC_DBG(SAC_DBG_INIT, "Failed to allocate Serial Port Buffer\n"); return FALSE; } /* Zero it out */ RtlZeroMemory(SerialPortBuffer, SAC_SERIAL_PORT_BUFFER_SIZE); /* Initialize command events. After this, driver data is good to go */ KeInitializeMutex(&SACCMDEventInfoMutex, FALSE); InitializeCmdEventInfo(); GlobalDataInitialized = TRUE; ProcessingType = 0; IoctlSubmitted = 0; /* Create the SAC event */ RtlInitUnicodeString(&EventName, L"\\SACEvent"); SACEvent = IoCreateSynchronizationEvent(&EventName, &SACEventHandle); if (!SACEvent) { /* Handle failure case */ SacFreePool(Utf8ConversionBuffer); TearDownGlobalMessageTable(); IoDeleteSymbolicLink(&LinkName); SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with event NULL\n"); return FALSE; } /* Cache machine information */ InitializeMachineInformation(); /* Register it */ Status = RegisterBlueScreenMachineInformation(); if (!NT_SUCCESS(Status)) { /* Handle failure case */ SacFreePool(Utf8ConversionBuffer); TearDownGlobalMessageTable(); IoDeleteSymbolicLink(&LinkName); SAC_DBG(SAC_DBG_INIT, "Failed to register blue screen machine info\n"); return FALSE; } SuccessExit: /* Success path -- everything worked */ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status TRUE\n"); return TRUE; }