Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WPF

A Simple Demo for WDF Driver Development

4.78/5 (7 votes)
26 Apr 2010CPOL2 min read 1   4.3K  
Access physical memory, I/O port in user mode

Introduction

WINFO, a well known tool on the internet, can directly access I/O and memory. It applied Microsoft undocumented function (NATIVE API) to fetch I/O data. The design structure of PCI View is based on WDF as to simulate the function of WINFO to access I/O and memory.

Background

Knowledge of Win32 SDK is required.

Program Structure

Image 1

PCI View can access I/O port and memory via IOMEM.DLL or the functions of DeviceIoControl or ReadFile/WriteFile.

Introduction of Application

The API functions of READ_PORT_UCHAR(USHORT/ULONG) or WRITE_PORT_UCHAR(USHORT/ULONG) can be applied to access I/O port in Windows NT environment. The usages of API functions are similar to the functions provided by Runtime Library of C language, such as _outp and _inp.

C++
case 1: //UCHAR 
   if (pvInputBuffer->Command == 0) //decide to write or read 
        WRITE_PORT_UCHAR((PUCHAR)pvInputBuffer->PortBase, (UCHAR)pvInputBuffer->Data); 
   else 
        *(PUCHAR)pvOutputBuffer = READ_PORT_UCHAR((PUCHAR)pvInputBuffer->PortBase); 
break; 

case 2: // USHORT 
   if (pvInputBuffer->Command == 0) 
       WRITE_PORT_USHORT((PUSHORT)pvInputBuffer->PortBase, (USHORT)pvInputBuffer->Data); 
   else 
       *(PUSHORT)pvOutputBuffer = READ_PORT_USHORT((PUSHORT)pvInputBuffer->PortBase); 
break; 

case 4: //ULONG 
   if (pvInputBuffer->Command == 0) 
       WRITE_PORT_ULONG((PULONG)pvInputBuffer->PortBase, (ULONG)pvInputBuffer->Data); 
   else 
       *(PULONG)pvOutputBuffer = READ_PORT_ULONG((PULONG)pvInputBuffer->PortBase); 
break;

The processing of memory is more complicated than the process of I/O which can be easily done by the API function.

  1. First of all, we need to get address and length where user would like to access in memory. Then, MmMapIoSpace function can map the address and length into a non-paged system space.
  2. If the previous process is success, the allocations of IoAllocateMdland MmBuildMdlForNonPagedPool will be enough to be buffered to mapping the real memory.
  3. MmMapLockedPagesSpecifyCache function can map the virtual memory to the caller. Therefore, the applications of RING 3 can directly fetch memory.
C++
//Step 1.
memReq.MapIo = MmMapIoSpace(Address, memReq.Length, MmNonCached);
if (memReq.MapIo == NULL)
{
    status = STATUS_INSUFFICIENT_RESOURCES;
    __leave;
};

// Step 2.
memReq.Mdl = IoAllocateMdl(memReq.MapIo, memReq.Length, FALSE, FALSE, NULL);
if (memReq.Mdl == NULL)
{
    status = STATUS_INSUFFICIENT_RESOURCES;
    __leave;
};
MmBuildMdlForNonPagedPool(memReq.Mdl);

// Step 3.
memReq.Buffer = (PUCHAR)MmMapLockedPagesSpecifyCache(memReq.Mdl,
                      UserMode, //set value as UserMode
                      MmNonCached,
                      NULL,
                      FALSE,
                      NormalPagePriority);
if (memReq.Buffer == NULL)
{
     status = STATUS_INSUFFICIENT_RESOURCES;
     __leave;
};

The dynamic functions in real mode provide outp, _outpw, _outpd, _inp, _inpw and _inpd to access I/O port. There are 4 functions, such as MapMemory, UnmapMemory, ReadPhyicalMemory and WritePhyicalMemory, that can be used to fetch memory.

Function: designed to access the address and length of memory:

C++
PUCHAR MapMemory(__in ULONG Address, __in ULONG Length);
Address : To access the beginning address of memory.
Length : To get the length of memory

The function will return the beginning address mapping in memory 
when executed successfully. 
Function: Release the assigned memory.
BOOLEAN UnmapMemory(VOID);

Sample Program

The application presents a sample to access IO-MEM. Without including DLL package, the application shows the information of the assigned memory or I/O port when directly calling IOMEM.DLL. The source code can be downloaded from http://bbs.codeheaven.com.tw/.

Image 2

Sample:

Image 3

History

  • 26th April, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)