zhengshangj
驱动牛犊
驱动牛犊
  • 注册日期2005-04-27
  • 最后登录2008-08-06
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望9点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
阅读:2091回复:5

如何在驱动中进行Socket通信

楼主#
更多 发布于:2005-06-16 11:05
(1)我要在驱动中实现与服务器(服务器是一个服务)进行Socket通信,
现在要是用Ksock.sys(一个可以驱动层实现Socket通信的驱动),但每次都是进行4次通信后,我的驱动就死掉了(没有反应).

(2)如果现在我想把Socket通信放在我的应用程序,让应用程序与服务器进行通信,然后把通信得到的结果传给驱动程序.请问这样是否可行??
如果可行,那怎么把通信后的内容传给驱动程序呢,通过内存共享吗?

请各位指教!!!
yuanyuan
驱动大牛
驱动大牛
  • 注册日期2003-01-15
  • 最后登录2010-08-04
  • 粉丝0
  • 关注0
  • 积分1025分
  • 威望300点
  • 贡献值0点
  • 好评度232点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-06-20 13:32
应用和驱动共享内存,我贴一个老帖子的代码:

#include <ntddk.h>
#include "CommDriver.h"
#include "..\include\IoControl.h"


PVOID       gpEventObject = NULL;

/*
Response to CreateFile
*/
NTSTATUS CommDriver_Create(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
       NTSTATUS status = STATUS_SUCCESS;

       DbgPrint("CommDriver_Create\n");

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

       return status;
}

/*
Response to CloseHandle
*/
NTSTATUS CommDriver_Close(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
       NTSTATUS status = STATUS_SUCCESS;

       DbgPrint("CommDriver_Close\n");

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

       return status;
}

/*
Resonse to DeviceIoControl
*/
NTSTATUS CommDriver_IoControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
       NTSTATUS                                   status = STATUS_SUCCESS;
       ULONG                                          controlCode;
       PIO_STACK_LOCATION                     irpStack;
       HANDLE                                          hEvent;
       OBJECT_HANDLE_INFORMATION       objHandleInfo;
       LONG*                                          outBuf;

       irpStack = IoGetCurrentIrpStackLocation(Irp);
       controlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
      
       switch(controlCode)
       {
       case IO_REFERENCE_EVENT:
              hEvent = (HANDLE) irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
              status = ObReferenceObjectByHandle(
                            hEvent,
                            GENERIC_ALL,
                            NULL,
                            KernelMode,
                            &gpEventObject,
                            &objHandleInfo);
              if(status != STATUS_SUCCESS)
              {
                     DbgPrint("ObReferenceObjectByHandle failed! status = %x\n", status);
                     break;
              }
              DbgPrint("Referenct object sussfully!\n");
              break;
              
       case IO_DEREFERENCE_EVENT:
              if(gpEventObject)
                     ObDereferenceObject(gpEventObject);
              DbgPrint("Dereferenct object sussfully!\n");
              break;

       case IO_SET_EVENT:
              KeSetEvent(gpEventObject,
                     0,
                     FALSE);
              DbgPrint("KeSetEvent sussfully!\n");
              break;
              
       case IO_CLEAR_EVENT:
              KeClearEvent(gpEventObject);
              DbgPrint("KeClearEvent sussfully!\n");
              break;
      
       case IO_QUERY_EVENT_STATE:
              DbgPrint("in KeReadStateEvent !\n");
              outBuf = (LONG*) Irp->UserBuffer;
              *outBuf = KeReadStateEvent(gpEventObject);
              DbgPrint("KeReadStateEvent sussfully!\n");
              
              Irp->IoStatus.Status = STATUS_SUCCESS;
              Irp->IoStatus.Information = sizeof(LONG);
              IoCompleteRequest(Irp, IO_NO_INCREMENT);
              return status;

       default:
              break;
       }

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

       return status;
}


void CommDriver_Unload(
    IN PDRIVER_OBJECT DriverObject
    )
{
       UNICODE_STRING       SymbolicName;

       RtlInitUnicodeString(&SymbolicName, COMM_DRIVER_WIN32_DEV_NAME);
       IoDeleteSymbolicLink(&SymbolicName);

       IoDeleteDevice(DriverObject->DeviceObject);
}

