If the acquisition of the remlock fails, you do not release it (the else case). Again, I strongly recommend that you consider KMDF, this type of cruft is taken care of for you.
If the create dispatch routine is being called and you are completing the request successfully, then either there is a driver layered on top of you which is failing the request (what device class are you installing under?) or your app is misinterpreting the results.
d
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Paul Ryan
Sent: Sunday, June 08, 2008 5:39 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Re: fopen vs CreateFile Driver Access issue
Ok I’ve done the symlink version using the example code from doron’s blog but am still getting the same results. What’s odd is my create interupt handler is getting called:
NTSTATUS
PsdoDispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PIO_STACK_LOCATION p_IO_STK;
PDEVICE_EXTENSION p_DVCEXT;
NTSTATUS status;
DbgPrint(“In print device\n”);
p_IO_STK = IoGetCurrentIrpStackLocation(Irp);
p_DVCEXT = DeviceObject->DeviceExtension;
status = IoAcquireRemoveLock(&p_DVCEXT->RemoveLock, p_IO_STK->FileObject);
if (NT_SUCCESS(status)) {
DbgPrint(“Lock remove success\n”);
CompleteRequest(Irp, STATUS_SUCCESS, 0);
return STATUS_SUCCESS;
} else {
DbgPrint(“Lock remove failure\n”);
IoReleaseRemoveLock(&p_DVCEXT->RemoveLock, p_IO_STK->FileObject);
CompleteRequest(Irp, status, 0);
return status;
}
}
as the Lock remove success is being printed in the debugger, however the client right away exits with the error because the file descriptor pointer is null. My new modified code is:
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
DbgPrint(“In driver entry: begin\n”);
RtlInitUnicodeString(
&Global_sz_Drv_RegInfo,
RegistryPath->Buffer);
// Initialize function pointers
DriverObject->DriverUnload = DriverUnload;
//DriverObject->DriverStartIo = (PVOID)StartIo;
DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->MajorFunction[IRP_MJ_CREATE] = PsdoDispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = PsdoDispatchClose;
DriverObject->MajorFunction[IRP_MJ_READ] = PsdoDispatchRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = PsdoDispatchWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PsdoDispatchDeviceControl;
DriverObject->MajorFunction[IRP_MJ_POWER] = PsdoDispatchPower;
DriverObject->MajorFunction[IRP_MJ_PNP] = PsdoDispatchPnP;
DbgPrint(“In driver entry: end\n”);
return STATUS_SUCCESS;
}
NTSTATUS
AddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
{
ULONG DeviceExtensionSize;
PDEVICE_EXTENSION p_DVCEXT;
PDEVICE_OBJECT ptr_PDO;
NTSTATUS status;
//UNICODE_STRING devname;
UNICODE_STRING dosdevname;
ULONG IdxPwrState;
static long lastIndex = -1;
long devIndex = InterlockedIncrement(&lastIndex);
//WCHAR name[32];
WCHAR symname[32];
DbgPrint(“*******************************Update 5\n”);
//_snwprintf(name, 32, L"\Device\OSEC%d", devIndex);
_snwprintf(symname, 32, L"\DosDevices\OSEC%d", devIndex);
//RtlInitUnicodeString(&devname, name);
RtlInitUnicodeString(&dosdevname, symname);
// TODO (pryan) point at actual device location.
DbgPrint(“Loading device in to %s file\n”, dosdevname);
//Get DEVICE_EXTENSION required memory space
DeviceExtensionSize = sizeof(DEVICE_EXTENSION);
status = IoCreateDevice(
DriverObject,
DeviceExtensionSize,
NULL,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
TRUE,
&ptr_PDO
);
if (NT_SUCCESS(status)) {
ptr_PDO->Flags |= DO_DIRECT_IO;
p_DVCEXT = ptr_PDO->DeviceExtension;
p_DVCEXT->DeviceObject = ptr_PDO;
RtlInitUnicodeString(
&p_DVCEXT->Device_Description,
L"This is a Direct I/O Driver for Pseudo Device\r\n"
L"Created by mjtsai 2003/8/4\r\n");
IoInitializeRemoveLock(
&p_DVCEXT->RemoveLock,
‘KCOL’,
0,
0
);
p_DVCEXT->DataBuffer = ExAllocatePoolWithTag(NonPagedPool, 1024, ‘datB’);
RtlZeroMemory(
p_DVCEXT->DataBuffer,
1024);
//Initialize driver power state
p_DVCEXT->SysPwrState = PowerSystemWorking;
p_DVCEXT->DevPwrState = PowerDeviceD0;
//Initialize device power information
Global_PowerInfo_Ptr = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_POWER_INFORMATION), ‘powP’);
RtlZeroMemory(
Global_PowerInfo_Ptr,
sizeof(DEVICE_POWER_INFORMATION));
Global_PowerInfo_Ptr->SupportQueryCapability = FALSE;
Global_PowerInfo_Ptr->DeviceD1 = 0;
Global_PowerInfo_Ptr->DeviceD2 = 0;
Global_PowerInfo_Ptr->WakeFromD0 = 0;
Global_PowerInfo_Ptr->WakeFromD1 = 0;
Global_PowerInfo_Ptr->WakeFromD2 = 0;
Global_PowerInfo_Ptr->WakeFromD3 = 0;
Global_PowerInfo_Ptr->DeviceWake = 0;
Global_PowerInfo_Ptr->SystemWake = 0;
for (IdxPwrState = 0;
IdxPwrState < PowerSystemMaximum;
IdxPwrState++)
{
Global_PowerInfo_Ptr->DeviceState[IdxPwrState] = 0;
}
status = setDeviceSymlink(PhysicalDeviceObject, dosdevname, p_DVCEXT);
if (!NT_SUCCESS(status)) {
DbgPrint(“Error creating symlink for device to \DosDevices\OSEC%d\n”, devIndex, devIndex);
return status;
}
//Store next-layered device object
//Attach device object to device stack
p_DVCEXT->NextDeviceObject =
IoAttachDeviceToDeviceStack(ptr_PDO, PhysicalDeviceObject);
ptr_PDO->Flags &= ~DO_DEVICE_INITIALIZING;
}
return status;
}
NTSTATUS setDeviceSymlink(PDEVICE_OBJECT pPdo, UNICODE_STRING symlinkName, PDEVICE_EXTENSION deviceExtension)
{
ULONG length;
NTSTATUS status;
PWSTR pName;
UNICODE_STRING pdoName;
length = 0;
status = IoGetDeviceProperty(pPdo,
DevicePropertyPhysicalDeviceObjectName,
0,
NULL,
&length);
if (status != STATUS_BUFFER_TOO_SMALL && !NT_SUCCESS(status)) {
DbgPrint(“Failed to get device name length: %s\n”, OsrNTStatusToString(status));
return status;
}
else if (length > USHORT_MAX) {
DbgPrint(“Name buffer overflow\n”);
return STATUS_INTEGER_OVERFLOW;
}
else if (length == 0) {
DbgPrint(“Error: invalid device state for making symlink”);
//
// We can get zero back if the PDO is being deleted. This can only happen if we are
// creating the symbolic link outside of AddDevice() or a PnP start.
//
return STATUS_INVALID_DEVICE_STATE;
}
pName = (PWSTR) ExAllocatePoolWithTag(PagedPool, length, ‘nBUF’);
if (pName == NULL) {
DbgPrint(“Error: insufficient resources to make symlink”);
return STATUS_INSUFFICIENT_RESOURCES;
}
status = IoGetDeviceProperty(pPdo,
DevicePropertyPhysicalDeviceObjectName,
length,
pName,
&length);
if (!NT_SUCCESS(status)) {
DbgPrint(“Failed to get device name: %s\n”, OsrNTStatusToString(status));
ExFreePool(pName);
pName = NULL;
return status;
}
pdoName.Buffer = pName;
pdoName.Length = (USHORT) length - sizeof(UNICODE_NULL);
pdoName.MaximumLength = (USHORT) length;
status = IoCreateSymbolicLink(&symlinkName, &pdoName);
if (NT_SUCCESS(status)) {
DbgPrint(“Generated symlink %s to %s\n”, symlinkName, pdoName);
// the type of DeviceExtension->PdoName is UNICODE_STRING
RtlCopyMemory(&deviceExtension->PdoName, &pdoName, sizeof(pdoName));
// now that we stored the buffer in our extension, remove all references to the buffer
// so that we don’t accidentally free it while still pointing to it in the extension
pName = NULL;
RtlZeroMemory(&pdoName, sizeof(pdoName));
}
else {
DbgPrint(“Could not generate symlink %s to %s: %s\n”, symlinkName, pdoName, OsrNTStatusToString(status));
ExFreePool(pName);
pName = NULL;
}
return status;
}
Thanks,
Paul Ryan
On Sun, Jun 8, 2008 at 3:50 PM, > wrote:
> Could you please explain what I should have done if I just wanted to name
> the PDO (something human readable).
You can choose either of the things below
1.Create a symlink to PDO’s name so that the user will be able to open it with CreateFile()
2. Don’t be bothered about the name in a driver, and, instead of CreateFile() library function, use
ZwCreateFile() system call in your app. If you do it this way you will be able to open PDO by its name
I would say that, for the sake of simplicity, it is better to take the former option, so that you will be able to hardcode your device name right in app’s code…
Anton Bassov
—
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer