При попытки чтения/записи в устройство программа виснет. Ошибку сам найти не могу, рассчитываю на помощь более опытных людей.
Код procgen.h
Код:
#pragma once
#define IOCTL_PROCGEN_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0000, METHOD_BUFFERED, FILE_ANY_ACCESS)
Код stdafx.h
Код:
#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifdef __cplusplus
extern "C"
{
#endif
#include <ntddk.h>
#include <ntddstor.h>
#include <mountdev.h>
#include <ntddvol.h>
#include <string.h>
#include "procgen.h"
#ifdef __cplusplus
}
#endif
Код stdafx.c
Код:
//This file is used to build a precompiled header
#include "stdafx.h"
Код драйвера, регистрирующего устройство:
Код:
#include "stdafx.h"
const WCHAR g_NtDevice[]=L"\\Device\\procgen";
const WCHAR g_Win32Device[]=L"\\DosDevices\\procgen";
const WCHAR g_Version[]=L"ProcGen version: 1.0";
typedef struct _DEVICE_EXTENSION
{
PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject;
HANDLE Handle;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
DRIVER_INITIALIZE DriverEntry;
DRIVER_UNLOAD DriverUnload;
DRIVER_DISPATCH DeviceCreate;
DRIVER_DISPATCH DeviceClose;
DRIVER_DISPATCH DeviceIoControl;
DRIVER_DISPATCH DefaultHandler;
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING lpszRegistryPath)
{
NTSTATUS retStatus;
UNICODE_STRING lpszNtDevice;
UNICODE_STRING lpszWin32Device;
PDEVICE_OBJECT pDevice;
PDEVICE_EXTENSION pDeviceExtension;
int i;
for(i=0; i<IRP_MJ_MAXIMUM_FUNCTION; i++)
pDriver->MajorFunction[i]=DefaultHandler;
pDriver->DriverUnload=DriverUnload;
pDriver->MajorFunction[IRP_MJ_CREATE]=DeviceCreate;
pDriver->MajorFunction[IRP_MJ_CLOSE]=DeviceClose;
pDriver->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DeviceIoControl;
pDevice=NULL;
RtlInitUnicodeString(&lpszNtDevice, g_NtDevice);
retStatus=IoCreateDevice(pDriver, sizeof(DEVICE_EXTENSION), &lpszNtDevice, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevice);
if(!NT_SUCCESS(retStatus))
return retStatus;
if(!pDevice)
return STATUS_UNEXPECTED_IO_ERROR;
RtlInitUnicodeString(&lpszWin32Device, g_Win32Device);
retStatus=IoCreateSymbolicLink(&lpszWin32Device, &lpszNtDevice);
if(!NT_SUCCESS(retStatus))
{
IoDeleteDevice(pDevice);
return retStatus;
}
pDeviceExtension=(PDEVICE_EXTENSION)pDevice->DeviceExtension;
pDeviceExtension->DeviceObject=pDevice;
pDeviceExtension->DriverObject=pDriver;
return retStatus;
}
VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
UNICODE_STRING lpszWin32Device;
RtlInitUnicodeString(&lpszWin32Device, g_Win32Device);
IoDeleteSymbolicLink(&lpszWin32Device);
IoDeleteDevice(pDriver->DeviceObject);
}
NTSTATUS DeviceCreate(PDEVICE_OBJECT pDevice, PIRP pIrp)
{
pIrp->IoStatus.Status=STATUS_SUCCESS;
pIrp->IoStatus.Information=0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DeviceClose(PDEVICE_OBJECT pDevice, PIRP pIrp)
{
pIrp->IoStatus.Status=STATUS_SUCCESS;
pIrp->IoStatus.Information=0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DeviceIoControl(PDEVICE_OBJECT pDevice, PIRP pIrp)
{
PIO_STACK_LOCATION pIoStack;
PVOID pIoBuffer;
ULONG uOutputLength;
ULONG uIoControlCode;
pIoStack=IoGetCurrentIrpStackLocation(pIrp);
pIoBuffer=pIrp->AssociatedIrp.SystemBuffer;
uIoControlCode=pIoStack->Parameters.DeviceIoControl.IoControlCode;
switch(uIoControlCode)
{
case IOCTL_PROCGEN_VERSION:
uOutputLength=pIoStack->Parameters.DeviceIoControl.OutputBufferLength;
wcsncpy_s((PWSTR)pIoBuffer, uOutputLength/sizeof(WCHAR), g_Version, wcslen(g_Version));
pIrp->IoStatus.Status=STATUS_SUCCESS;
pIrp->IoStatus.Information=0;
break;
default:
pIrp->IoStatus.Status=STATUS_INVALID_PARAMETER;
pIrp->IoStatus.Information=0;
}
return pIrp->IoStatus.Status;
}
NTSTATUS DefaultHandler(PDEVICE_OBJECT pDevice, PIRP pIrp)
{
pIrp->IoStatus.Status=STATUS_NOT_SUPPORTED;
pIrp->IoStatus.Information=0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return pIrp->IoStatus.Status;
}
Код управляющей программы:
Код:
#include <Windows.h>
#include <stdio.h>
#include "procgen.h"
int main(int argc, char** argv)
{
HANDLE hDevice=INVALID_HANDLE_VALUE;
hDevice=CreateFile(L"\\\\.\\procgen", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if(hDevice==INVALID_HANDLE_VALUE)
{
printf("Can't open device (error %i) \n",GetLastError());
return EXIT_FAILURE;
}
WCHAR wcBuffer[64];
ZeroMemory(wcBuffer, sizeof(WCHAR)*64);
DWORD iReadCounter=0;
DeviceIoControl(hDevice, IOCTL_PROCGEN_VERSION, NULL, 0, wcBuffer, 64, &iReadCounter, NULL);
wprintf(L"Device: %s \n", wcBuffer);
CloseHandle(hDevice);
system("PAUSE");
return EXIT_SUCCESS;
}
Компилирую с помощью WDK
Текст sources
Код:
TARGETNAME=procgen
TARGETTYPE=DRIVER
SOURCES=stdafx.c \
procgen.c