⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winio.c

📁 很好的串口读写程序
💻 C
字号:
// ------------------------------------------------- //
//                   WinIo v1.3                      //
//  Direct Hardware Access Under Windows 9x/NT/2000  //
//        Copyright 1998-2001 Yariv Kaplan           //
//           http://www.internals.com                //
// ------------------------------------------------- //

#include <ntddk.h>
#include "winio.h"

#define OutputDebugString

// Function definition section
// -----------------------------------------------------------------
NTSTATUS WinIoDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
void WinIoUnload(IN PDRIVER_OBJECT DriverObject);
NTSTATUS UnmapPhysicalMemory(HANDLE PhysicalMemoryHandle, PVOID pPhysMemLin);
NTSTATUS MapPhysicalMemoryToLinearSpace(PVOID *ppPhysAddress,
                                        ULONG PhysMemSizeInBytes,
                                        PVOID *ppPhysMemLin,
                                        HANDLE *pPhysicalMemoryHandle);
// -----------------------------------------------------------------

// Installable driver initialization entry point.
// This entry point is called directly by the I/O system.

NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,
                      IN PUNICODE_STRING RegistryPath)
{
  UNICODE_STRING  DeviceNameUnicodeString;
  UNICODE_STRING  DeviceLinkUnicodeString;
  NTSTATUS        ntStatus;
  PDEVICE_OBJECT  DeviceObject = NULL;

  OutputDebugString ("Entering DriverEntry");

  RtlInitUnicodeString (&DeviceNameUnicodeString, L"\\Device\\WinIo");

  // Create an EXCLUSIVE device object (only 1 thread at a time
  // can make requests to this device).

  ntStatus = IoCreateDevice (DriverObject,
                             0,
                             &DeviceNameUnicodeString,
                             FILE_DEVICE_WINIO,
                             0,
                             TRUE,
                             &DeviceObject);
	
  if (NT_SUCCESS(ntStatus))
  {
    // Create dispatch points for device control, create, close.

    DriverObject->MajorFunction[IRP_MJ_CREATE]         =
    DriverObject->MajorFunction[IRP_MJ_CLOSE]          =
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = WinIoDispatch;
    DriverObject->DriverUnload                         = WinIoUnload;

    // Create a symbolic link, e.g. a name that a Win32 app can specify
    // to open the device.

    RtlInitUnicodeString (&DeviceLinkUnicodeString, L"\\DosDevices\\WinIo");

    ntStatus = IoCreateSymbolicLink (&DeviceLinkUnicodeString,
                                     &DeviceNameUnicodeString);

    if (!NT_SUCCESS(ntStatus))
    {
      // Symbolic link creation failed- note this & then delete the
      // device object (it's useless if a Win32 app can't get at it).

      OutputDebugString ("ERROR: IoCreateSymbolicLink failed");

      IoDeleteDevice (DeviceObject);
    }

  }
  else
  {
    OutputDebugString ("ERROR: IoCreateDevice failed");
  }

  OutputDebugString ("Leaving DriverEntry");

  return ntStatus;
}


// Process the IRPs sent to this device

