wangwolue1
驱动牛犊
驱动牛犊
  • 注册日期2002-10-19
  • 最后登录2008-11-26
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
阅读:2180回复:4

关于用deviceiocontrol实现应用程序与驱动的通信问题(蓝屏)?

楼主#
更多 发布于:2002-12-24 22:08
这是动态加载驱动程序的例子修改的。
我刚学驱动,希望个位大虾帮帮忙。


驱动程序:

#include <ntddk.h>
#define IOCTL_SET_FILTER \\
     CTL_CODE(0x8000, 801, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define NT_DEVICE_NAME L\"\\\\Device\\\\Twdm1\"
#define DOS_DEVICE_NAME L\"\\\\DosDevices\\\\Twdm1\"

NTSTATUS DriverEntry( IN PDRIVER_OBJECT  DriverObject, IN PUNICODE_STRING RegistryPath );
NTSTATUS DispatchCreate(PDEVICE_OBJECT fdo, PIRP Irp);
NTSTATUS DispatchClose(PDEVICE_OBJECT fdo, PIRP Irp);
NTSTATUS DispatchControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID GpdUnload(PDRIVER_OBJECT DriverObject);
NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info);

//////////////////////
PDEVICE_OBJECT fdo;
BOOLEAN                         fSymbolicLink;




NTSTATUS DriverEntry( IN PDRIVER_OBJECT  DriverObject, IN PUNICODE_STRING RegistryPath )
{

    //UNREFERENCED_PARAMETER (RegistryPath);
NTSTATUS status;
    UNICODE_STRING                  ntDeviceName;
    UNICODE_STRING                  win32DeviceName;

DbgPrint( \"TWDM: DriverEntry for Twdm.sys ...... \\n\" );
fSymbolicLink = FALSE;
    
    //
    // Create dispatch points for the IRPs.
    //
    
    DriverObject->MajorFunction[IRP_MJ_CREATE]          = DispatchCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]           = DispatchClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = DispatchControl;
    DriverObject->DriverUnload                          = GpdUnload;
    //DriverObject->MajorFunction[IRP_MJ_PNP]            = GpdDispatchPnp;
    //DriverObject->MajorFunction[IRP_MJ_POWER]          = GpdDispatchPower;
    //DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = GpdDispatchSystemControl;
    //DriverObject->DriverExtension->AddDevice           = GpdAddDevice;

    RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);

status = IoCreateDevice(DriverObject,
0,
&ntDeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&fdo);

    if (!NT_SUCCESS (status))
{
DbgPrint( \"TWDM: IoCreateDevice() faild ! \\n\" );
}
else
{
DbgPrint( \"TWDM: IoCreateDevice() ok ! \\n\" );
RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);

status = IoCreateSymbolicLink( &win32DeviceName, &ntDeviceName );
   if (!NT_SUCCESS(status))
{
DbgPrint( \"TWDM: IoCreateSymbolicLink() faild ! \\n\" );
}
else
{
DbgPrint( \"TWDM: IoCreateSymbolicLink() ok ! \\n\" );
   fSymbolicLink = TRUE;
}

   fdo->Flags &= ~DO_DEVICE_INITIALIZING;

}

    if (!NT_SUCCESS(status))
{
if(fdo)
{
IoDeleteDevice(fdo);
}
if(fSymbolicLink)
{
IoDeleteSymbolicLink(&win32DeviceName);
}
}

    return status;
}
NTSTATUS DispatchControl(PDEVICE_OBJECT fdo, PIRP Irp)
{
unsigned long info;
unsigned long cbin;
unsigned long cbout;
unsigned long code;
PDEVICE_EXTENSION pdx;
PIO_STACK_LOCATION stack;
NTSTATUS status;
// DispatchControl
       pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

               status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);

               if (!NT_SUCCESS(status))
                  return CompleteRequest(Irp, status, 0);
                    info = 0;

               stack = IoGetCurrentIrpStackLocation(Irp);
               cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
               cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
               code = stack->Parameters.DeviceIoControl.IoControlCode;

switch (code)
    
     {
        
// process request

                 case IOCTL_SET_FILTER:
                 break;
                
        default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;

} // process request

     IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
    return CompleteRequest(Irp, status, info);
}

NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info)
{ // CompleteRequest
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = info;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
} // CompleteRequest
// DispatchControl

