http://blog.csdn.net/ithzhang/article/details/7916732转载请注明出处!! 第二章:字符和字符串处理 使用vc编程时项目-->属性-->常规栏下我们可以设置项目字符集合,它可以是ANSI(多字节)字符集,也可以是unicode字符集.一般情况下说Unicode都是指UTF-16.也就是说每个字符编码为两个字节.65535个字符可以表示世界上大部分的语言.为了软件使国际化大家再编程时应该使用unicode字符集.由于原来学过c语言,不习惯使用Un…
Windows线程池 上一篇博文我们介绍了IO完成端口.得知IO完成端口可以非常智能的分派线程.但是IO完成端口仅对等待它的线程进行分派,创建和销毁线程的工作仍然需要我们自己来做. 我们自己也可以创建线程,但是涉及到线程的编码操作比较复杂,容易出现差错.为了简化程序员的工作,Windows提供了一个线程池机制来简化线程的创建.销毁以及日常管理.这个新线程池可能不适用于所有的情况,但大多数情况下它都能够满足我们的需要. 这个线程池能够帮助我们做一下事情: 一:以异步的方式调用一个函数. 二:每隔一…
错误处理 我们写的函数会用返回值表示程序执行的正确与否,使用void,就意味着程序一定不会出错.Bool类型标识true时为真,false时为假.其他类型根据需要可以定义成不同意义. Windows除了使用返回值标识函数执行情况,外还引入了错误代码机制.返回值指出函数已发生一个错误.要查看具体是什么错误,就应该使用错误代码.如当我们调用函数打开一个文件,如果打开失败,可能出现多种原因.一是:文件不存在,另一种是该文件被其他程序互斥使用.在这两种情况下都导致文件打开失败,返回值仅仅标识打开失败,但…
本篇文章将介绍DLL显式链接的过程和模块基地址重定位及模块绑定的技术. 第一种将DLL映射到进程地址空间的方式是直接在源代码中引用DLL中所包含的函数或是变量,DLL在程序运行后由加载程序隐式的载入,此种方式被称为隐式链接. 第二种方式是在程序运行时,通过调用API显式的载入所需要的DLL,并显式的链接所想要链接的符号.换句话说,程序在运行时,其中的一个线程能够显式的将该DLL调用到进程地址空间中,并得到DLL中某函数的在进程地址空间的虚拟地址,然后调用该函数.此种方式被称为显式链接. 注意:显…
每个DLL和可执行文件都有一个首选基地址.它表示该模块被映射到进程地址空间时最佳的内存地址.在构建可执行文件时,默认情况下链接器会将它的首选基地址设为0x400000.对于DLL来说,链接器会将它的首选基地址设为0x10000000,然后将该地址以及代码.数据的相关地址都写入它们的PE文件中.当它们被加载时,加载程序读取首选基地址的值,并试图把它们加载到相应位置. 对于可执行文件和DLL中的代码,它们运行的时候所引用的的数据的地址,在链接的时候就已经确定.并且这些都是当exe文件或是DLL被加载…
DLL全称dynamic linking library.即动态链接库.广泛应用与windows及其他系统中.因此对dll的深刻了解,对计算机软件开发专业人员来说非常重要. windows中所有API都包含在DLL中.三个最重要的DLL是Kernel32.dll,User32.dll,GDI32.dll. 使用dll的好处: 1:扩展了应用程序的特性. 2:简化了项目管理 可以让不同的开发团队管理不同的模块. 3:有助于节省内存. 一个dll可被多个程序共享.多个程序调用同一个dll内的同一个函…
在应用程序中使用虚拟内存 Windows提供了以下三种机制对内存进行操控: 一:虚拟内存.最适合来管理大型对象数据或大型结构数组. 二:内存映射文件.最适合用来管理大型数据流,以及在同一机 器上运行的多个进程之间共享数据. 三:堆.最适合用来管理大量的小型对象. 很多人都对VirtualAlloc和malloc 或new的区别不是很清楚,我也一样.今天搜索下了,发现这句话说的很清楚了: VirtualAlloc要进入内核模式,算法特复杂,比较慢,而且分配粒度是4k,用来分配小块内存很浪费 mal…
一个模块的导入段包含一组DLL.为了让模块能够运行,这些DLL是必须的.导入段还包含一个符号表.它列出了该模块从各DLL中导入的符号.当模块调用这些导入符号的时候,系统实际上会调用转换函数,获得导入函数在导入表的地址,然后再跳到相应的位置.如果我们能将导入段中相应导入函数的地址替换成自定义的函数的地址,即可实现对该函数的拦截.在自定义的函数中,我们既可以调用拦截的函数,也可以执行其他工作. 要实现修改导入段来拦截API必须对PE文件格式有很好的了解.网上关于它的资料铺天盖地,自己搜吧.此处不打算…
用户模式下的线程同步 系统中的线程必须访问系统资源,如堆.串口.文件.窗口以及其他资源.如果一个线程独占了对某个资源的访问,其他线程就无法完成工作.我们也必须限制线程在任何时刻都能访问任何资源.比如在一个线程读内存时要限制其他线程对此块内存进行写入. 线程之间的通信很重要,尤其是在以下两种情况下: 1:需要让多个线程同时访问一个共享资源,同时不能破坏资源的完整性. 2:一个线程需要通知其他线程某项任务已经完成. 线程同步包括许多方面,windows提供了许多基础设施使线程同步变得容易. 用户模式…
线程调度.优先级和关联性 每个线程都有一个CONTEXT结构,保存在线程内核对象中.大约每隔20ms windows就会查看所有当前存在的线程内核对象.并在可调度的线程内核对象中选择一个,将其保存在CONTEXT结构的值载入cpu寄存器.这被称为上下文切换.大约又过20ms  windows将当前cpu寄存器存回内核对象,线程被挂起.Windows再次检查内核对象,并在可调度的内核对象中选择一个进行调度.此过程不断重复直到系统关闭. Windows被称为抢占式多线程系统,系统可以在任何时刻停止一…
同步设备IO 所谓同步IO是指线程在发起IO请求后会被挂起,IO完成后继续执行. 异步IO是指:线程发起IO请求后并不会挂起而是继续执行.IO完毕后会得到设备的通知.而IO完成端口就是实现这种通知的很好的一种方式. 线程是我们开发高性能.响应性好的一个必不可少的工具.这样在多处理器上就可以同时执行多个操作,从而提高吞吐量.当线程发出一个同步设备IO请求的时候,它会被临时挂起,直到设备完成IO请求为止.但线程阻塞会损害性能,这里有个问题是我们如何让线程不被挂起. 让线程始终进行有用的工作就需要它们…
使用内核对象进行线程同步. 前面我们介绍了用户模式下线程同步的几种方式.在用户模式下进行线程同步的最大好处就是速度非常快.因此当需要使用线程同步时用户模式下的线程同步是首选. 但是用户模式下的线程同步也存在缺点.如InterLocked系列函数只能对一个值进行操作.关键段虽然可以对一段代码进行操作,但是只能对同一个进程内的线程进行同步.为了解决上述问题,我们将会讨论使用内核对象进行线程同步. 与用户模式下的速度快相比较,使用内核对象进行线程同步性能很低.原因就是:在创建或清除内核对象时调用线程必…
第二部分:工作机理 第一章:进程 上一章介绍了内核对象,这一节开始就要不断接触各种内核对象了.首先要给大家介绍的是进程内核对象.进程大家都不陌生,它是资源和分配的基本单位,而进程内核对象就是与进程相关联的一个数据结构.操作系统内核通过它管理进程,也就是操作系统原理上介绍的进程控制块(PCB).举个例子,它就相当于每个学生都有的学籍,学校管理我们都是通过学籍,什么记过了,处分了,开除学籍了,都是在学籍上做文章. 进程一般被定义为一个正在运行的程序的一个实例,它由两部分组成: 1:内核对象,操作系统…
线程基础 与前面介绍的进程一样,线程也有两部分组成.一个是线程内核对象.它是一个数据结构,操作系统用它来管理线程以及用它来存储线程的一些统计信息.另一个是线程栈,用于维护线程执行时所需的所有函数参数和局部变量.位于同一个进程的线程共享进程的地址空间且它们共享进程句柄表.因为句柄表是针对进程的.进程需要很多的系统资源,而线程仅仅需要一个线程内核对象和线程栈就可以了,因此线程比进程的开销要小得多.采用多线程来处理问题也是理所当然的了. 采用多线程可以提高程序的执行效率,但是多线程也存在很多问题.在尝…
内核对象 本章讨论的是相对抽象的概念,不涉及任何具体的内核对象的细节而是讨论所有内核对象的共有特性. 首先让我们来了解一下什么是内核对象.内核对象通过API来创建,每个内核对象是一个数据结构,它对应一块内存,由操作系统内核分配,并且只能由操作系统内核访问.在此数据结构中少数成员如安全描述符和使用计数是所有对象都有的,但其他大多数成员都是不同类型的对象特有的.内核对象的数据结构只能由操作系统提供的API访问,应用程序在内存中不能访问.调用创建内核对象的函数后,该函数会返回一个句柄,它标识了所创建的…
第1 2章 纤 程 M i c r o s o f t公司给Wi n d o w s添加了一种纤程,以便能够非常容易地将现有的 U N I X服务器应用程序移植到Wi n d o w s中.U N I X服务器应用程序属于单线程应用程序(由 Wi n d o w s定义) ,但是它能够为多个客户程序提供服务.换句话说, U N I X应用程序的开发人员已经创建了他们自己的线程结构库,他们能够使用这种线程结构库来仿真纯线程.该线程包能够创建多个堆栈, 保存某些C P U寄存器,并且在它们之间进行切…
windows内的各个进程有各自的地址空间.它们相互独立互不干扰保证了系统的安全性.但是windows也为调试器或是其他工具设计了一些函数,这些函数可以让一个进程对另一个进程进行操作.虽然他们是为调试器设计的,但是任何应用程序都可以调用它们 .接下来我们来谈谈使用远程线程来注入DLL. 从根本上说,DLL注入就是将某一DLL注入到某一进程的地址空间.该进程中的一个线程调用LoadLibrary来载入想要注入的DLL.由于我们不能直接控制其他进程内的线程,因此我们必须在其他进程内创建一个我们自己的…
windows应用程序是基于消息驱动的.各种应用程序对各种消息作出响应从而实现各种功能. windows钩子是windows消息处理机制的一个监视点,通过安装钩子能够达到监视指定窗体某种类型的消息的功能.所谓的指定窗体并不局限于当前进程的窗体,也能够是其它进程的窗体.当监视的某一消息到达指定的窗体时,在指定的窗体处理消息之前,钩子函数将截获此消息,钩子函数既能够加工处理该消息,也能够不作不论什么处理继续传递该消息.使用钩子是实现dll注入的方法之中的一个.其它经常使用的方法有:注冊表注入,远程线…
堆 前面我们说过堆非常适合分配大量的小型数据.使用堆可以让程序员专心解决手头的问题,而不必理会分配粒度和页面边界之类的事情.因此堆是管理链表和数的最佳方式.但是堆进行内存分配和释放时的速度比其他方式都慢,而且无法对物理存储器的调拨和撤销调拨进行控制. 什么是堆? 在系统内部堆就是一块预定的地址空间区域.刚开始堆的大部分页面都没有调拨物理存储器.随着我们不断的从堆中分配内存,堆管理器会给堆调拨越来越多的物理存储器.这些物理存储器始终是从页交换文件中分配的.释放堆中的内存时,堆管理器会撤销已调拨的物…
内存映射文件允许开发人员预订一块地址空间并为该区域调拨物理存储器,与虚拟内存不同的是,内存映射文件的物理存储器来自磁盘中的文件,而非系统的页交换文件.将文件映射到内存中后,我们就可以在内存中操作他们了,就像他们被载入内存中一样. 内存映射文件主要有三方面的用途: 1:系统使用内存映射文件来将exe或是dll文件本身作为后备存储器,而非系统页交换文件,这大大节省了系统页交换空间,由于不需要将exe或是dll文件加载到页系统交换文件,也提高了启动速度. 2:使用内存映射文件来将磁盘上的文件映射到进程…
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面 学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面 学习ASP.NET C…
Windows内存体系结构 理解Windows内存体系结构是每一个励志成为优秀的Windows程序员所必须的. 进程虚拟地址空间 每个进程都有自己的虚拟地址空间.对于32位操作系统来说,它的地址空间是4GB.这是因为32位指针可以表示从0x00000000到0xFFFFFFFF之间的任一值.对于64位的操作系统来说有0--2的64次方之间的任一值. 由于每个就进程都有自己的地址空间,因此每个进程都只能访问属于自己的地址空间而不能访问其他进程的空间.这保护了进程,也是之所以我们说进程是资源分配和保…
谈谈windows线程栈. 当系统创建线程时会为线程预订一块地址空间区域,注意仅仅是预订.默认情况下预定的这块区域的大小是1MB,虽然预订这么多,但是系统并不会给全部区域调拨物理存储器.默认情况下,仅仅为两个页面挑拨.x86系统下每个页面是4KB.其他页面会在访问的时候由系统调拨.这仅仅是在创建线程时,程序员指定CreateThread的第二个参数StackSize为0时才会发挥作用.如果程序员传入的是非零值,那么调拨的物理存储器的数量就是这个非零值. 这两个默认的页面是从哪里来的呢?原来是在链…
第1 8章 堆 栈 对内存进行操作的第三个机制是使用堆栈.堆栈可以用来分配许多较小的数据块.例如,若要对链接表和链接树进行管理,最好的方法是使用堆栈,而不是第 1 5章介绍的虚拟内存操作方法或第1 7章介绍的内存映射文件操作方法.堆栈的优点是,可以不考虑分配粒度和页面边界之类的问题,集中精力处理手头的任务.堆栈的缺点是,分配和释放内存块的速度比其他机制要慢,并且无法直接控制物理存储器的提交和回收. 从内部来讲,堆栈是保留的地址空间的一个区域.开始时,保留区域中的大多数页面没有被提交物理存储器.当…
第1 5章 在应用程序中使用虚拟内存 Wi n d o w s提供了3种进行内存管理的方法,它们是: • 虚拟内存,最适合用来管理大型对象或结构数组. • 内存映射文件,最适合用来管理大型数据流(通常来自文件)以及在单个计算机上运行的多个进程之间共享数据. • 内存堆栈,最适合用来管理大量的小对象. 本章将要介绍第一种方法,即虚拟内存.内存映射文件和堆栈分别在第 1 7章和第1 8章介绍.用于管理虚拟内存的函数可以用来直接保留一个地址空间区域,将物理存储器(来自页文件)提交给该区域,并且可以设置…
第1 9章 D L L基础 这章是介绍基本dll,我就记录一些简单应用,dll的坑点以及扩展后面两章会说,到时候在总结. 自从M i c r o s o f t公司推出第一个版本的Wi n d o w s操作系统以来,动态链接库(D L L)一直是这个操作系统的基础. Windows API中的所有函数都包含在 D L L中.3个最重要的 D L L是K e r n e l 3 2 . d l l,它包含用于管理内存.进程和线程的各个函数: U s e r 3 2 . d l l,它包含用于执行…
第1 4章 虚 拟 内 存 <这一章没啥,是说的几个内存相关的函数 > 14.1 系统信息 许多操作系统的值是根据主机而定的,比如页面的大小,分配粒度的大小等.这些值决不应该用硬编码的形式放入你的源代码.相反,你始终都应该在进程初始化的时候检索这些值,并在你的源代码中使用检索到的值.G e t S y s t e m I n f o函数将用于检索与主机相关的值:VOID WINAPI GetSystemInfo(_Out_ LPSYSTEM_INFO lpSystemInfo); 必须传递S …
Github https://github.com/gongluck/Windows-Core-Program.git //第11章 Windows线程池.cpp: 定义应用程序的入口点. // #include "stdafx.h" #include "第11章 Windows线程池.h" VOID NTAPI SimpleCB( _Inout_ PTP_CALLBACK_INSTANCE Instance, _Inout_opt_ PVOID Context )…
小续 这是我11年看<windows核心编程>时所作的一些笔记,现整理出来共享给大家 windows核心编程整理(上) windows核心编程整理(下) 线程的基础知识 进程是不活泼的,进程从来不执行任何东西,进程只是线程的容器 线程用于描绘进程中的运行路径 每个进程必须拥有一个进入点函数,线程从这个进入点开始运行 线程的退出代码在线程的内核对象中维护 进程由进程内核对象和地址空间组成 线程由线程内核对象和线程堆栈组成 大多数线程拥有的所有用户对象是由包含创建这些对象的线程的进程拥有的,但是,…
最近在学习Windows底层原理,准备写个系列文章分享给大家,Michael Li(微软实习期间的Mentor,为人超好)在知乎回答过一些关于学习Windows原理的书籍推荐,大家可以拜读其中一本来入门.我是先从<Windows核心编程>开始了解一些Windows底层管理与硬件交互的原理,然后买了一套冬瓜哥撰写的<大话计算机>系列丛书,学有余力的童鞋强烈推荐你去看看,这套书对计算机整体的运作原理讲解的很系统,涉及了计算机组成原理.网络原理.编译原理.操作系统.硬件等,可以作为不错的…