用户名: 密码: 免费注册 忘记密码? 网站地图 | 加入收藏 | 设为首页
首页 | 新闻 | 工具 | 系统 | 办公 | 聊天 | 多媒体 | 网页 | 运营 | 平面 | 欣赏 | 数据库 | 程序 | 服务器 | 组网
网页 | 3dmax | Ghost | Windows Xp| Dreamweaver | photoshop | Flash | office | Alexa | Css | QQ | Asp | PHP | Jsp | Access
Flash MX 2004入门 | 网站推广策略 | CorelDRAW入门 | ASP学习 | 网站建设大师功 | Word入门
  iTbulo.com > 学院 > 操作系统教程 > Windows2000教程 > 文章正文
《Undocumented Windows 2000 Secrets》翻译 --- 第四章(4)
iTbulo.COM 2005-8-3 ccxunmeng()

翻译: Kendiv ( fcczj@263.net )

更新: Sunday, February 17, 2005

声明:转载请注明出处,并保证文章的完整性,本人保留译文的所有权利。

尽管 Spy 设备使用可缓冲的 I/O ,但它还是会检查输入 / 输出缓冲区的有效性。因为客户端程序传入的数据可能比所需的少或者提供的缓冲区不够容纳输出数据。系统不能捕获这些语意错误,因为它不知道在一次 IOCTL 传输中所传输的数据的类型。因此, SpyDispatcher() 调用帮助函数 SpyInput*() 和 SpyOutput*() 来从 I/O 缓冲区中复制或写入数据。这些函数仅在缓冲区大小与操作的需求相匹配时才执行。 列表 4-10 给出了基本的输入函数, 列表 4-11 给出了基本的输出函数。 SpyInputBinary() 和 SpyOutputBinary() 被广泛的使用,它们测试缓冲区的大小,如果 OK ,则使用 Windows 2000 运行时库函数 RtlCopyMemory() 复制被请求的数据。剩余的函数只是上述两个基本函数的简单外包,用来操作常见的数据类型 DWORD , BOOL , PVOID 和 HANDLE 等。 SpyOutputBlock() 复制由调用者在 SPY_MEMORY_BLOCK 结构中指定的数据块,当然这需要首先验证请求范围内的字节都是可读的。如果传入的输入缓冲区的大小不正确, SpyInput*() 函数将返回 STATUS_INVALID_BUFFER_SIZE ,如果输出缓冲区比需要的小, SpyOutput*() 函数将返回 STATUS_BUFFER_TOO_SMALL 。

NTSTATUS SpyInputBinary (PVOID pData,

DWORD dData,

PVOID pInput,

DWORD dInput)

{

NTSTATUS ns = STATUS_INVALID_BUFFER_SIZE;

if (dData <= dInput)

{

RtlCopyMemory (pData, pInput, dData);

ns = STATUS_SUCCESS;

}

return ns;

}

// -----------------------------------------------------------------

NTSTATUS SpyInputDword (PDWORD pdValue,

PVOID pInput,

DWORD dInput)

{

return SpyInputBinary (pdValue, DWORD_, pInput, dInput);

}

// -----------------------------------------------------------------

NTSTATUS SpyInputBool (PBOOL pfValue,

PVOID pInput,

DWORD dInput)

{

return SpyInputBinary (pfValue, BOOL_, pInput, dInput);

}

// -----------------------------------------------------------------

NTSTATUS SpyInputPointer (PPVOID ppAddress,

PVOID pInput,

DWORD dInput)

{

return SpyInputBinary (ppAddress, PVOID_, pInput, dInput);

}

// -----------------------------------------------------------------

NTSTATUS SpyInputHandle (PHANDLE phObject,

PVOID pInput,

DWORD dInput)

{

return SpyInputBinary (phObject, HANDLE_, pInput, dInput);

}

列表 4-10. 从 IOCTL 缓冲区中读取输入数据

NTSTATUS SpyOutputBinary (PVOID pData,

DWORD dData,

PVOID pOutput,

DWORD dOutput,

PDWORD pdInfo)

{

NTSTATUS ns = STATUS_BUFFER_TOO_SMALL;

*pdInfo = 0;

if (dData <= dOutput)

{

RtlCopyMemory (pOutput, pData, *pdInfo = dData);

ns = STATUS_SUCCESS;

}

return ns;

}

// -----------------------------------------------------------------

NTSTATUS SpyOutputBlock (PSPY_MEMORY_BLOCK psmb,

PVOID pOutput,

DWORD dOutput,

PDWORD pdInfo)

{

NTSTATUS ns = STATUS_INVALID_PARAMETER;

if (SpyMemoryTestBlock (psmb->pAddress, psmb->dBytes))

{

ns = SpyOutputBinary (psmb->pAddress, psmb->dBytes,

pOutput, dOutput, pdInfo);

}

return ns;

}

// -----------------------------------------------------------------

NTSTATUS SpyOutputDword (DWORD dValue,

PVOID pOutput,

DWORD dOutput,

PDWORD pdInfo)

{

return SpyOutputBinary (&dValue, DWORD_,

pOutput, dOutput, pdInfo);

}

// -----------------------------------------------------------------

NTSTATUS SpyOutputBool (BOOL fValue,

PVOID pOutput,

DWORD dOutput,

PDWORD pdInfo)

{

return SpyOutputBinary (&fValue, BOOL_,

pOutput, dOutput, pdInfo);

}

// -----------------------------------------------------------------

NTSTATUS SpyOutputPointer (PVOID pValue,

PVOID pOutput,

DWORD dOutput,

PDWORD pdInfo)

{

return SpyOutputBinary (&pValue, PVOID_,

pOutput, dOutput, pdInfo);

}

列表 4-11. 向 IOCTL 的缓冲区中写入数据

你可能注意到 列表 4-7 中的 SpyDispatcher() 还引用了其他的 SpyInput*() 和 SpyOutput*() 函数。尽管这些函数最终还是调用 SpyInputBinary() 和 SpyOutputBinary() ,但它们还是比 列表 4-10 4-11 中的基本函数要复杂些,因此,稍后我们在讨论它们。现在,让我们从 SpyDispatcher() 开始,一步步的分析它的 switch/case 语句。

IOCTL 函数 SPY_IO_VERSION_INFO

IOCTL 的 SPY_IO_VERSION_INFO 函数用有关 Spy 驱动自身的数据填充调用者提供的 SPY_VERSION_INFO 结构。该功能不需要输入参数,需要使用 SpyOutputVersionInfo() 帮助函数。 列表 4-12 给出了该函数和 SPY_VERSION_INFO 结构,该函数很简单,它将 dVersion 成员设置为 SPY_VERSION 常量(当前是 100 ,表示 V1.00 ),该常量定义于 w2k_spy.h 中。然后复制驱动程序的符号化名称,即字符串常量 DRV_NAME (“ SBS Windows 2000 Spy Device ”)到 awName 成员。通过整除 dVersion 可获取主版本号,剩下的是次版本号。

[1] [2] [3] 下一页

文章搜索
相关资讯
相关文章 相关下载
没有相关文章
焦点信息