YJX_Driver_012_为DDK_HelloWorld添加设备例程

1、

【00:50】vs2003编译环境,它有一个功能vc6没有,稳定性 比 VC6高一些,另外 它是中文的 而非汉化的

【01:15】将 第10课 的代码copy过来

  【01:42】VC6的工程 转换为 vs2003 的工程

【01:52】vs2003 --> 项目 --> 属性 --> "配置管理器..." --> 新建一个配置 --> 【366】"项目配置名(C)" 填为 "check" -->>

【439】"解决方案窗口" 选中"mini_ddk",然后 菜单栏 --> 项目 --> 属性 --> C/C++ --> 常规  中,(1)、"调试信息格式"选为"C7 兼容(/Z7)",(2)、"取消显示启动版权标志" 选为 "否",(3)、"警告等级" 选为 "3级(/W3)",(4)、"将警告视为错误" 选为 "是(/WX)"

  【493】项目 --> 属性 --> C/C++ --> 优化  中,"优化"选为"禁用(/Od)"

  【505】项目 --> 属性 --> C/C++ --> 预处理器  中,我们参考 第7课的配置,填入"WIN32=100;_X86_=1;WINVER=0x501;DBG=1"

  【567】项目 --> 属性 --> C/C++ --> 代码生成  中,"运行时库"选为"多线程调试(/MTd)"

  【590】项目 --> 属性 --> C/C++ --> 高级  中,(1)、"调用约定"选为"__stdcall(/Gz)"(ZC: 其他选项分别为"__cdecl(/Gd)" 和 "__fastcall(/Gr)"),(2)、"编译为"选为"编译为C代码(/TC)"

  【649】项目 --> 属性 --> 链接器 --> 常规  中,(1)、"输出文件"由"$(OutDir)/$(ProjectName).exe"改为"$(OutDir)/$(ProjectName).sys",(2)、"启用增量链接"改为"否(/INCREMENTAL:NO)"

  【678】项目 --> 属性 --> 链接器 --> System  中,(1)、"堆栈保留大小"由"0"改为"0x400000"(填入的是16进制数,转到下一行后,vs2003会自动转为10进制数),(2)、"堆栈提交大小"由"0"改为"0x1000"

    ZC: 记得在哪本书上看到过,内核中的程序堆栈都比较小,嵌套不能太深,这里是在强制指定本驱动的堆栈大小吗?使得本驱动能够使用较大的堆栈?

  【738】项目 --> 属性 --> 链接器 --> 优化  中,"Windows98 优化"改为"否(/OPT:NOWIN98)"

  【760】项目 --> 属性 --> 链接器 --> 高级  中,(1)、"基址"填入"0x10000",(2)、"入口点"填入"DriverEntry"

  【798】项目 --> 属性 --> 链接器 --> 输入  中,"附加依赖项"填入"ntoskrnl.lib"

  【833】这样设置基本完毕。

  【840】项目 --> 属性 --> 链接器 --> 命令行  中,"附加选项(D):"填入"/Driver /system:native"(ZC: 听他的意思,"/system:native"是指“内核的”?)

  【886】项目 --> 属性 --> 链接器 --> System  中,"子系统"由"未设置"改为"控制台(/SUBSYSTEM:CONSOLE)"

【903】重新生成解决方案 mini_ddk, OK,可以正常的生成驱动了

  【930】注意,这里只是正常的生成了驱动,并不是说这个驱动就能正常的运行,这是 我们的参数设置所导致的,如果没有设置的好的话 有可能导致蓝屏。比如说我们驱动 装载/卸载 的时候 出现 蓝屏 或 不稳定的现象,后面给出解决的办法

【1033】我们这里(对vs2003)进行配置,主要是为了方便我们在IDE环境里面编辑程序

ZC: 搞了这么多,难道只是为了写代码方便?编译 还是用 ddk的自带命令行?

 