NTSTATUS DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
       NTSTATUS              status = STATUS_SUCCESS;
       UNICODE_STRING       DeviceName;
       UNICODE_STRING       SymbolicName;

       /* Driver unload routine */
       DriverObject->DriverUnload = CommDriver_Unload;

       /* Initialize major functions */
       DriverObject->MajorFunction[IRP_MJ_CREATE] = CommDriver_Create;
       DriverObject->MajorFunction[IRP_MJ_CLOSE] = CommDriver_Close;
       DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CommDriver_IoControl;

       /* Initizlize device name and symbolic name */
       RtlInitUnicodeString(&DeviceName, COMM_DRIVER_DEV_NAME);
       RtlInitUnicodeString(&SymbolicName, COMM_DRIVER_WIN32_DEV_NAME);

       /*
       Create a communication object,
       GUI application can open the device and communicate with this kernel module.
       */
       status = IoCreateDevice(
                     DriverObject,
                     sizeof(COMM_DRIVER_EXT),
                     &DeviceName,
                     FILE_DEVICE_UNKNOWN,
                     0,
                     TRUE,
                     &DriverObject->DeviceObject
                     );
       if(status != STATUS_SUCCESS)
       {
              DbgPrint("IoCreateDevice failed\n");
              return status;
       }
      
       /* Create symbilic link */
       status = IoCreateSymbolicLink(&SymbolicName, &DeviceName);
       if(status != STATUS_SUCCESS)
       {
              DbgPrint("IoCreateSymbolicLink failed\n");
              return status;
       }
      
       DbgPrint("Exit DriverEntry\n");

       return  status;
}

// CommTestDlg.cpp : implementation file
//

#include "stdafx.h"
#include "CommTest.h"
#include "CommTestDlg.h"

#include <winioctl.h>
#include "..\include\iocontrol.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CCommTestDlg dialog

CCommTestDlg::CCommTestDlg(CWnd* pParent /*=NULL*/)
       : CDialog(CCommTestDlg::IDD, pParent)
{
       //{{AFX_DATA_INIT(CCommTestDlg)
              // NOTE: the ClassWizard will add member initialization here
       //}}AFX_DATA_INIT
       // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
       m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

       m_hCommEvent = NULL;
       m_hCommDevice = NULL;
}