NTSTATUS DispatchCreate(PDEVICE_OBJECT fdo, PIRP Irp)
{
NTSTATUS status;

DbgPrint( \"TWDM: IRP_MJ_CREATE for Twdm.sys ...... \\n\" );
status = STATUS_SUCCESS;

Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return status;

} // DispatchCreate

NTSTATUS DispatchClose(PDEVICE_OBJECT fdo, PIRP Irp)
{ // DispatchClose
NTSTATUS status;

DbgPrint( \"TWDM: IRP_MJ_CLOSE for Twdm.sys ...... \\n\" );
status = STATUS_SUCCESS;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return status;
} // DispatchClose

VOID GpdUnload(PDRIVER_OBJECT DriverObject)
{
    UNICODE_STRING                  win32DeviceName;

DbgPrint( \"TWDM: GpdUnload() for Twdm.sys ...... \\n\" );

RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
if(fdo)
{
IoDeleteDevice(fdo);
}
if(fSymbolicLink)
{
IoDeleteSymbolicLink(&win32DeviceName);
}

}

应用程序:
#include \"stdafx.h\"
#include <windows.h>
#include <winsvc.h>
#include <conio.h>
#include <devioctl.h>
void DelSvr( char *  );

#define IOCTL_SET_FILTER \\
     CTL_CODE(0x8000, 801, METHOD_BUFFERED, FILE_ANY_ACCESS)

int main(int argc, char* argv[])
{
HANDLE hWdm;
printf(\"Hello World!\\n\");

SC_HANDLE hServiceMgr, hServiceTwdm;
BOOL bRtn;
DWORD dwRtn, dwSize = 256;
char szDir[256];

if( argc > 1 )
{
DelSvr( \"Twdm1\" );
return 0;
}

GetCurrentDirectory( dwSize, szDir );
strcat( szDir, \"\\\\Twdm.sys\" );

LPCTSTR lpszBinaryPathName = TEXT(szDir);
hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

if( hServiceMgr == NULL )
{
printf( \"OpenSCManager() Faild  %d ! \\n\", GetLastError() );
return 0;
}
else
{
printf( \"OpenSCManager()  ok ! \\n\" );
}

hServiceTwdm = CreateService( hServiceMgr,
TEXT(\"Twdm1\"),
TEXT(\"Twdm1\"),
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_IGNORE,
lpszBinaryPathName,
NULL,
NULL,
NULL,
NULL,
NULL);



if( hServiceTwdm == NULL )
{
dwRtn = GetLastError();

if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS )
{
CloseServiceHandle( hServiceMgr );
printf( \"CrateService() Faild %d ! \\n\", dwRtn );
return 0;
}
else
{
printf( \"CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \\n\" );
}

hServiceTwdm = OpenService( hServiceMgr, TEXT(\"Twdm1\"), SERVICE_ALL_ACCESS );

if( hServiceTwdm == NULL )
{
dwRtn = GetLastError();
CloseServiceHandle( hServiceMgr );
printf( \"OpenService() Faild %d ! \\n\", dwRtn );
return 0;
}
else
{
printf( \"OpenService() ok ! \\n\" );
}

}
else
{
printf( \"CrateService() ok  ! \\n\" );
}
  

bRtn = StartService( hServiceTwdm, NULL, NULL );

if( !bRtn )
{
//ERROR_PATH_NOT_FOUND
dwRtn = GetLastError();

if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING )
{
printf( \"StartService() Faild  %d ! \\n\", dwRtn );

CloseServiceHandle( hServiceTwdm );
CloseServiceHandle( hServiceMgr );

return 0;
}
else
{
if( dwRtn != ERROR_IO_PENDING  )
{
printf( \"StartService() Faild  ERROR_IO_PENDING ! \\n\");
}
else
{
printf( \"StartService() Faild  ERROR_SERVICE_ALREADY_RUNNING ! \\n\");
}
}
}


hWdm = CreateFile(\"\\\\\\\\.\\\\Twdm1\",
                         GENERIC_WRITE | GENERIC_READ,
                         0,
                         NULL,
                         OPEN_EXISTING,
                         FILE_FLAG_OVERLAPPED,
                         NULL
                         );
if( hWdm != INVALID_HANDLE_VALUE )
{

       //每调用这里的时候会蓝屏。

char m_dwOptions[10];
DWORD bytesWrite;
m_dwOptions[0] = \'a\';
m_dwOptions[1] = \'b\';
m_dwOptions[2] = \'c\';
m_dwOptions[3] = \'d\';
m_dwOptions[4] = \'e\';

printf( \"Open Driver Twdm ok ! \\n\" );

if( DeviceIoControl(hWdm ,IOCTL_SET_FILTER, ( char * )m_dwOptions, 10, ( char * )m_dwOptions, 10, &bytesWrite, NULL ) ) {
printf( \"IOCTL_SET_FILTER ! \\n\" );
}
else {

     printf( \"IOCTL_SET_FILTER erro \\n\" );
}

}
else
{
printf( \"Open Driver Twdm faild %d ! \\n\", GetLastError() );
}

CloseHandle( hWdm );

CloseServiceHandle( hServiceTwdm );
CloseServiceHandle( hServiceMgr );

printf( \"按任意键 卸载驱动程序 !\\n\" );
getch();

DelSvr( \"Twdm1\" );

return 0;
}

void DelSvr( char * szSvrName )
{

SC_HANDLE hServiceMgr, hServiceTwdm;
SERVICE_STATUS  SvrSta;

hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

if( hServiceMgr == NULL )
{
printf( \"DelSvr::OpenSCManager() Faild  %d ! \\n\", GetLastError() );
return;
}
else
{
printf( \"DelSvr::OpenSCManager()  ok ! \\n\" );
}

hServiceTwdm = OpenService( hServiceMgr, TEXT(szSvrName), SERVICE_ALL_ACCESS );

if( hServiceTwdm == NULL )
{
CloseServiceHandle( hServiceMgr );
printf( \"DelSvr::OpenService() Faild %d ! \\n\", GetLastError() );
return;
}
else
{
printf( \"DelSvr::OpenService() ok ! \\n\" );
}


if( !ControlService( hServiceTwdm, SERVICE_CONTROL_STOP , &SvrSta ) )
{
printf( \"DelSvr::ControlService() Faild  %d !\\n\", GetLastError() );
}
else
{
printf( \"DelSvr::ControlService() ok !\\n\" );
}


if( !DeleteService( hServiceTwdm ) )
{
printf( \"DelSvr::DeleteSrevice() Faild  %d !\\n\", GetLastError() );
}
else
{
printf( \"DelSvr::DeleteSrevice() ok !\\n\" );
}

CloseServiceHandle( hServiceTwdm );
CloseServiceHandle( hServiceMgr );

return;

}


最新喜欢:

sunmaculasunmac... okincnokincn
ss
Coolice
驱动小牛
驱动小牛
  • 注册日期2002-11-13
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-12-25 09:48
DeviceExtension没有初始化,

把下面几行去掉:
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status, 0);
info = 0;

...

IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
wangwolue1
驱动牛犊
驱动牛犊
  • 注册日期2002-10-19
  • 最后登录2008-11-26
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-12-25 22:30
谢谢,现在不会蓝屏了,但是现在又出现了一点问题,
那就是应用程序与驱动程序发几个信息之后便不可以在发了。
错误代码是 1061(服务无法在此时接受控制信息。)
这个时候该驱动也无法用
NET STOP Twdm1 关闭,必须重新启动电脑才可以再发控制信息。

////应用程序:
hWdm = CreateFile(\"\\\\\\\\.\\\\Twdm1\",
GENERIC_WRITE | GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
if( hWdm != INVALID_HANDLE_VALUE )
{


char m_dwOptions[10];
DWORD bytesWrite;
m_dwOptions[0] = \'a\';
m_dwOptions[1] = \'b\';
m_dwOptions[2] = \'c\';
m_dwOptions[3] = \'d\';
m_dwOptions[4] = \'e\';

printf( \"Open Driver Twdm ok ! \\n\" );

if( DeviceIoControl(hWdm ,IOCTL_SET_FILTER, ( char * )m_dwOptions, 10, ( char * )m_dwOptions, 10, &bytesWrite, NULL ) ) {
printf( \"IOCTL_SET_FILTER ! \\n\" );
}
else {

printf( \"IOCTL_SET_FILTER erro \\n\" );
}

}
else
{
printf( \"Open Driver Twdm faild %d ! \\n\", GetLastError() );
}

CloseHandle( hWdm );



ss
Coolice
驱动小牛
驱动小牛
  • 注册日期2002-11-13
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-12-26 12:30
DeleteService执行后一般需要重启,所以CreateService后,以后不用再调用CreateService和DeleteService,否则会返回io重叠错误。

另外,CreateFile不能使用FILE_FLAG_OVERLAPPED标志,参数必须如下:
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
wangwolue1
驱动牛犊
驱动牛犊
  • 注册日期2002-10-19
  • 最后登录2008-11-26
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-12-31 13:21
////应用程序已经改为(set.exe):
在基于对话框应用中:
void OnClickSetData()
{
HANDLE hWdm = CreateFile(\"\\\\\\\\.\\\\Twdm1\",
GENERIC_WRITE | GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if( hWdm != INVALID_HANDLE_VALUE )
{


char m_dwOptions[10];
DWORD bytesWrite;
m_dwOptions[0] = \'a\';
m_dwOptions[1] = \'b\';
m_dwOptions[2] = \'c\';
m_dwOptions[3] = \'d\';
m_dwOptions[4] = \'e\';

printf( \"Open Driver Twdm ok ! \\n\" );

if( DeviceIoControl(hWdm ,IOCTL_SET_FILTER, ( char * )m_dwOptions, 10, ( char * )m_dwOptions, 10, &bytesWrite, NULL ) ) {
printf( \"IOCTL_SET_FILTER ! \\n\" );
}
else {

printf( \"IOCTL_SET_FILTER erro \\n\" );
}

}
else
{
printf( \"Open Driver Twdm faild %d ! \\n\", GetLastError() );
}

CloseHandle( hWdm );
}
}
我用DriverStudio的Driver monitor加载它后,再用上面的应用程序(set.exe)
对它控制,发现虽然应用程序窗口关闭了,但是在按CTRL+ALT+DEL时set.exe 居然还在进程列表中。我猜这就是导致
错误代码 1061(服务无法在此时接受控制信息。)的原因。不知应该怎么样解决?另外,我想在驱动中传递字符串“HELLO WORLD”给
应用程序,驱动程序和应用程序应该改那些地方?



[编辑 -  12/31/02 by  wangwolue1]
ss
游客

返回顶部