【1111】创建设备的具体步骤

1、用 RtlInitUnicodeString 初始化设备名称(ZC: 字符串)指针

2、用 IoCreateDevice创建设备,如果不成功 则返回

3、用 IoCreateSymlicLink创建符号链接,创建成功返回 STATUS_SUCCESS,创建不成功 则调用IoDeleteDevice删除设备

ZC: 一直没明白,干嘛要创建设备?它是干嘛用的?貌似是用于和上层通信的

【1220】http://msdn.microsoft.com/en-us/library/default.aspx

  ZC: 貌似这个地址的内容变化了...

【1723】写代码测试

#pragma INITCODE // 【3015】指 代码运行后 就从内存中释放掉,减少资源占用

NTSTATUS CreateMyDevice(IN PDRIVER_ONJECT _pDriverObject)

{

  NTSTATUS stauts;

  PDEVICE_OBJECT pDevObj;/*用来返回创建设备*/

 

  // 创建设备名称

  UNICODE_STRING devName;

  UNICODE_STRING symLinkName;

  RtlInitUnicodeString(&devName, L"\\Device\\yjxDDK_Device"); // 对devName初始化

 

  // 创建设备

  stauts = IoCreateDevice(_pDriverObject,\

    0,\    // 【2245】扩展结构的大小。创建的设备的扩展指针的大小(DEVICE_OBJECT中的一个成员)

    &devName,\

    FILE_DEVICE_UNKNOWN,\

    0, TRUE,\

    &pDevObj);

  if (! NT_SUCCESS(stauts))

  {

    if (stauts == STATUS_INSUFFICIENT_RESOURCES)

      KdPrint(("资源不足 STATUS_INSUFFICIENT_RESOURCES"));

    else if (stauts == STATUS_OBJECT_NAME_EXISTS)

      KdPrint(("指定对象名存在"));

    else if (stauts == STATUS_OBJECT_NAME_COLLISION)

      KdPrint(("对象名有冲突"));

    KdPrint(("设备创建 失败"));

    return stauts;

  }

  KdPrint(("设备创建 成功"));

 

  pDevObj->Flags != DO_BUFFERED_IO;

 

  // 创建符号链接

  RtlInitUnicodeString(&symLinkName, L"\\??\\yjx888");

  stauts = IoCreateSymbolLink(&symLinkName, &devName);

  if (! NT_SUCCESS(stauts))

  {

    IoDeleteDevice(pDevObj);

    return stauts;

  }

 

  return STATUS_SUCCESS;

}

【2348】DEVICE_OBJECT 位于 ntddk.h中,wdm.h中也存在该结构的定义

  _DEVICE_OBJECT

  【2403】PVOID _DEVICE_OBJECT.DeviceExtension; //指向一个自定义结构(编程人员可以自己定义该结构内容)

【2528】FILE_DEVICE_UNKNOWN  指定创建设备的类型

【2720】ZC: 独占的设备 什么意思?

【3195】#define INITCODE code_seg("INIT")

  #define PAGECODE code_seg("PAGE")  // 这里的 "PAGECODE"这个名字是可以随便取的

    【3240】表示 当内存不足时(或者 相应的内存 没有用到的时候),可以被置换到虚拟内存(硬盘)中

【3438】L"\\Device\\yjxDDK_Device" 中

  前面的部分"\\Device\\" 是不能变的

  后面的部分"yjxDDK_Device" 是可以变化的

【3577】符号链接 中 前面部分"\\??\\" 也是不能变化的,后面能变化

【3593】如果前面部分变化了,会报错,类似于: 驱动的格式/设备的格式 不正确,这个设备不能够被正常的加载

【4150】编译一下,用的是 vs2003编译的"重新生成解决方案",成功了

【4348】设备对象 是内核态 里面才能使用的,符号链接 暴露给 用户层使用

 