NTSTATUS WinIoDispatch(IN PDEVICE_OBJECT DeviceObject,
                       IN PIRP Irp)
{
  PIO_STACK_LOCATION IrpStack;
  ULONG              dwInputBufferLength;
  ULONG              dwOutputBufferLength;
  ULONG              dwIoControlCode;
  PVOID              pvIOBuffer;
  NTSTATUS           ntStatus;
  struct             tagPort32Struct Port32Struct;
  struct             tagPhys32Struct Phys32Struct;

  OutputDebugString ("Entering WinIoDispatch");

  // Init to default settings

  Irp->IoStatus.Status      = STATUS_SUCCESS;
  Irp->IoStatus.Information = 0;
  
  IrpStack = IoGetCurrentIrpStackLocation(Irp);

  // Get the pointer to the input/output buffer and it's length

  pvIOBuffer           = Irp->AssociatedIrp.SystemBuffer;
  dwInputBufferLength  = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
  dwOutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

  switch (IrpStack->MajorFunction)
  {
    case IRP_MJ_CREATE:

      OutputDebugString("IRP_MJ_CREATE");

    break;

    case IRP_MJ_CLOSE:

      OutputDebugString("IRP_MJ_CLOSE");

    break;

    case IRP_MJ_DEVICE_CONTROL:

      OutputDebugString("IRP_MJ_DEVICE_CONTROL");

      dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;

      switch (dwIoControlCode)
      {
        case IOCTL_WINIO_MAPPHYSTOLIN:

          OutputDebugString("IOCTL_WINIO_MAPPHYSTOLIN");

          if (dwInputBufferLength)
          {
            memcpy (&Phys32Struct, pvIOBuffer, dwInputBufferLength);

            ntStatus = MapPhysicalMemoryToLinearSpace(&Phys32Struct.pvPhysAddress,
                                                      Phys32Struct.dwPhysMemSizeInBytes,
                                                      &Phys32Struct.pvPhysMemLin,
                                                      &Phys32Struct.PhysicalMemoryHandle);

            if (NT_SUCCESS(ntStatus))
            {
              memcpy (pvIOBuffer, &Phys32Struct, dwInputBufferLength);
              Irp->IoStatus.Information = dwInputBufferLength;
            }

            Irp->IoStatus.Status = ntStatus;
          }
          else
            Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

        break;

        case IOCTL_WINIO_UNMAPPHYSADDR:

          OutputDebugString("IOCTL_WINIO_UNMAPPHYSADDR");

          if (dwInputBufferLength)
          {
            memcpy (&Phys32Struct, pvIOBuffer, dwInputBufferLength);

            ntStatus = UnmapPhysicalMemory(Phys32Struct.PhysicalMemoryHandle, Phys32Struct.pvPhysMemLin);

            Irp->IoStatus.Status = ntStatus;
          }
          else
            Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

        break;

        case IOCTL_WINIO_WRITEPORT:

          OutputDebugString("IOCTL_WINIO_WRITEPORT");

          if (dwInputBufferLength)
          {
            memcpy (&Port32Struct, pvIOBuffer, dwInputBufferLength);

            switch (Port32Struct.bSize)
            {
              case 1:
                WRITE_PORT_UCHAR(Port32Struct.wPortAddr, (UCHAR)Port32Struct.dwPortVal);
              break;

              case 2:
                WRITE_PORT_USHORT(Port32Struct.wPortAddr, (USHORT)Port32Struct.dwPortVal);
              break;

              case 4:
                WRITE_PORT_ULONG(Port32Struct.wPortAddr, Port32Struct.dwPortVal);
              break;
            }
          }
          else
            Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

        break;

        case IOCTL_WINIO_READPORT:

          OutputDebugString("IOCTL_WINIO_READPORT");

          if (dwInputBufferLength)
          {
            memcpy (&Port32Struct, pvIOBuffer, dwInputBufferLength);

            switch (Port32Struct.bSize)
            {
              case 1:
                Port32Struct.dwPortVal = (ULONG)READ_PORT_UCHAR(Port32Struct.wPortAddr);
              break;

              case 2:
                Port32Struct.dwPortVal = (ULONG)READ_PORT_USHORT(Port32Struct.wPortAddr);
              break;

              case 4:
                Port32Struct.dwPortVal = READ_PORT_ULONG(Port32Struct.wPortAddr);
              break;
            }

            memcpy (pvIOBuffer, &Port32Struct, dwInputBufferLength);
            Irp->IoStatus.Information = dwInputBufferLength;
          }
          else
            Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

        break;
 
        default:

          OutputDebugString("ERROR: Unknown IRP_MJ_DEVICE_CONTROL");

          Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

        break;
      }

    break;
  }

  // DON'T get cute and try to use the status field of the irp in the
  // return status.  That IRP IS GONE as soon as you call IoCompleteRequest.

  ntStatus = Irp->IoStatus.Status;

  IoCompleteRequest (Irp, IO_NO_INCREMENT);

  // We never have pending operation so always return the status code.

  OutputDebugString("Leaving WinIoDispatch");

  return ntStatus;
}

