传东's profile浩瀚空间PhotosBlogListsMore Tools Help

Blog


    December 03

    AutoPager是个好东西, 值得推荐

    欢迎大家使用autopager, 这个Firefox的插件非常实用, 为你省去了点击下一页的烦恼.平时我们经常会遇见这样的情况, 在一个页面没法找到自己要的东西, 不得不再去点击下一页,就这样一直下去,很烦. 有了这个, 一切的烦恼就没了, 在你浏览当前页面的时候, 下一页autopagerr就自动为你装载并且贴在当前页面的下面, 你所要做的就是看看,往下传滚轮, 一页页的数据会会自动的为你打开并且接在上个页面的下方. 所有你看过的页面最后都形成了一页, 这样方便你回滚查看一些资料,真是太方便了.
     
    强烈推荐大家使用. 好东西要共享.
    这个插件现在被mozilla官方推荐, 你可以在firefox里插件里面搜索autopager然后安装即可. 作者是wind.
    October 16

    读写锁的OO分析


    我们有时会遇到对同一个内存区域如数组或者链表进行多线程读写的情况,一般来说有以下几种处理方式:
    1.不加任何限制,多见于读取写入都很快的情况,但有时也会出现问题.
    2.对读写函数都加以同步锁,比如使用singleton模式,这下问题是没了,但效率也下去了,比如说两个读取线程不是非要排队进入不可.
    3.读写锁,安全和效率都得到了解决,特别合适读线程多于写线程的情况.也就是下面将要展现的模式.

    读写锁的本意是分别对读写状态进行互斥区分,有互斥时才加锁,否则放行.互斥的情况有:
    1.读写互斥.
    2.写写互斥.
    不互斥的情况是:读读,这种情况不该加以限制.

    我们只要让锁对象知道当前读写状态就可以了,再根据情况进行锁定和解锁,然后再分情况进行锁定.请看代码

    代码如下:
    DataLib类,注意其中try...finally 的写法,它保证了加锁解锁过程是成对调用的:
    package com.sitinspring.readwritelock;

    import java.util.ArrayList;
    import java.util.List;

    /** *//**
     * 数据仓库类,用于保存数据
     *
     * @author sitinspring(junglesong@gmail.com)
     *
     */
    public class DataLib {
        private List<String> datas;

        private ReadWriteLock lock;

        public DataLib() {
            datas = new ArrayList<String>();
            lock = new ReadWriteLock();
        }

        // 写入数据,这时不能读取
        public void writeData(List<String> newDatas) {
            try {
                lock.writeLock();
                Test.sleep(2);
                datas=newDatas;
            } finally {
                lock.writeUnlock();
            }
        }

        // 读取数据,这时不能写入
        public List<String> readData() {
            try {
                lock.readLock();
                Test.sleep(1);           
                return datas;
            } finally {
                lock.readUnlock();
            }

        }

    }
    ReadWriteLock类,很重要:
    package com.sitinspring.readwritelock;

    /** *//**
     * 读写锁,用于线程控制
     * @author sitinspring(junglesong@gmail.com)
     *
     */
    public class ReadWriteLock{
        // 读状态
        private boolean isRead;
       
        // 写状态
        private boolean isWrite;
       
        public synchronized void readLock(){
            // 有写入时读取线程停止
            while(isWrite){
                try{   
                    System.out.println("有线程在进行写入,读取线程停止,进入等待状态");
                    wait();
                }
                catch(InterruptedException ex){
                    ex.printStackTrace();
                }
            }
           
            System.out.println("设定锁为读取状态");
            isRead=true;
        }
       
        public synchronized void readUnlock(){
            System.out.println("解除读取锁");
            isRead=false;
            notifyAll();
        }
       
        public synchronized void writeLock(){
            // 有读取时读取线程停止
            while(isRead){
                try{   
                    System.out.println("有线程在进行读取,写入线程停止,进入等待状态");
                    wait();
                }
                catch(InterruptedException ex){
                    ex.printStackTrace();
                }
            }
           
            // 有写入时写入线程也一样要停止
            while(isWrite){
                try{   
                    System.out.println("有线程在进行写入,写入线程停止,进入等待状态");
                    wait();
                }
                catch(InterruptedException ex){
                    ex.printStackTrace();
                }
            }
           
            System.out.println("设定锁为写入状态");
            isWrite=true;
        }
       
        public synchronized void writeUnlock(){
            System.out.println("解除写入锁");
            isWrite=false;
            notifyAll();
        }
    }

    Writer类:
    package com.sitinspring.readwritelock;

    import java.util.ArrayList;
    import java.util.Random;

    /** *//**
     * 用于读取文件,写入数据仓库
     * @author sitinspring(junglesong@gmail.com)
     *
     */
    public class Writer implements Runnable{
        private DataLib dataLib;
        private static final Random random=new Random();
        private String[] mockDatas={"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};   
       
        public Writer(DataLib dataLib,String[] mockDatas){
            this.dataLib=dataLib;
            this.mockDatas=mockDatas;
           
            Thread thread=new Thread(this);
            thread.start();
        }
       
        public void run(){
            while(true){
                Test.sleep(random.nextInt(3));
               
                int startIndex=random.nextInt(mockDatas.length);
               
                ArrayList<String> newDatas=new ArrayList<String>();
                for(int i=startIndex;i<mockDatas.length;i++){
                    newDatas.add(mockDatas[i]);
                }
               
                dataLib.writeData(newDatas);
            }
        }
    }

    Reader类:
    package com.sitinspring.readwritelock;

    import java.util.List;
    import java.util.Random;

    /** *//**
     * 用于从数据仓库中得到数据
     * @author sitinspring(junglesong@gmail.com)
     *
     */
    public class Reader implements Runnable{
        private DataLib dataLib;
        private static final Random random=new Random();
       
        public Reader(DataLib dataLib){
            this.dataLib=dataLib;
       
            Thread thread=new Thread(this);
            thread.start();
        }
       
        public void run(){
            while(true){
                Test.sleep(random.nextInt(2));           
                List<String> datas=dataLib.readData();
               
                System.out.print(">>取得数组为:");
                for(String data:datas){
                    System.out.print(data+",");
                }
                System.out.print("\n");
            }
        }
    }

    测试类:
    package com.sitinspring.readwritelock;

    /** *//**
     * main函数所在类
     * @author sitinspring(junglesong@gmail.com)
     *
     */
    public class Test{
        public static void main(String[] args){
            DataLib dataLib=new DataLib();
           
            String[] mockDatas1={"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};
            Writer writer1=new Writer(dataLib,mockDatas1);
           
            String[] mockDatas2={"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};
            Writer writer2=new Writer(dataLib,mockDatas2);
           
            Reader reader1=new Reader(dataLib);
            Reader reader2=new Reader(dataLib);
            Reader reader3=new Reader(dataLib);
        }
       
       
        // 用于延时
        public static void sleep(int sleepSecond){
            try{
                Thread.sleep(sleepSecond*1000);
            }
            catch(Exception ex){
                ex.printStackTrace();
            }
        }
    }

    September 26

    time date 的output

    这个命令有一定的代表性。分析一下:
    1. 其实这个命令要拆成两个命令看。一是time这个命令(这个time命令指的是bash的builtin命令),他有自己的stderr。还有就是date这个命令,它有自己的stdout.
    2. time这个命令特殊的地方就是对命令的重定向无法在当前shell环境完成。可以试试
    代码:
    time 1>/dev/null OR time 2>/dev/null OR time &>/dev/null
    ,无论怎么样,stderr都会显示。现在知道的唯一的方法是采用subshell的方式,让time在subshell生成stderr,然后在主shell来重定向操作。date命令输出方式是简单的。
    3. 这个命令的执行顺序应该是:1. time执行并等待下一个命令结束。2. date执行并结束。3. time计算命令运行时间并结束.
    3. 知道了原因,就可以对time date这个命令的重定向进行操作了。对date的输出进行操作可以在命令运行同时来完成, 或放到subshell来完成,或放到上层的主shell。而对time的stderr转stdout的操作就必须放在主shell来完成。这样的话我们可以重定向这样几种情况:
    1. 只需要time的输出。
    代码:
    time date 1>/dev/null OR (time date) 1>/dev/null OR (time date 1>/dev/null) OR eval time date 1>/dev/null
    虽然结果一样,但是重定向的层和次序不一样。第一和第三中方式的重定向只单单的对date命令,根本不涉及对time的输出,同时重定向的层是一样的,但第二种重定向发生在命令运行的上层主shell,且是对time和date命令的共同输出做处理。第四种是利用了eval来将time和date作为整个命令一起执行,意义和第二种一样。
    2. 只需要date的输出。
    代码:
    (time date) 2>/dev/null OR eval time date 2>/dev/null
    重定向都是在time和date的输出完成后执行的。
    3。屏蔽所有输出。
    代码:
    (time date) &>/dev/null OR (time date &>/dev/null) 2>/dev/null
    第一种是在所有输出结束后整体屏蔽掉,后一种是先屏蔽date的输出,然后在屏蔽time的输出。
    类似的,我们可以实现对不同的输出转入文件。
    ----------------------------------- 
    $cat 1.c
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

    int main()
    {
    int fd;
    fd = open("/dev/tty",O_WRONLY);
    write(fd,"never blocked\n",14);
    }

    $gcc 1.c -o 1

    $./1 &>/dev/null
    never blocked
    September 21

    Javascript----文件操作

    一、功能实现核心:FileSystemObject 对象
    要在javascript中实现文件操作功能,主要就是依靠FileSystemobject对象。
    二、FileSystemObject编程
    使用FileSystemObject 对象进行编程很简单,一般要经过如下的步骤: 创建FileSystemObject对象、应用相关方法、访问对象相关属性 。
    (一)创建FileSystemObject对象
    创建FileSystemObject对象的代码只要1行:
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    上述代码执行后,fso就成为一个FileSystemObject对象实例。
    (二)应用相关方法
    创建对象实例后,就可以使用对象的相关方法了。比如,使用CreateTextFile方法创建一个文本文件:
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    var f1 = fso.createtextfile("c:\\myjstest.txt",true");
    (三)访问对象相关属性
    要访问对象的相关属性,首先要建立指向对象的句柄,这就要通过get系列方法实现:GetDrive负责获取驱动器信息,GetFolder负责获取文件夹信息,GetFile负责获取文件信息。比如,指向下面的代码后,f1就成为指向文件c:\test.txt的句柄:
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    var f1 = fso.GetFile("c:\\myjstest.txt");
    然后,使用f1访问对象的相关属性。比如:
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    var f1 = fso.GetFile("c:\\myjstest.txt");
    alert("File last modified: " + f1.DateLastModified);
    执行上面最后一句后,将显示c:\myjstest.txt的最后修改日期属性值。
    但有一点请注意:对于使用create方法建立的对象,就不必再使用get方法获取对象句柄了,这时直接使用create方法建立的句柄名称就可以:
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    var f1 = fso.createtextfile("c:\\myjstest.txt",true");
    alert("File last modified: " + f1.DateLastModified);
    三、操作驱动器(Drives)
    使用FileSystemObject对象来编程操作驱动器(Drives)和文件夹(Folders)很容易,这就象在Windows文件浏览器中对文件进行交互操作一样,比如:拷贝、移动文件夹,获取文件夹的属性。
    (一)Drives对象属性
    Drive对象负责收集系统中的物理或逻辑驱动器资源内容,它具有如下属性:
    l TotalSize:以字节(byte)为单位计算的驱动器大小。
    l AvailableSpace或FreeSpace:以字节(byte)为单位计算的驱动器可用空间。
    l DriveLetter:驱动器字母。
    l DriveType:驱动器类型,取值为:removable(移动介质)、fixed(固定介质)、network(网络资源)、CD-ROM或者RAM盘。
    l SerialNumber:驱动器的系列码。
    l FileSystem:所在驱动器的文件系统类型,取值为FAT、FAT32和NTFS。
    l IsReady:驱动器是否可用。
    l ShareName:共享名称。
    l VolumeName:卷标名称。
    l Path和RootFolder:驱动器的路径或者根目录名称。
    (二)Drive对象操作例程
    下面的例程显示驱动器C的卷标、总容量和可用空间等信息:
    var fso, drv, s ="";
    fso = new ActiveXObject("Scripting.FileSystemObject");
    drv = fso.GetDrive(fso.GetDriveName("c:\\"));
    s += "Drive C:" + " - ";
    s += drv.VolumeName + "\n";
    s += "Total Space: " + drv.TotalSize / 1024;
    s += " Kb" + "\n";
    s += "Free Space: " + drv.FreeSpace / 1024;
    s += " Kb" + "\n";
    alert(s);
    四、操作文件夹(Folders)
    涉及到文件夹的操作包括创建、移动、删除以及获取相关属性。
    Folder对象操作例程 :
    下面的例程将练习获取父文件夹名称、创建文件夹、删除文件夹、判断是否为根目录等操作:
    var fso, fldr, s = "";
    // 创建FileSystemObject对象实例
    fso = new ActiveXObject("Scripting.FileSystemObject");
    // 获取Drive 对象
    fldr = fso.GetFolder("c:\\");
    // 显示父目录名称
    alert("Parent folder name is: " + fldr + "\n");
    // 显示所在drive名称
    alert("Contained on drive " + fldr.Drive + "\n");
    // 判断是否为根目录
    if (fldr.IsRootFolder)
    alert("This is the root folder.");
    else
    alert("This folder isn't a root folder.");
    alert("\n\n");
    // 创建新文件夹
    fso.CreateFolder ("C:\\Bogus");
    alert("Created folder C:\\Bogus" + "\n");
    // 显示文件夹基础名称,不包含路径名
    alert("Basename = " + fso.GetBaseName("c:\\bogus") + "\n");
    // 删除创建的文件夹
    fso.DeleteFolder ("C:\\Bogus");
    alert("Deleted folder C:\\Bogus" + "\n");
    五、操作文件(Files)
    对文件进行的操作要比以上介绍的驱动器(Drive)和文件夹(Folder)操作复杂些,基本上分为以下两个类别:对文件的创建、拷贝、移动、删除操作和对文件内容的创建、添加、删除和读取操作。下面分别详细介绍。
    (一)创建文件
    一共有3种方法可用于创建一个空文本文件,这种文件有时候也叫做文本流(text stream)。
    第一种是使用CreateTextFile方法。代码如下:
    var fso, f1;
    fso = new ActiveXObject("Scripting.FileSystemObject");
    f1 = fso.CreateTextFile("c:\\testfile.txt", true);
    第二种是使用OpenTextFile方法,并添加上ForWriting属性,ForWriting的值为2。代码如下:
    var fso, ts;
    var ForWriting= 2;
    fso = new ActiveXObject("Scripting.FileSystemObject");
    ts = fso.OpenTextFile("c:\\test.txt", ForWriting, true);
    第三种是使用OpenAsTextStream方法,同样要设置好ForWriting属性。代码如下:
    var fso, f1, ts;
    var ForWriting = 2;
    fso = new ActiveXObject("Scripting.FileSystemObject");
    fso.CreateTextFile ("c:\\test1.txt");
    f1 = fso.GetFile("c:\\test1.txt");
    ts = f1.OpenAsTextStream(ForWriting, true);
    (二)添加数据到文件
    当文件被创建后,一般要按照“打开文件->填写数据->关闭文件”的步骤实现添加数据到文件的目的。
    打开文件可使用FileSystemObject对象的OpenTextFile方法,或者使用File对象的OpenAsTextStream方法。
    填写数据要使用到TextStream对象的Write、WriteLine或者WriteBlankLines方法。在同是实现写入数据的功能下,这3者的区别在于:Write方法不在写入数据末尾添加新换行符,WriteLine方法要在最后添加一个新换行符,而WriteBlankLines则增加一个或者多个空行。
    关闭文件可使用TextStream对象的Close方法。
    (三)创建文件及添加数据例程
    下面的代码将创建文件、添加数据、关闭文件几个步骤结合起来进行应用:
    var fso, tf;
    fso = new ActiveXObject("Scripting.FileSystemObject");
    // 创建新文件
    tf = fso.CreateTextFile("c:\\testfile.txt", true);
    // 填写数据,并增加换行符
    tf.WriteLine("Testing 1, 2, 3.") ;
    // 增加3个空行
    tf.WriteBlankLines(3) ;
    // 填写一行,不带换行符
    tf.Write ("This is a test.");
    // 关闭文件
    tf.Close();
    (四)读取文件内容
    从文本文件中读取数据要使用TextStream对象的Read、ReadLine或ReadAll 方法。Read方法用于读取文件中指定数量的字符;ReadLine方法读取一整行,但不包括换行符;ReadAll方法则读取文本文件的整个内容。读取的内容存放于字符串变量中,用于显示、分析。在使用Read或ReadLine方法读取文件内容时,如果要跳过一些部分,就要用到Skip或 SkipLine方法。
    下面的代码演示打开文件、填写数据,然后读取数据:
    var fso, f1, ts, s;
    var ForReading = 1;
    fso = new ActiveXObject("Scripting.FileSystemObject");
    // 创建文件
    f1 = fso.CreateTextFile("c:\\testfile.txt", true);
    // 填写一行数据
    f1.WriteLine("Hello World");
    f1.WriteBlankLines(1);
    // 关闭文件
    f1.Close();
    // 打开文件
    ts = fso.OpenTextFile("c:\\testfile.txt", ForReading);
    // 读取文件一行内容到字符串
    s = ts.ReadLine();
    // 显示字符串信息
    alert("File contents = '" + s + "'");
    // 关闭文件
    ts.Close();
    (五)移动、拷贝和删除文件
    对于以上三种文件操作,javascript各有两种对应的方法:File.Move 或 FileSystemObject.MoveFile用于移动文件;File.Copy 或 FileSystemObject.CopyFile用于拷贝文件;File.Delete 或 FileSystemObject.DeleteFile用于删除文件。
    下面的代码演示在驱动器C的根目录下创建一个文本文件,填写一些内容,然后将文件移动到\tmp目录下,再在目录\temp下面建立一个文件拷贝,最后删除这两个目录的文件:
    var fso, f1, f2, s;
    fso = new ActiveXObject("Scripting.FileSystemObject");
    f1 = fso.CreateTextFile("c:\\testfile.txt", true);
    // 写一行
    f1.Write("This is a test.");
    // 关闭文件
    f1.Close();
    // 获取C:\根目录下的文件句柄
    f2 = fso.GetFile("c:\\testfile.txt");
    // 移动文件到\tmp目录下
    f2.Move ("c:\\tmp\\testfile.txt");
    // 拷贝文件到\temp目录下
    f2.Copy ("c:\\temp\\testfile.txt");
    // 获取文件句柄
    f2 = fso.GetFile("c:\\tmp\\testfile.txt");
    f3 = fso.GetFile("c:\\temp\\testfile.txt");
    // 删除文件
    f2.Delete();
    f3.Delete();
    六、结 语
    通过以上对FileSystemObject的各种对象、属性和方法的介绍和示例,相信你已经对如何使用javascript语言在页面中操作驱动器、文件和文件夹有了清晰的认识。但是上述提及的例程都非常简单,要全面、灵活地掌握javascript文件操作技术,还需要大量的实践练习。而且还有一点提醒大家,由于涉及到在浏览器中进行文件读写这样的高级操作,对于默认的浏览器安全级别而言,在代码运行前都会有一个信息提示,这点请在实际环境中提示访问者注意。
    </td> </tr> <tr> <td vAlign=top align=left height="100%">  

    September 17

    键盘驱动原理

    0 概述

        我们将讨论 ps/2 键盘的驱动。主要讨论的内容有,ps/2 键盘的硬件,使用键盘驱动的应用层,键盘驱动的初始化,键盘驱动如何完成自己的工作,以及一些涉及到的相关内容。需要注意的是,以后我们提到的键盘,如果没有特殊说明,都是指 ps/2  键盘。

    1 ps/2 键盘的硬件

        要以写一个硬件的驱动为目的的话,需要对这个硬件有一定的了解,但并不需要太深入,只要对于写驱动足够就可以了。关于 ps/2 键盘的硬件知识,我们也是对讨论键盘驱动足够就可以了,一些对于驱动没有帮助的硬件实现的细节,我们不讨论。

    1.1 ps/2 键盘硬件概述

        对于驱动来说,和键盘相关的最重要的硬件是两个芯片。一个是 intel 8042 芯片,位于主板上,CPU 通过 IO 端口直接和这个芯片通信,获得按键的扫描码或者发送各种键盘命令。另一个是 intel 8048 芯片或者其兼容芯片,位于键盘中,这个芯片主要作用是从键盘的硬件中得到被按的键所产生的扫描码,与  i8042 通信,控制键盘本身。

        当键盘上有键被按下时,i8048 直接获得键盘硬件产生的扫描码。i8048 也负责键盘本身的控制,比如点亮 LED 指示灯,熄灭 LED 指示灯。i8048 通过 ps/2 口和 i8042 通信,把得到的扫描码传送给 i8042。CPU 通过读写端口,可以直接把 i8042 中的数据读入到 CPU 的寄存器中,或者把 CPU 寄存器中的数据写入 i8042 中。ps/2 口一共有 6 个引脚,可以拔下 ps/2 插头看一下,这 6 个引脚分别为,时钟,数据,电源地,电源+5V,还有2 个引脚没有被用到。由于只有一个引脚传输数据,所以 ps/2 口上的数据传输是串行的。

        下面几幅图是一个键盘的内部,可以看到用来产生扫描码的按键矩阵( Key Martix ),可以看到键盘中的芯片(这里不是i8048,是一个兼容的其他型号的芯片)。

     

     

      

    注意,i8042 并不一定在主板上单独出现,可能被整合在某一芯片中。

    1.2 扫描码 ,Make Code ,Break Code ,Typematic

        当键盘上有键被按下,松开,按住,键盘将产生扫描码( Scan Code ),这些扫描码将被  i8048 直接得到。扫描码有两种,Make Code 和 Break Code。当一个键被按下或按住时产生的是 Make Code ,当一个键被松开产生的是 Break Code。每个键被分配了唯一的 Make Code 和 Break Code ,这样主机通过扫描码就可以知道是哪一个键。简单的说就是按下键,产生一个 Make Code。松开键,产生一个 Break Code。

        而对于按住不放的情况呢。我们可以打开一个记事本,把 $1$a$1$ 键按住不放,可以看到会不停的产生 $1$a$1$ 直到我们松开。这是由于,当按住一个键不放时,将会 Typematic ,也就是自动打。每隔一定时间,自动产生一个被按住的键的 Make Code,直到最后松开该键。对于 Typematic 有两个重要的参数,一个是 Typematic Delay ,决定了按下多长时间之后,进入 Typematic,另一个是 Typematic Rate,决定了在进入 Typematic 之后,一秒钟内能产生多少个 Make Code 。现在我们再打开记事本,按住 $1$a$1$ 不放,仔细观察,将看到第一个 $1$a$1$ 和第二个  $1$a$1$ 之间间隔的时间明显比其他的要长,而之后每个$1$a$1$之间的时间间隔是一样的。

        而对于同时按下多个键的情况呢。在一个键被按下,产生了 Make Code,而没有被松开,没有产生  Break Code 的时候,再按下另一个键,于是产生了另一个键的 Make Code ,就算是这两个键被同时按下。之后,这两个键松开时,各自产生各自的 Break Code。更多的键的情况也是一样。比如要按 Ctrl 和 A,下面的情况就算作是同时按下了 Ctrl 和  A。按Ctrl,产生 Ctrl 的 Make Code,然后按A,产生  A 的 Make Code,然后各自松开,各自产生各自的 Break Code。

        而对于按一个键不放的时候,再按另一个键的情况呢。我们可以打开一个记事本,把$1$a$1$键按住不放,不要松开,然后再按$1$s $1$键不放。我们可以看到当按下$1$s$1$时,$1$a$1$键并没有松,但是并没有$1$a$1$再出现了,而是$1$s$1$开始出现,这时即使松开了$1$s$1$,$1$a$1$也不会继续出现了。


    1.3 扫描码集

        到目前为止一共有三套扫描码集( Scan Code Set ),ps/2 键盘默认使用第二套。不过可以设置 i8042,让 i8042 把得到的 Scan Code 翻译成 Scan Code Set 1 中的 Scan Code ,这样键盘驱动从 i8042 得到的所有 Scan Code 都是第一套中的 Scan Code(实际中驱动也是这么做的)。所以我们只讨论 Scan Code Set 1 。需要说明的是 Scan Code 和 ASCII码完全不相同。

        在 Scan Code Set 1 中,大多数键的 Make Code,Break Code 都是一个字节。他们的 Make Code 的最高位都为0,也就是他们的 Make Code 都小于 0x7F。而他们的  Break Code 为其 Make Code 或运算 80h ,也就是把 Make Code 的低7位不变,最高位设置为1。

        还有一些扩展按键,他们的 Scan Code 是双字节的。他们的第一个字节都是E0h,表明这是一个扩展键。第2个字节,和单字节 Scan Code 的情况相同。

        还有一个特殊的键,Pause/Break 键,它的 Make Code 为 E1,1D,45 E1,9D,C5,注意是 E1h 开头。而且它没有 Break Code 。

    我们按键的 Make Code 的值的大小,列出 Scan Code Set 1 中的所有扫描码

    KEY MAKE BREAK

    ESC 01 81
    1 02 82
    2 03 83
    3 04 84
    4 05 85
    5 06 86
    6 07 87
    7 08 88
    8 09 89
    9 0A 8A
    0 0B 8B
    - 0C 8C
    = 0D 8D
    BKSP 0E 8E

    TAB 0F 8F
    Q 10 19
    W 11 91
    E 12 92
    R 13 93
    T 14 94
    Y 15 95
    U 16 96
    I 17 97
    O 18 98
    P 19 99
    [ 1A 9A
    ] 1B 9B
    ENTER 1C 9C

    L_CTRL 1D 9D
    A 1E 9E
    S 1F 9F
    D 20 A0
    F 21 A1
    G 22 A2
    H 23 A3
    J 24 A4
    K 25 A5
    L 26 A6
    ; 27 A7
    $1$ 28 A8

    ` 29 89
    L_SHFT 2A AA
    \ 2B AB
    Z 2C AC
    X 2D AD
    C 2E AE
    V 2F AF
    B 30 B0
    N 31 B1
    M 32 B2
    , 33 B3
    . 34 B4
    / 35 B5
    R_SHFT 36 B6

    KP * 37 B7
    L_ALT 38 B8
    SPACE 39 B9
    CAPS 3A BA

    F1 3B BB
    F2 3C BC
    F3 3D BD
    F4 3E BE
    F5 3F BF
    F6 40 C0
    F7 41 C1
    F8 42 C2
    F9 43 C3
    F10 44 C4

    NUM 45 C5
    SCROLL 46 C6

    KP 7 47 C7
    KP 8 48 C8
    KP 9 49 C9
    KP - 4A CA

    KP 4 4B CB
    KP 5 4C CC
    KP 6 4D CD
    KP + 4E CE

    KP 1 4F CF
    KP 2 50 D0
    KP 3 51 D1

    KP 0 52 D2
    KP . 53 D3

    F11 57 D7
    F12 58 D8

    KP EN E0,1C E0,9C
    R_CTRL E0,1D E0,9D

    KP / E0,35 E0,B5
    R_ALT E0,38 E0,B8

    HOME E0,47 E0,C7
    UP ARROW E0,48 E0,C8
    PG UP E0,49 E0,C9

    L ARROW E0,4B E0,CB
    R ARROW E0,4D E0,CD

    END E0,4F E0,CF
    D ARROW E0,50 E0,D0
    PG DN E0,51 E0,D1
    INSERT E0,52 E0,D2
    DELETE E0,53 E0,D3

    L GUI E0,5B E0,DB
    R GUI E0,5C E0,DC
    APPS E0,5D E0,DD

    PRNT SCRN E0,2A, E0,37 E0,B7, E0,AA

    PAUSE E1,1D,45 E1,9D,C5 -NONE

    这里说几句对驱动没有帮助的题外话,记不清是由于先有了关于 Scan Code 的值的猜测,才去按这个顺序列 Scan Code ,还是先这样列 Scan Code ,才有了关于  Scan Code 的值的猜测。总之,用这个 Make Code 的顺序,和我们现在键盘上键的布局做对照,我们大致就能猜到为什么 A 键的 Make Code 值为 0x1e,为什么 H 键的 Make Code 值为 0x23。我们拿其中的一小段举例子,A 1E,S 1F,D 20,F 21,G 22,H 23,看看键盘上 A,S,D,F,G,H 的位置吧。能感觉到些什么吧,感觉不到就算了,这个和驱动是无关的。从 Scan Code Set 1,可能还能推测出来最早的键盘的样子。以及发生在键盘上的一些变化。我们注意到 F10 和 F11,F12 的 Make Code 不是连在一起的,估计比较早的键盘只有10个功能键,而不是现在的12个功能键。从键的 Make Code 来看,有可能曾经使用的一些键,现在已经不出现在键盘上了。

    还有一个值得注意的是,如果有 Make Code 为 0x60 的键,那么它的 Break Code 应该为 0x60+0x80=0xE0。那么这个键的 Break Code 将会和 表示扩展码的 0xE0 搞混。不过还好,并没有 Make Code 为 0x60 的键,所以不会发生搞混的情况。

    1.4 i8042 键盘控制器

        键盘驱动直接读写 i8042 芯片,通过 i8042 间接的向键盘中的 i8048 发命令。所以对于驱动来说,直接发生联系的只有 i8042 ,因此我们只介绍 i8042 ,不介绍 i8048。

        象 i8042,i8048 这样的芯片,本身就是一个小的处理器,它的内部有自己的处理器,有自己的 Ram,有自己的寄存器,等等。

        i8042 有 4 个 8 bits 的寄存器,他们是 Status Register(状态寄存器),Output Buffer(输出缓冲器), Input Buffer(输入缓冲器),Control Register(控制寄存器)。使用两个 IO 端口,60h 和 64h。


    Status Register(状态寄存器)

    状态寄存器是一个8位只读寄存器,任何时刻均可被cpu读取。其各位定义如下

    Bit7: PARITY-EVEN(P_E): 从键盘获得的数据奇偶校验错误
    Bit6: RCV-TMOUT(R_T): 接收超时,置1
    Bit5: TRANS_TMOUT(T_T): 发送超时,置1
    Bit4: KYBD_INH(K_I): 为1,键盘没有被禁止。为0,键盘被禁止。
    Bit3: CMD_DATA(C_D): 为1,输入缓冲器中的内容为命令,为0,输入缓冲器中的内容为数据。
    Bit2: SYS_FLAG(S_F): 系统标志,加电启动置0,自检通过后置1
    Bit1: INPUT_BUF_FULL(I_B_F): 输入缓冲器满置1,i8042 取走后置0
    BitO: OUT_BUF_FULL(O_B_F): 输出缓冲器满置1,CPU读取后置0


    Output Buffer(输出缓冲器)

    输出缓冲器是一个8位只读寄存器。驱动从这个寄存器中读取数据。这些数据包括,扫描码,发往 i8042 命令的响应,间接的发往 i8048 命令的响应。


    Input Buffer(输入缓冲器)

    输入缓冲器是一个8位只写寄存器。缓冲驱动发来的内容。这些内容包括,发往 i8042 的命令,通过 i8042 间接发往 i8048 的命令,以及作为命令参数的数据。


    Control Register(控制寄存器)

    也被称作 Controller Command Byte (控制器命令字节)。其各位定义如下

    Bit7: 保留,应该为0
    Bit6: 将第二套扫描码翻译为第一套
    Bit5: 置1,禁止鼠标
    Bit4: 置1,禁止键盘
    Bit3: 置1,忽略状态寄存器中的 Bit4
    Bit2: 设置状态寄存器中的 Bit2
    Bit1: 置1,enable 鼠标中断
    BitO: 置1,enable 键盘中断

    2个端口 0x60,0x64

    驱动中把 0x60 叫数据端口
    驱动中把 0x64 叫命令端口

    1.5 命令

    驱动可以直接给 i8042 发命令,可以通过 i8042 间接给 i8048 发命令。命令这部分内容直接来自 < 参考资料 [1] >。


    1.5.1 发给i8042的命令

    驱动对键盘控制器发送命令是通过写端口64h实现的,共有12条命令,分别为

    20h
    准备读取8042芯片的Command Byte;其行为是将当前8042 Command Byte的内容放置于Output Register中,下一个从60H端口的读操作将会将其读取出来。

    60h
    准备写入8042芯片的Command Byte;下一个通过60h写入的字节将会被放入Command Byte。

    A4h
    测试一下键盘密码是否被设置;测试结果放置在Output Register,然后可以通过60h读取出来。测试结果可以有两种值:FAh=密码被设置;F1h=没有密码。

    A5h
    设置键盘密码。其结果被按照顺序通过60h端口一个一个被放置在Input Register中。密码的最后是一个空字节(内容为0)。

    A6h
    让密码生效。在发布这个命令之前,必须首先使用A5h命令设置密码。

    AAh
    自检。诊断结果放置在Output Register中,可以通过60h读取。55h=OK。

    ADh
    禁止键盘接口。Command Byte的bit-4被设置。当此命令被发布后,Keyboard将被禁止发送数据到Output Register。

    AEh
    打开键盘接口。Command Byte的bit-4被清除。当此命令被发布后,Keyboard将被允许发送数据到Output Register。

    C0h
    准备读取Input Port。Input Port的内容被放置于Output Register中,随后可以通过60h端口读取。

    D0h
    准备读取Outport端口。结果被放在Output Register中,随后通过60h端口读取出来。

    D1h
    准备写Output端口。随后通过60h端口写入的字节,会被放置在Output Port中。


    D2h
    准备写数据到Output Register中。随后通过60h写入到Input Register的字节会被放入到Output Register中,此功能被用来模拟来自于Keyboard发送的数据。如果中断被允许,则会触发一个中断。


    1.5.2 发给8048的命令

    共有10条命令,分别为

    EDh
    设置LED。Keyboard收到此命令后,一个LED设置会话开始。Keyboard首先回复一个ACK(FAh),然后等待从60h端口写入的LED设置字节,如果等到一个,则再次回复一个ACK,然后根据此字节设置LED。然后接着等待。。。直到等到一个非LED设置字节(高位被设置),此时LED设置会话结束。

    EEh
    诊断Echo。此命令纯粹为了检测Keyboard是否正常,如果正常,当Keyboard收到此命令后,将会回复一个EEh字节。

    F0h
    选择Scan code set。Keyboard系统共可能有3个Scan code set。当Keyboard收到此命令后,将回复一个ACK,然后等待一个来自于60h端口的Scan code set代码。系统必须在此命令之后发送给Keyboard一个Scan code set代码。当Keyboard收到此代码后,将再次回复一个ACK,然后将Scan code set设置为收到的Scan code set代码所要求的。

    F2h
    读取Keyboard ID。由于8042芯片后不仅仅能够接Keyboard。此命令是为了读取8042后所接的设备ID。设备ID为2个字节,Keyboard ID为83ABh。当键盘收到此命令后,会首先回复一个ACK,然后,将2字节的 Keyboard ID一个一个回复回去。

    F3h
    设置Typematic Rate/Delay。当Keyboard收到此命令后,将回复一个ACK。然后等待来自于60h的设置字节。一旦收到,将回复一个ACK,然后将Keyboard Rate/Delay设置为相应的值。

    F4h
    清理键盘的Output Buffer。一旦Keyboard收到此命令,将会将Output buffer清空,然后回复一个ACK。然后继续接受Keyboard的击键。

    F5h
    设置默认状态(w/Disable)。一旦Keyboard收到此命令,将会将Keyboard完全初始化成默认状态。之前所有对它的设置都将失效——Output buffer被清空,Typematic Rate/Delay被设置成默认值。然后回复一个 ACK,接着等待下一个命令。需要注意的是,这个命令被执行后,键盘的击键接受是禁止的。如果想让键盘接受击键输入,必须Enable Keyboard。

    F6h
    设置默认状态。和F5命令唯一不同的是,当此命令被执行之后,键盘的击键接收是允许的。

    FEh
    Resend。如果Keyboard收到此命令,则必须将刚才发送到8042 Output Register 中的数据重新发送一遍。当系统检测到一个来自于Keyboard的错误之后,可以使用自命令让Keyboard重新发送刚才发送的字节。

    FFh
    Reset Keyboard。如果Keyboard收到此命令,则首先回复一个ACK,然后启动自身的Reset程序,并进行自身基本正确性检测(BAT-Basic Assurance Test)。等这一切结束之后,将返回给系统一个单字节的结束码(AAh=Success, FCh=Failed),并将键盘的Scan code set 设置为2。


    1.5.3 读到的数据


    00h/FFh
    当击键或释放键时检测到错误时,则在Output Bufer后放入此字节,如果Output Buffer已满,则会将Output Buffer的最后一个字节替代为此字节。使用Scan code set 1时使用00h,Scan code 2和Scan Code 3使用FFh。

    AAh
    BAT完成代码。如果键盘检测成功,则会将此字节发送到8042 Output Register中。

    EEh
    Echo响应。Keyboard使用EEh响应从60h发来的Echo请求。

    F0h
    在Scan code set 2和Scan code set 3中,被用作Break Code的前缀。

    FAh
    ACK。当Keyboard任何时候收到一个来自于60h端口的合法命令或合法数据之后,都回复一个FAh。

    FCh
    BAT失败代码。如果键盘检测失败,则会将此字节发送到8042 Output Register中。

    FEh
    Resend。当Keyboard任何时候收到一个来自于60h端口的非法命令或非法数据之后,或者数据的奇偶交验错误,都回复一个FEh,要求系统重新发送相关命令或数据。

    83ABh
    当键盘收到一个来自于60h的F2h命令之后,会依次回复83h,ABh。83AB是键盘的ID。

    Scan code
    除了上述那些特殊字节以外,剩下的都是Scan code。


    1.6 端口操作

        首先介绍一下端口的读写操作,驱动中使用函数 READ_PORT_UCHAR 进行读操作, READ_PORT_UCHAR 中使用CPU读端口指令,in。驱动中使用函数 WRITE_PORT_UCHAR 进行写操作, WRITE_PORT_UCHAR 中使用CPU写端口指令,out。

    1.6.1 读取状态寄存器

    读取状态寄存器的方法,对64h端口进行读操作。

    1.6.2 读数据

    需要读取的数据有,i8042从i8048得到的按键的扫描码,i8042命令的ACK,i8042从i8048得到的i8048命令的ACK,需要命令重发的RESEND,一些需要返回结果的命令得到的结果。

    当有数据需要被驱动读走的时候,数据被放入输出缓冲器,同时将状态寄存器的bit0(OUTPUT_BUFFER_FULL)置1,引发键盘中断(键盘中断的IRQ为1)。由于键盘中断,引起由键盘驱动提供的键盘中断服务例程被执行。在键盘中断服务例程中,驱动会从i8042读走数据。一旦数据读取完成,状态寄存器的bit0会被清0。

    读数据的方法,首先,读取状态寄存器,判断bit0,状态寄存器bit0为1,说明输出缓冲器中有数据。保证状态寄存器bit0为1,然后对60h端口进行读操作,读取数据。

    这里我们要谈一点很有用的题外话,前面提到的 IRQ,是 Interrupt Request line,中断请求线,是一个硬件线,它和中断向量是不同的。中断向量是用来在中断描述符表(IDT)中查找中断服务例程的那个序号。键盘的 IRQ 是1,键盘中断服务例程对应的中断向量可不是1。这点要弄清楚。

    1.6.3 向i8042发命令

    当命令被发往i8042的时候,命令被放入输入缓冲器,同时引起状态寄存器的 Bit1 置1,表示输入缓冲器满,同时引起状态寄存器的 Bit2 置1,表示写入输入缓冲器的是一个命令。

    向i8042发命令的方法,首先,读取状态寄存器,判断bit1,状态寄存器bit1为0,说明输入缓冲器为空,可以写入。保证状态寄存器bit1为0,然后对64h端口进行写操作,写入命令。


    1.6.4 间接向i8048发命令

    向i8042发这些命令,i8042会转发i8048,命令被放入输入缓冲器,同时引起状态寄存器的Bit1 置1,表示输入缓冲器满,同时引起状态寄存器的 Bit2 置1,表示写入输入缓冲器的是一个命令。这里我们要注意,向i8048发命令,是通过写60h端口,而后面发命令的参数,也是写60h端口。i8042如何判断输入缓冲器中的内容是命令还是参数呢,我们在后面发命令的参数中一起讨论。

    向i8048发命令的方法,首先,读取状态寄存器,判断bit1,状态寄存器bit1为0,说明输入缓冲器为空,可以写入。保证状态寄存器bit1为0,然后对60h端口进行写操作,写入命令。

    1.6.5 发命令的参数

    某些命令需要参数,我们在发送命令之后,发送它的参数,参数被放入输入缓冲器,同时引起状态寄存器的Bit1 置1,表示输入缓冲器满。这里我们要注意,向i8048发命令,是通过写60h端口,发命令的参数,也是写60h端口。i8042如何判断输入缓冲器中的内容是命令还是参数呢。i8042 是这样判断的,如果当前状态寄存器的Bit3 为1,表示之前已经写入了一个命令,那么现在通过写60h端口放入输入缓冲器中的内容,就被当做之前命令的参数,并且引起状态寄存器的 Bit3 置0。如果当前状态寄存器的 Bit3 为0,表示之前没有写入命令,那么现在通过写60h端口放入输入缓冲器中的内容,就被当做一个间接发往i8048的命令,并且引起状态寄存器的 Bit3 置1。

    向i8048发参数的方法,首先,读取状态寄存器,判断bit1,状态寄存器bit1为0,说明输入缓冲器为空,可以写入。保证状态寄存器bit1为0,然后对60h端口进行写操作,写入参数。

     

    "1ps/2 键盘的硬件" 主要参考下面的资料,关于 ps/2 键盘硬件更多的内容也请参考下面的资料

    [1] http://pagoda-ooos.51.net/os_book/driver/driver-keyboard_2.htm (中文)
    [2] http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/PS2.pdf (中文)
    [3] http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/ (英文)


    http://jiurl.yeah.net

    WINDOWS XP服务和进程优化详解

    1.Alerter
     Alerter(警示器)服务的进程名是Services.exe(即启动这个服务后在后台运行的进程的名称,可以通过任务管理器看到)。Alerter服务的功能是,WinXP将系统上发生的与管理有关的事件以警示(Alert)信息传送至网络上指定的电脑或用户,例如当发生打印错误或硬盘即将写满等事件,这类警示信息由XP的警示器服务(Alerter Service)收集、送出。
     尽管Alerter依存的服务并没有Messenger(信使)服务,但Alerter服务必须依赖后者才能送出信息,故在启动Alerter服务后还必须确定Messenger服务也是在工作中,而接收的电脑也必须启动Messenger服务。由于 Alerter服务运行后,服务使用户可以发送弹出(Pop-up)信息给其他用户,这些信息有可能被攻击者用来实施攻击,如诱骗用户修改口令等,从而造成安全隐患。同时该服务使得用户帐号名泄漏,也有可能被攻击者利用来进行口令猜测攻击。所以对于家庭单机用户,甚至对于绝大多数小型的局域网来说,这个功能是完全可禁用的,不仅节省了系统资源和加快启动速度,也提高了机器的安全性。
    2.Application Layer Gateway Service
     简称"ALG"(应用层网关),其进程名是alg.exe,WinXP Home/PRO默认安装的启动类型为手动。ALG又被称为代理服务器(Proxy Server),是网络防火墙从功能面上分类的一种。当内部计算机与外部主机连结时,将由代理服务器(Proxy Server)担任内部计算机与外部主机的连结中继者。使用ALG的好处是隐藏内部主机的地址和防止外部不正常的连接,如果代理服务器上未安装针对该应用程序设计的代理程序时,任何属于这个网络服务的封包将完全无法通过防火墙。通俗点说,具体到ALG本身,它就是WinXP附带的Internet连接共享 /防火墙的具体控管程序,如果你需要启用这二者,这个服务是必备的。当然,只有一台计算机的上网家庭可以考虑禁用这个服务,不过笔者个人觉得WinXP内置的防火墙效果还是不错的,如果不是坚持要使用第三方的防火墙,还是建议开着它吧。
    3.Application Management
     AppMgmt (应用程序管理服务)的进程名是Svchost.exe,WinXP Home/Pro默认安装的启动类型是手动,没有任何依存服务关系。从Win2000开始微软引入了一种基于MSI文件格式(应用程序安装信息程序包文件)的全新、有效软件管理方案——即应用程序管理组件服务(Application Management),它不仅管理软件的安装、删除,而且可使用此项服务修改、修复现有应用程序,监视文件复原并通过复原排除基本故障等。通常这个服务我们保持其默认状态较好。
     可能许多朋友都有印象,当年ACDSee 4.0刚发布时,由于安装制作上的考虑不周,并没有考虑到那个时候大多数人的系统还并不支持MSI安装格式,结果只得又去下载安装一个名为Windows Installer的MSI辅助文件才解决问题。通常以MSI文件格式安装的软件十分好认,比如说Office XP,当你安装后再次运行软件的安装程序时,它一般会有"重新安装"、"修复软件"、"卸载软件"等多个选项,而不是以前安装程序那种就简单的卸载或覆盖安装了事。
    4.Automatic Updates
     Wuauserv(自动更新服务)的进程名是 Svchost.exe,WinXP Home/Pro默认安装的启动类型为自动,没有任何依存服务关系。这个是大家都非常熟悉的系统自动更新功能,就不多说了。用小猫上网而深受其苦的朋友记得在系统属性中关闭是不够的,还要将Automatic Updates这个服务禁用才可以。以后需要更新的话,直接到在IE中键入Windows Update 网站地址手动更新即可。
    5.Background Intelligent Transfer Service
    BITS (后台智能传输服务)的进程名是Svchost.exe,WinXP Home/Pro默认安装的启动类型是手动,依赖于Remote Procedure Call、Workstation服务。微软宣称BITS能够利用剩余的带宽传输文件,当网络切断或计算机需重启时,后台智能传输服务会自动对文件传输加以维护,当网络重新连接时,后台智能传输服务将继续从停止的地方继续开始传输文件。其实这个服务原是用来实现HTTP 1.1服务器之间的信息传输,基本上它的应用也就是支持Windows自动更新时的断点续传。如果你禁用了Automatic Updates,留着它基本上也没有什么意义。
    6.ClipBook
     ClipSrv(剪贴板查看器服务)的进程名是clipsrv.exe,WinXP Home/Pro默认安装的启动类型是手动,依赖Network DDE服务。ClipBook通过Network DDE和Network DDE DSDM提供的网络动态数据交换服务,可查阅远程机器中的剪贴板,通俗的说就是ClipBook支持剪贴板查看器(ClipBook Viewer)程序,该程序可允许剪贴页被远程计算机上的ClipBook浏览。
     例如有个较大的文档工程,由A、B、C共同开发,A负责 Excel数据部分,B负责Visio制图部分,而C负责将两部分文档的整合。C经常需要对A、B的数据进行拷贝,愚蠢的做法是C打开A、B在网络邻居上共享的文档,然后将相关内容拷贝。而对Windows体系有一定了解的用户应该听说过OLE这个东西,上面说的EXCEL数据和Visio制图都可以认为是独立的OLE对象,如果A、B、C的3台机器上的Clipbook服务都为开启,就可利用ClipBook共享这些OLE对象,C只要在自己的文档中建立OLE对象的链接指向A、B的Excel和Visio,A、B对自己工作的任何改动即可在C的复合文档里自动体现。由此可见,ClipBook是基于对象的共享,而非简单的文件共享。所以也很好理解,这是一把双刃剑,在带来极大方便的同时,也带来被非法远程访问ClipBook剪贴页面的安全隐患。对于没有上述类似工作,又不准备使用或极少使用远程桌面的用户,这个服务完全可以禁用,在需要的时候再打开。
    7.COM+ Event System
     EventSystem (COM+事件系统服务)的进程名是Svchost.exe,WinXP Home/Pro默认安装的启动类型是手动,依赖Remote Procedure Call服务。对于非软件开发专业的朋友来说,COM+是个非常难理解的名词。简单的说COM+是一种软件构件/组件的标准。比如写一个软件好比是盖一座房子。而门窗等部件会根据标准设计,以求得省时省力,COM组件即是Windows的门窗等标准组件了,COM+是对COM的进一步扩展,其具体含义在此就不详细介绍了,Windows系统又是个典型的消息(事件)处理型系统,很多功能都是由消息来触发的,这就产生了COM+ Event System。我们要学习的是如何简单判断自己的系统中是否有程序依靠此服务。检查你的系统安装盘下的"Program files\ComPlus Applications "目录,如果没有东西就可以把这个服务关闭了。
    8.COM+ System Application
    COMSysApp (COM+系统应用服务)的进程名是Dllhost.exe,WinXP Home/Pro默认安装的启动类型是手动,依赖Remote Procedure Call服务。简单的说,COM+ System Application是COM+ Event System的具体执行者,如果禁用了COM+ Event System也就自然禁用它。
    9.Computer Browser
    Browser (计算机浏览器服务)的进程名是Svchost.exe,WinXP Home/Pro默认安装的启动类型是自动,依赖Server和Workstation服务。Browser服务维护着一个网络资源的清单,其中包括基于 Windows的域、工作组和计算机,还有其他支持NetBIOS协议的网络设备,我们在"网上邻居"上看到显示的内容正是来源于此。显然对于一般家庭用的计算机这个服务并不需要,除非计算机位于局域网之上,例如用长城宽带的朋友,用它可方便地知道社区内的网络环境。这个服务还是慎重对待较好,若不是太在意还是将其设置成自动吧。
    10.Cryptographic services
     CryptSvc (认证服务)的进程名是Svchost.exe,WinXP Home/Pro默认安装的启动类型为自动,依赖Remote Procedure Call服务。CryptSvc是整个微软公钥体系(PKI,Public Key Infrastructure)的核心元件。所谓的PK是一种公匙加密法,通过加密来保证数据的安全和传送,它与传统的秘密(对称)钥匙密码法不相同, PK密码法的基本特性是加密和解密的钥匙不同,每一个用户两把钥匙,一把公开密匙,一把私匙。撇开这些难以一下子理解的术语,具体到CryptSvc本身来说,如果我们在WinXP中使用Automatic Updates自动更新,或在Internet上使用证书进行身份验证以及正确管理这些证书等,那么这个服务就不要关闭。其中这个功能最有用的是,当你安装一个驱动程序时,以确定它是不是通过微软认证的。因为驱动程序在操作系统内可以获得很高的运行权限,含有恶意代码的驱动程序会让你玩完,因而开发驱动程序的厂家一般都会去做微软认证,通过验证后,微软会在里面添加它的认证数据,再到你机器上安装时就可以通过CryptSvc检测升级。


    11.DHCP Client
     Dhcp (DHCP客户端服务)的进程名是Svchost.exe,WinXP Home/Pro默认安装的启动类型为自动,依赖AFD Networking Support Environment、NetBIOS over TCP/IP以及TCP/IP Protocol Driver服务。简单的说DHCP过程就是由网络中一台主机(DHCP Server)将所有的网络参数自动分配给网络内的任何一台计算机,而DHCP Client就是网络中被分配网络参数的对象计算机了。如果能在网络中被自动分配IP地址等网络参数,那么这个DHCP Client服务就必不可少。对于家庭单机用户来说,只要是使用DSL/Cable上网、开启ICS和IPSEC服务的人都需要这个来指定静态IP,所以通常这个服务是不关闭的,除非你的机器是完全的单机应用环境。
    12.Distributed Link Tracking Client
    TrkWks (分布式连结追踪客户端服务)的进程名是Svchost.exe,WinXP Home/Pro默认安装的启动类型为自动,依赖Remote Procedure Call服务。对于计算机有一定了解的人对于"分布式"这个词并不陌生,这里就不作解释。TrkWks服务简单说,就是将整个网络中分散于各台计算机上互相有连接的NTFS文件看作一个整体,相当于一台机器上的文件系统,所以当系统内发生文件移动,就会记录这个信息。它是针对"域用户"的"NTFS文件" 的"分布式连接",这3个条件缺一个你就用不上它,对于不在局域网的单机用户来说,当然是禁用它。
    13.Distributed Transaction coordinator
    MSDTC (分布式交易协调器)的进程名是Msdtc.exe,WinXP Home/Pro默认安装的启动类型是手动,依赖Remote Procedure Call和Security Accounts Manager服务。MSDTC主要用来处理分布式交易,所谓分布式交易,就是跨越两个或多个数据库的单一SQL Server内部的交易。同一数据库内不同数据表间的交易,则不能称作分布式交易。显然对于需要同时处理多个数据库或文件系统的用户来说,这个服务意义重大,但它也是通常意义上一般用户不会使用到的服务,通常来默认手动启动就好了,其实这个服务也容易受到远程拒绝服务攻击,禁用它也没有问题,而且更安全。
    14.DNS Client
      Dnscache(DNS客户端服务)的进程名是Svchost.exe,WinXP Home/Pro默认安装的启动类型为自动,依赖TCP/IP Protocol Driver服务。DNS(Domain Name System)也是常见的名词了,简单的解释就是当使用网页浏览器去上网时,会键入网站的网址,而这些网址名称在因特网上就是透过网域名称服务器(DNS 服务器)来完成名称转换为IP地址的解释。实际上一些网站并不是只有一台服务器在工作,而是有多台服务器在同时工作,也就是说同样一个网站名称地址可对应不同的IP地址(在Win2000以前的操作系统可执行此查询)。但如果将操作系统换到Win2000或XP,同样的网站你又会发现总是查到同一个IP地址。为什么会这样呢?这就是DNS Client服务的作用。
     为了要达到用最快速、最有效率的方式,让客户端能够迅速找到网域的验证服务,在Win2000/XP系统中,加入了DNS快取(Cache)的功能,当第一次在找到了目的主机的IP地址后,操作系统就会将所查询到的名称及IP地址记录在本机的DNS快取缓冲区中,下次客户端还需要再查询时,就不需要到 DNS服务器上查询,而直接使用本机DNS Cache中的数据即可,所以你查询的结果始终是同一IP地址。这个服务关闭与否影响并不大,在安全性上最多只是可以泄漏你的缓存内容,确定你曾经访问过的网站。
    15.Error Reporting Service

    ERSvc(错误报告服务)的进程名是Svchost.exe,WinXP Home/Pro默认安装的启动类型为自动,依赖Remote Procedure Call服务。这个服务我们经常碰到,当使用程序出错时会跳出对话框,问你是否需要向微软发送报告,就是这个服务的功能。此服务完全可设置为手动或禁止。如果你想对错误报告进行更详细的设置,可以右键单击"我的电脑"图标,选择"属性",在"高级选项卡"下点击"错误报告"按钮,在那里你可以决定是否发送错误报告以及发送怎样的错误报告。而对于没有上网的用户就可直接禁用此服务了,上网用户如果担心报告会向微软透漏你的私人信息(当然微软保证不会发生这种事情),也大可禁用它。  
    16.Event Log
     Eventlog(系统日志纪录服务)的进程名是Services.exe,WinXP Home/Pro默认安装的启动类型为自动,没有服务依存关系。Event Log服务负责记录来自系统和运行中程序的管理事件消息,为Windows和应用程序提供了一个标准而集中的方法来记录重要的软件和硬件事件。打开事件查看器的方法是依次打开"开始→控制面板",然后选择打开"管理工具→事件查看器"。这个服务是基础服务,无法调整关闭。
    17.Fast User Switching Compatibility
     Fast User Switching Compatibility(多用户快速切换服务)的进程名是svchost.exe,WinXP Home/Pro默认安装的启动类型是手动,依赖Terminal Services服务。此服务是WinXP的新技术,即快速的多用户切换环境。解决了以前的多用户环境虽然安全但是切换用户环境需要重新启动,并丢失上一用户工作环境的问题。使用很简单,只要进行"开始→注销→切换用户"操作即可方便地切换用户环境,是非常不错的多用户技术,如果用不着多用户环境就不用打开它(加入域后默认不能进行快速切换,当然可禁用)。

    18.FAX Service
     FAX (传真服务)的进程名是Fxssvc.exe,WinXP Home/Pro中默认是没有安装的,依赖Plug and Play、Print Spooler、Remote Procedure Call、Telephony服务。FAX服务在默认情况下是没有安装的,但如果你安装了它就可以进行"开始→所有程序→附件→通讯→传真"操作,使用 WinXP内置的传真服务来收发传真了,当然你要保证你的机器至少还保留了一只小猫。不需要的人就禁用吧。
    19.Help and Support
     Helpsvc (帮助服务)的进程名是Svchost.exe,WinXP Home/Pro中默认安装的启动类型为自动,依赖Remote Procedure Call服务。这个服务用于支持WinXP帮助和支持中心的功能,如果你刚开始使用WinXP,这个帮助中心能解决不少问题,如果你觉得不需要它了,那就禁用吧。
    20.Human Interface Device Access
     HidServ (人性化接口装置服务)的进程名是Svchost.exe,WinXP Home/Pro中默认安装的启动类型是禁用,依赖Remote Procedure Call服务。这个服务简单说就是支持那些所谓的带有多媒体功能智能键盘,比如音量调节。当然你有符合人体工程学标准的设备(主要指键盘和鼠标),那么这个服务就设置为自动,否则这些设备的一些功能将不能正常使用。而如果你没有这类设备或者你的设备有自己的驱动,即可禁用此服务。
    21.IMAPI CD-Burning COM Service
    ImapiService (IMAPI CD刻录服务)的进程名是Imapi.exe,WinXP Home/Pro中默认安装的启动类型是手动,没有任何的服务依存关系。这个就是WinXP内置的CD刻录服务了,杂志2003年第12期对此有过较详细的介绍。总的来说该服务的功能和性能十分有限,有刻录机的朋友还是安装成熟的第三方刻录软件,关闭这个服务吧。
    22.Indexing Service
     Cisvc (索引服务)的进程名是Cisvc.exe,WinXP Home/Pro中默认安装的启动类型是手动,依赖Remote Procedure Call服务。这个服务可为本地和远程计算机上的文件编制索引,也就是说像图书馆里为图书编制的查询索引一样,这样可加快寻找文件的速度。开启此项服务对个人用户而言有一个很大的帮助,就是文件浏览速度(即双击某文件夹后的等待时间)会明显增加,因为系统已将目录结构读入了内存,需要时会直接调用。但此服务启用后某此情况会导致系统极度繁忙,通过任务管理器,可看见Cidaemon.exe这个进程占用了大部分CPU资源。因此对待这个不成熟的服务请根据自己机器的情况设为"自动"或"禁用"。
    23.Internet Connection Firewall/Internet Connection Sharing
     SharedAccess (Internet连接共享和防火墙服务)的进程名是Svchost.exe,WinXP Home/Pro中默认安装的启动类型分别是手动和自动,依赖Application Layer Gateway Service、Network Connections、Network Location Awareness、Remote Access Connection Manager服务。这个服务提供WinXP内置的Internet连接共享和防火墙功能。笔者比较喜欢这两个功能,性能都不错而且方便,具体关闭与否看个人喜好,不用就可以关闭它。
    24.IPSEC Services
     PolicyAgent (IP安全策略服务)的进程名是Lsass.exe,WinXP Home/Pro中默认安装的启动类型为自动,依赖IPSEC driver、Remote Procedure Call、TCP/IP Protocol Driver服务。IPSEC是一种用来保护内部网、专用网络以及外部网(Internet、Extranet)免遭攻击的重要防御方法,主要特征在于它可对所有IP级的通信进行加密和认证,正是这一点才使IPSEC可以确保包括远程登录、客户/服务器、电子邮件、文件传输及Web访问在内的多种应用程序的安全。由于企业及政府用户非常注重于部署安全的IP,所以这一服务显得很重要。同时也可以看到,对于绝大多数用户来说,这是个根本就不用关心的东西。所以禁用它吧。
    25.Logical Disk Manager
      Dmserver(逻辑磁盘管理员服务)的进程名是Svchost.exe,WinXP Home/Pro中默认安装的启动类型分别是手动和自动,依赖Plug and Play、Remote Procedure Call服务。Dmserver用来动态管理磁盘,如显示磁盘可用空间和使用Microsoft Management Console(MMC)主控台中的磁盘管理功能。这个服务对于经常使用移动硬盘、U盘等外设的朋友来说必不可少,没有的话可选择禁用它。


    26.Logical Disk Manager Administrative Service
    Dmadmin (逻辑磁盘管理系统管理服务)的进程名是Svchost.exe,WinXP Home/Pro中默认安装的启动类型分别是手动和自动,依赖Logical Disk Manager、Plug and Play、Remote Procedure Call服务。Dmadmin主要用来配置硬盘信息,平时基本上没用。打开"计算机管理"(Microsoft Management Console,简称MMC)时,你可以看到"磁盘管理",这时就会用上它,可设为手动。

    -------------------

    【掸子增补】

    [mdm.exe]

    进程文件: mdm or mdm.exe

    进程名称: Machine Debug Manager

    描 述: Debug除错管理用于调试应用程序和Microsoft Office中的Microsoft Script Editor脚本编辑器。

    介绍:Mdm.exe的主要工作是针对应用软件进行排错(Debug),说到这里,扯点题外话,如果你在系统见到fff开头的0字节文件,它们就是 mdm.exe在排错过程中产生一些暂存文件,这些文件在操作系统进行关机时没有自动被清除,所以这些fff开头的怪文件里是一些后缀名为CHK的文件都是没有用的文件,只要系统中有Mdm.exe存在,就有可能产生以fff开头的怪文件。可以按下面的方法让系统停止运行Mdm.exe来彻底删除以fff 开头的怪文件:首先按"Ctrl+Alt+Del"组合键,在弹出的"关闭程序"窗口中选中"Mdm",按"结束任务"按钮来停止Mdm.exe在后台的运行,接着把Mdm.exe(在C:\Windows\System目录下)改名为Mdm.bak。运行msconfig程序,在启动页中取消对 "Machine Debug Manager"的选择。这样可以不让Mdm.exe自启动,然后点击"确定"按钮,结束msconfig程序,并重新启动电脑。另外,如果你使用IE 5.X以上版本浏览器,建议禁用脚本调用(点击"工具→Internet选项→高级→禁用脚本调用"),这样就可以避免以fff开头的怪文件再次产生。

    OFF:如何关闭计算机调试管理器 Mdm.exe

    found.000文件夹的问题
    问:我的电脑有的时候在C盘或D盘的根目录下有个名为found.000的文件夹,里面有一些后缀名为CHK的文件。在c:\windows下有很多以fff开头的怪文件,而且大小全部为0字节。请问这些是什么文件?能否将它们删除?

    答: found.000文件夹里面的一些后缀名为CHK的文件是你在使用"磁盘碎片整理程序"整理硬盘后所产生的"丢失簇的恢复文件"。在c:\ windows下有很多以fff开头的文件是由Mdm.exe(Machine Debug Manager)这个程序产生的。Mdm.exe的主要工作是针对应用软件进行排错(Debug),在排错过程中会产生一些暂存文件,这些文件在操作系统进行关机时没有自动被清除,所以这些fff开头的怪文件和found.000文件夹里面的一些后缀名为CHK的文件都是没有用的:s33文件,可以任意删除而不会对系统产生不良影响。

    但只要系统中有Mdm.exe存在,那么以fff开头的怪文件就又有可能产生。你可以按下面的方法让系统停止运行Mdm.exe来彻底删除以fff开头的怪文件:首先按"Ctrl+Alt+Del"组合键,在弹出的"关闭程序"窗口中选中"Mdm",按" 结束任务"按钮来停止Mdm.exe在后台的运行,接着把Mdm.exe(在C:\Windows\System目录下)改名为Mdm.bak。运行 msconfig程序,在启动页中取消对"Machine Debug Manager"的选择。这样可以不让Mdm.exe自启动,然后点击"确定"按钮,结束msconfig程序,并重新启动电脑。另外,如果你使用IE 5.X,建议禁用脚本调用(点击"工具→Internet选项→高级→禁用脚本调用"),这样就可以避免以fff开头的怪文件再次产生。

    -----------------

    27.Messenger
     Messenger (信使服务)的进程名是Services.exe,WinXP Home/Pro中默认安装的启动类型为自动,依赖NetBIOS Interface、Plug and Play、Remote Procedure Call、Workstation服务。Messenger这个服务上过网的人都应该比较熟悉,本来Microsoft开发"信使服务"是为了方便同一域中的管理员进行信息交流,后来有些人开发了突破域限制的信使发送工具,于是大家挂在网上时,计算机上经常会弹出一个名为"信使服务"的对话框,这些不请自到的"信使"基本上是一些垃圾信使信息,有无聊的广告,有非法的信息等。通常这些信息是用一些名为"凶宝宝信使"、"妖刺"的软件发布的,但实际上如果是在同一域中,只需要用NET SEND命令就可以轻易发送消息了。突然出现的"信使服务"不仅会干扰工作,影响心情,而且还容易遭到"社会工程"攻击,所以禁用它吧。
    28.MS Software Shadow Copy Provider
      SwPrv(管理磁盘区卷影复制服务)的进程名是dllhost.exe,WinXP Home/Pro中默认安装的启动类型是手动,依赖Remote Procedure Call服务。这个服务是为WinXP中的MS Backup备份程序提供支持,奇怪的是即使关掉它我的备份工作也可以顺利完成,用不着的话就禁用它吧。
    29.Net Logon
    Netlogon (网域登录服务)的进程名是lsass.exe,WinXP Home/Pro中默认安装的启动类型分别是手动和自动,依赖Workstation服务。这个服务是用来做网域审查的。当你的计算机处在一个域网内时,如果要使用网内的域服务器登录到域网时,就要通过它来登录了。一般用户用不着,禁用即可。
    30.NetMeeting Remote Desktop Sharing
     Mnmsrvc (NetMeeting远程桌面共享服务)的进程名是Mnmsrvc.exe,WinXP Home/Pro中默认安装的启动类型是手动,依赖Remote Procedure Call服务。使用NetMeeting可透过公司内部网络,让使用者将计算机的控制权分享给局域网上或因特网上的其他使用者,很多人都因为安全问题关掉它,而且它很占网络资源。但如果你想和别人做些非文字的交流,还是比较好玩的。注意关掉它后,远程桌面共享功能将无法使用。
    31.Network Connections
    Netman (网络连接服务)的进程名是svchost.exe,WinXP Home/PRO默认安装的启动类型是手动,依赖于Remote Procedure Call服务。Netman也是非常重要的基础服务,它管理着"网络和拨号连接"文件夹中的所有对象,任何有关于网络上(局域网、Internet)的连接都需要这个服务。如果被禁用,在"网络和拨号连接"文件夹中将什么都看不到,更不用说新建连接和拨号上网了。因此除非你的机器是绝对的单机环境,才可将其关闭。
    32.Network DDE
     NetDDE(网络动态数据交换服务)的进程名是 netdde.exe,WinXP Home/PRO默认安装的启动类型是手动,依赖于Network DDE DSDM服务。NetDDE(Network Dynamic Data Exchange)是微软早期设计的一种方法,可让应用程序在不同PC上的Windows之间交换动态数据,现在已经很少使用。实际上在WinXP中,真正使用它的只有ClipBook服务,回顾上一期中提到的3人共同开发文档,通过ClipBook来交换动态数据的例子就可以很好理解这个服务的作用了。数据共享服务通常是经过可信赖的沟通渠道,负责管理这项服务的是网络DDE代理(Network DDE Agent),实际上网络DDE代理会使机器非常容易遭受攻击而失去本机的管理员控制权。因此如果无需ClipBook共享这个特殊服务,不妨禁用。 33.Network DDE DSDM
      NetDDE dsdm(网络动态数据交换网络共享服务)的进程名是netdde.exe,WinXP Home/PRO默认安装的启动类型是手动,它不依赖于其他服务。如果此服务终止,Network DDE服务将不可用,实际上如果不用Network DDE,那么Network DDE DSDM也禁用好了。
    34.Network Location Awareness
     NLA (网络位置识别服务)的进程名是svchost.exe,WinXP Home/PRO默认安装的启动类型是手动,依赖于AFD网络支持环境和TCP/IP Protocol Driver服务,而ICF/ICS服务依赖于它。NLA可以探测网络系统的相关信息,当这些信息发生变化时通知相关的应用程序。基本上,这个服务主要针对的对象是笔记本电脑。因为在实际工作和生活中,人们的笔记本电脑常常在超过一个以上的网络环境中应用。经常可能遇到在一个网络中需要使用动态IP地址,而在另一网络中需要使用静态IP地址的问题。比如说你在办公室里使用的是动态IP,而在家里却使用静态IP来连接宽带,那么NLA就可让你在家里及单位网络(有线)之间切换时自动辨认出不同网络环境,从而自动选择合适的配置而无需重新调整网络参数。对于经常移动办公的人,这确实是个不错的功能。
    35.NT LM Security Support Provider
     NtLmSsp (NT LM安全性支持提供者服务)的进程名是lsass.exe,WinXP Home/PRO默认安装的启动类型是手动,它不依赖于其他服务。NT LM的意思即NT LanManger,是NT下提供的认证方法之一,使用了64位的加密手段。NtLmSsp这个服务主要针对RPC(远程过程调用),通常RPC可以选择基于两种通信方式,一种是传输协议,比如TCP/IP、UDP、IPX等,另一种为命名管道(Pipeline)。通常情况下Windows默认选择都是传输协议,而由于RPC是采用非加密传输的,通信数据安全无法得到保证,而NtLmSsp就可向这一类RPC提供安全服务。WinXP中已知的这类RPC 应用就是Telnet服务(Telnet也依赖于NtLmSsp),因此无需Telnet服务的单机用户可将NtLmSsp其关闭。
    36.Performance Logs and Alerts
     SysmonLog (效能记录日志及警示服务)的进程名是smlogsvc.exe,WinXP Home/PRO默认安装的启动类型是手动,它没有任何服务依存关系。如果打开控制面板的管理工具,可以看到有"性能"这个工具,它较详细地反映了系统的性能,但配置起来相当复杂,不好上手,而且大多数人也会认为这个性能工具没什么意义。
     SysmonLog就是为它提供日志记录的服务。如果你对自己机器的工作状态比较在意,这绝对是一个值得研究的工具,因为它可以严格监视硬盘、内存、CPU甚至于软件在系统中的运行,并通过记录下的日志数据分析机器软硬件资源的具体情况。更有用的是,如果你比较了解计数器这个参数的设置,就可为各部分资源设置合适的计数器值,一旦服务监视到资源的性能值超过或是低于此值,就会通过Messenger服务发出警告,如此很容易就能觉察到机器的某部分资源不足(如若升级电脑就可先从这里考虑)或发生了故障等。当然,并不关心自己机器具体工作的用户也可将其关闭。  
    37.Plug and Play
      PlugPlay(即插即用服务)的进程名是services.exe,WinXP Home/PRO默认安装的启动类型是自动,它不依赖于任何服务。这个服务想必大家相当熟悉,从Win98开始这个技术就始终是微软操作系统的核心部分。即插即用是Intel开发的一组规范,它赋予了计算机自动检测和配置设备并安装相应驱动程序的能力,当有设备被更改时能自动通知当前设备的状况并使用该设备变更后的程序。PlugPlay是WinXP的几个基础服务之一,在服务管理工具中无法调整它,而且如果本服务一旦失败就只有重新启动机器了。
    38.Portable Media Serial Number Service
      WmdmPmSp(便携的媒体序号服务)的进程名是svchost.exe,WinXP Home/PRO默认安装的启动类型是自动,它没有任何服务依存关系。这个服务其实非常简单,它是微软用来防盗版的工具之一,但目前基本上只是针对音乐。微软用它获得你系统中媒体播放器的序列号,做什么用呢?其实它是在试图控制你将盗版的音乐文件拷贝到类似MP3、MD等便携播放器上。尽管微软声称关掉这个服务会影响将正版音乐下载到便携播放器,但笔者还是关掉这个服务,一是影响并不大,至少手上的正版CD拷贝到MP3是没有问题的,二是微软也刺探得太多了吧,我们用什么还都得报告它?
    39.Print Spooler
     Spooler(打印后台处理服务)的进程名是spoolsv.exe,WinXP Home/PRO默认安装的启动类型是自动,依赖于Remote Procedure Call。Spooler是为了提高文件打印效率,将多个请求打印的文档统一进行保存和管理,先将要打印的文件拷贝到内存,待打印机空闲后,再将数据送往打印机处理。这样处理速度更快些。建议将其设置为手动,有打印任务时再打开。如果没有打印机自然是禁用了。
    40.Protected Storage
     ProtectedStorage (受保护存放区服务)的进程名是lsass.exe,WinXP Home/PRO默认安装的启动类型是自动,依赖于Remote Procedure Call。这一服务提供对敏感性数据保护的功能,比如密码、证书等,但通常它只针对Windows自身的敏感数据进行保护,可用来储存你计算机上的密码。通常上网的用户都比较喜欢开这个服务,毕竟像自动填表这些功能给人带来不少方便。但如果你的电脑是多用户环境,或是使用笔记本电脑,经常移动办公,那么这个服务就要谨慎使用了。有不少密码破解软件就是针对这个ProtectedStorage的,比较有名的有Protected Storage PassView,用它可以轻易得到被储存在ProtectedStorage中你曾经上过的论坛的帐号密码、拨号密码等。因此,对于这个服务要视使用环境而定,在不安全的环境下还是关闭较好。
    备此功能,不然可关闭。
    41.QoS RSVP
     RSVP(QoS 许可控制服务)的进程名是rsvp.exe,WinXP Home/PRO默认安装的启动类型是手动,依赖于AFD Networking Support Environment、Remote Procedure Call、TCP/IP Protocol Driver服务。这就是微软那个饱受争议的占用了20%网络带宽的服务了。对大多数朋友来说,关掉它是简单正确的选择。但是要理解这个服务究竟是干什么的就不这么简单了。QoS这个词的意思是服务质量(Quality of Service),而RSVP这个词的意思是资源预留协议(ReSerVation Protocol)。
     随着IP技术和网络的发展,世界各国的运营商基于IP网络已开发出多种多样的新业务。由于目前基于存储转发机制的Internet(IPv4标准)只为用户提供了"尽力而为(best- effort)"的服务,不能保证数据包传输的实时性、完整性以及到达的顺序性,更无法保障实时多媒体业务服务质量(QoS),所以主要应用在文件传送和电子邮件服务。而随着Internet的飞速发展,人们对于在Internet上传输多媒体信息的需求越来越大,这就要求网络应能根据用户的要求分配和调度资源,传统的"尽力而为"转发机制已不能满足用户的要求。为解决这一问题,美国于1996年底开始了以提高网络服务质量研究为核心的InternetⅡ 以及NGI(下一代Internet)等研究项目。相关的权威组织IETF(Internet Engineering Task Force)也成立了专门的工作小组来研究多媒体服务质量的定义和相关标准。IETF在IP网络的QoS方面提出了多种服务模型和机制,其中的综合业务模型(Int-Serv)引入了一个重要的网络控制协议RSVP(资源预留协议),这一模型的思想是"为了给特定的客户包流提供特殊的QoS,要求路由器必须能够预留资源。反过来要求路由器中有特定流的状态信息"。所以可以看出,这一模型能提供绝对有保证的QoS,是以预留下的资源作为代价的,对资源的要求实际上是更高的。因此,对于WinXP中的QoS RSVP服务保留了20%的网络带宽也就不足为奇了,由于对于个人应用几乎毫无意义,禁用它是不二选择。
    42.Remote Access Auto Connection Manager
     RasAuto (远程访问自动联机管理员服务)的进程名是svchost.exe,WinXP Home/PRO默认安装的启动类型是手动,依赖于Remote Access Connection Manager、Telephony服务。RasAuto主要针对宽带使用,当有网络连接请求时它会自动打开网络连接,我们在使用WinXP时会经常弹出一个自动拨号窗口,就是它在工作。如果你的机器提供网络共享服务就开着它,避免网络断线后手动连接,否则可将其关闭。  
    43.Remote Access Connection Manager
     RasMan(远程访问联机管理员服务)的进程名是svchost.exe,WinXP Home/PRO默认安装的启动类型是手动,依赖于Telephony服务,其简单描述是"创建网络连接",这个解释简单明了,所以根据自己系统的情况来使用这个服务即可。
    44.Remote Desktop Help Session Manager
     RDSessMgr (远程桌面协助服务)的进程名是sessmgr.exe,WinXP Home/PRO默认安装的启动类型是手动,依赖于Remote Procedure Call服务。这是与NetMeeting Remote Desktop Sharing很类似的一个服务。鼠标点击"开始→所有程序→附件→通讯→远程桌面连接"可开远程桌面功能,而RDSessMgr就是为它提供支持。微软的原意是通过它做远程帮助,其代价是牺牲安全与4MB内存的占用,不需要时一定得关闭。
    45.Remote Procedure Call
     RpcSs (远程过程调用服务)的进程名是svchost.exe,WinXP Home/PRO默认安装的启动类型是自动。太多服务依赖于这一服务了,最近"冲击波"横行,恐怕大家都对RPC有此印象了吧,它原名远程进程调用,是早期IBM、SUN等公司定义的功能级通信协议,随后被微软采纳,但作了改动,称之为MRPC。总的来说RPC是一种消息传递功能,上一期说过 Windows系统是个典型的消息(事件)处理型系统,所以RPC对于系统的重要性不言而喻。由于Windows内部结构已相当复杂了,很难搞清楚哪些模块在用RPC哪些不用,事实上你只要关掉它,系统就可能崩溃。所以这个服务也是不可禁用的。
    46.Remote Procedure Call(RPC)Locator
     RpcLocator (远程过程调用定位服务)的进程名是locator.exe,WinXP Home/PRO默认安装的启动类型是手动,依赖于Workstation服务。这一服务和上面的RPC服务并无太多关系,是用来给RPC的命名服务的。其用途简单解释就是,通过它对RPC的命名管理,调用者才能找到被调用者的位置。但由于微软系统注册表的存在,使得这些命名服务在本机上的调用上毫无意义。因此对于一般用户完全可以关闭。
    47.Remote Registry
     RemoteRegistry (远程注册表服务)的进程名是svchost.exe,在WinXP Home下不可用,在WinXP PRO下默认安装的启动类型是自动,依赖于Remote Procedure Call服务。此服务是向其他连机的计算机开放你的注册表,微软总是让这种明显是安全隐患的服务自动启动实在让人费解。不过如果你有这种特殊需求的话可以尝试一下。打开注册表编辑器Regedit,在文件菜单栏里找到"连接网络注册表"这一项,可让你打开甚至编辑其他机器上的注册表。当然那些机器上的 RemoteRegistry也必须是打开的,而且对你计算机的一些相应权限同样必须开放。
    48.Removable Storage
     NtmsSvc (卸除式存放装置服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是手动,依赖于Remote Procedure Call服务。此服务的名称太容易让人误解,实际上它只是对特殊可移动存储器的管理,比如ZIP软驱和磁带驱动器,不要担心你的CD和DVD等设备。从事图像设计的用户经常会用ZIP同苹果机交换文件,一般人恐怕很少使用这些特殊设备,因此可将其关闭。
    49.Routing and Remote Access
     RemoteAccess (路由和远程访问服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型分别为禁用和手动,依赖于NetBIOSGroup、Remote Procedure Call服务。Routing and Remote Access为软路由,即在一台连接多个网络的计算机上通过运行路由软件,以实现网络间路由的一种方法,相对于硬件路由来说很是方便经济。WinXP也把这个功能集成到系统里来了,不过可能比较少人知道是在哪里配置路由,主要原因就是这个服务默认为关闭。首先启动此服务,网络连接文件夹里会多出一个"传入的连接",值得注意的是,在VPN连接(传入的连接)的属性"Internet协议(TCP/IP)"里一般要指定TCP/IP地址(一般来说都必须是合法地址)才行。感兴趣的朋友可以自己继续研究,而大多数不需要的朋友直接禁用它吧。
    50.Secondary Logon
     Seclogon (二次登录服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动,没有任何服务依存关系。这个服务对应于用户临时权限分配功能,在多用户使用的计算机上,某些用户因为是非管理员权限,导致某些程序无法执行。为了让没有管理员权限的已经登录用户可以使用这些程序,WinXP设计了这个功能来分配临时的管理员权限。打开这个服务后,右键点击鼠标选择"运行方式"将会出现对话框,让你选择执行这个程序的用户身份。对多用户环境下的管理员,这确实是方便的功能,不过依然是以安全作为代价的,对单人环境的笔记本电脑用户来说尤其无用而且危险!所以要谨慎使用。
    51.Security Accounts Manager
     SamSs (安全账户管理服务)的进程名是lsass.exe,在WinXP Home/PRO下默认安装的启动类型是自动,依赖于Remote Procedure Call服务。熟悉WinXP启动过程的用户都知道SAM文件的重要性,SamSs是负责SAM数据库的控制和维护的服务。SAM数据库位于注册表 "HKLM\SAM\SAM"下,可使用Regedit32.exe打开注册表编辑器,并设置适当权限查看SAM中的内容。SAM数据库保存在磁盘上的" 系统盘\windows\system32\config"目录下的sam文件中,在这个目录下还包括一个security文件,是安全数据库的内容,两者有不少关系。SAM数据库中包含了系统中所有组、账户的信息。而WinXP启动时就需要在SAM文件中读取诸如用户名、用户全名(full name)、所属组、描述、密码、注释、是否可以更改密码、密码设置时间等信息。这也是系统中不可关闭的几个基础服务之一,如果服务启动失败,系统就只有重启了。
    52.Server
      Lanmanserver(服务器服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动。Server服务对应的是网络上的文件/打印机器共享,以及网络的路径映射共享功能。没有这些方面的需要你就可以关闭它。
    53.Shell Hardware Detection
     ShellHWDetection (外壳硬件探测服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动,依赖于Remote Procedure Call服务。对这个服务微软是语焉不详,也没有给出详细的硬件描述或列表,不过根据网络上不少人的测试,这个服务主要还是和具有自动运行(播放)功能的硬件有关系,例如数字相机、CD-ROM等。通过这个服务,当这些硬件接上系统或放入相应媒介时,WinXP能自动探测到并做出对应动作。对于外设越来越多的现在,没有把握还是不要轻易关闭它。
    54.Smart Card
     SCardSvr(智能卡服务)的进程名是SCardSvr.exe,在WinXP Home/PRO下默认安装的启动类型是手动,依赖于Plug and Play服务。Smart Card(智能卡)其外型和一般信用卡大小一样,但多了一块指甲大小的IC芯片后,使原本普通的一张卡片变成拥有资料控管与逻辑运算的能力。智能卡包括金融卡、GSM卡等,与我们一般常用的电话IC卡相比,内部的IC线路设计不同。由于卡内本身即已包含了CPU功能、ROM、EEPROM、RAM等元件,智能卡就像一台可随身携带的超微型电脑,可用来储存及处理重要资料。在安全性方面,智能卡具有自我毁灭系统,想窃取卡上的资料非常困难。如果你拥有智能卡及相关的读卡设备就开启这个服务,否则就禁用吧。
    55.Smart Card Helper
      SCardDrv(智能卡协助服务)的进程名是SCardSvr.exe,在WinXP Home/PRO下默认安装的启动类型是手动,它没有任何服务依存关系。只要没有相关的设备就禁用好了。
    56.SSDP Discovery Service
    SSDPSRV (简易服务发现协议之发现服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是手动。SSDPSRV主要用于局域网上UPnP(Universal Plug and Play,统一即插即用)设备的搜索。UPnP并不同于我们平常熟悉的PnP,UPnP技术PnP对进行了扩展,简化了家庭或企业中智能设备的联网过程。 UPnP规范基于TCP/IP协议和针对设备彼此间通信而制订的其他Internet协议,这就是它之所以被称作"通用"的原因所在-——UPnP技术不依赖于特定的设备驱动程序,而是使用标准协议。与即插即用相比,这种技术的意义在于,能够轻易地使家庭等非专业用户享受到智能化技术带来的更舒适完美的生活,例如,正是UPnP才使得能在网上冲浪的电冰箱成为可能。UPnP是个较新的协议,也不是非常成熟,对应设备在市场上非常罕见,市场上流行的 Linksys BEFSR41W无线路由器是这方面的例子。对于大多数现在还无缘使用此类设备的朋友,关闭这个服务吧。
    57.System Event Notification
    SENS (系统事件通知服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动,依赖于COM+ Event System服务。它的简单描述是"跟踪系统事件,如登录Windows、网络以及电源事件等。将这些事件通知给COM+事件系统‘订阅者(subscriber)’"。这已将服务的内容解释得很清楚了。尽管有人认为这个服务无关紧要,事实上系统是否需要它取决于你在系统里安装了些什么,而许多应用程序的运行是要通过SENS来实现的,所以建议还是让它自动打开为好。
    58.System Restore Service
     Srservice (系统还原服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动,依赖于Remote Procedure Call服务。这是大家都非常熟悉的系统还原功能了,如果不使用的话,先在"我的电脑"属性中的系统还原选项卡关闭,然后在这里将服务禁用即可。
    59.Task Scheduler
     Schedule (计划任务服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动,依赖于Remote Procedure Call服务。此服务支持WinXP的计划任务,它能使程序在预定的时间自动运行,如定期进行磁盘碎片整理、病毒扫描、更新等,可根据自己的需要选择是否开启。
    60.TCP/IP NetBIOS Helper
      LmHosts(TCP/IP NetBIOS 助手服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动,依赖于AFD网络支持环境、NetBios Over TCP/IP服务。该服务能在TCP/IP上提供NetBIOS支持。大家应该对TCP/IP比较熟悉了,相对来说NetBIOS网络协议对读者来说可能比较陌生,它是由IBM开发的一个很古老的协议,当年在局域网上占据主导。由于NetBIOS不具备路由功能,也就是说它的数据包无法跨网段传输,因此在广域网、城域网大行其道的今天,它只能退居配角。其实在Win95/98的网络协议中仍然保留着NetBIOS,不过它已经改名叫NetBEUI (NetBIOS扩展用户接口),是NetBIOS的Microsoft改进版。由于NetBIOS是完全基于局域网的,因此作为访问Internet资源的一般用户可以禁用它,除非你的系统处在小局域网中,而且使用的也正是NetBIOS协议。
    61.Telephony
     TapiSrv (电话服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是手动,依赖于Plug and Play、Remote Procedure Call服务。简单地说这个服务能为计算机提供电话拨号的能力。如果你使用了任何形式的拨号,不管是用拨号调制解调器还是DSL/Cable连接到 Internet,还是通过电话线连接其他计算机,或是拨打电脑IP电话、发传真等,你就有必要保留这个服务,反之就可关掉它。
    62.Telnet
      TapiSrv(远程登录服务)的进程名是tlntsvr.exe,在WinXP Home下不可用,在WinXP PRO下默认安装的启动类型是手动,依赖于NT LM Security Support Provider、Remote Procedure Call、TCP/IP Protocol Driver服务。这是一个容易遭到误会的服务名称,一般人会误以为这是以前DOS下那个Telnet,关了之后就无法使用BBS。其实它与BBS无关,完全是微软自己的Telnet系统,尽管两者的原理相差不大,即让用户以模拟终端的方式,登录到Internet的某台主机上,一旦连接成功,这些个人计算机就好像是远程计算机的一个终端,可以像使用自己的计算机一样输入命令,运行远程计算机中的程序。基于安全性理由,如果没有特别需求,这个服务一定要关掉禁用。
    63.Terminal Services
     TermService(终端机服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是手动,依赖于Remote Procedure Call服务。它的简单描述是"允许多位用户连接并控制一台机器,并且在远程计算机上显示桌面和应用程序。这是远程桌面(包括管理员的远程桌面)、快速用户转换、远程协助和终端服务器的基础结构"。这段描述已将该服务的用途解释得很清楚了,需要强调的是,这些方便都是以安全为代价的,如果平时不用就一定要关掉。
    64.Themes
     Themes(主题服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动,没有服务依存关系。很多人都喜欢使用XP的布景主题,不过如果用户没有使用就关闭好了。
    65.Uninterruptible Power Supply
     UPS (UPS电源管理服务)的进程名是UPS.exe,在WinXP Home/PRO下默认安装的启动类型是手动,没有服务依存关系。它的简单描述是"管理连接到计算机的不间断电源(UPS)",同样很好理解,UPS(不间断电源供应)一般用户极少用到,除非你的电源供应器具
    66.Universal Plug and Play Device Host
     UPNPhost (统一即插即用驱动主机服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是手动,依赖于SSDP Discovery Service服务。它同SSDP Discovery Service是继承关系,后者搜索发现UPnP设备,而UPNPhost为UPnP设备提供驱动支持。当然通常情况下关闭即可。
    67.Upload Manager
     Uploadmgr (上传管理服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动,依赖于Remote Procedure Call服务。这个服务的具体效果不明,关闭它后实际使用中的网络上传下载并没有受到什么影响,也许它跟微软的服务器和相关服务有关?请根据需要关闭。
    68.Volume Shadow Copy
     VSS(上传管理服务)的进程名是 vssvc.exe,在WinXP Home/PRO下默认安装的启动类型是手动,依赖于Remote Procedure Call服务。它的简单描述是"管理并执行用于备份和其他目的的卷影复制",依然是和WinXP备份有关的服务,它默认就是关闭的,也并没有在笔者的机器上对备份造成影响,其具体应用依是未解之谜。
    69.WebClient
     WebClient (Web客户端服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动,依赖于WebDav Client Redirector系统组件。使用WebDav可将档案或数据夹上传到某个Web服务,这个服务对于未来.NET意义更大。基于安全性的理由,现在你可以尝试关闭它。
    70.Windows Audio
     AudioSrv(Windows音频服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动,依赖于Plug and Play、Remote Procedure Call服务。理解这个服务再简单不过了,如果你的机器没有声卡可以关闭它。
    71.Windows Image Acquisition(WIA)
     Stisvc (Windows影像取得服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是手动,依赖于Remote Procedure Call服务。该服务为控制面板中的"扫描仪和照相机"功能提供支持。通过这个功能,用户在安装好设备驱动后无需要再安装相关管理软件,就能轻易操作扫描仪和数码相机来获得图像。不需要的用户可关闭它。
    72.Windows Installer
     MSIServer (Windows安装服务)的进程名是msiexec\.exe,在WinXP Home/PRO下默认安装的启动类型是手动,依赖于Remote Procedure Call服务。这一服务同Application Management服务基本是一样的。从微软的解释看,Windows Installer服务应该是.MSI文件的最直接执行者。同样让人奇怪的是,这个服务默认就是关闭的,可.MSI文件的安装、修复或删除却很正常,和备份工具一样,究竟这个服务在系统中扮演什么角色,如何工作,只有微软的工程师才知道了。
    73.Windows Time
      W32Time(Windows时间服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动,它没有服务依存关系。这一服务对应WinXP的Internet对时服务,如不需要关闭即可。
    74.Windows Management Instrumentation(WMI)
     Winmgmt (Windows管理规范服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动,依赖于Event Log、Remote Procedure Call服务。WMI是Windows中的基础管理结构,它通过一组常用接口来控制和监视系统(如对系统属性的查看与更改、设置用户权限等)。WMI为访问大量的Windows管理数据提供了一个统一的机制。WMI通过脚本、C++程序接口、.NET类(系统管理)和命令行工具(WMIC)提供了对信息的访问。WMI的功能还包括事件、远程、查询、查看、计划和实施用户扩展及更多内容。总而言之,虽然在服务管理工具中可以关闭,但最好别动它,否则会出现许多莫名的问题。
    75.Windows Management Instrumentation Driver Extensions
     Wmi (Windows管理规范驱动延伸服务)的进程名是svchost.exe,在WinXP Home下不可用,在WinXP PRO下默认安装的启动类型是手动,没有服务依存关系。微软的白皮书介绍,该服务是作为WMI服务在驱动程序方面的一个延伸,简单说主要就是为让系统方便地获知计算机中OEMs(original equipment manufacturers)以及IHVs(independent hardware vendors)等与硬件厂商相关的硬件信息。不过让人奇怪的是,为什么它在WinXP Home下不可用呢?
    76.Wireless Zero Configuration
     WZCSVC (无线配置服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动,依赖于NDIS Usermode I/O Protocol组件、Remote Procedure Call服务。它的简单描述是"为您的802.11适配器提供自动配置"。802.11是大家都比较熟悉的无线局域网协议标准了,其已经在市场上占据了优势。当然,802.11协议、蓝牙标准和HomeRF工业标准是无线局域网所有标准中最主要的竞争对手,它们也各有优劣。然而802.11b无线局域网技术已经在美国得到了广泛的应用,所以微软的WinXP内置服务支持也就不足为奇了。如果你没有使用无线网络适配卡装置,那么可以关闭服务。
    77.WMI Performance Adapter
     WmiApSrv (WMI性能适配器服务)的进程名是wmiapsrv.exe,在WinXP Home/PRO下默认安装的启动类型是手动,依赖于Remote Procedure Call服务。此服务提供了从WMI HiPerf 提供者获得的性能库信息,需要以手动方式进行配置,并不会在缺省状态下实现运行。该服务太过专业,无法解释得浅显,对于普通的使用者最好保持其默认状态。
    78.Workstation
     Lanmanworkstation(工作站服务)的进程名是svchost.exe,在WinXP Home/PRO下默认安装的启动类型是自动,它不依赖于其他服务,但有不少服务都依赖它。该服务同样为基础服务,请保持其默认状态不要关闭。

     
    September 08

    消息钩子函数入门篇


    Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的。而钩子是Windows系统中非常重要的系统接口,用它可以截获并处理送给其他应用程序的消息,来完成普通应用程序难以实现的功能。钩子可以监视系统或进程中的各种事件消息,截获发往目标窗口的消息并进行处理。这样,我们就可以在系统中安装自定义的钩子,监视系统中特定事件的发生,完成特定的功能,比如截获键盘、鼠标的输入,屏幕取词,日志监视等等。可见,利用钩子可以实现许多特殊而有用的功能。因此,对于高级编程人员来说,掌握钩子的编程方法是很有必要的。

    钩子的类型
      一. 按事件分类,有如下的几种常用类型
      (1) 键盘钩子和低级键盘钩子可以监视各种键盘消息。
      (2) 鼠标钩子和低级鼠标钩子可以监视各种鼠标消息。
      (3) 外壳钩子可以监视各种Shell事件消息。比如启动和关闭应用程序。
      (4) 日志钩子可以记录从系统消息队列中取出的各种事件消息。
      (5) 窗口过程钩子监视所有从系统消息队列发往目标窗口的消息。
      此外,还有一些特定事件的钩子提供给我们使用,不一一列举。
    下面描述常用的Hook类型:
    1、WH_CALLWNDPROC和WH_CALLWNDPROCRET Hooks
    WH_CALLWNDPROC和WH_CALLWNDPROCRET Hooks使你可以监视发送到窗口过程的消息。系统在消息发送到接收窗口过程之前调用WH_CALLWNDPROC Hook子程,并且在窗口过程处理完消息之后调用WH_CALLWNDPRO
    CRET Hook子程。WH_CALLWNDPROCRET Hook传递指针到CWPRETSTRUCT结构,再传递到Hook子程。CWPRETSTRUCT结构包含了来自处理消息的窗口过程的返回值,同样也包括了与这个消息关联的消息参数。
    2、WH_CBT Hook
    在以下事件之前,系统都会调用WH_CBT Hook子程,这些事件包括:
    1. 激活,建立,销毁,最小化,最大化,移动,改变尺寸等窗口事件;
    2. 完成系统指令;
    3. 来自系统消息队列中的移动鼠标,键盘事件;
    4. 设置输入焦点事件;
    5. 同步系统消息队列事件。
    Hook子程的返回值确定系统是否允许或者防止这些操作中的一个。
    3、WH_DEBUG Hook
    在系统调用系统中与其他Hook关联的Hook子程之前,系统会调用WH_DEBUG Hook子程。你可以使用这个Hook来决定是否允许系统调用与其他Hook关联的Hook子程。
    4、WH_FOREGROUNDIDLE Hook
    当应用程序的前台线程处于空闲状态时,可以使用WH_FOREGROUNDIDLE Hook执行低优先级的任务。当应用程序的前台线程大概要变成空闲状态时,系统就会调用WH_FOREGROUNDIDLE Hook子程。
    5、WH_GETMESSAGE Hook
    应用程序使用WH_GETMESSAGE Hook来监视从GetMessage or PeekMessage函数返回的消息。你可以使用WH_GETMESSAGE Hook去监视鼠标和键盘输入,以及其他发送到消息队列中的消息。
    6、WH_JOURNALPLAYBACK Hook
    WH_JOURNALPLAYBACK Hook使应用程序可以插入消息到系统消息队列。可以使用这个Hook回放通过使用WH_JOURNALRECORD Hook记录下来的连续的鼠标和键盘事件。只要WH_JOURNALPLAYBACK Hook已经安装,正常的鼠标和键盘事件就是无效的。WH_JOURNALPLAYBACK Hook是全局Hook,它不能象线程特定Hook一样使用。WH_JOURNALPLAYBACK Hook返回超时值,这个值告诉系统在处理来自回放Hook当前消息之前需要等待多长时间(毫秒)。这就使Hook可以控制实时事件的回放。 WH_JOURNALPLAYBACK是system-wide local hooks,它們不會被注射到任何行程位址空間。(估计按键精灵是用这个hook做的)
    7、WH_JOURNALRECORD Hook
    WH_JOURNALRECORD Hook用来监视和记录输入事件。典型的,可以使用这个Hook记录连续的鼠标和键盘事件,然后通过使用WH_JOURNALPLAYBACK Hook来回放。WH_JOURNALRECORD Hook是全局Hook,它不能象线程特定Hook一样使用。WH_JOURNALRECORD是system-wide local hooks,它們不會被注射到任何行程位址空間。
    8、WH_KEYBOARD Hook
    在应用程序中,WH_KEYBOARD Hook用来监视WM_KEYDOWN and WM_KEYUP消息,这些消息通过GetMessage or PeekMessage function返回。可以使用这个Hook来监视输入到消息队列中的键盘消息。
    9、WH_KEYBOARD_LL Hook
    WH_KEYBOARD_LL Hook监视输入到线程消息队列中的键盘消息。
    10、WH_MOUSE Hook
    WH_MOUSE Hook监视从GetMessage 或者 PeekMessage 函数返回的鼠标消息。使用这个Hook监视输入到消息队列中的鼠标消息。
    11、WH_MOUSE_LL Hook
    WH_MOUSE_LL Hook监视输入到线程消息队列中的鼠标消息。
    12、WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks
    WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我们可以监视菜单,滚动条,消息框,对话框消息并且发现用户使用ALT+TAB or ALT+ESC 组合键切换窗口。WH_MSGFILTER Hook只能监视传递到菜单,滚动条,消息框的消息,以及传递到通过安装了Hook子程的应用程序建立的对话框的消息。WH_SYSMSGFILTER Hook监视所有应用程序消息。WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我们可以在模式循环期间过滤消息,这等价于在主消息循环中过滤消息。通过调用CallMsgFilter function可以直接的调用WH_MSGFILTER Hook。通过使用这个函数,应用程序能够在模式循环期间使用相同的代码去过滤消息,如同在主消息循环里一样。
    13、WH_SHELL Hook
    外壳应用程序可以使用WH_SHELL Hook去接收重要的通知。当外壳应用程序是激活的并且当顶层窗口建立或者销毁时,系统调用WH_SHELL Hook子程。
    WH_SHELL 共有5钟情況:
    1. 只要有个top-level、unowned 窗口被产生、起作用、或是被摧毁;
    2. 当Taskbar需要重画某个按钮;
    3. 当系统需要显示关于Taskbar的一个程序的最小化形式;
    4. 当目前的键盘布局状态改变;
    5. 当使用者按Ctrl+Esc去执行Task Manager(或相同级别的程序)。
    按照惯例,外壳应用程序都不接收WH_SHELL消息。所以,在应用程序能够接收WH_SHELL消息之前,应用程序必须调用SystemParametersInfo function注册它自己。
    以上是13种常用的hook类型!
      二. 按使用范围分类,主要有线程钩子和系统钩子
      (1) 线程钩子监视指定线程的事件消息。
      (2) 系统钩子监视系统中的所有线程的事件消息。因为系统钩子会影响系统中所有的应用程序,所以钩子函数必须放在独立的动态链接库(DLL)
    中。这是系统钩子和线程钩子很大的不同之处。
       几点需要说明的地方:
      (1) 如果对于同一事件(如鼠标消息)既安装了线程钩子又安装了系统钩子,那么系统会自动先调用线程钩子,然后调用系统钩子。
      (2) 对同一事件消息可安装多个钩子处理过程,这些钩子处理过程形成了钩子链。当前钩子处理结束后应把钩子信息传递给下一个钩子函数。而且最近安装的钩子放在链的开始,而最早安装的钩子放在最后,也就是后加入的先获得控制权。
      (3) 钩子特别是系统钩子会消耗消息处理时间,降低系统性能。只有在必要的时候才安装钩子,在使用完毕后要及时卸载。
    编写钩子程序
       编写钩子程序的步骤分为三步:定义钩子函数、安装钩子和卸载钩子。
      1.定义钩子函数
      钩子函数是一种特殊的回调函数。钩子监视的特定事件发生后,系统会调用钩子函数进行处理。不同事件的钩子函数的形式是各不相同的。下面以鼠标钩子函数举例说明钩子函数的原型:
    LRESULT CALLBACK HookProc(int nCode ,WPARAM wParam,LPARAM lParam)
    参数wParam和 lParam包含所钩消息的信息,比如鼠标位置、状态,键盘按键等。nCode包含有关消息本身的信息,比如是否从消息队列中移出。
    我们先在钩子函数中实现自定义的功能,然后调用函数 CallNextHookEx.把钩子信息传递给钩子链的下一个钩子函数。CallNextHookEx.的原型如下:
    LRESULT CallNextHookEx( HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam )
    参数 hhk是钩子句柄。nCode、wParam和lParam 是钩子函数。
    当然也可以通过直接返回TRUE来丢弃该消息,就阻止了该消息的传递。
    2.安装钩子
      在程序初始化的时候,调用函数SetWindowsHookEx安装钩子。其函数原型为:
    HHOOK SetWindowsHookEx( int idHook,HOOKPROC lpfn, INSTANCE hMod,DWORD dwThreadId )
    参数idHook表示钩子类型,它是和钩子函数类型一一对应的。比如,WH_KEYBOARD表示安装的是键盘钩子,WH_MOUSE表示是鼠标钩子等等。
      Lpfn是钩子函数的地址。
      HMod是钩子函数所在的实例的句柄。对于线程钩子,该参数为NULL;对于系统钩子,该参数为钩子函数所在的DLL句柄。
       dwThreadId 指定钩子所监视的线程的线程号。对于全局钩子,该参数为NULL。
      SetWindowsHookEx返回所安装的钩子句柄。
      3.卸载钩子
       当不再使用钩子时,必须及时卸载。简单地调用函数 BOOL UnhookWindowsHookEx( HHOOK hhk)即可。
      
    值得注意的是线程钩子和系统钩子的钩子函数的位置有很大的差别。线程钩子一般在当前线程或者当前线程派生的线程内,而系统钩子必须放在独立的动态链接库中,实现起来要麻烦一些。

    线程钩子的编程实例:
      按照上面介绍的方法实现一个线程级的鼠标钩子。钩子跟踪当前窗口鼠标移动的位置变化信息。并输出到窗口。
      (1)在VC++6.0中利用MFC
    APPWizard(EXE)生成一个不使用文档/视结构的单文档应用mousehook。打开childview.cpp文件,加入全局变量:
    HHOOK hHook;//鼠标钩子句柄
    CPoint point;//鼠标位置信息
    CChildView *pView;
    // 鼠标钩子函数用到的输出窗口指针

      在CChildView::OnPaint()添加如下代码:
    CPaintDC dc(this);
    char str[256];
    sprintf(str,“x=%d,y=%d",point.x,point.y);
    //构造字符串
    dc.TextOut(0,0,str); //显示字符串

      (2)childview.cpp文件中定义全局的鼠标钩子函数。
    LRESULT CALLBACK MouseProc
    (int nCode, WPARAM wParam, LPARAM lParam)
    {//是鼠标移动消息
    if(wParam==WM_MOUSEMOVE||wParam
    ==WM_NCMOUSEMOVE)
    {
    point=((MOUSEHOOKSTRUCT *)lParam)->pt;
    //取鼠标信息
    pView->Invalidate(); //窗口重画
    }
    return CallNextHookEx(hHook,nCode,wParam,lParam);
    //传递钩子信息
    }
    (3)CChildView类的构造函数中安装钩子。
    CChildView::CChildView()
    {
    pView=this;//获得输出窗口指针
    hHook=SetWindowsHookEx(WH_MOUSE,MouseProc,0,GetCurrentThreadId());
    }
    (4)CChildView类的析构函数中卸载钩子。
    CChildView::~CChildView()
    {
    if(hHook)
    UnhookWindowsHookEx(hHook);
    }

    系统钩子的编程实例:
    由于系统钩子要用到dll,所以先介绍下win32 dll的特点:
    Win32 DLL与 Win16 DLL有很大的区别,这主要是由操作系统的设计思想决定的。一方面,在Win16 DLL中程序入口点函数和出口点函数(LibMain和WEP)是分别实现的;而在Win32 DLL中却由同一函数DLLMain来实现。无论何时,当一个进程或线程载入和卸载DLL时,都要调用该函数,它的原型是BOOL WINAPI DllMain
    (HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved);,其中,第一个参数表示DLL的实例句柄;第三个参数系统保留;这里主要介绍一下第二个参数,它有四个可能的值: DLL_PROCESS_ATTACH(进程载入),DLL_THREAD_ATTACH(线程载入),DLL_THREAD_DETACH(线程卸载),DLL_PROCESS_DETACH(进程卸载),在DLLMain函数中可以对传递进来的这个参数的值进行判别,并根据不同的参数值对DLL进行必要的初始化或清理工作。举个例子来说,当有一个进程载入一个DLL时,系统分派给DLL的第二个参数为DLL_PROCESS_ATTACH,这时,你可以根据这个参数初始化特定的数据。另一方面,在Win16环境下,所有应用程序都在同一地址空间;而在Win32环境下,所有应用程序都有自己的私有空间,每个进程的空间都是相互独立的,这减少了应用程序间的相互影响,但同时也增加了编程的难度。大家知道,在Win16环境中,DLL的全局数据对每个载入它的进程来说都是相同的;而在Win32环境中,情况却发生了变化,当进程在载入DLL时,系统自动把DLL地址映射到该进程的私有空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间,也就是说每个进程所拥有的相同的DLL的全局数据其值却并不一定是相同的。因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。亦即把这些需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。
    在VC6中有三种形式的MFC DLL(在该DLL中可以使用和继承已有的MFC类)可供选择,即Regular statically linked to MFC DLL(标准静态链接MFC DLL)和Regular using the shared MFC DLL(标准动态链接MFC DLL)以及Extension MFC DLL(扩展MFC DLL)。第一种DLL的特点是,在编译时把使用的MFC代码加入到DLL中,因此,在使用该程序时不需要其他MFC动态链接类库的存在,但占用磁盘空间比较大;第二种DLL的特点是,在运行时,动态链接到MFC类库,因此减少了空间的占用,但是在运行时却依赖于MFC动态链接类库;这两种DLL既可以被 MFC程序使用也可以被Win32程序使用。第三种DLL的特点类似于第二种,做为MFC类库的扩展,只能被MFC程序使用。
    下面说说在VC6中全局共享数据的实现
      在主文件中,用#pragma data_seg建立一个新的数据段并定义共享数据,其具体格式为:
      #pragma data_seg ("shareddata")
      HWND sharedwnd=NULL;//共享数据
      #pragma data_seg()
      仅定义一个数据段还不能达到共享数据的目的,还要告诉编译器该段的属性,有两种方法可以实现该目的(其效果是相同的),一种方法是在.DEF文件中加入如下语句:
    SETCTIONS shareddata READ WRITE SHARED
      另一种方法是在项目设置链接选项中加入如下语句:
      /SECTION:shareddata,rws
    好了,准备知识已经学完了,让我们开始编写个全局的钩子程序吧!



    由于全局钩子函数必须包含在动态链接库中,所以本例由两个程序体来实现。
    1.建立钩子Mousehook.DLL
      (1)选择MFC AppWizard(DLL)创建项目Mousehook;
      (2)选择MFC Extension DLL(共享MFC拷贝)类型;
      (3)由于VC5没有现成的钩子类,所以要在项目目录中创建Mousehook.h文件,在其中建立钩子类:
      class AFX_EXT_CLASS Cmousehook:public CObject
      {
      public:
      Cmousehook();
      //钩子类的构造函数
      ~Cmousehook();
      //钩子类的析构函数
      BOOL starthook(HWND hWnd);
      //安装钩子函数
      BOOL stophook();
      卸载钩子函数
      };
      (4)在Mousehook.app文件的顶部加入#include"Mousehook.h"语句;
      (5)加入全局共享数据变量:
      #pragma data_seg("mydata")
      HWND glhPrevTarWnd=NULL;
      //上次鼠标所指的窗口句柄
      HWND glhDisplayWnd=NULL;
      //显示目标窗口标题编辑框的句柄
      HHOOK glhHook=NULL;
      //安装的鼠标钩子句柄
      HINSTANCE glhInstance=NULL;
      //DLL实例句柄
      #pragma data_seg()
      (6)在DEF文件中定义段属性:
      SECTIONS
      mydata READ WRITE SHARED
      (7)在主文件Mousehook.cpp的DllMain函数中加入保存DLL实例句柄的语句:
      DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
      {
      //如果使用lpReserved参数则删除下面这行
      UNREFERENCED_PARAMETER(lpReserved);
      if (dwReason == DLL_PROCESS_ATTACH)
      {
       TRACE0("MOUSEHOOK.DLL Initializing!\n");
       //扩展DLL仅初始化一次
       if (!AfxInitExtensionModule(MousehookDLL, hInstance))
       return 0;
       new CDynLinkLibrary(MousehookDLL);
       //把DLL加入动态MFC类库中
       glhInstance=hInstance;
       //插入保存DLL实例句柄
      }
      else if (dwReason == DLL_PROCESS_DETACH)
      {
       TRACE0("MOUSEHOOK.DLL Terminating!\n");
       //终止这个链接库前调用它
       AfxTermExtensionModule(MousehookDLL);
      }
      return 1;
      }
      (8)类Cmousehook的成员函数的具体实现:
      Cmousehook::Cmousehook()
      //类构造函数
      {
      }
      Cmousehook::~Cmousehook()
      //类析构函数
      {
      stophook();
      }
      BOOL Cmousehook::starthook(HWND hWnd)
      //安装钩子并设定接收显示窗口句柄
      {
      BOOL bResult=FALSE;
      glhHook=SetWindowsHookEx(WH_MOUSE,MouseProc,glhInstance,0);
      if(glhHook!=NULL)
       bResult=TRUE;
      glhDisplayWnd=hWnd;
      //设置显示目标窗口标题编辑框的句柄
      return bResult;
      }
      BOOL Cmousehook::stophook()
      //卸载钩子
      {
      BOOL bResult=FALSE;
      if(glhHook)
      {
       bResult= UnhookWindowsHookEx(glhHook);
       if(bResult)
       {
       glhPrevTarWnd=NULL;
       glhDisplayWnd=NULL;//清变量
       glhHook=NULL;
       }
      }
      return bResult;
      }
      (9)钩子函数的实现:
      LRESULT WINAPI MouseProc(int nCode,WPARAM wparam,LPARAM lparam)
      {
      LPMOUSEHOOKSTRUCT pMouseHook=(MOUSEHOOKSTRUCT FAR *) lparam;
       if (nCode>=0)
       {
      HWND glhTargetWnd=pMouseHook->hwnd;
      //取目标窗口句柄
       HWND ParentWnd=glhTargetWnd;
       while (ParentWnd !=NULL)
       {
       glhTargetWnd=ParentWnd;
       ParentWnd=GetParent(glhTargetWnd);
       //取应用程序主窗口句柄
       }
       if(glhTargetWnd!=glhPrevTarWnd)
       {
       char szCaption[100];
       GetWindowText(glhTargetWnd,szCaption,100);
       //取目标窗口标题
       if(IsWindow(glhDisplayWnd))
       SendMessage(glhDisplayWnd,WM_SETTEXT,0,(LPARAM)(LPCTSTR)szCaption);
       glhPrevTarWnd=glhTargetWnd;
       //保存目标窗口
       }
       }
       return CallNextHookEx(glhHook,nCode,wparam,lparam);
       //继续传递消息
      }
      (10)编译项目生成mousehook.dll。
      2.创建钩子可执行程序
      (1)用MFC的AppWizard(EXE)创建项目Mouse;
      (2)选择“基于对话应用”并按下“完成”键;
      (3)编辑对话框,删除其中原有的两个按钮,加入静态文本框和编辑框,用鼠标右键点击静态文本框,在弹出的菜单中选择“属性”,设置其标题为“鼠标所在的窗口标题”;

      (4)在Mouse.h中加入对Mousehook.h的包含语句#Include"..\Mousehook\Mousehook.h";
      (5)在CMouseDlg.h的CMouseDlg类定义中添加私有数据成员:
      CMouseHook m_hook;//加入钩子类作为数据成员
      (6)修改CmouseDlg::OnInitDialog()函数:
      BOOL CMouseDlg::OnInitDialog()
      {
      CDialog::OnInitDialog();
      ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
      ASSERT(IDM_ABOUTBOX <0xF000);
      CMenu* pSysMenu = GetSystemMenu(FALSE);
      if (pSysMenu != NULL)
      {
       CString strAboutMenu;
       strAboutMenu.LoadString(IDS_ABOUTBOX);
       if (!strAboutMenu.IsEmpty())
       {
       pSysMenu->AppendMenu(MF_SEPARATOR);
       pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
       }
      }
      SetIcon(m_hIcon, TRUE);//Set big icon
      SetIcon(m_hIcon, FALSE);//Set small icon
      //TODO: Add extra initialization here
      CWnd * pwnd=GetDlgItem(IDC_EDIT1);
      //取得编辑框的类指针
      m_hook.starthook(pwnd->GetSafeHwnd());
      //取得编辑框的窗口句柄并安装钩子
      return TRUE;
      //return TRUE unless you set the focus to a control
      }
      (7)链接DLL库,即把..\Mousehook\debug\Mousehook.lib加入到项目设置链接标签中;
      (8)编译项目生成可执行文件;
      (9)把Mousehook.DLL拷贝到..\mouse\debug目录中;
      (10)先运行几个可执行程序,然后运行Mouse.exe程序,把鼠标在不同窗口中移动,在Mouse.exe程序窗口中的编辑框内将显示出鼠标所在的应用程序主窗口的标题。  
    February 27

    关掉闹心的 PC 喇叭

     PC 喇叭总是喜欢在敲命令时嘟嘟的乱叫,让人闹心。其实,打开设备管理器,在查看里,选上显示隐藏的设备,然后下面就列出一个非即插即用驱动程序列表来,选中 Beep 设备,把它禁用就 OK 了。

    在 VMware Player 里装了个 Ubuntu 6.06 Server,它的命令行下,那个 PC 喇叭也总是嘟嘟乱叫,上网一搜,找到好几种办法来禁止它。最简单的就是在 /etc/profile 文件中添加一句:
    setterm -blength 0
    或者在 /etc/inputrc 文件中把
    set bell-style none
    这句开启。
    最狠的一种办法是直接干掉 PC 喇叭模块,在 /etc/modprobe.d/blacklist 中添加:
    #silly speaker beep
    blacklist pcspkr
    这样下次启动后,PC 喇叭就滚蛋了。
    如果不想等到下次启动,直接敲入:
    sudo rmmod pcspkr
    之后,整个世界就清静了!
    December 25

    最新消息(转载)

    【IT168 专稿】电信工作人员强制在用户计算机上安装星空极速拨号软件一直引来很多使用者的不满,网上也纷纷传出这个星空极速软件安装后将禁止其他拨号软件的使用,监控使用者上网信息,不时弹出广告窗口,删除后也会保留很多垃圾文件在注册表和系统文件夹中。

      然而电信部门一直对这个事情避而不谈,然而今天我们却得到了可靠消息,电信内部员工就电信针对星空极速软件安装和使用以及针对用户,媒体询问时的答复进行了规范,就答复内容进行了“统一”。看来网上针对星空极速的种种质问引起了电信部门管理层人士的重视。

      一、内部爆料:

      一位中国电信的员工将自己在办公OA系统中收到的“关于星空极速的统一媒体解释口径”的邮件。该邮件的主要目的是让电信各个员工能够了解“星空极速”客户端的主要功能和基本参数设置,能够在别人问到此问题时给出正式的中性的回答;另外该通知还针对用户和媒体询问时的答复内容进行了规范。

      

      二、通知内容细分析:

      通知是以附件的形式发放的,而且每个附件都是WORD文档,在文件上盖有“中国电信市场拓展部”的公章,真实性还是有一定保障的。从通知标题上我们可以看出此通知出自安徽省电信有限公司蚌埠市分公司。——从下文中可以看到通知要求针对省公司的规定来实施,可见此次通知发布是在安徽省范围内进行的。

      

      在通知的开头主要是布置工作,并提醒各位员工针对当前媒体和用户就星空极速客户端,强制弹出广告窗口等问题的报道和投诉严格遵守省公司提出的统一解释答复口径,作为解决此类问题的答复依据。——看来媒体和用户的反应已经引起了电信部门相关领导的重视。

      另外通知中严格要求各个宽带装维人员和客户经理在上门安装星空极速软件时要根据用户的需要正确配置相关参数,诸如上网时间长短统计日期以及广告弹出窗口等,避免草草安装完毕就走人事情的发生,从而杜绝产生不必要的投诉。——在安装过程中做一些对用户有利的设置来避免不必要的投诉,这就是电信目前的策略,流氓软件照样给你装,但是给用户些小好处来转移视线。

      

      三、对用户统一解释口径:

      通知的关键内容就是针对星空极速客户端和强制弹出广告窗口的询问给出了统一解释口径,在通知的附件一中给出了针对普通用户就星空极速客户端和强制弹出广告窗口进行投诉时的统一解释答复口径。从统一解释答复口径可以看出电信主要强调以下几点:

      (1)星空极速可以为用户进行电脑硬件检测,网络故障诊断,免费发送小灵通短信息,帮助用户解决很多上网过程中遇到的难题,方便用户使用。

      (2)星空极速是正版且免费提供给用户,用户可以自行选择安装或使用其他拨号软件。

      (3)该软件是经过国家软件评测中心检测过的,他采用了绿色软件的卸载方式,对用户操作系统没有任何影响,并不存在强制安装的问题。

      (4)弹出的窗口并不是广告窗口,而是欢迎页面,他是为了表达对用户的友好和尊重,弹出的窗口里都是电信为用户提供的大量免费服务,用户可以在星空极速客户端设置中修改参数实现不弹出广告窗口的功能。

      四、对媒体统一解释口径:

      在通知附件二中还针对媒体就同样问题询问时给出的统一解释口径,具体内容如下:

      (1)星空极速客户端是为了满足广大互联网用户使用网络的需求而研发的,他可以为用户带来很多便利。该程序是正版免费提供给用户,卸载方式也很正规是绿色的删除后不会留下任何垃圾文件。

      (2)中国电信本着对国家和社会高度负责的精神,始终致力于营造健康文明的网络环境,坚决支持打击各种形式的网络不文明现象,在最近几年连续获得中国互联网协会办法的贡献奖。

      (3)星空极速软件是自主开发的,是借鉴了国内外众多主流上网软件设置的。上网弹出的是欢迎界面,显示的都是电信的免费服务,也是为了帮助众多用户更好的享受网络冲浪带来的乐趣而提供的。

      (4)前一段出现的针对星空极速进行的报道是片面的,是由于电信员工没有很好的和用户沟通交流造成的,是下属企业在推广星空极速软件过程中与用户沟通交流不够充分造成某些用户对此软件的体验和我们推广该软件初衷出现偏差。当然近期我们会加大这方面的沟通,让更多的用户享受到更好的服务。

      五、统一解释口径细分析:

      不管如何至少这个通知说明了前一段时间针对星空极速的报道是具有一定真实性的,否则电信部门会出来辟谣而不是统一解释口径,这种统一解释口径总给人一种“串供”的感受。

      另外从统一口径中我们可以看出电信的这种解释大部分都是官话和套话,例如中国电信本着对国家和社会高度负责的精神,始终致力于营造健康文明的网络环境在最近几年连续获得中国互联网协会办法的贡献奖,该软件是经过国家软件评测中心检测过的,他采用了绿色软件的卸载方式,对用户操作系统没有任何影响,并不存在强制安装的问题等。

      不过唯一令人欣慰的就是统一口径中提到的“星空极速是正版且免费提供给用户,用户可以自行选择安装或使用其他拨号软件”,了解了这一点后我们再遇到工作人员要强制安装此程序时完全可以和他说“不”了。

    破解星空极速的方法(转载)

    (个人疑问,为什么不退掉电信转向网通呢)

     

    对于普通的家庭用户来说,也许不觉得有什么,但是对于绝大多数网民来说,星空极速就像网络上的各种插件,使用非常麻烦,更不用说那些免费广告和收费的增值服务了。好在我们熊坛的一位网友找到了破解星空极速的方法,在这里提供给大家做个参考,希望能有所帮助。内容详贴请访问: 小熊西安论坛

    在了解了星空极速的工作原理之后,我们知道在登陆的时候星空极速会对帐号密码再次加密,生成一个新的密码,因此只要通过优秀的网络协议分析软件就能找到该密码,从而破解星空极速。简单的说就是一个破解密码的过程。

    首先我们需要一款网络分析软件SNIFFER PRO 4.7.5 ,容量大小约33MB,有中、英文两个版本。然后安装SNIFFER PRO ,安装汉化补丁,重新启动系统。不要运行星空极速连接网络,运行程序,点击"文件"---"选定设置",选择你的网卡,确定。

    第四步点击菜单"监视器"、"主机列表",出现如图显示,点击图中2处"本地",点击图中3处"捕捉", 这时连接运行星空极速连接网络,连接上网后可以看到图中4处,变为望远镜有个红点,这时候点击图中4处,这样就停止了捕捉。

    第五,点击图中1处解码,出现如图报告,在2处,可以通过单击每一步序号,观察3处本机与服务器通讯记录,找到你的用户名(涂红处),和加过密的密码(涂黑处)。

    第六:删除星空极速,用XP自带程序拨号,注意!你的用户名不变,密码改为刚才截获的密码。

    该方法根据测试绝对可行,解除后不会出现其它问题,一位汉中的网友提供了截图,测试网速未受影响。唯一需要的担心的是,今后如果大量出现绕过星空极速上网的用户,电信又会采取何种措施呢?

    让星空极速彻底下岗 熊坛高手放出破解秘技(转载)

    随着ADSL宽带的普及,很多家庭用户都步入了网络时代,可是慢慢大家觉得512K的速度还不够快,要是再快一些就好了。在安装宽带的时候,中国电信的工作人员会告诉你,还有1M和2M的宽带可以选择,不过费用是很贵的,没办法,512K先将就着吧。

    中国电信大力推广的星空极速

    可如今不同了,中国电信推出了“星空极速”,这玩意真不错,可以免费升级为1M的带宽,对于众多网友来说无疑是天上掉馅饼啊。赶快申请安装,哇,速度果然快了不少,可是……怎么不支持路由了?原来家里两台电脑如今必须只能一个上网;怎么打开浏览器就跳至星空极速了?还好电信是大公司,服务还是不错的,装了星空极速后,每天上网都有大量免费的广告,以及一些收费的增值服务提供给我们,这些是强行嵌入,你所能做的就是无条件接受。 关于星空极速的相关报道

    在很早的时候,电信的上网方式是通过第三方软件实现的,但是网络经常出现问题,后经查证是属于客户端异常,为了能提高网络质量,解决用户潜在问题,电信有了自己做拨号程序的打算。后来共享宽带的流行令电信非常不爽,一个宿舍多台电脑,只需要一个路由就能使用一个宽带帐号上网,占用了大量的网络资源,于是电信有了扼杀路由的念头。后来BT的流行就令电信大为震怒,据中国电信介绍,20%的BT用户却占用了80%的网络资源,这对于电信来说是不能容忍的,于是电信就花费大笔资金弄了个“星空极速”出来。

    为了尽快普及“星空极速”,电信想尽各种措施,如西安就是免费升级1M宽带,而新宽带用户则是强制安装该软件。为什么电信要花如此大的力气来推广该软件呢?是为了给用户提供更好的宽带质量?这话估计上过小学的人都不会信。有了星空极速,电信就能掌握你的一举一动,路由?BT?今后将成为你的梦想。而电信的目的还不仅仅在,嵌入式广告,各种收费的增值服务,用电信的话来说,就是占领用户端的桌面。

    电信推广星空极速的真正目的

    首先我们来看看星空极速的工作原理,这款软件的工作原理就是给你的帐号密码再次加密,然后才能登陆成功。也就是说你得到的并不是真实的密码,所以你无法使用其它PPPOE软件拨号,即使是XP自带的拨号软件也不行。这样一来你就无法使用路由了,电信消灭路由的计划成功。

    你的隐私将无所遁形

    第二,只要你安装了一次星空极速,你所有的信息就会被电信记录在案,隐私对于电信来说是不存在的。记得南京电信曾宣布要按流量收费,说是为了限制 BT下载流量,提高网络质量,但是受到了多方指责。如今只要电信对客户端进行监测,很容易就能找到BT用户并加以限制。用了星空极速你还想BT?那可真是断的随时随地。

    第三,星空极速客户端软件除了具有基本的拨号功能外,还可以进行其他业务的宣传营销。客户端软件运行在用户端,是电信运营商到目标客户群最直接的渠道,在用户达到一定规模的时候,通过客户端向用户发送广告消息、推送增值服务是最快捷、最有效也是成本最低的方式。电信将采取“内嵌浏览器显示营销页面”、“增值服务插件按钮”等桌面营销手段。这样我们就要被强制“享受”电信提供的免费广告和收费增值服务了。

    附:普通PPPOE和星空极速的拨号原理

    PPPOE是一个二层的协议,不需要3层IP的支持,所以抓到的广播包是你计算机上的网卡MAC地址。其工作原理是:主机程序启动PPPOE拨号,PPPOE协议使用主机网卡MAC地址作为原地址,由于目标radius服务器地址不明,所以采用广播方式广播,此时ADSLmodem应处于RFC1483桥接方式,只负责将以太网信号转换成能够在电话线上传输的高频数字信号向对段电信服务器传输,而对端一般是电信级的ADSL接入设备,说白了就是个巨大的ADSLmodem池,然后将接收到高频数字信号转换成以太网信号,同时判断这个数据是做什么的,当接到的是用户网卡发来的PPPOE拨号请求,就将这个请求发给radius认证服务器,而服务器认证后将返回认证信息给ADSL接入设备,以让ADSL接入设备判断是否允许该用户数据通过,同时返回给用户3层IP地址和DNS和网关(这由DHCP服务器完成),此时用户端接收到返回信息,就得到了相应的参数,在按照标准以太网的工作原理工作,也就是说,ADSLmodem对于用户来说是透明的。

    首先是一批IPARP广播,而不是PPPOE的广播!这个ARP广播将直接将你的网卡MAC地址广播给电信端,有理由相信这样电信局能够得到你的MAC地址并在端口上进行基于MAC地址的限制,但是PPPOE也会广播MAC地址,所以这个不因该是导致电信局发现你路由共享原因。在朝下看,网络抓包中会出现224.0.0.22 IGMP(internt组管理协议),该协议主要的作用是将信息发布给参加入组的所有路由器和主机!看到这里大家应该明白了吧!这个是其他PPPOE软件根本不具备的,所以在普通宽带路由器中的规范PPPOE拨号是根本没有办法发出IGMP请求的,这样自然对方的特殊服务器就能区分你使用的是不是电信的星空急速。另外,由于使用星空急速相当于将计算机加入到IGMP组中,这样IGMP服务器下发任何信息都会忠实地发送到这个组的所有成员。

    December 24

    难以置信:电信竟然WC到这个地步(转载)

    在中国互联网关于流氓软件的新一轮讨伐如火如荼之际,上海电信推出一款涉嫌广告推送的拨号软件引发了网民激烈的反应。

      上海电信力推“星空极速”软件属于中国电信集团代号为“星火燎原”计划的一部分,最早开始于广东电信,由于很好的契合了中国电信业务的整体转型,开始在中国电信各省业务中迅速流行;作为“后来者”的上海电信则在近期刚刚启动了这个计划,在本月中旬一场所谓“魔波病毒导致电信用户大规模断网”事件之后加快脚步。

      中国电信集团公司内部人士对本报称:“向ADSL用户推荐安装涉嫌广告推送的拨号软件,最早是广东电信搞出来的,期间电信集团公司曾经声明不准这么搞。不过后来四川电信或重庆电信那边也来广东学习,到现在这种做法已经蔚然成风,因为各省分公司发现,集团总公司提出的‘向互联网转型,向全面信息服务提供商转型’的目标,用这个手段实现起来效果很好。”

      谁在“做局”?

      上海《新闻晨报》17日称,“从本月13日开始,申城宽带用户断网故障集中出现。最近三天里,市计算机病毒防范中心接到有关求助电话已超过800个。”

      而就在报道的前一天的8月16日,上海电信公司发布了《致广大ADSL用户紧急公告》,称“自8月13日开始,我公司受理部门陆续接到不少 ADSL用户报障,反映使用ADSL上网一段时间后会发生网络中断,拨号工具同时会处于锁死,无法响应状态的故障现象……”最后“建议ADSL用户在发生上述断网时,可通过重启XP操作系统,或更换其他的PPPoE拨号软件”。

      非常蹊跷的是这个公告的落款时间竟然也是8月13日——这意味上海电信早在病毒爆发前就已“预料”到会出现大规模断网。这引发了网友质疑,是不是运营商人为制造了所谓“断网危机”,然后诱导用户更新拨号软件。

      在公告当天,上海电信更是“极其迅速”地开始在各区大规模上门为用户更新“星空极速”拨号软件。在本报获得的《上海电信公司南区分公司电信局的通知书》中,上海电信以“宽带拨号软件来源多样,有可能存在病毒和安全漏洞”等为由,声称将在其预约后上门安装。

      在出现装机高潮的这一周,很多未安装新拨号软件的上海ADSL用户反映上网困难。

      微软在例行的每个月第二周周二发布补丁软件(8月8日),在病毒爆发前提前发布了对于攻击WINDOWS的“魔波”病毒的补丁。

      上海计算机病毒防范服务中心技术部副主任吴恩平在接受媒体采访时称微软已提前发布补丁程序,只要安装该补丁程序,就不会受到“魔波”侵害。

      上海电信综合管理部郑建平先生则对本报强调,“此次用户更新拨号软件属于自愿行为,我们不强制要求。”

      上海市汇业律师事务所律师吴冬对本报称:“从目前掌握的初步证据显示,上海电信以及工作人员在具体执行中已经具备欺诈嫌疑。”

      “拨号门”快速蔓延

      浙江的大二学生张越是国内人气新闻站点cnBeta.com的站长,他在网上率先发起的“星空极速事件专题”迅速引发了网友的共鸣。

      “我们从全国各地接到了大量有关中国电信星空极速或http劫持的异常报告,在简单整理后让我们大跌眼镜的是,全国各地的电信流氓手段均不相同,大有一切从实际出发,为受害者定做的味道。”张越对本报说。

      上海使用MSN的白领们则在近期纷纷把后缀改为了“友情提醒,千万别更新上海电信ADSL客户端软件”,而在一些热门论坛上类似的贴子更是屡见不鲜,一致反击电信“拨号门”事件。

      8月29日,上海电信不再沉默。在当天发布的一份名为《关于向电信宽带上网用户推送“欢迎页面”的说明》中,上海电信承认,近期更新的星空极速客户端存在“推送广告”,但称其为“欢迎页面”。

      上海电信综合管理部郑建平先生对本报称:“上海并不是特例,这是中国电信在全国开展的活动,我们已经比广东省等其他地方晚了一到两年。”他同时认为“欢迎页面”的推送方式“只在拨号成功,第一次访问IE时弹出一次”,不能称为所谓的广告推送功能。

      中国电信集团公司内部人士对本报称,上海电信并不是最早开始此项业务的,只是因为在近期做推广而过于被瞩目,其业务相对广州等地已经非常“温和”。

      在本报获得的数份中国电信内部资料中,广东电信的模式被“包装”成了推广的典型,早在2003年,VnetClient客户端(星空极速是其升级版)在广东电信得以广泛使用,新装用户渗透率达到90%,总用户渗透率达到35%,截至2004年12月13日,全省VnetClient用户超过宽带总用户数的50%。

      中国电信集团公司转发的《广东互联星空“星火燎原”培训材料(终稿)》已在各省广为流传,在这份长达67页的文件中,广州电信详细讲解了该项目的操作细节。

      据本报了解,在某些采取这种做法的省份,终端软件被修改的机器比例已经超过50%。在广州、深圳等地的电信ADSL用户,在上网的时候会自动给用户弹出“富媒体”的广告内容。

      这份资料中称,“业务营销管理人员可以通过(‘星空极速’)客户端的增值服务管理平台,向客户端推送各类业务信息和应用功能。”这正是业内所公认的“流氓软件”。

      “广告及推送”、“插件加载及推送”、“占领终端用户的桌面”等更为直接的表述,更是频繁出现在其他数份来自中国电信以及旗下研究与开发中心的内部资料中。

      控制终端

      在中国移动、中国联通的步步紧逼之下,中国电信正在积极谋求转型——从传统基础网络运营商向现代综合信息服务提供商转变。

      未来五六年,中国电信战略转型的主要目标为:非话音业务收入占企业收入(含移动通信)比例达到45%左右;传统固网及宽带接入投资占其收入比控制在25%左右。其“星火燎原”计划显然是这个巨人转身的一个关键。

      本报在其内部文件中发现,中国电信认为推广“星空极速”的意义是:解决PPPoE拨号软件版权问题,解决应用推送渠道问题,最终实现“占领用户端的桌面”。

      这意味着每台电脑都将像手机一样成为电信运营商真正意义上的终端。

      本报获悉,众多受到中移动打压的SP公司已经对电信的新业务跃跃欲试,甚至一些广告投放主也看好这种投放,这显然再度激发了中国电信的热情。

      中国电信的做法已经开始在市场上体现出其“独特”的商业价值,一家名为fsjoy.com的网站在利用了中国电信的推广后,访问量大幅跃升。

      而越来越多的以所谓“中国电信合作——定向网络信息管理平台”为主营业务的公司开始涌现,他们代理的正是中国电信“星空极速”推送广告。

      浙江大学计算机博士毛郁欣分析认为:“除了用星空极速拨打,会带来大量强制性播放的广告,而且很可能用户将无法使用Linux和路由器拨号(目前比较普遍的家庭‘一拖二’上网可以在技术上被控制),这帮助电信解决了一号多机的问题,可以快速扩大用户装机量。”

      业内人士指出,中国电信转型的急切心情可以理解,但采取如此做法似乎有拔苗助长之嫌,因为在这样一个时代,消费者的选择正日趋理性和成熟。

    September 05

    怎样清除病毒Trojan.Spy

    [蠕虫简单分析]:

    蠕虫名称:Worm.Win32.Delf.aj(AVP)
    蠕虫别名:Trojan.Spy.UsbSpy.a(瑞星)、TrojanSpy.USBSpy.a(江民)
    蠕虫大小:47,104字节
    加壳方式:UPX
    MD5:07adddef653a702b9a11edbcee07e82b
    CRC32:100A382A

    [发作现象]:

    电脑开机时会自动弹出记事本,会生成wincfgs.exe、KB20060111.exe等文件

    [行为分析]:

    1. 在注册表中创建USBSpyRunMutex互斥量,避免重复感染。
    2. 在系统中生成
    C:\%system%\wincfgs.exe(系统、隐藏、只读属性)
    C:\%WINDOWS%\KB20060111.exe(大小66,560 字节,非病毒,是记事本程序)
    3. 在注册表中添加:
    HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\Load=“C:\windows\system32\wincfgs.exe”
    4. 在移动设备中生成RECYCLER\RECYCLER目录和autorun.inf,在这个目录下生成autorun.exe、desktop.ini。

    autorun.inf的内容:

    [autorun]
    open=.\RECYCLER\RECYCLER\autorun.exe

    shell\1=Open
    shell\1\Command=.\RECYCLER\RECYCLER\autorun.exe
    shell\2\=Browser
    shell\2\Command=.\RECYCLER\RECYCLER\autorun.exe

    shellexecute=.\RECYCLER\RECYCLER\autorun.exe


    autorun.exe同wincfgs.exe

    desktop.ini的内容:

    [.ShellClassInfo]
    CLSID={645FF040-5081-101B-9F08-00AA002F954E}

    由此可见,当含有病毒的移动设备接入电脑时,蠕虫会被自动运行。
    开机弹出的记事本便是这个KB20060111.exe文件了,诱发这个KB20060111.exe的启动可能不是常规启动项,而是 wincfgs.exe这个文件启动(呼叫)KB20060111.exe文件的。就是说KB20060111.exe这个文件并非病毒或者Joke程序本身,其实KB20060111.exe就是一个记事本程序(这也就是为什么KB20060111.exe文件的图标也是一个记事本程序的图标的缘故)。另外没有清理wincfgs.exe的计算机再次接入一个干净的移动存储设备可能会再次传染这个移动存储设备。

    [修改办法]
    1、修改注册表
    a.运行“regedit”启动注册表编辑器;
    b.分别删除注册表项
    HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows
    下的Load注册表键里的键值内容。
    不放心的话可以搜索“wincfgs.exe”的注册表键并删除之
    2、删除文件
    %SystemRoot%\system32\wincfgs.exe
    %SystemRoot%\KB20060111.exe
    3移动存储设备:
    连接好USB后,打开我的电脑,点右键选择打开(不要直接点击打开或点“open”),然后打开菜单栏的"工具"->"文件夹选项"->"查看 ",去掉“隐藏受保护的系统文件(推荐)”前面的勾。删除掉优盘里面的desktop.ini,wincfgs.exe和autorun.inf
    移动硬盘的手动删除每个盘符下面的desktop.ini,wincfgs.exe和autorun.inf文件。。

    还有个方便的方法 批处理删除注册表修改:
    复制下面文字到记事本,另存为“Wincfgs_kill.bat”(注意保存时选择文件类型为“所有文件”)

    echo off
    tskill KB20060111
    tskill wincfgs
    del %windir%\kb20060111.exe
    del %windir%\system32\wincfgs.exe
    reg delete "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows" /v "load" /f
    reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows" /v "load" /t REG_SZ /d "" /f

    然后运行,完毕后重启电脑
    November 25

    (转贴)IT人 离开IT还能干什么

     今天一位同事(已30多了),被老板叫到他的办公室去。老总对他说,由于效益不好,公司不再和他续订到期的合同!我看到他很落寞地离去。他前年才结婚,还供着房子,老婆孩子要养,这一下子就失业了,而且又是快过年的时候!我跑去和他道别,他没有说什么,只让我好好干,公司还是大有前途的。

      他是一个好人,在技术上决不保密。记得三年前我刚进公司的时候,他正是公司的主力,他对我这个应届毕业生十分关照,只要我不懂的,他一定尽力相告。那时公司的老板也很器重他,可能是正当壮年的时候(还有很多剥削价值)。但自去年开始,公司转向了。NET平台,我们都去研发新技术了,原有的PB 老版本程序基本上都由一些老程序员来维护(可能老板想他们年龄不小了,学新技术有些障碍)。公司产品的升级工作进展很快,PB版本的程序越来越少了,我们晚上经常加班,而他由于年龄和家庭的缘故,并不经常加班了。我渐渐地从老板对他的态度的变化——从最早的极为欣赏到一般到渐渐地嫌弃。今年公司的效益不太好,也许正是到了鸟尽弓藏、兔死狗烹的时候了?

      上世纪末那会儿,曾有“做IT,35岁就可以退休”的说法,历经沧海这么多年,35岁退休成了童话,35岁的职业坎儿却无法让众多IT人回避。有人说,可以转为管理,然而管理的一条线就像窄窄的独木桥,又有多少人可以通过呢(据统计平均大约100名程序员也就只有一两个做管理的机会)?转向传统行业?已经30多了,能再重新来过吗?绝大多数平凡IT人的出路又在哪儿呢?

      35岁对于IT人是个坎儿,过了这个年纪基本技术生涯即告终结,这是IT界多数人认可的。所以,也让IT人着实为35岁后的自己生了不少忧虑:IT人离开IT后能干什么?

      印象中的IT人都因为职业的缘故而木讷寡言。他们与机器沟通的能力显然优于与人沟通的能力。从机器到人,IT人必须跨过来。

      IT业的技术语言过于狭窄。社会却是复杂的。IT人的知识面不够广泛。社会上不需要人人都懂如何设计程序,但IT人却必须要懂社会。

      IT内的项目,有些人也有些经验,但这些经验性的东西多数是专业性的,个别种类项目的经验能否转化为普遍的社会经验,也确实需要时间。

      这些劣势,可以说,凡是地球上的IT人大概都知道。除了IT,要重新换个活法一时还真的玩不转。

      但IT人毕竟是IT人。IT是高薪行业,IT人从业几年十几年,一般都有了一定的物质基础。这是IT人比其他行业的人具有的优势。
      有了这样的物质基础,我认为,后IT人的关键是要实现思维方式的转变:从技术性思维到社会性思维,从而开创人生事业的第二高峰。

      技术性思维是面向机器的、僵硬的、封闭的、单向性的;社会性思维要求是面向常识和社会的、灵活的、开放的、多向综合的。后IT的人士最需要的是这种思维方式的转变。

      思维一转天地宽。后IT人会发现社会比IT里面其实更精彩。

      后IT人可以走出来干销售。这个工作富于挑战,而且收入与工作业绩直接挂钩。IT人有很强的技术背景,更擅长发掘产品性能的优缺点,对于IT产品的介绍具有权威性,容易被客户相信。

      后IT人可以走出程序迷宫来做培训。IT人在运用某一技术语言上相当精深,另外他们在技术研发中的实战经验,对于学员来说也是相当宝贵的教学资源。

      后IT人也可以由直面数字转为面向众人做咨询。成功的咨询师决不会因为年龄而贬值。有过实际项目经验的IT人,解决实际问题的能力非常强,出身IT的人作为咨询师是其他行业人士无法取代的。还可以做老板,做IT活动策划等等。

      需要提醒的是,思维方式的转变不是一朝一夕的事。一旦离开IT,IT人所要做的是不断调整自我,保持对社会的参与激情。阅读一些人际沟通技巧之类的书籍是必要的,还可以参加社会活动,给自己洗洗脑,从以数字中心、个人中心的思维方式转换到以人为中心、社会为中心的模式中。要注意多与人沟通。同时,个人应该尽早明确自己的发展方向,并根据新的事业来重新积累,不断升级完善自身的“软硬件”。