experiment : ip convert to DWORD value on nt driver

demo下载: prjIpV4Convert_2013_0406_1749.iso

experiment : ip convert to DWORD value on nt driver_第1张图片

experiment : ip convert to DWORD value on nt driver_第2张图片

需求:

* 用户输入IP串,  转换成DWORD值.  e.g. 1.1.1.1 => 0x01010101

* 计算过程在驱动中完成, 应用层只负责用户输入处理, 显示, 调用DLL.


概要设计:

* 为了维护方便, 采用 app => dll => nt driver

* 加入用户输入数据的校验

* 应用层加入输入提示, 可以运行多次, 由用户决定退出时机.

* 环境: vs2008sp1 + wdk7600 + win7x64sp1 + vmware9.0(win7x86家庭普通版)


驱动部分的实现:

NTSTATUS DispatchIoctrl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
    PVOID   pInputBuffer    =   NULL;
    ULONG   ulinputSize     =   0;
    PVOID   pOutputBuffer   =   NULL;
    ULONG * pulOutputSize   =   NULL;
    ULONG   ulCtrlCode      =   0;
    ULONG   ulIp            =   0;
    NTSTATUS sRc            =   STATUS_SUCCESS;

    PIO_STACK_LOCATION pIostack;

    DbgPrint(">> DispatchIoctrl\r\n");

    pIostack = IoGetCurrentIrpStackLocation(pIrp);

    ulCtrlCode = pIostack->Parameters.DeviceIoControl.IoControlCode;

    pInputBuffer = pIrp->AssociatedIrp.SystemBuffer;
    ulinputSize = pIostack->Parameters.DeviceIoControl.InputBufferLength;

    pOutputBuffer = pIrp->AssociatedIrp.SystemBuffer;
    pulOutputSize = &pIostack->Parameters.DeviceIoControl.OutputBufferLength;

    switch(ulCtrlCode)
    {
    case IO_CTRL_CODE_IP_CONVERT:
        DbgPrint("IO_CTRL_CODE_IP_CONVERT\r\n");
        sRc = fnIpConvert(pInputBuffer, ulinputSize, &ulIp);
        pIrp->IoStatus.Status = sRc;
        pIrp->IoStatus.Information = (STATUS_SUCCESS == sRc) ? sizeof(ULONG) : 0;
        if (STATUS_SUCCESS == sRc)
        {
            if (*pulOutputSize >= sizeof(ULONG))
            {
                RtlCopyMemory(pOutputBuffer, (PVOID)(&ulIp), sizeof(ULONG));
            }
            else
            {
                pIrp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
                pIrp->IoStatus.Information = 0;
            }
        }
        break;
    default:
        DbgPrint("Unknown ulCtrlCode\r\n");
        pIrp->IoStatus.Status = STATUS_SUCCESS;
        pIrp->IoStatus.Information = 0;
        break;
    }

    IoCompleteRequest(pIrp, IO_NO_INCREMENT);

    DbgPrint("<< DispatchIoctrl\r\n");
    return STATUS_SUCCESS;
}

/// @file           sysInc\IpConvertFunction.h
/// @brief          IP转换功能的实现

#ifndef __IP_CONVERT_FUNCTION_H__
#define __IP_CONVERT_FUNCTION_H__

#include <ntddk.h>
#include "IpConvertConst.h"

NTSTATUS fnIpConvert(PVOID pcIpContent, ULONG ulLenIpContent, ULONG * pulIp);
BOOLEAN IsInCharset(wchar_t cLetter, wchar_t * pcCharset, ULONG ulLenCharset);
BOOLEAN IsValidIpField(USHORT uIpField);

#endif

/// @file           sysInc\IpConvertFunction.c
/// @brief          IP转换功能的实现

#include "IpConvertFunction.h"

NTSTATUS fnIpConvert(PVOID pcIpContent, ULONG ulLenIpContent, ULONG * pulIp)
{
    /// ulLenIpContent 是字节长度
    /// pcIpContent is xx.xx.xx.xx e.g. 192.l68.1.1
    ULONG   ulIp        =   0;
    ULONG   ulPos       =   0;
    wchar_t cTmp        =   0;
    USHORT  uIpSection  =   0;  ///< 要装下 255~999之间的数
    size_t  nDotCnt     =   0;

    wchar_t cDigit[] = {L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9', L'.'};

    if (
        (NULL == pcIpContent)
        || (NULL == pulIp)
        || (ulLenIpContent <= 0))
    {
        return STATUS_INVALID_PARAMETER;
    }

    for (ulPos = 0; ulPos < ulLenIpContent;)
    {
        cTmp = *((wchar_t *)((UCHAR *)pcIpContent + ulPos));
        if (!IsInCharset(cTmp, cDigit, sizeof(cDigit) / sizeof(wchar_t)))
        {
            return STATUS_INVALID_PARAMETER;
        }

        if (L'.' == cTmp)
        {
            nDotCnt++;
            if (!IsValidIpField(uIpSection))
            {
                return STATUS_INVALID_PARAMETER;
            }

            ulIp = (ulIp << 8) + uIpSection;
            uIpSection = 0;
        }
        else
        {
            uIpSection = uIpSection * 10 + cTmp - L'0';
        }

        ulPos += sizeof(wchar_t);
    }

    if (3 != nDotCnt)
    {
        return STATUS_INVALID_PARAMETER;
    }

    if (!IsValidIpField(uIpSection))
    {
        return STATUS_INVALID_PARAMETER;
    }

    ulIp = (ulIp << 8) + uIpSection;   ///< 加上最后一个IP字段值

    *pulIp = ulIp;
    return STATUS_SUCCESS;
}

BOOLEAN IsInCharset(wchar_t cLetter, wchar_t * pcCharset, ULONG ulLenCharset)
{
    /// ulLenCharset 是字符数
    ULONG   ulPos   =   0;
    wchar_t cTmp    =   0;

    if (NULL == pcCharset)
    {
        return FALSE;
    }

    for (ulPos = 0; ulPos < ulLenCharset; ulPos++)
    {
        cTmp = *(pcCharset + ulPos);
        if (cTmp == cLetter)
        {
            return TRUE;
        }
    }

    return FALSE;
}

BOOLEAN IsValidIpField(USHORT uIpField)
{
    return ((uIpField >= 0) && (uIpField <= 255));
}



你可能感兴趣的:(experiment : ip convert to DWORD value on nt driver)