// Delete the associated device and return

void WinIoUnload(IN PDRIVER_OBJECT DriverObject)
{
  UNICODE_STRING DeviceLinkUnicodeString;
  NTSTATUS ntStatus;

  OutputDebugString ("Entering WinIoUnload");

  RtlInitUnicodeString (&DeviceLinkUnicodeString, L"\\DosDevices\\WinIo");
  
  ntStatus = IoDeleteSymbolicLink (&DeviceLinkUnicodeString);

  if (NT_SUCCESS(ntStatus))
  {
    IoDeleteDevice (DriverObject->DeviceObject);
  }
  else
  {
    OutputDebugString ("ERROR: IoDeleteSymbolicLink");
  }

  OutputDebugString ("Leaving WinIoUnload");
}


NTSTATUS MapPhysicalMemoryToLinearSpace(PVOID *ppPhysAddress,
                                        ULONG PhysMemSizeInBytes,
                                        PVOID *ppPhysMemLin,
                                        HANDLE *pPhysicalMemoryHandle)
{
  UNICODE_STRING     PhysicalMemoryUnicodeString;
  PVOID              PhysicalMemorySection = NULL;
  OBJECT_ATTRIBUTES  ObjectAttributes;
  PHYSICAL_ADDRESS   ViewBase;
  NTSTATUS           ntStatus;

  OutputDebugString ("Entering MapPhysicalMemoryToLinearSpace");

  RtlInitUnicodeString (&PhysicalMemoryUnicodeString,
                        L"\\Device\\PhysicalMemory");

  InitializeObjectAttributes (&ObjectAttributes,
                              &PhysicalMemoryUnicodeString,
                              OBJ_CASE_INSENSITIVE,
                              (HANDLE) NULL,
                              (PSECURITY_DESCRIPTOR) NULL);

  *pPhysicalMemoryHandle = NULL;

  ntStatus = ZwOpenSection (pPhysicalMemoryHandle,
                            SECTION_ALL_ACCESS,
                            &ObjectAttributes);

  if (NT_SUCCESS(ntStatus))
  {

    ntStatus = ObReferenceObjectByHandle (*pPhysicalMemoryHandle,
                                          SECTION_ALL_ACCESS,
                                          (POBJECT_TYPE) NULL,
                                          KernelMode,
                                          &PhysicalMemorySection,
                                          (POBJECT_HANDLE_INFORMATION) NULL);

    // Let ZwMapViewOfSection pick a linear address

    *ppPhysMemLin = NULL;

    ViewBase.QuadPart = (ULONGLONG)*ppPhysAddress;

    ntStatus = ZwMapViewOfSection (*pPhysicalMemoryHandle,
                                   (HANDLE) -1,
                                   ppPhysMemLin,
                                   0L,
                                   PhysMemSizeInBytes,
                                   &ViewBase,
                                   &PhysMemSizeInBytes,
                                   ViewShare,
                                   0,
                                   PAGE_READWRITE | PAGE_NOCACHE);

    if (!NT_SUCCESS(ntStatus))
      OutputDebugString ("ERROR: ZwMapViewOfSection failed");
  }
  else
    OutputDebugString ("ERROR: ZwOpenSection failed");

  *ppPhysAddress = (PVOID)ViewBase.LowPart;

  OutputDebugString ("Leaving MapPhysicalMemoryToLinearSpace");

  return ntStatus;
}


NTSTATUS UnmapPhysicalMemory(HANDLE PhysicalMemoryHandle, PVOID pPhysMemLin)
{
  NTSTATUS ntStatus;

  OutputDebugString ("Entering UnmapPhysicalMemory");

  ntStatus = ZwUnmapViewOfSection((HANDLE)-1, pPhysMemLin);

  if (!NT_SUCCESS(ntStatus))
    OutputDebugString ("ERROR: UnmapViewOfSection failed");

  ZwClose(PhysicalMemoryHandle);

  OutputDebugString ("Leaving UnmapPhysicalMemory");

  return ntStatus;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -