Hello,
Sorry for my english.
I’ve wrote a little driver to manage memory some times ago, it is managing a pool of memory with physical address below 4GB.
I have an open source driver that have some issue when the system is under heavy memory load. This driver require some memory with physical address below 4GB that may not be avaible when it is loading.
So i tryed to remplace the MmAllocatePagesForMdl and the MmFreePagesFromMdl from the open source driver to ioctl call to my driver.
Here is the call function, i wrote, in the open source driver:
RtlInitUnicodeString(&ObjectPhysMem, L"\Device\MyDriver");
ntStatus = IoGetDeviceObjectPointer(&Object, FILE_ANY_ACCESS, &File, &Device);
if(!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
KeInitializeEvent(&Event, NotificationEvent, FALSE);
irp = IoBuildDeviceIoControlRequest(ioCode, Device, inData, inSize, outData, outSize, FALSE, &Event, &ioStatusBlock);
if(NULL == irp)
{
ObDereferenceObject(File);
return ntStatus;
}
ntStatus = IoCallDriver(Device, irp);
if (STATUS_PENDING == ntStatus)
{
ntStatus = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
if (!NT_SUCCESS(ntStatus))
{
ObDereferenceObject(File);
return ntStatus;
}
ntStatus = ioStatusBlock.Status;
}
if(!NT_SUCCESS(ntStatus))
{
ObDereferenceObject(File);
return ntStatus;
}
ObDereferenceObject(File);
return STATUS_SUCCESS;
For allocation : inData = size_t*, inSize = sizeof(size_t), outData = PMDL*, outSize = sizeof(PMDL). I init the outData this way : *outData = NULL;
For free : inData = PMDL*, inSize = sizeof(PMDL), outData = NULL, outSize = 0
The IOCTL code are :
CTL_CODE(XXXX, YYYY, METHOD_BUFFERED, FILE_ANY_ACCESS)
The dispatch function of my driver is :
PIO_STACK_LOCATION irpStack;
ULONG dwInBufLen;
ULONG dwOutBufLen;
ULONG dwIoCtlCode;
NTSTATUS ntStatus;
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = 0;
irpStack = IoGetCurrentIrpStackLocation(irp);
dwInBufLen = irpStack->Parameters.DeviceIoControl.InputBufferLength;
dwOutBufLen = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch (irpStack->MajorFunction)
{
case IRP_MJ_DEVICE_CONTROL:
dwIoCtlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
switch (dwIoCtlCode)
{
case LOWALLOCATE:
if (dwInBufLen == sizeof(size_t) && dwOutBufLen == sizeof(PMDL))
{
int status;
PMDL pmdl = NULL;
status = myFuncAllocate(*((size_t*)irp->AssociatedIrp.SystemBuffer), &pmdl);
if (0 == status)
{
RtlCopyMemory(irp->AssociatedIrp.SystemBuffer, &pmdl, sizeof(PMDL));
irp->IoStatus.Information = sizeof(PMDL);
}
else
irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
}
else
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
break;
case LOWFREE:
if (dwInBufLen == sizeof(PMDL) && dwOutBufLen == 0)
{
myFuncFree(*((PMDL*)irp->AssociatedIrp.SystemBuffer));
irp->IoStatus.Information = 0;
}
else
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
break;
}
break;
}
ntStatus = irp->IoStatus.Status;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return ntStatus;
In my test the dispatch function return 100% ntStatus = STATUS_SUCCESS with correct value as output. When i look at the content irp->UserBuffer and ipr->AssociatedIrp.SystemBuffer then value seems always good : irp->UserBuffer has the address of where to store the mdl address and ipr->AssociatedIrp.SystemBuffer have the address returned by my driver.
My problem is 50% of the time Windows freeze and when i watch the log display when it froze, it tell me that *outData is NULL. It is like the data returned by my driver are copied at a wrong place, making windows freeze, even if irp->UserBuffer seems right.
It seems i have not understand something in the driver world.
Anyone can explain me this issue, and what i do wrong ?
Best regards,
O.D.