Device read/write Method for driver development: direct mode

Source: Internet
Author: User
Tags readfile

The previous section introduces the buffer-based read/write method. Let's take a look at the direct read/write method.

1.

Directly read and write the device. The operating system locks the buffer in user mode, and then the operating system maps the buffer address in kernel mode again. In this way, the user-mode buffer and the kernel-mode buffer point to the physical memory in the same region. No matter how the operating system switches the process, the kernel mode address remains unchanged.

After iocreatedevice is created, you need to set do_direct_io, p1_bj-> flags | = do_direct_io.

2.

Memory Descriptor Table (MDL)

The MDL structure declaration is as follows:
Typedef struct _ MDL {
Struct _ MDL * next;
Cshort size;
Cshort mdlflags;
Struct _ eprocess * process;
Pvoid mappedsystemva;
Pvoid startva; // specifies the virtual address of the user buffer. The address on the first page is valid only in the context of the user mode process that owns the data buffer.
Ulong bytecount; // The length of the buffer in bytes.
Ulong byteoffset; // The Offset Value of the starting position of the buffer on a page frame. The first address of the buffer is MDL-> startva + MDL-> byteoffset.
} MDL, * pmdl;

The structure of the memory Descriptor Table (MDL) is as follows:

The figure shows that the buffer in user mode is continuous in virtual memory, but it may be discrete in physical memory.

3. The following describes some MDL-related functions.

Ioallocatemdl Create MDL
Iobuildpartialmdl Create a child MDL with an existing MDL
Iofreemdl Destroy MDL
Mmbuildmdlfornonpagedpool Modify MDL to describe a non-Paging memory area in kernel mode
Mmgetmdlbytecount Buffer byte size (get MDL-> bytecount)
Mmgetmdlbyteoffset Take the offset of the buffer on the first memory page (get MDL-> byteoffset)
Mmgetmdlvirtualaddress Obtain the virtual address (pvoid) (pchar) (MDL-> startva + MDL-> byteoffset ))
Mmgetsystemaddressformdl Create a kernel mode virtual address mapped to the same memory location
Mmgetsystemaddressformdlsafe Same as mmgetsystemaddressformdl, but preferred for Windows 2000
Mminitializemdl (Again) initialize MDL to describe a given virtual buffer
MMP reparemdlforreuse Initialize MDL again
MMP robeandlockpages Lock the memory page after address validity Verification
Mmsizeofmdl The memory size occupied by the MDL that describes a given virtual buffer.
Mmunlockpages Unlock the Memory Page for this MDL
4. The following uses readfile as an example to describe how to directly read a device.

Call readfile in user mode:

Uchar outputbuffer [10];
DWORD retlen = 0;
Readfile (hdevice, outputbuffer, sizeof (outputbuffer), & retlen, null );

The number of bytes to be read in kernel mode: (same as the buffer read/write mode)

// Obtain the current stack
Pio_stack_location stack = iogetcurrentirpstacklocation (pirp );
// Obtain the number of bytes read by readfile.
Ulong cbread = stack-> parameters... read. length;

In addition, the MDL data structure is obtained through the pirp-> mdladdress of the IRP. This structure describes the memory of the locked buffer.

The following is a dispatch function of irp_mj_read for your reference only.

Ntstatus dispathread; pio_stack_location stack = iogetcurrentirpstacklocation (pirp); ulong ulreadlength = stack-> parameters. read. length; // get the read length kdprint ("ulreadlength: % d \ n", ulreadlength); ulong mdl_length = mmgetmdlbyteco Unt (pirp-> mdladdress); // MDL Virtual Memory Length pvoid mdl_address = mmgetmdlvirtualaddress (pirp-> mdladdress ); // starting address of the virtual memory ulong mdl_offset = mmgetmdlbyteoffset (pirp-> mdladdress); // offset of the first address of the virtual memory on the first page kdprint ("mdl_address: 0x % 08x \ n ", mdl_address); kdprint (" mdl_length: % d \ n ", mdl_length); kdprint (" mdl_offset: % d \ n ", mdl_offset); If (mdl_length! = Ulreadlength) {// the MDL length should be equal to the read length; otherwise, this operation should be set to unsuccessful pir-> iostatus. information = 0; status = status_unsuccessful;} else {// use mmgetsystemaddressformdlsafe to obtain the MDL ing in kernel mode and map it To the memory address in kernel mode, pvoid kernel_address = Priority (pirp-> mdladdress, normalpagepriority); kdprint ("kernel_address: 0x % 08x \ n", kernel_address); memset (kernel_address, 0xaa, ulreadlength); // perform operations on the memory address in kernel mode pirp-> iostatus. information = ulreadlength; // set the actual number of bytes for the Operation} pirp-> iostatus. status = status; iocompleterequest (pirp, io_no_increment); kdprint ("Leave dispatchread \ n"); Return status ;}

Device read/write mode for driver development: Buffer mode see: http://blog.csdn.net/liyun123gx/article/details/38042125

Neither method reference: http://blog.csdn.net/liyun123gx/article/details/38046865


 

Device read/write Method for driver development: direct mode

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.