void CCommTestDlg::DoDataExchange(CDataExchange* pDX)
{
       CDialog::DoDataExchange(pDX);
       //{{AFX_DATA_MAP(CCommTestDlg)
       DDX_Control(pDX, IDC_LIST, m_LogList);
       //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CCommTestDlg, CDialog)
       //{{AFX_MSG_MAP(CCommTestDlg)
       ON_WM_PAINT()
       ON_WM_QUERYDRAGICON()
       ON_BN_CLICKED(IDC_OPEN_DEVICE, OnOpenDevice)
       ON_BN_CLICKED(IDC_CLOSE_DEVICE, OnCloseDevice)
       ON_BN_CLICKED(IDC_QUERY_EVENT, OnQueryEvent)
       ON_BN_CLICKED(IDC_CLEAR_EVENT, OnClearEvent)
       ON_BN_CLICKED(IDC_SET_EVENT, OnSetEvent)
       ON_BN_CLICKED(IDC_CREATE_THREAD, OnCreateThread)
       //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCommTestDlg message handlers

BOOL CCommTestDlg::OnInitDialog()
{
       CDialog::OnInitDialog();

       // Set the icon for this dialog.  The framework does this automatically
       //  when the application's main window is not a dialog
       SetIcon(m_hIcon, TRUE);                     // Set big icon
       SetIcon(m_hIcon, FALSE);              // Set small icon
      
       // TODO: Add extra initialization here

       return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CCommTestDlg::OnPaint()
{
       if (IsIconic())
       {
              CPaintDC dc(this); // device context for painting

              SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

              // Center icon in client rectangle
              int cxIcon = GetSystemMetrics(SM_CXICON);
              int cyIcon = GetSystemMetrics(SM_CYICON);
              CRect rect;
              GetClientRect(&rect);
              int x = (rect.Width() - cxIcon + 1) / 2;
              int y = (rect.Height() - cyIcon + 1) / 2;

              // Draw the icon
              dc.DrawIcon(x, y, m_hIcon);
       }
       else
       {
              CDialog::OnPaint();
       }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CCommTestDlg::OnQueryDragIcon()
{
       return (HCURSOR) m_hIcon;
}

void CCommTestDlg::OnOpenDevice()
{
       // TODO: Add your control notification handler code here
       m_hCommDevice = CreateFile(
                     "\\\\.\\CommDriverDev",
                     GENERIC_READ | GENERIC_WRITE,
                     FILE_SHARE_READ, NULL,
                     OPEN_EXISTING,
                     FILE_ATTRIBUTE_NORMAL,
                     NULL);
       if(m_hCommDevice == INVALID_HANDLE_VALUE)
       {
              int error = GetLastError();
              m_LogList.AddString("Please install the device driver and start it firstly!");
       }
       else
              m_LogList.AddString("Successfully opened the device");

       DWORD dwReturn;

       m_hCommEvent = CreateEvent(NULL, false, false, NULL);
      
       //download event object to device driver
       DeviceIoControl(m_hCommDevice,
                     IO_REFERENCE_EVENT,
                     (LPVOID) m_hCommEvent,
                     0,
                     NULL,
                     0,
                     &dwReturn,
                     NULL);
}

void CCommTestDlg::OnCloseDevice()
{
       // TODO: Add your control notification handler code here
       DWORD dwReturn;

       if(m_hCommDevice)
       {
              if(m_hCommEvent)
              {
                     DeviceIoControl(m_hCommDevice,
                            IO_DEREFERENCE_EVENT,
                            NULL,
                            0,
                            NULL,
                            0,
                            &dwReturn,
                            NULL);
                     CloseHandle(m_hCommEvent);
              }

              CloseHandle(m_hCommDevice);
       }
}


void CCommTestDlg::OnQueryEvent()
{
       // TODO: Add your control notification handler code here
       DWORD       dwReturn;
       ULONG       dwState;

       if(m_hCommEvent)
       {
              DeviceIoControl(m_hCommDevice,
                            IO_QUERY_EVENT_STATE,
                            NULL,
                            0,
                            (LPVOID) &dwState,
                            sizeof(dwState),
                            &dwReturn,
                            NULL);
              if(dwState)
                     m_LogList.AddString("Event signaled");
              else
                     m_LogList.AddString("Event non signaled");
       }
}

void CCommTestDlg::OnClearEvent()
{
       // TODO: Add your control notification handler code here
       DWORD       dwReturn;

       if(m_hCommEvent)
       {
              DeviceIoControl(m_hCommDevice,
                            IO_CLEAR_EVENT,
                            NULL,
                            0,
                            NULL,
                            0,
                            &dwReturn,
                            NULL);
       }
}

void CCommTestDlg::OnSetEvent()
{
       // TODO: Add your control notification handler code here
       DWORD       dwReturn;

       if(m_hCommEvent)
       {
              DeviceIoControl(m_hCommDevice,
                            IO_SET_EVENT,
                            NULL,
                            0,
                            NULL,
                            0,
                            &dwReturn,
                            NULL);
       }
}

DWORD WINAPI CCommTestDlg::TestThread(LPVOID lpParam)
{
       CCommTestDlg* pThis = (CCommTestDlg*) lpParam;
      
       if(pThis->m_hCommEvent)
       {
              WaitForSingleObject(pThis->m_hCommEvent, INFINITE);
              AfxMessageBox("Get the event!!!");
       }

       return true;
}

void CCommTestDlg::OnCreateThread()
{
       // TODO: Add your control notification handler code here
       DWORD dwThreadID;

       HANDLE hThread = CreateThread(NULL,
                     0,
                     TestThread,
                     this,
                     0,
                     &dwThreadID);

       CloseHandle(hThread);
}
zhengshangj
驱动牛犊
驱动牛犊
  • 注册日期2005-04-27
  • 最后登录2008-08-06
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望9点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-06-17 14:57
to fenghaifu:
呵呵
能给个倒子吗?

我现在又有个想法:
(1)把IRP_MJ_READ中的内存共享给应用程序.这样的话,应用程序通过Socket通信后就可以直接把内容放到这个共享内存中了.驱动也可以读取到了.  这样可以吗?
(2)驱动程序如何能主动的给应用程序参数呢,因为应用程序的Socket通信中需要这些参数给服务器

谢谢了
再帮我一下!
fenghaifu
驱动牛犊
驱动牛犊
  • 注册日期2005-01-17
  • 最后登录2008-06-24
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-06-17 14:21
可以通过在应用层和驱动层共同创建一个命名事件来实现两者得通讯。
zhengshangj
驱动牛犊
驱动牛犊
  • 注册日期2005-04-27
  • 最后登录2008-08-06
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望9点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-06-17 14:00
呵呵
谢谢你的回答的
不过的Socket通信是在IRP_MJ_READ这个这个函数中进行的.
用DeviceIoControl这个函数不方便通信吧.DeviceIoControl这个函数是应用程序传给驱动程序的.而我要实现的是由驱动程序传到应用程序.
因为IRP_MJ_READ这个读取不是由我的应用程序触发的.而是操作系统执行的.这样的话我的驱动怎样能及时把这个信息传给应用程序呢!!

不知怎么才能实现呢?
fenghaifu
驱动牛犊
驱动牛犊
  • 注册日期2005-01-17
  • 最后登录2008-06-24
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-06-16 14:47
2)如果现在我想把Socket通信放在我的应用程序,让应用程序与服务器进行通信,然后把通信得到的结果传给驱动程序.请问这样是否可行??
如果可行,那怎么把通信后的内容传给驱动程序呢,通过内存共享吗?


这样是可行的,你可以通过DeviceIoCtrl函数来实现两者通讯,然后在你的驱动中实现就可以了。
游客

返回顶部