【4675】用DDK来编译一下(ZC: 还是用 DDK来编译...)

  【4702】用 vs2003 编译出来的驱动,并非一定稳定 有可能会蓝屏 保险起见用DDK来编译一下

 

【4960】光写  函数CreateMyDevice(...) 是没有任何作用的,我们要把它 加到 入口函数里面去

NTSTATUS DriverEntry(PDRIVER_OBJECT _pDrvierObject, PUNICODE_STRING B)
{
  KdPrint(("驱动成功被加载...OK+++++++++"));

  CreateMyDevice(_pDrvierObject);
  _pDrvierObject->DriverUnload = DDK_Unload;
  return 1;
}

【5202】用DDK重新编译一下

【5295】打开 DebugView、DriverMonitor

  【5433】DriverMonitor 中报错信息(ZC:貌似是路径里面不能有 中文/空格 之类的?)

  【5497】用 WinObj 查看一下

    【5503】左侧 选择的是 "Driver",在 右侧 查看 是否已经有我们刚刚加载的驱动

    【5560】ZC: 此时,可以看到,他 双击的是"360AntiARP",弹出来的对话框是"Unable to open \Driver\360AntiARP",可以猜想 这里的 列"Name" 显示的就是 驱动的设备名称的 后半部分。又∵ 在这里找不到"yjxDDK_Device",∴ 个人觉得 应该说明 驱动刚才没有加载成功

  【5577】左侧 选择 "Device",又 换回 "Driver" 了...

 

【5645】把名字改一下,再加载 (ZC: 该说明名字?驱动设备名?.sys文件的名称?)

  【5655】直接改的是 .sys的文件名... "DDK_HelloWorld.sys"改为"oWorld1.sys"

    说可能已经存在了一个叫"DDK_HelloWorld.sys" 的驱动。∵一个驱动只允许一个实例

  【5753】此时,加载 成功了,有调试信息输出

  【5780】再用 WinOBJ.exe 查看一下

    ZC: 看到 列"Name" 中有名为 "OWorld1"(ZC: 这里首字母是大写的) 的一条记录了。说明上面的我的猜想是不对的,这里的列"Name" 显示的就是 .sys的文件名,于是刚才也不是 中文路径的问题。疑问:列"Name"中 也没有"DDK_HelloWorld"啊,为何之前加载 "DDK_HelloWorld.sys"会不成功?

    【5970】说 WinOBJ.exe显示的不是很详细

【6005】DDK中自带有工具,显示的驱动信息更为详细

  开始 --> Development Kits --> Windows DDK 3790.1830 --> Tools --> Device Tree

    【6073】ZC: 这里左侧 显示的也是 .sys的文件名

  【6240】点击"Device Tree"的工具栏上面的 按钮"P",以PDO的方式来看一下(ZC: PDO是啥?啥意思?)

    【6335】这里,找到了 我们的符号链接

    【6460】找到的是 "[RootLEGACY_YJX_888]",我们没有加入 下划线,∴肯定不是这个

      【6590】ZC: 找到这里,没找到类似"??yjx888??"的项,他也不找了,直接退出"Device Tree"...

【6630】DriverMonitor 中 "STOP"掉驱动,再次"GO"的时候 肯定会报错。为何会有出错信息呢

  【6672】驱动没有成功的卸载掉,需要重命名.sys文件(ZC: 为何没有成功卸载?不是有卸载例程了吗?)

  【6685】改名 "oWorld1.sys"改为"11oWorld1.sys"

  【6708】此时 加载驱动,"GO"之后 有"设备名有冲突"等 的信息打印出来

    【6740】因为 设备被创建出来之后,没有被正常的删掉

 

【6840】继续编程

【6930】下一节课再讲 如何在卸载例程中删除 设备(名称) 和 符号链接,这样才能成功的卸载驱动对象

 

2、

 

posted @ 2016-03-29 21:25  DebugSkill  阅读(637)  评论(0编辑  收藏  举报