I know this question can be answered by searching in google. But I have spent nights in searching to try make my application connect with my programmed driver. When I start searching I read some Techniques to how to share information between user-mode and kernel-mode and these Techniques are:
• I/O requests
• Synchronization and notification
• Shared handles
• Shared memory
this white paper explain these Techniques. But I am confused!!! which technique is the best???? For I/O requests: well..., I don't understand it perfeclty but what I know (briefly) about it that exchange data whenever an application requests an I/O operation, and this msdn article explain I/O control codes.
I have read many complex articles, but I don't know the road that lead me to the right way to make my program works fast without delay in exchanging data with the driver.
So, I asked : what is the best way to connect my application with kernel?? And I mean "the best way". This is my driver code:
#include <ntddk.h>
VOID
Unload(
IN PDRIVER_OBJECT DriverObject
)
{
DbgPrint("Driver Unloaded");
};
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPathName
)
{
DbgPrint("Driver Loaded");
DriverObject->DriverUnload = Unload;
return STATUS_SUCCESS;
};
As you see, the driver is simple. Do nothing except output "Driver loaded" when it load and "Driver unloaded" when it unload. Only I want is make this driver able to receive from the user and print it, make the program receive from the driver and print it. I don't want made code, I just want from you to guide me : what I must to do? and what is the best way to do it?
thank you very much
Easiest way is to create a Symbolic link in DriverEntry using IoCreateSymbolicLink
Then from the user mode program call CreateFile
with the name of the symbolic link and use either ReadFile
/WriteFile
or DeviceIoControl
to send/receive data to/from the driver.
For ReadFile
/WriteFile
option you need to implement IRP_MJ_READ
/IRP_MJ_WRITE
processing in your driver.
For DeviceIoControl
you need to handle IRP_MJ_DEVICE_CONTROL
.
Here's a very nice article demonstrating this technique, with sample code for both kernel and user mode. I copied main parts from it related to your question:
//how to create symbolic link
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
UNICODE_STRING usDriverName, usDosDeviceName;
RtlInitUnicodeString(&usDriverName, L"\\Device\\Example");
RtlInitUnicodeString(&usDosDeviceName, L"\\DosDevices\\Example");
IoCreateDevice(pDriverObject, 0, &usDriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);
IoCreateSymbolicLink(&usDosDeviceName, &usDriverName);
}
//How to use from user mode
int main()
{
hFile = CreateFile("\\\\.\\Example", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
//use ReadFile, WriteFile, or DeviceioControl here
return 0;
}