暂无个人介绍
前面,我总结过关于va_list,va_start,va_arg,va_end的一些知识点: http://www.cnblogs.com/mydomain/archive/2010/07/27/1785667.
在c和c++中,可变参数使用的最多函数有:scanf,printf,以及fprintf,fscanf,sprintf等,MFC也提供CString::Format实现可变参数。 本示例通过va_list来实现自己的可变参数函数,实现程序写日志功能。
I/O端口操作在Windows操作系统中属于特权命令,必须在内核模式下运行。在DOS中,I/O端口操作主要通过IN/OUT指令来进行。 一、I/O端口操作实现 1、DDK实现I/O端口操作 READ_PORT_UCHAR The READ_PORT_UCHAR macro reads a byte from the specified port address。
在WDM程序中,创建设备等功能都被转移到AddDevice例程中。AddDevice是WDM驱动与老式NT式驱动的重要区别。 当有设备插入电脑后,系统总线驱动(根总线)会枚举到有新设备被插入;这时会通知PNP管理器寻找需要加载的设备驱动。
即插即用 1、即插即用(IRP_MJ_PNP)功能能够通过操作系统协调自动分配设备上的资源,如中断号,I/O地址,DMA资源,设备物理内存等。 WDM框架程序是分层驱动,WDM处于分层的高端,而总线驱动程序处于分层的低端。
C/C++编程规范精述 (匈牙利命名法) 1、排版上不同小结构间要空行分开,子逻辑项相对父逻辑项要缩进;{及if,while等判断语句应独占行并对齐,且后加空格以显突出。 2、注释位于相应代码上面或右旁边。
[问题描述] 用VS2008编译windows shell时,成功;相同的方法在VS2005下,提示错误: error C2787: 'IContextMenu' : no GUID has been associated with this object error C2440: 'initia...
第三部分 SHELL Additional 一、编程中的一些关键点 1、 We implemented the IShellExtInit interface, which was how Explorer initialized our object.
第二部分 Windows SHELL编程 There are many types of shell extensions, each type being invoked when different events happen.
第一部分 SHELL基本概念 Windows外壳扩展(Windows Shell Extension),是一类特殊的COM对象,在这类COM对象中用户可以加入自己的特殊功能,而Windows外壳扩展最终都会被Windows Explorer所引用[1]。
小结 归纳为以下几点: • 对象是属性、值对的集合。一个对象的开始于“{”,结束于“}”。每一个属性名和值间用“:”提示,属性间用“,”分隔。 • 数组是有顺序的值的集合。一个数组开始于"[",结束于"]",值之间用","分隔。
JSON定义 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成。它基于ECMA262语言规范(1999-12第三版)中JavaScript 编程语言的一个子集。
JSON定义 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成。它基于ECMA262语言规范(1999-12第三版)中JavaScript 编程语言的一个子集。
CreateFile FunctionZeroMemory MacroSetupDiEnumDeviceInterfaces FunctionSetupDiGetDeviceInterfaceDetail FunctionSetupDiGetDeviceInfoListDetail Function...
11. API之进程和线程函数 CancelWaitableTimer 这个函数用于取消一个可以等待下去的计时器操作 CallNamedPipe 这个函数由一个希望通过管道通信的一个客户进程调用 ConnectNamedPipe 指示一台服务器等待下去,直至客户机同一个命名管道连接 CreateEvent 创建一个事件对象 CreateMailslot 创建一个邮路。
9. API之设备场景函数 CombineRgn 将两个区域组合为一个新区域 CombineTransform 驱动世界转换。它相当于依顺序进行两次转换 CreateCompatibleDC 创建一个与特定设备场景一致的内存设备场景 CreateDC 为专门设备创建设备场景 CreateE...
7. API之位图、图标和光栅运算函数 BitBlt 将一幅位图从一个设备场景复制到另一个 CopyIcon 制作指定图标或鼠标指针的一个副本。这个副本从属于发出调用的应用程序 CopyImage 复制位图、图标或指针,同时在复制过程中进行一些转换工作 CreateBitmap 按照规定的格...
4. API之打印函数 AbortDoc 取消一份文档的打印 AbortPrinter 删除与一台打印机关联在一起的缓冲文件 AddForm 为打印机的表单列表添加一个新表单 AddJob 用于获取一个有效的路径名,以便用它为作业创建一个后台打印文件。
1. API之网络函数 WNetAddConnection 创建同一个网络资源的永久性连接 WNetAddConnection2 创建同一个网络资源的连接 WNetAddConnection3 创建同一个网络资源的连接 WNetCancelConnection 结束一个网络连接 WNetC...
1、一些相关概念 在Windows NT/XP下的对象,不一定是文件系统,还有其它的一些对象,如:进程、命名管道、打印机、网络共享、或是注册表等等,都可以设置用户访问权限。在 Windows系统中,其是用一个安全描述符(Security Descriptors)的结构来保存其权限的设置信息,简称为SD,其在Windows SDK中的结构名是“SECURITY_DESCRIPTOR”,这是包括了安全设置信息的结构体。
网上关于这个问题讨论较多,但也不外乎几种方法。总结一下,如附中。顺便了解一个UAC。 UAC,全称User Account Control(用户帐户控制) System Safe Monitor(主机入侵防御系统) UAC是如何工作的[3] 我们可以简单的把UAC当作权限临时重分配的工具。
把功能复杂的驱动分解成多个简单的驱动。多个分层驱动程序形成一个设备堆栈,IRP请求首先发送到设备堆栈的顶层,然后以次穿越每层的设备堆栈,最终完成IRP的请求。 1、相关概念 分层驱动是指两个或两个以上的驱动程序,他们分别创建设备对象,并且形成一个由高到低的设备对象栈。
有两种方法,一种是以文件句柄的形式,另外一种是通过设备指针调用其它驱动程序。 1、以文件句柄形式调用 1)应用程序 调用 驱动A 调用 驱动B 这种方法类似于在应用程序中调用驱动程序。
一般两种方法使用/设置定时器,一种是使用I/O定时器例程,一种是使用DPC例程。 1、定时器的实现 1)使用I/O定时器例程 NTSTATUS IoInitializeTimer( IN PDEVICE_OBJECT DeviceObject, IN PIO_TIMER_ROUTINE TimerRoutine, IN PVOID Context ); IoStartTimer IoStopTimer 开启定时器后,每隔1s系统调用一次定时器例程。
3、StartIo例程 1)系统处理的StartIo StartIo例程能够保证各个并行的IRP顺序执行,即串行化。 DDK提供一个内部队列,并将IRP用StartIo例程串行化处理。当设备由忙转入空闲状态时,从队列中抽取一个IRP进行处理,并将状态设为忙。
对设备的任何操作都会转化为IRP请求,而IRP一般都是由操作系统异步发送的。但是有时需要同步来避免逻辑错误。同步方法有:StartIO例程,使用中断服务例程等。 1、应用程序对设备的同步异步操作 1)同步操作原理 大部分IRP是由应用程序的Win32 API发起。
4、内核模式下的同步对象 用户模式下用句柄来操作同步对象,而内核模式下可以获得同步对象的指针。每种同步对象在内核中均对应一种数据结构。 1)等待 KeWaitForMultipleObjects KeWaitForSingleObject 如果超时则返回STATUS_TIMEOUT。
驱动程序的同步处理 可重入,是指函数的执行结果不和执行顺序有关。同步机制很大程度上依赖于中断请求级。 IRQ编号 设备名称 用途 IRQ0 Tine 计算机系统计时器 IRQ1 KeyBoard 键盘...
今天我在实践中,需要将一个项目运行在另外一个项目的基础之上。于是在VS2005中,将需要依存的项目依赖于被依存的项目。由于被依存的项目导出的是dll,依存的项目导出是exe,所以在被依存的项目的类前面加如下一句: class __declspec(dllexport) OSManager 这样就可以了。
1、直接读写方式 操作系统将用户模式下的缓冲区锁住,然后操作系统将这段缓冲区在内核模式地址再映射一遍。这样,用户模式的缓冲区和内核模式的缓冲区指向的是同一区域的物理地址。 操作系统将用户模式的地址锁定后,用内存描述符MDL记录这段内存。
驱动程序的主要功能是负责处理I/O请求,其中大部分I/O请求是在派遣函数中处理的。用户模式下所有对驱动程序的I/O请求,全部由操作系统转化为一个叫做IRP的数据结构,不同的IRP数据会被“派遣”到不同的派遣函数(Dispatch Function)中。
注册表项相当于文件夹,注册表子项子文件夹(类似目录)。 1、创建关闭 ZwCreateKey 示例代码 代码 1 VOID CreateRegTest() 2 { 3 //创建或打开某注册表项目 4 UNICODE_STRING RegUnico...
1、创建 ZwCreateFile 注意CreateDisposition 参数。 代码 1 VOID CreateFileTest() 2 { 3 OBJECT_ATTRIBUTES objectAttributes; 4 IO_STATUS_BLOCK iostatu...
1、字符串 1)两种字符串,一种是char型,记录ansi字符集。每个字符一个字节。以0标志结束。在KdPrint中用%s输出。 宽字符型,wchar_t,描述unicode字符集的字符串,每个字符两个字节,以0标志结束。
1、虚拟地址 Windows的所有程序(ring0,ring3),可以操作的都是虚拟内存。CPU中寄存器CR0一个位PG位来告诉系统是否分页的。1为允许分页。DDK中宏PAGE_SIZE记录着分页大小,一般为4K,4GB的虚拟内存会被分割成1M个单元。
#include using namespace std; void f1(int a,int b) { } int main() { f1(3,4); system("pause"); } 将上述代码反汇编如下(vs05debug): int main() { 004113...
解释一:[1,2] ●Unix编程中所谓"僵尸进程"指什么,什么情况下会产生僵尸进程,如何杀掉僵尸进程: 在fork()/execve()过程中,假设子进程结束时父进程仍存在,而父进程fork()之前既没安装SIGCHLD信号处理函数调用wait或waitpid()等待子进程结束,又没有显式忽略该信号,则子进程成为僵尸进程,无法正常结束,此时即使是root身份kill -9也不能杀死僵尸进程(僵死进程实际上是已死的进程,你当然不能杀死一个死人) ●在一个进程调用了exit之后,该进程并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构。
8086CPU的指令,可以处理两种尺寸的数据,byte和word。所以在机器指令中要指明,指令进行的是字操作还是字节操作。对于这个问题,汇编语言中用一下方法处理。 (1)通过寄存器名指明要处理的数据的尺寸。
SOURCES的文件格式: TARGETNAME=drivername , -本参数用于指定生成的设备驱动程序名称(不需后缀名),所产生的文件 -为drivername.sys. TARGETPATH=.
1)默认情况下,内核加载器会加载所有的代码部分和全局数据到非分页内存中。而且,加载器是一次加载整个驱动的可执行文件,包括相关的DLL。加载后,内核加载器关闭驱动程序文件,甚至你可以删除当前正在执行的驱动文件。
在《Windows驱动开发技术详解》书中讲述了如何设定VC以编译驱动程序,不过稍有点麻烦。 在[2,3]中也有用VC设置的方法。不过有点麻烦。 下面,我们用另外一种方法来进行编译: 在[4]官网上下载如下几个文件: ddkwizard_setup_v1.3.0a.exe, ddkbuild_bat.zip, ddkbuild_cmd.zip 不过太慢,我下了,在CSDN上传中[7]。
9、Windows驱动程序的入口函数规定为_DriverEntry@8,所以用C++编写时要用extern。 驱动程序中,不能使用编译器运行时函数,甚至C语言中的malloc,C++的new函数都不能用,因为他们在VC中的实现都是调用了Win32 API了。
一、基本框架 二、基本概念 1、操作系统的主要任务是调度线程,还有一些必要的工作,如:内存管理,进程管理,安全管理和I/O管理,这些部分叫做执行部件。 2、Ring是CPU的概念,而用户/内核模式是操作系统的概念。
10、HOOK SSDT 的实现 SSDT 的全称是System Services Descriptor Table,即系统服务描述符表。这个表的作用是把ring3 的Win32 API 与ring0 的内核API 联系起来。
8、加裁驱动,驱动与设备 1)前面我们主要通过Driver Studio和KmdManager。现在了解一下程序加裁。 Windows NT式驱动是基于服务方式加载的,可以通过修改注册表内容完成,也可以通过服务相关API完成。
9、驱动程序与应用程序通信 1)使用WriteFile通信 可以在应用层调用ReadFile 和WriteFile 分别从驱动中读取和写入数据,他们通过两个不同的IRP来传递信息。 http://msdn.
7、I/O Request Package,输入输出请求包 1)基本概念 IRP 的全名是I/O Request Package,即输入输出请求包,它是Windows 内核中的一种非常重要的数据结构。
5、在驱动中获取系统时间 1)获取启动毫秒数 在ring3 我们可以通过一个GetTickCount 函数来获得自系统启动开始的毫秒数,在ring0也有一个与之对应的KeQueryTickCount 函数。
4、注册表操作 和文件操作类似,在操作注册表之前需要首先打开注册表,获得一个句柄,这可以通过函数ZwCreateKey 完成。与ZwCreateFile函数类似,它通过一个OBJECT_ATTRIBUTES 获得需要创建或打开的路径信息,但在内核中这个路径与用户模式下不相同,实际上,因为用户模式下的应用程序总是由某个“当前用户”打开的,因此在用户模式下可以直接访问HKEY_CLASSES_ROOT 和HKEY_CURRENT_USER,但工作在内核模式下的驱动程序不属于任何一个用户,因此不能直接访问这两个根键。
1、字符串 Unicode 字符串有一个结构体定义如下: typedef struct _UNICODE_STRING { USHORT Length; // 字符串的长度(字节数) USHORT MaximumLength; // 字符串缓冲区的长度(字节数) PWSTR Buffer; // 字符串缓冲区 } UNICODE_STRING, *PUNICODE_STRING; 需要注意的是,当我们定义了一个UNICODE_STRING 变量之后,它的Buffer 域还没有分配空间,因此我们不能直接赋值,好的做法是使用微软提供的Rtl 系列函数。