精华内容
下载资源
问答
  • 可视化tensorflow中间层

    千次阅读 2017-09-28 09:47:57
    如何可视化使用tensorflow框架的网络中间层呢,网上找的答案都是使用tensor board,但是我想的是将网络的中坚层用一张一张图片显示并保存下来,下面附上代码: #-*-coding:utf-8-*- #此函数用来可视化tensorflow中间...

    如何可视化使用tensorflow框架的网络中间层呢,网上找的答案都是使用tensor board,但是我想的是将网络的中坚层用一张一张图片显示并保存下来,下面附上代码:

    附上一句,这里导入的库都是从faster rcnn tensorflow版本里面导入的,如果想用这个代码,需要clone faster_rcnn的代码下来才能用!

    #-*-coding:utf-8-*-
    #此函数用来可视化tensorflow中间层
    import _init_paths
    from fast_rcnn.config import cfg
    import argparse
    from utils.timer import Timer
    import numpy as np
    import cv2
    import sys
    from utils.cython_nms import nms
    from utils.transform import lidar_3d_to_corners, corners_to_bv, lidar_cnr_to_img_single, lidar_cnr_to_img
    from utils.draw import show_lidar_corners, show_image_boxes, scale_to_255
    import cPickle
    from utils.blob import im_list_to_blob
    import os

    import math
    from networks.factory import get_network
    import tensorflow as tf
    import matplotlib.pyplot as plt
    import time
    import mayavi.mlab as mlab
    from utils.draw import draw_lidar, draw_gt_boxes3d
    #from fast_rcnn.test_mv import box_detect
    from datasets.factory import get_imdb
    from fast_rcnn.train_mv import get_training_roidb
    import argparse

    def parse_args():#用来解析从命令行输入的参数
        parser = argparse.ArgumentParser(description='Visulize the MV3D network')
        parser.add_argument('--ceng',dest='ceng',help='which ceng to visulize',default='None',type=str)
        parser.add_argument('--gpu', dest='gpu_id', help='GPU device id to use [0]',
                            default=0, type=int)
        parser.add_argument('--net', dest='demo_net', help='Network to use [vgg16]',
                            default='MV3D_test')
        parser.add_argument('--model', dest='model', help='Model path',
                            default='/home/lingck/MV3D_TF/output/faster_rcnn_end2end/train/VGGnet_fast_rcnn_iter_50000.ckpt.meta')
        if len(sys.argv) == 1:
            parser.print_help()
            sys.exit(1)

        args = parser.parse_args()
        return args

    def check_file(path):
        if not os.path.exists(path):
            os.mkdir(path)


    def visulize(sess, net, im,image_name, bv, calib,  ceng):
        """Detect object classes in an lidar bv  given object proposals.
        Arguments:
            net (caffe.Net): Fast R-CNN network to use
            bv (ndarray): lidar bv to test
            boxes (ndarray): R x 4 array of object proposals
        Returns:
            scores (ndarray): R x K array of object class scores (K includes
                background as object category 0)
            boxes (ndarray): R x (4*K) array of predicted bounding boxes
        """


        im_blob = im - cfg.PIXEL_MEANS #图像减去均值
        lidar_bv_blob = bv

        im_blob = im_blob.reshape((1, im_blob.shape[0], im_blob.shape[1], im_blob.shape[2]))#(1,375,1242,3)
        lidar_bv_blob = lidar_bv_blob.reshape((1, lidar_bv_blob.shape[0], lidar_bv_blob.shape[1], lidar_bv_blob.shape[2]))#(1,601,601,9)

        blobs = {'image_data': im_blob,
                 'lidar_bv_data': lidar_bv_blob}

        im_scales = [1]

        blobs['calib'] = calib
        bv_blob = blobs['lidar_bv_data']
        blobs['im_info'] = np.array(
            [[bv_blob.shape[1], bv_blob.shape[2], im_scales[0]]],
            dtype=np.float32)#此处因为输入的是鸟瞰图,故此处的信息为鸟瞰图的信息
        # forward pass
        #conv1_1 = net.get_output('conv1_1')
        feed_dict={net.lidar_bv_data: blobs['lidar_bv_data'],
                   net.image_data: blobs['image_data'],
                   net.im_info: blobs['im_info'],
                   net.calib: blobs['calib'],
                   net.keep_prob: 1.0}

        CENG = sess.run(net.get_output(ceng),feed_dict = feed_dict)
        
        print "ceng->shape:",CENG.shape
        # # print deconv1.shape
        activation = CENG
        img_path = '/home/lingck/MV3D_TF/tools/vis_feat/' + str(image_name) + '/'
        check_file(img_path)
        feat_path=img_path + str(ceng) + '/'
        check_file(feat_path)
        #feat_path = '/home/lingck/MV3D_TF/tools/vis_feat'
        # # featuremaps = activation.shape[3]
        featuremaps = 48
        plt.figure(1, figsize=(15,15))
        for featuremap in range(featuremaps):
             plt.figure() # sets the number of feature maps to show on each row and column
             plt.title('FeatureMap ' + str(featuremap)) # displays the feature map number
             plt.axis('off')
             plt.imshow(activation[0,:,:, featuremap], interpolation="nearest", cmap="jet")
             plt.savefig(feat_path + ceng+'_'+str(featuremap) + ".jpg", dpi = 400, bbox_inches = "tight")
        plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0.01, hspace=0.01)
        plt.tight_layout(pad=0.1, h_pad=0.001, w_pad=0.001)
        #plt.show()


    def make_calib(calib_dir):


        with open(calib_dir) as fi:
            lines = fi.readlines()

        obj = lines[2].strip().split(' ')[1:]
        P2 = np.array(obj, dtype=np.float32)
        obj = lines[3].strip().split(' ')[1:]
        P3 = np.array(obj, dtype=np.float32)
        obj = lines[4].strip().split(' ')[1:]
        R0 = np.array(obj, dtype=np.float32)
        obj = lines[5].strip().split(' ')[1:]
        Tr_velo_to_cam = np.array(obj, dtype=np.float32)

        calib = np.empty((4, 12))
        calib[0,:] = P2.reshape(12)
        calib[1,:] = P3.reshape(12)
        calib[2,:9] = R0.reshape(9)
        calib[3,:] = Tr_velo_to_cam.reshape(12)

        return calib


    def make_bird_view(velo_file):

        #print("Processing: ", velo_file)
        scan = np.fromfile(velo_file, dtype=np.float32)
        scan = scan.reshape((-1, 4))
        bird_view = []
        return scan, bird_view

    def demo(sess, net, root_dir,im_name, image_name, ceng):
        """Test a Fast R-CNN network on an image database."""

        # Load the demo image

        im_file = os.path.join(root_dir, 'image_2' , image_name+'.png')
        velo_file = os.path.join(root_dir, 'velodyne', image_name+'.bin')
        calib_file = os.path.join(root_dir, 'calib', image_name+'.txt')
        bv_file = os.path.join(root_dir, 'lidar_bv', image_name+'.npy')
        

        im = cv2.imread(im_file)
        velo = make_bird_view(velo_file)[0]
        bv = np.load(bv_file)
        calib = make_calib(calib_file)
        image_name = image_name
        #timer = Timer()
        #timer.tic()
        visulize(sess, net, im,im_name, bv, calib, ceng)
        #timer.toc()

        


    if __name__=='__main__':

        cfg.TEST.HAS_RPN = True
        args = parse_args()
        
        if args.model == ' ':
            raise IOError(('Error: Model not found.\n'))

        sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True)) #创建一个sess会话
        # 如果你指定的设备不存在,允许TF自动分配设备,设置gpu
        # load network
        net = get_network(args.demo_net)#构建网络
        #print net
        # load model
        saver = tf.train.Saver(max_to_keep=5)#构建一个saver对象来管理checkpoint文件
        net.load(args.model, sess, saver, True)
        #print '\n\nLoaded network {:s}'.format(args.model)

        # im_names = ['000456', '000542', '001150',
        #             '001763', '004545']

        root_dir = '/home/lingck/MV3D_TF/data/KITTI/object/training'

        
        im_name = 21   
        print '~~~~~~~~~~~~visulize feature map~~~~~~~~~~~~~~'
        print 'Demo for data/demo/{}'.format(im_name)
        demo(sess, net, root_dir,im_name, str(im_name).zfill(6),args.ceng)
        print"~~~DONE~~~"

        #plt.show()

    此函数的重点部分在于visulize函数,中间层的名字要和网络中层的名字对应上。

    下面看几张效果图



















    展开全文
  • Windows驱动开发(中间层)

    千次阅读 2016-03-01 10:07:33
    十、NDIS中间层驱动开发   1、前言 TDI(传输层驱动接口)是传输层的过滤技术,在Windows Vista之前,常用来开发网络数据过滤,Windows Vista之后的操作系统中不再支持,取而代之的是WFP(Widows过滤平台...
    
      一、前言

    依据《Windows内核安全与驱动开发》及MSDN等网络质料进行学习开发。

     

    二、初步环境

    1、下载安装WDK7.1.0(WinDDK\7600.16385.1)

    地址:https://msdn.microsoft.com/en-us/windows/hardware/hh852365

     

    2、下载InstDrv软件(用于安装、启动、停止、卸载驱动)

    界面如下:

     

     

    注:srvinstw.exe 也可以安装、卸载sys文件,但需要手动开启、关闭,即在cmd命令窗口下执行net start 驱动名、net stop 驱动名来启动、停止服务。

     

    3、下载DbgWiew.exe 软件(查看内核模块的输出信息)

    地址:https://technet.microsoft.com/en-us/sysinternals/bb896647.aspx

     

    注:详见DebugView的使用文档。

     

    4、下载64Signer-V1.2(Win7 64位 私有测试数字签名软件)

    地址:http://www.yiiyee.cn/Blog/64signer-download/

     

    5、其他软件:虚拟光驱DAEMON Tools Lite、EasyBCD(系统引导文件修复工具)、PartitionManager(将C盘设置为活动分区)等

     

    三、初步示例

    1、编写一个简单的驱动样例(加载、卸载及信息输出等)

     

    注:详见TestDriver.c

     

    内核模块的入口是DriverEnter函数,在加载时被系统进程System调用。若想能卸载驱动,必须设置驱动对象的DriverUnload函数指针。

     

    Windows内核编程不是应用程序编程,它有自己的一套东西,所有的Win32函数都不能使用,部分C Runtime函数也不能使用,需要调用内核API函数,因此在使用函数前,现在帮助里查询该函数。

    帮助文档在“开始”-->“所有程序”-->“Windows Driver Kits”下。如图:

     

     

    2、使用WDK的build工具,编译时需要makefile.def和SOURCES文件。

    1)makfile.def文件固定,拷贝一份即可,不需要任何改动。

    2)SOURCES文件内容关联编译那些文件及编译出的.sys文件的名字等。

     

    WDK的build工具在“开始”-->“所有程序”-->“Windows Driver Kits”-->“WDK 7600.16385.1”下,选择要根据本地主机的版本,如:本机是64位的Win7旗舰版,则build工具要选x64 Checked build Environment(对应debug)或x64 Free build Environment(对应Release)。

     

    3、InstDrv软件直接安装生成的.sys文件,安装、卸载成功,启动失败,并提示“Windows需要已数字签名的驱动程序”,DebugView软件中无自定义信息输出。图如下:

     

     

     

    解决方法:

    1、从http://www.yiiyee.cn/Blog/64signer-download/下载Win7 64位私有测试数字签名软件(64Signer-V1.2),以管理员身份运行,浏览驱动文件,进行测试数字签名。图如下:

     

    2、重新安装签名后的.sys驱动文件,并启动,依然报并提示“Windows需要已数字签名的驱动程序”。 图如下:

     

    3、以管理员身份运行cmd.exe,,并执行bcdedit /set testsigning true 命令,若提示“操作成功完成”,则表示命令执行成功;否则,若失败,请将bcdedit命令所在boot文件夹的所在盘(一般C盘)设置为活动状态;若依然失败,请修复boot文件夹的所在盘下的Boot(系统引导文件所在),或干脆恢复|重装系统。

     

    4、将Windows 7 设置为测试版本成功后,须重启计算机,重启后,以管理员身份运行InstDrv.exe软件,对已数字签名的.sys驱动文件进行安装、启动、关闭、卸载均成功。图如下:

     

     

    注:若驱动中包含中断或错误,则计算机蓝屏,须重启恢复。恢复后的计算机系统内新安装的软件会遭到卸载或损坏,须重新安装。

     

     

     

     

     

    以上是一个简单的驱动程序开发步骤。若要进行较复杂的开发,一般需要配置VS开发环境、安装虚拟机、WinDgb.exe等软件进行调试等。

     

     

     

     

     

    四、完善环境

     

    1、下载并安装VS2010(64位)

    地址:https://www.visualstudio.com/downloads/download-visual-studio-vs

     

    2、下载WinDbg.exe软件

    地址:http://www.microsoft.com/whdc/devtools/debugging/default.mspx

     

    3、虚拟机(WMware10.0供双机调试)

    地址:http://www.microsoft.com/zh-CN/download/confirmation.aspx?id=8002

     

     

    五、配置VS2010

     

    1、依据本机版本配置管理器。win7旗舰64位系统配置如下:

    点击VS内工具栏中的解决方案配置的下按钮(即debug所处的下拉框按钮),点击配置管理器,点击活动方案配置,点击新建,输入DriverDebug64、默认空,在项目上下文中的平台项新建X64并在活动解决方案平台:选X64。

     

    注:32位系统选Win32

     

    2、在VS中VisualC++下新建“空项目”,将TestDrive.c文件添加到工程中(或直接新建.c文件),.c文件添加后,在属性中就显示出C/C++配置项。

     

    3、点击VS中“视图”菜单->“其他窗口”->“属性管理器”,右击属性管理器中的DriverDebug64,选择属性,在弹出的窗体中进行必要的设置。(或直接点击项目的属性)

     

    注: 1、WDK7.1.0默认安装在C:\WinDDK\7600.16385.1文件夹下

    2、此处的设置都是必须的, 对复杂些的驱动开发也许还要额外另加设置

    具体如下:

    1)常规

    目标文件扩展名:.sys

     

    2)VC++目录

    可执行文件目录(编译器路径):

    C:\WinDDK\7600.16385.1\bin\amd64

    包含目录:

    C:\WinDDK\7600.16385.1\inc\api

    C:\WinDDK\7600.16385.1\inc\crt

    C:\WinDDK\7600.16385.1\inc\ddk

    库目录:

    C:\WinDDK\7600.16385.1\lib\win7\amd64

    3)C/C++

    预处理器->预处理器定义:

    _AMD64_=1,AMD64=1,STD_CALL=1,WINVER=0x0501,_DEBUG =1

    高级->调用约定:

    __stdcall (/Gz)

    代码生成-->运行库:

    选择多线程调试/MTd 或者 多线程调试DLL/MDd

    (主要解决_DEBUG未预定义的问题)

     

    常规-->调试信息格式:用于“编辑并继续”的程序数据库 (/ZI)

    优化:已禁用 (/Od)

     

    4)连接器

    输入->附加依赖项:                                                                                        ntoskrnl.lib;Hal.lib;wdm.lib;wdmsec.lib;wmilib.lib;ndis.lib;MSVCRT.LIB;LIBCMT.LIB;%(AdditionalDependencies)

    输入->忽略所有默认库:是 (/NODEFAULTLIB)

    清单文件->启用用户账户控制(UAC):否 (/MANIFESTUAC:NO)

    系统->子系统:控制台 (/SUBSYSTEM:CONSOLE)

    系统->驱动程序:驱动程序 (/Driver)

    系统->堆栈保留大小:4194304(可修改)

    系统->堆栈提交大小:4096  (可修改)

    高级->入口点:DriverEntry

    高级->基址:0x10000

    高级->随机基址:(清空)

    高级->数据执行保护(dep):(清空)

            调试->生成调试信息:是 (/DEBUG)

    注:参考C:\WinDDK\7600.16385.1文件夹的ia64、X86等路径,进行修改可以配置为ia64、32位系统。编译若通过,则配置成功,并生产.sys等文件。

     

     

     

    六、配置WinDbg

     

    1、设置系统字符表路径:WinDbg->File->Symbol File Path界面中输入

    SRV*C:\WINDOWS\Symbols*http://msdl.microsoft.com/download/symbols; 并选择Reload,WinDbg会自动下载字符表,关键是勾选reload。

     

    2)设置自己生成的.sys对应的字符(Symbol)路径:

    C:\Users\shenc\Desktop\TestDriver\objchk_win7_amd64\amd64

    3)设置自己生成.sys的原代码路径:

    C:\Users\shenc\Desktop\TestDriver

     

    注:

    1)在调试源码时,若发生窜码(调试驱动与对应的源码不一致),须将WinDbg软件File菜单下存储的旧源码路径删除。

    2)调试时WinDbg默认不输出Dbgprintf信息,须执行ednt!Kd_DEFAULT_Mask 0x8 命令。

    3)驱动运行时,按下Ctrol+Break组合键,进入中断状态,点击工具按钮(快捷键:F8、F10等)可进行详细调试。

    4)中断调试时,可查看局部变量等信息

     

    七、虚拟机

     

    1、安装虚拟机

     

    若主板默认没有开启虚拟化技术,则一般方法是开机或重启时按F12键进入BIOS菜单,将虚拟化(Virtualization)设置为Enable。

     

    2、配置虚拟机

    1)开始-->WMware Work Stations-->双击“我的电脑”下的一个虚拟机(Windows 7 x64)-->编辑虚拟机设置-->移除打印机-->添加窜行端口

    2)选中刚添加的窜行端口,在右侧的对话框中,设置如下:

    勾选 启动时连接

    选择 使用命名的管道(N)

    其下的两个下拉框分别选择:该端是服务器、另一端是应用程序

     

    八、安装并配置虚拟机上的Win7 64位系统

     

    1、将Win7设置为可调试状态

    1)以管理员身份打开cmd命令窗口:Win + R 打开运行输入框,输入cmd;或鼠标 点击系统开始图标,在输入框中输入cmd,右击上方搜索显示出的cmd.exe,以管理员身份运 行。

    2)依次输入:

    bcdedit /?

    Bcdedit /enum OSLOADER

    Bcdedit /copy {current} /d “Windows 7 Copy”

    Bcdedit /debug on

    Bcdedit /bootdebug on

    Bcdedit /dbgsettings

    Bcdedit /timeout 7

     

    2、将Win7设置为测试版

    管理员身份运行cmd命令,bcdedit /set testsigning true

     

    3、测试证书数字签名

    以管理员身份运行64Signer V1.2.exe,点击浏览找到并双机.sys文件,点击签名。

     

     4、安装.sys文件

    以管理员身份运行运行InstDrv.exe,选择.sys文件,进行安装、启动等操作

     

    5、查看内核输出信息

    以管理员身份运行Dbgview.exe,点击Capture菜单,勾选上Captrue kernel项。

     

    注:测试含有断点的内核,否则卡机,无法进行任何操作,因此不在本地主机测试,而采用双机调试(即新建个虚拟机,本地机与虚拟机通过管道进行通信)。

     

     

    九、双机调试

     

    1、源代码中添加中断语句

    #if _DEBUG   //DBG

                     __debugbreak(); //64位

    #endif

     

    注: 1)汇编_asm int 3 中断,在64位Win7上报错。

    2)如果未能进入断点进行调试,请检查sys文件是否在客户机(虚拟Win7系统)安装成功,系统字符集(Symbols)、本人字符Symbols是否下载或设置正确,管道端口是否正确等。

     

    2、虚拟机共享主机文件夹

    方法:

    1)启动VMware,选择虚拟机,点击编辑虚拟机设置;

    2) 点击选项,点击共享文件夹,右侧点击总是启用,然后点击添加按钮;

    3) 输入win7主机下需要共享的文件夹路径,制定共享名,点击下一步;

    4) 点击确定,点击虚拟机内的计算机,在网络下就可以访问共享的文件夹喽。

     

    /*

    3、Windows 7系统中的驱动签名强制要求,关闭强制驱动签名的命令为:

    bcdedit /set loadoptions DISABLE_INTEGRITY_CHECKS

    使用管理员的身份打开CMD命令行,然后输入上面的命令,完成之后重新启动计算机, 就可以在64位win7系统上使用未有数字签名的驱动程序。(测试时不签名启动失败!)

     */

     

     

    十、NDIS中间层驱动开发

     

    1、前言

    TDI(传输层驱动接口)是传输层的过滤技术,在Windows Vista之前,常用来开发网络数据过滤,Windows Vista之后的操作系统中不再支持,取而代之的是WFP(Widows过滤平台)技术,一套系统API和服务,其简单稳定,但微软没有介绍XP等Windows Vista之前的系统如何支持WFP。NDIS Filter(网络驱动接口规范)过滤框架,即支持XP等Windows Vista之前的系统,又支持Win7等Windows Vista之前的系统;并且WDK7.1.0安装环境下的passthru工程,就是NDIS Filter开发的示例,在其基础上可以方便开发。passthru工程路径如下图:

     

     

    2、Windows 网络架构

    1)最上层是网络应用层。Socket、WinInet编写的程序。

    2)第二层是网络API层,也是系统最顶层,为应用程序提供编程接口,且接口协议无关性。接口的定义必须在用户层,内部逻辑实现常在内核层。如:Windows套接字、WinInet库 API等

    3)第三层是网络API的内核实现(即第二层的内核层)。内核实现层总是以内核模式设备驱动程序的形式体现,并且他有一个统一的责任:将上层网络请求格式化为TDI格式,并将这个格式化后的IRP发送到下层NDIS协议驱动。

    4)再下一层是NDIS协议驱动,又叫TDI传输器。TCP/IP等都是NDIS协议驱动。

    5)最下层是NDIS小端口驱动程序,直接驱动物理网卡。

    图如下:

     

    网络驱动模型的每一层都定义了对外的公开的公共接口,与其相连的上下层驱动模块,不需要关心其内部实现就可以很好的支持扩展性、完成工作。

     

    3、NDIS中间层

    为了方便对网络操作进行过滤,依据网络驱动模型内NDIS协议驱动、NDIS小端口驱动的公共接口进行扩展出来的一层。对上面的NDIS协议驱动,扮演NDIS小端口特征的角色;对下面的NDIS小端口驱动,扮演NDIS协议特征的角色。

    图如下:

     

     

    注:NDIS中间层的数量理论上不限数量

     

    协议驱动绑定了所有小端口驱动,于是能截获所有接受到的包;而中间层驱动不仅绑定了所有小端口驱动,而且还被“所有驱动协议”绑定,因此理论上能截获所有发送和接受到的包。

     

    4、NDIS中间层驱动开发示例Passthru工程

    1)NDIS驱动的入口函数DriverEntry:做了初始化包装句柄、注册NDIS小端口特征集、注册NDIS协议特征集、关联NDIS两个接口等必做工作,也可以在其中创建设备对象、初始化分发函数表。

    初始化包装句柄:NdisMInitializeWrapper函数,获得NDIS包装句柄;

    注册小端口特征:先填写小端口特征,再使用NdisIMRegisterLayeredMiniport函数进行注册,输入参数是小端口特征、NDIS包装句柄等,获得关联小端口的NDIS_HANDLE类型句柄(DriverHandle)。

    注册小端口卸载关联程序:NdisMRegisterUnloadHandler函数,参数是NDIS包装句柄、卸载出来程序函数句柄。

    注销小端口:NdisIMDeregisterLayeredMiniport函数,参数是注册小端口特征时获得的DriverHandle句柄。

    注册协议特征:NdisRegisterProtocol函数,输入参数是协议特征、NDIS包装句柄等,获得关联协议的NDIS_HANDLE类型句柄(ProtHandle)。

    关联两个接口:NdisIMAssociateMiniport函数,输入参数是DriverHandle、ProtHandle两句柄,这样小端口层和协议层,在一个不透明体中进行了关联。

     

    注:中间层驱动本身就是集小端口驱动、协议驱动于一体的一个混合体驱动。

     

    2)动态绑定NIC设备

    绑定过程是由PNP管理器发起,当PNP管理器发现系统中有可用的NIC设备时,它最终会找到所有注册过的中间层驱动。依次调用它们的AddDevice函数。

     

    注:驱动的AddDevice函数都是被NDIS库中函数托管的。

     

    绑定的过程中会调用PtBindAdapter函数,在其函数内实现了协议驱动对小端口的绑定。PtBindAdapter函数调用NdisAllocatepacketPoolEx函数分配用于发送和接受数据包的缓冲池;调用NDISOpenAdapter函数绑定下层的NIC,本质是在NDIS的内核对象中,建立起中间层驱动和下层被绑定驱动之间的注册函数的调用关系;调用NdisIMInitializeDeviceInstanceEx函数,在这个函数内部,调用中间层驱动程序的MpInitialize函数来初始化驱动的虚拟NIC。

     

    3)小端口的初始化(MpInitialize)

     

    通过传入的DriverHandle句柄参数,驱动可以很方便地找到两个特征结构中的函数接口。

    调用NdisMSetAttributesEx函数设置适配器上下文,其第三个参数必须设置属性值:

    NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT :不对未决包进行超时处理。

                NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT:不对驱动程序维持的队         列中的查询和设置命令进行超时处理

    NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER:告诉NDIS这是一个中间层驱动

    调用PtRegisterDevice函数,生成一个控制设备对象,并设置其派遣函数。

     

    4)中间层发送数据包

    中间层驱动要发送网络数据包,最终都必须调用NDISSend/NDISSendPacket/NDISCoSendPackets这个系列的函数。以NDISSend为例,NdisSend在内部通过协议驱动的绑定句柄,找到所绑定的中间层驱动,并找到中间层驱动的MpSend/MpSendPackets函数调用。

     

    因此可以在MpSend/MpSendPackets中对发送的数据包直接进行处理。

     

    (包描述符进行重利用或重申请)

    MpSend返回值是NDIS_STATUS_PENDING,则表示发送数据包的异步完成。那么久不能再对包描述符做任何操作了,因为已经对它失去了控制权,响应的操作应该保留到完成函数PtSendComplete中进行。

     

    5)中间层驱动接受数据包

    底层面向无连接的小端口驱动可通过下面两种方式指示数据包接收。

    方式一:小端口驱动调用过滤无关的NdisMindicateReceivePacket函数,向上层驱动传递数据包描述符指针。当上层驱动处理完毕后,将向NIC驱动程序返回那些包描述符及其所指向的资源。此方式下,如果中间层驱动提供了PtReceivePacket处理函数,则PtReceivePacket函数被调用;否则PtReceive函数被调用。

    方式二:小端口驱动调用过滤相关的NdisMXxxindicateReceivePacket函数,传递包头及数据缓冲区指针和缓冲区大小。此方式下,PtReceive函数被调用。

     

    因此可以在PtReceive/PtReceivePacket中对接受的数据包直接进行处理。

     

    上层驱动收到网络包接收通知后,会在合适的时候调用NdisTransferData函数来要求底层驱动将完整的包数据发送给它。我们会在MpTransferData函数中得到上层的这个请求;但因为我们没有完整的报数据,所以应该在这个函数中继续把请求往底层传递。底层驱动如果立刻返回包数据。那么我们在MpTransferData中即能立刻截获到;否则在MpTransferData的异步完成函数PtTransferDataComplete中才能截获到完整的包内容。

     

    因此可以在MpTransferData、PtTransferDataComplete中对数据包进行处理。

     

    6)中间层驱动程序查询和设置

    查询和设置,是小端口特征回调中两个重要的接口:一个用来处理OID查询请求,一个用来处理OID设置请求。Passthru中分别对应的是MPQueryInformation和MPSetInformation.

     

     

    综上,可以在MpSend/MpSendPackets,PtReceive/PtReceivePacket,MpTransferData、PtTransferDataComplete中对数据包进行处理。

     

     

    5、NDIS包描述符

    调用NdisQueryPacket函数,可以找到第一个Ndis_Buffer,然后通过NdisGetNextBuffer函数,来获得后续的NDIS_BUFFER。

    调用NdisQueryBufferSafe函数,可以取得Ndis_Buffer中存储缓冲区的虚拟地址。

    调用NdisMoveMemory函数,可以将各NDIS_BUFFER内容拷贝到指定的存储区。

     

     

    十一、安装驱动

     

    1、将netsf.inf、netsf_m.inf、Passthru.sys放在同一目录下。

    2、安装

    (1) 打开“网络和共享中心”。

    (2) 右击“本地连接”或“无线网络”,选择“属性”。

    (3) 在弹出的“本地连接 属性”对话框中选中“常规”属性页,点击“安装”按钮。

    (4) 在弹出的“选择网络组件类型”对话框中选中“服务”,然后点击“添加”按钮。

    (5) 在弹出的“选择网络服务”对话框中点击“从磁盘安装”按钮。

    (6) 在弹出的“从磁盘安装”对话框中点击“浏览...”按钮。“netsf.inf”文件,点击“打开”按钮,确定。

    (7) 在弹出的“选择网络服务”对话框中选中“Passthru”,点击“确定”按钮。

    (8) 在安装过程中对弹出的数字签名对话框都要点击“确认”按钮。

    (9) 安装完成后,“Passthru”就出现在了组件列表中。

     

    十二、 其他

     first.c

    ///
    /// @file first.c
    /// @author crazy_chu
    /// @date2008-11-1
    /// 
    
    #include <ntddk.h>
        
    
    // 提供一个Unload函数只是为了
    VOID DriverUnload(PDRIVER_OBJECT driver)
    {
        // 但是实际上我们什么都不做,只打印一句话:
        DbgPrint("first: Our driver is unloading…\r\n");
    }
    
    // DriverEntry,入口函数。相当于main。
    NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
    {
    #if DBG
          // _asm int 3
    #endif
        // 这是我们的内核模块的入口,可以在这里写入我们想写的东西。
        // 我在这里打印一句话。因为”Hello,world” 常常被高手耻笑,所以
        // 我们打印一点别的。
        DbgPrint("first: Hello, my salary!");
    
        // 设置一个卸载函数便于这个函数能退出。
        driver->DriverUnload = DriverUnload;
        return STATUS_SUCCESS;
    }
    View Code

    makefile

    !IF 0
    
    Copyright (C) Microsoft Corporation, 1999 - 2002
    
    Module Name:
    
        makefile.
    
    Notes:
    
        DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source
        file to this component.  This file merely indirects to the real make file
        that is shared by all the components of Windows NT (DDK)
    
    !ENDIF
    
    !INCLUDE $(NTMAKEENV)\makefile.def
    View Code

    sources

    TARGETNAME=first
    TARGETTYPE=DRIVER
    SOURCES=first.c
    TARGETPATH=obj
    View Code
    展开全文
  • 简介 中间层 (Middle Tier)称作“应用程序服务器层或应用服务层”,是用户接口或 Web 客户端与数据库之间的逻辑层。典型情况下 Web 服务器位于该层,业务逻辑在此实例化。中间层是生成并操作接收信息的业务规则和...

    简介

      中间层 (Middle Tier)也称作“应用程序服务器层或应用服务层”,是用户接口或 Web 客户端与数据库之间的逻辑层。典型情况下 Web 服务器位于该层,业务逻辑在此实例化。中间层是生成并操作接收信息的业务规则和函数的集合。它们通过业务规则(可以频繁更改)完成该任务,并由此被封装到在物理上与应用程序程序逻辑本身相独立的组件中。请参见客户端层、数据源层。

    三层网络结构

      指的是将数据处理过程分为三部分:第一层是客户端(用户界面层),提供用户与系统的友好访问;第二层是应用服务层(也叫中间层),专司业务逻辑的实现;第三层是数据源层(数据服务层,数据库系统),负责数据信息的存储、访问及其优化。由于业务逻辑被提取到应用服务层,大大降低了客户端负担,因此也成为瘦客户(Thin Client)结构,三层结构在传统的二层结构的基础上增加了应用服务层,将应用逻辑单独进行处理,从而使得用户界面与应用逻辑位于不同的平台上,两者之间的通信协议由系统自行定义。通过这样的结构设计,使得应用逻辑被所有用户共享,这是两层结构应用软件与三层应用软件之间最大的区别。三层结构将表示部分和业务逻辑部分按照客户层和应用服务层相分离,客户端和应用服务层、应用服务层和数据库服务层之间的通讯、异构平台之间的数据交换等都可以通过中间件或者相关程序来实现。当数据库或者应用服务层的业务逻辑改变时,客户端并不需要改变,反之亦然,大大提高了系统模块的复用性,缩短开发周期,降低维护费用。以Java Applet为客户端, 以Java Servlet为中间层的三层网络结构,在目前的实时网络信息平台得到了广泛的应用,其结构和一般的三层结构如图1所示。

    展开全文
  • 原文链接如下: ... 原文内容: 一....中间层驱动对上层来说,扮演一个Miniport Driver的角色,它在上边沿向NDIS注册一组Miniportxxx函数;对于下层Miniport Driver来说,中间层驱动扮演一个

    原文链接如下:

    http://www.cppblog.com/aurain/archive/2009/01/12/71814.html


    原文内容:

    一.绑定过程

    1. DriverEntry

    中间层驱动对上层来说,扮演一个Miniport Driver的角色,它在上边沿向NDIS注册一组Miniportxxx函数;对于下层Miniport Driver来说,中间层驱动扮演一个Protocol Driver的角色,因此它在下边沿向NDIS注册一组Protocolxxx函数。Miniport Driver通过调用NdisMRegisterMiniport向NDIS注册一组MiniportXxx函数;Protocol Driver 通过调用 NdisRegisterProtocol向NDIS注册一组ProtocolXxx函数。

    首先通过调用NdisMInitializeWrapper(&NdisWrapperHandle, DriverObject, RegistryPath, NULL);来初始化NdisWrapperHandle,该句柄用来代表IM Driver的自身。

    接着调用NdisIMRegisterLayeredMiniport来向NDIS注册一组MiniportXxx函数,返回指向Miniport的DriverHandle。

    随后调用NdisRegisterProtocol来向NDIS注册一组Protocolxxx函数,返回指向Protocol的ProtHandle。

    然后调用NdisIMAssociateMiniport(DriverHandle, ProtHandle);将两者绑定。

    2. PtBindAdapter

           NDIS在完成第一步之后,将会调用PtBindAdapter来完成对适配器的绑定(注意:此函数的调用次数是根据用户电脑上的适配器数目而定的,一般至少有两块,会有一块叫NDISWANIP),PtBindAdapter中有用的参数主要是DeviceName和SystemSpecific1,其中DeviceName是下层NIC驱动的服务名,SystemSpecific1可以用来读取注册表中相关的值。(参考注册表HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Linkage下的Bind子键值)

           首先调用NdisOpenProtocolConfiguration ,NdisReadConfiguration来读取注册表信息,然后初始化PADAPT pAdapt结构体。

           接着调用NdisOpenAdapter来将IM的下层协议驱动(ProtHandle)绑定适配器。

           调用NdisIMInitializeDeviceInstanceEx来触发对MPInitialize的调用

    3. MPInitialize

    在MpInitialize里面主要做三件事情:

    1). 判断介质类型

    2). 调用NdisMSetAttributesEx设置一些特性

    3). 调用PtRegisterDevice函数向NDIS注册设备

    4. PtRegisterDevice

           在PtRegisterDevice里,主要是设置IM Driver自己要处理的一些派遣例程和注册设备名和设备符号链接名。要注意的是,这个函数提供的功能是为整个设备服务而不是每个适配器都需要注册,所以通过一个全局变量MiniportCount来控制。

    在这里,定义了PDRIVER_DISPATCH       DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];

    然后如下的设置:DispatchTable[IRP_MJ_CREATE] = DevOpen;…

           接着调用NdisMRegisterDevice注册设备名和设备符号链接名。

     

    二.卸载过程

    1. PtUnbindAdapter

           针对每个绑定的适配器,首先查看对IM的miniport是否有还在排队的请求,如果有,则先调用PtRequestComplete完成它(返回NDIS_STATUS_FAILURE),然后查看状态是否为pending,是的话则调用NdisIMCancelInitializeDeviceInstance。再调用NdisIMDeInitializeDeviceInstance来卸载设备,在此会触发对MPHalt的调用。

    2. MPHalt

           在MPHalt里,首先调用PtDeregisterDevice来卸载设备,然后调用NdisCloseAdapter关闭绑定的适配器。

    3. PtDeregisterDevice (MiniportCount == 0?)

           在PtDeregisterDevice 里,调用NdisMDeregisterDevice来卸载设备。同PtRegisterDevice类似,要注意的是,这个函数提供的功能是为整个设备服务而不是每个适配器都需要注册,所以通过一个全局变量MiniportCount来控制。只有最后一个绑定的适配器卸载时,才调用NdisMDeregisterDevice。

    4. PtUnloadProtocol

           在CloseAdapterComplete完成后,NDIS会调用PtUnloadProtocol来完成下层绑定的协议驱动(ProtHandle)的卸载,调用NdisDeregisterProtocol函数。

    5. PtUnload

           首先,要说明的是,在DriverEntry函数里,有注册该函数(NdisMRegisterUnloadHandler(NdisWrapperHandle, PtUnload);)。该函数是整个卸载过程的最后一步,在这里,会继续完成对绑定的上层miniport,下层的protocol的卸载(其实protocol的卸载在第4步已经完成),调用如下两个函数PtUnloadProtocol,NdisIMDeregisterLayeredMiniport。


    展开全文
  • 最近在写一个基于XE2 DATASNAP的中间层,以前写过基于DCOM的MIDAS中间层,看到网上一些同仁对中间层的提问。我摘录俩个典型的提问,如下: 第一个提问: Midas三层程序,如何支持大量用户同时请求连接? 系统...
  • 架构

    2013-11-29 18:01:45
    所谓三层体系结构,是在客户端与数据库之间加入了一个中间层也叫组件层。这里所说的三层体系,不是指物理上的三层,三层是指逻辑上的三层,即使这三个层放置到一台机器上。 三层体系的应用程序将业务规则、数据...
  • .bg{position:absolute;z-index:999;...点击上方“显示”页面中间弹出。JS特效大全在中国站长寨 中国站长寨为中国站长提示精品站长资讯,网页特效,JS特效,网站特效,网站源码,图库素材,站长下载
  • OSI七协议大白话解读

    万次阅读 多人点赞 2018-08-02 16:59:48
    互联网的本质就是一系列的网络协议,这个协议就OSI协议(一系列协议),按照功能不同,分工不同,人为的分层七。实际上这个七是不存在的。没有这七的概念,只是人为的划分而已。区分出来的目的只是让你明白...
  • 学习总结

    千次阅读 热门讨论 2015-01-16 17:58:01
    所谓三层体系结构,就是在客户端与数据库之间加入了一个“中间层”,也叫组件层。三层体系的应用程序将业务规则、数据访问、合法性校验等工作放到了中间层进行处理。通常情况下,客户端不直接与数据库进行交互,而是...
  • 浅析三架构

    千次阅读 热门讨论 2014-03-12 10:50:21
    所谓三层架构,是在客户端与数据库之间加入了一个“中间层”,也叫组件层。这里所说的三层体系,不是指物理上的三层,不是简单地放置三台机器就是三层体系结构,不仅仅有B/S应用才是三层体系结构,三层是指逻辑上...
  • Hive开发要知道数据仓库的四个层次设计

    万次阅读 多人点赞 2018-02-12 18:11:09
    数据仓库:数据仓库全面接收源系统数据,ETL进程对数据进行规范... ETL(extractiontransformation loading)负责将分散的、异构数据源中的数据抽取到临时中间层后进行清洗、转换、集成,最后加载到数据仓库或数据集...
  • delphi三架构

    千次阅读 2014-03-11 00:11:58
    这是我多年前在深圳工作时写的,现在都迁移来CSDN上,免的丢失了。 ... 三层架构指的是界面,业务逻辑和数据存储分离,不是指物理上是否分离。... 业务逻辑的话要分析清楚,就是中间层界面,也叫客户端
  • 池化理解

    万次阅读 多人点赞 2019-04-15 14:31:41
    参考网址: ... ... 池化夹在连续的卷积层中间, 用于压缩数据和参数的量,减小过拟合。 简而言之,如果输入是图像的话,那么池化的最主要作用就是压缩图像。...下采样层也叫池化,其具体操作与卷积层...
  • 体系结构

    千次阅读 2007-10-01 10:34:00
    所谓三层体系结构,是在客户端与数据库之间加入了一个"中间层",也叫组件层。三层体系的应用程序将业务规则、数据访问、合法性校验等工作放到了中间层进行处理。开发人员可以将应用的商业逻辑放在中间层应用服务器上...
  • .Net三架构

    千次阅读 2013-05-19 16:13:45
    三层体系结构,是在客户端与数据库之间加上了一个“中间层”,也叫组件层。这里所说的三层体系,不是指物理上的三层,不是简单地放置三台机器就是三层体系结构,不仅仅有B/S应用才是三层体系结构,三层是指逻辑上...
  • 概述  在软件体系架构设计中,分层式结构是最常见,是最重要的一种结构。... 所谓三层体系结构,是在客户端与数据库之间加入了一个“中间层”,也叫组件层。这里所说的三层体系,不是指物理上的三层
  • 这本书,从中间

    千次阅读 热门讨论 2012-07-03 21:16:48
    当我们拿到一本书,毫不犹豫地开始... 有种精神打破传统,也叫创新!我从来没有放弃过!在"百度百科"里处处碰壁后,在网络的海洋里畅游了半天终于被我找到一个巨人“维基百科”,他对于osi(Open System Interconn
  • 架构优缺点

    千次阅读 2015-06-11 00:03:28
    所谓三体系结构,是在客户端与数据库之间加入了一个中间件也叫组件。这里所 说的三体系,不是指物理上的三,不是简单地放置三台机器就是三体系结构, 不仅仅有B/S应用才是三体系结构,三是指...
  • 【三架构】——COM/DCOM初识

    万次阅读 多人点赞 2016-03-23 16:08:23
    背景:在学习三层架构的时候,知道三层分为UI层(表现层)、BLL层(业务逻辑层)、DAL层(数据访问层),相对于传统的二层架构(客户端和数据库)来说,多了一个中间层BLL(业务逻辑层),处于UI层和DAL层之间,起到...
  • 网络(1)

    千次阅读 2016-04-25 17:38:01
    网络的作用是:将分组从一台发送主机移动到一台接收主机。为此需要两种重要的网络功能: 转发:将分组从一个输入链路接口转移到适当的输出链路接口的路由器本地动作。 选路:分组从源到目的地时,决定端到端...
  • Delphi 三

    千次阅读 2013-04-18 10:51:56
    业务逻辑的话要分析清楚,就是中间层 界面,也叫客户端。  这里就是得到数据和显示数据的部分了,不做其它处理。但是数据有效性分析最好放在界面层,以充分利用客户端的性能。不然的话业务逻辑层的负
  • MLP多层感知机(人工神经网络)原理及代码实现

    万次阅读 多人点赞 2018-07-05 11:23:19
    一、多层感知机(MLP)原理简介多层感知机(MLP,Multilayer Perceptron)也叫人工神经网络(ANN,Artificial Neural Network),除了输入输出,它中间可以有多个隐,最简单的MLP只含一个隐,即三的结构,如...
  • 架构概念

    千次阅读 热门讨论 2017-05-09 10:29:51
    三层结构的应用程序将业务规则、数据访问、合法性校验等工作放到了中间层进行处理。通常情况下,客户端不直接与数据库进行交互,而是通过COM/DCOM通讯与中间层建立连接,再经由中间层与数据库进行交互,这样会大大...
  • 构架+winform实例(以注册和登录为例)

    千次阅读 多人点赞 2018-05-08 21:14:59
    三层架构 所谓三层体系结构,是在客户端与数据库之间加入了一个“中间层”,也叫组件层。三层指的是逻辑上的三层,三层结构让客户端与数据库不直接交互。(1)三层结构及其各层作用三层结构包括数据访问层(DAL),...
  • 当rate=2时,之前的卷积核,需要在每个点中间插入1个'0',于是乎,之前的卷积核就是如下图所示: 以上就是新的卷积核。根据公式计算出新的输入需要pad的像素点: padding='SAME': new_width = 5: 需要pad的像素点是...
  • 建立多层次的数据访问服务体系,有力提升数据仓库的价值。基于指标汇总层、集市层、可以...汇总指标层也叫中间层,他提炼出对ODS具有共性的数据访问、统计需求,从而构建出的一个面向支持应用的、提供共享的数据访...
  • Keras中dense原理及用法解释

    千次阅读 多人点赞 2021-01-20 23:11:05
    全连接层Fully Connection作用二.API解释2.1 示例1:dense层为输入层2.2 示例2:dense层为中间层2.3 示例3:dense层为输出层三.实现过程四.数学解释 一.全连接层Fully Connection作用 全连接的核心操作就是矩阵向量...
  • PADS Layout中各代表的含义

    千次阅读 2021-02-21 18:16:02
    TOP是顶层,BOTTOM是底层,可以用来摆件和走线,layer是中间层,只能走线 Silkscreen Top 顶层丝印 放丝印的层,如常见的位号、日期等 Silkscreen bottom 底层丝印 底层丝印需要镜像,在设计时需要注意 Solder...
  • 亮剑.NET的系列文章之初识三架构

    千次阅读 2013-05-07 11:30:09
    先跟大家介绍一下三的来源,为什么?  在现代的社会的软件开发体系中结构可以简单的概括是N体系结构,N大于等于1,他们的开发方式不同:  换句话说:单机体系(N=1)、Client/Server结构体系(N=2)、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 139,856
精华内容 55,942
关键字:

中间层也叫