欢迎来到【分时图显示竞价量比源码】【x站源码php】【安卓生肖源码】windows nt源码-皮皮网网站!!!

皮皮网

【分时图显示竞价量比源码】【x站源码php】【安卓生肖源码】windows nt源码-皮皮网 扫描左侧二维码访问本站手机端

【分时图显示竞价量比源码】【x站源码php】【安卓生肖源码】windows nt源码

2024-12-22 22:26:49 来源:{typename type="name"/} 分类:{typename type="name"/}

1.电脑的工作原理
2.VC++ MFC如何获取CPU ID及硬盘的序列号?

windows nt源码

电脑的工作原理

       ç”µè„‘原理概述

        前面我们已经提过,电脑的工作原理跟电视机、VCD机差不多,您给它发一些指令,它就会按您的意思执行某项功能。不过,您可知道,这些指令并不是直接发给您要控制的硬件,而是先通过前面提过的输入设备,如键盘、鼠标,接收您的指令,然后再由中央处理器(CpU)来处理这些指令,最后才由输出设备输出您要的结果。

        现在,让我们用一道简单的计算题来回想一下人脑的工作方式。

        题目很简单:8+8÷4=?

        首先,我们得用笔将这道题记录在纸上,记在大脑中,再经过脑神经元的思考,结合我们以前掌握的知识,决定用四则运算规则和九九乘法口诀来处理,先用脑算出8÷4=2这一中间结果,并记录于纸上,然后再用脑算出8+2=这一最终结果,并记录于纸上。

        通过做这一简单运算题,我们发现一规律:首先通过眼、耳等感觉器官将捕捉的信息输送到大脑中并存储起来,然后对这一信息进行加工处理,再由大脑控制人把最终结果,以某种方式表达出来。

       ç”µè„‘正是模仿人脑进行工作的(这也是“电脑”名称的来源),其部件如输入设备、存储器、运算器、控制器、输出设备等分别与人脑的各种功能器官对应,以完成信息的输入、处理、输出。

        下图即为计算机的工作原理图。接下来我们将从几个概念来了解一下电脑。

       äºŒã€ç¡¬ä»¶å’Œè½¯ä»¶çš„概念

        在前面我们介绍了电脑是什么样的,及电脑内部是怎样组成的,这些都是我们能够实实在在地“看到”的东西或设备,那些构成电脑的看得见摸得着的东西,如元器件、电路板、零部件等物理实体和物理装置,我们把这些设备都叫做电脑硬件。一个电脑系统中只有硬件是不够的,因为它不能为我们做任何事情,只有在电脑系统中添加了相应的软件后,电脑才能发挥它巨大的作用,才能实现我们所要求的目的。给硬件配备“思想”即指挥它如何工作的软件就使它成为令我们惊奇的电“脑”。

       æ‰€è°“软件,就是安装或存储在电脑中的程序,有时这些软件也存储在外存储器上,如光盘或软盘上。我们所知道的软件有: Windows、Office办公软件、金山词霸、幸福之家、超级解霸等等。

       æˆ‘们可以通过一些例子,来进一步理解软件、硬件的概念。比如:我们经常使用的VCD碟片,就这张碟片本身来说,它只是一个硬件,用来播放VCD的影碟机也是一个硬件,而存储在碟片上的图象和音乐就是软件。

       è½¯ä»¶å¯åˆ†ä¸ºç³»ç»Ÿè½¯ä»¶å’Œåº”用软件,象Windows 这样的软件(也叫做操作系统)就是系统软件,而象“金山词霸”这样的软件就是应用软件。

       é€šè¿‡äº†è§£è½¯ä»¶ã€ç¡¬ä»¶çš„概念,我们也就知道了它们之间的关系,那就是,硬件和软件是相互依存的,硬件为软件提供了物质基础,也就是说软件离开了相应硬件的支持,是无法发挥其作用的,而只有有了软件的支持,也才能使硬件有了用武之地。但是,并不是有了某种硬件就能运行所有的软件,也不是有了某个软件就能在所有的硬件上运行,这就是电脑中很普遍的兼容性问题。

       ç”µè„‘的硬件和软件是相辅相成的。它们共同构成完整的电脑系统,缺一不可,没有软件的电脑等于一堆废铜烂铁,无任何作用;同样,没有硬件,软件也就如无源之水,尤如空中楼阁。它们只有相互配合,电脑才能正常运行。

       ä¸‰ã€åŸºæœ¬è¾“入输出系统

        首先,我们介绍一下裸机的概念,简单的说,裸机即是电脑硬件的组合,也就是大家平时所说的电脑。一般情况下,我们不能直接操作裸机,必须通过一个叫做“基本输入输出系统”的软件系统(英文为basic Input/Output System,简称bIOS),才能操作控制裸机,之所以这样称呼它,是因为它提供了最基本的计算机操作功能,如在屏幕上显示一点,接收一个键盘字符的输入等。

        基本输入输出系统对电脑来说是非常重要的,这个系统的作用直接影响电脑的能否使用。同时几乎所有电脑功能最终都是分解为一个个简单的基本输入输出操作来实现。辟如画一幅风景,就是由一系列不同颜色和亮度点的基本输入输出操作来完成。

        基本输入输出系统存放在主板的只读存储器(英文为Read Only Memory,简称ROM)芯片中,平时不可修改,也没必要修改,但恶性计算机病毒除外,年4月日席卷全球的CIH病毒就破坏了相当一部份电脑的bIOS系统,弄得大家只好找专家才能修复。

       å››ã€æ“ä½œç³»ç»Ÿçš„概念

       åœ¨åŸºæœ¬è¾“入输出系统的外面,才是我们平常念叨的Windows或Windows系统,在电脑界,这些软件又叫操作系统(Operating System简称OS),专门负责管理计算机的各种资源,并提供操作电脑所需的工作界面。有了它们,人们才可以方便自如地使用电脑。正是由于操作系统的飞速发展,才使计算机的使用从高度专业化的技术人员手中,走向了广大普通用户手中,同样也正是由于操作系统的飞速发展,才使得计算机的应用出现了多姿多彩的今天。

        操作系统是管理计算机软硬件资源的一个平台,没有它,任何计算机都无法正常运行。在个人电脑发展史上,出现过许多不同的操作系统,其中最为常用的有五种:Dos、windows、Linux、Unix/Xenix、OS/2,下面分别介绍这五种电脑操作系统的发展过程和功能特点。

       Dos操作系统

        从年问世至今,Dos经历了7次大的版本升级,从1.0版到现在的7.0版,不断地改进和完善。但是,Dos系统的单用户、单任务、字符界面和位的大格局没有变化,因此它对于内存的管理也局限在Kb的范围内。

        Dos最初是为IbM-pC开发的操作系统,因此它对硬件平台的要求很低,即使对于Dos6.这样的高版本Dos,在Kb内存、Mb硬盘、处理器的环境下也可正常运行,因此Dos系统既适合于高档电脑使用,又适合于低档电脑使用。

        常用的Dos有三种不同的品牌,它们是Microsoft公司的MS-Dos、IbM公司的pC-Dos以及Novell公司的DR_Dos,这三种Dos都是兼容的,但仍有一些区别,三种Dos中使用最多的是MS-Dos。

        Dos系统一个最大的优势是它支持众多的通用软件,如各种语言处理程序、数据库管理系统、文字处理软件、电子表格。而且围绕Dos开发了很多应用软件系统,如财务、人事、统计、交通、医院等各种管理系统。鉴于这个原因,尽管Dos已经不能适应位机的硬件系统,但是仍广泛流行,而且在未来的几年内也不会很快被淘汰。

       windows系统

        windows是Microsoft公司在年月发布的第一代窗口式多任务系统,它使pC机开始进入了所谓的图形用户界面(GUI:Graphic User Interface)时代。在图形用户界面中,每一种应用软件(即由windows支持的软件)都用一个图标(Icon)表示,用户只需把鼠标移到某图标上,双击该图标即可进入该软件应用窗口,这种界面方式为用户提供了很大的方便,把计算机的使用提高到了一个新的阶段。

        windows1.X版是一个具有多窗口及多任务功能的版本,但由于当时的硬件平台为pC/XT,速度很慢,所以windows1.X版本并未十分流行。年底Microsoft公司又推出了MS-windows2.X 版,它具有窗口重叠功能,窗口大小也可以调整,并可把扩展内存和扩充内存作为磁盘高速缓存,从而提高了整台计算机的性能,此外它还提供了众多的应用程序:写字板Write、记事本Notepad、计算器Calculator、日历Calendar……等。随后在年、年又先后推出了MS-windows/-V2.1和MS-windows/ V2.1这两个版本。

        年,Microsoft公司推出了windows3.0,它的功能进一步加强,具有强大的内存管理,且提供了数量相当多的windows应用软件,因此成为、微机新的操作系统标准。随后,windows发表3.1版,而且推出了相应的中文版。3.1版较之3.0版增加了一些新的功能,受到了用户欢迎,是当时最流行的windows版本。其中文版为windows 3.2。

        年,Microsoft公司推出了windows(也称为Chicago或windows4.0)。在此之前的windows都是由Dos引导的,也就是说它们还不是一个完全独立的系统,而windows是一个完全独立的系统,并在很多方面作了进一步的改进,还集成了网络功能和即插即用(plug and play)功能,是一个全新的位操作系统。

       å¹´ï¼ŒMicrosoft公司推出了windows的改进版windows,windows的一个最大特点就是把微软的Internet浏览器技术整合到了windows里面,使得访问Internet资源就像访问本地硬盘一样方便,从而更好地满足了人们越来越多的访问Internet资源的需要。

       windows是目前实际使用的主流操作系统。

        近来,有关windows的宣传是越来越多,说到windows,我们不能不提一下Microsoft公司的另一个产品----windowsNT系统(NT是New Technology即新技术的缩写),windowsNT是真正的位操作系统,与普通的windows系统不同,它主要面向商业用户,有服务器版和工作版之分,按原计划,Microsoft公司准备在年将最新的工作站版本NT 5.0和普通的windows统一为一个完整的操作系统,即windows professional,这样,无论对商业用户还是普通个人用户,以后Microsoft公司就只有一个windows操作系统了。

       Linux系统

        Linux是当今电脑界一个耀眼的名字,它是目前全球最大的一个自由免费软件,其本身是一个功能可与Unix和windows相媲美的操作系统,具有完备的网络功能。

        Linux最初由芬兰人Linus Torvalds开发,其源程序在Internet网上公开发布,由此,引发了全球电脑爱好者的开发热情,许多人下载该源程序并按自己的意愿完善某一方面的功能,再发回网上,Linux也因此被雕琢成为一个全球最稳定的、最有发展前景的操作系统。曾经有人戏言:要是比尔·盖茨把windows的源代码也作同样处理,现在windows中残留的许多bUG(错误)早已不复存在,因为全世界的电脑爱好者都会成为windows的义务测试和编程人员。

        Linux操作系统具有如下特点:

        1.它是一个免费软件,您可以自由安装并任意修改软件的源代码。

        2.Linux操作系统与主流的UNIX系统兼容,这使得它一出现就有了一个很好的用户群。

        3.支持几乎所有的硬件平台,包括Intel系列,x0系列,Alpha系列,MIpS系列等,并广泛支持各种周边设备。

        目前,Linux正在全球各地迅速普及推广,各大软件商如Oracle、Sybase、Novell、IbM等均发布了Linux版的产品,许多硬件厂商也推出了预装Linux操作系统的服务器产品,当然,pC用户也可使用Linux。另外,还有不少公司或组织有计划地收集有关Linux的软件,组合成一套完整的Linux发行版本上市,比较著名的有RedHat(即红帽子)、Slackware等公司。目前较为流行的版本有RedHat Linux、红旗Linux等。虽然,现在说Linux会取代Unix和windows还为时过早,但一个稳定性、灵活性和易用性都非常好的软件,肯定会得到越来越广泛的应用。

       Unix系统

        Unix系统是年问世的,最初是在中小型计算机上运用。最早移植到微机上的Unix系统,称为Xenix。Xenix系统的特点是短小精干,系统开销小,运行速度快。经过多年的发展,Xenix已成为十分成熟的系统,最新版本的Xenix是SCO Unix和SCO CDT。当前的主要版本是Unix 3.2 V4.2以及ODT 3.0。

        Unix是一个多用户系统,一般要求配有8M以上的内存和较大容量的硬盘。

       OS/2系统

        å¹´IbM公司在激烈的市场竞争中推出了pS/2(personal System/2)个人电脑。pS/2系列电脑大幅度突破了现行pC机的体系,采用了与其它总线互不兼容的微通道总线MCA,并且IbM自行设计了该系统约%的零部件,以防止其它公司仿制。

        OS/2系统正是为pS/2系列机开发的一个新型多任务操作系统。OS/2克服了Dos系统Kb主存的限制,具有多任务功能。OS/2也采用图形界面,它本身是一个位系统,不仅可以处理位OS/2系统的应用软件,也可以运行位Dos和windows软件。

        OS/2系统通常要求在4Mb内存和Mb硬盘或更高的硬件环境下运行。

        五、应用软件的概念

        顾名思义,应用软件即是提供某种特定功能的软件,如现在您使用的《WpS》、《WORD》等,它们一般都运行在操作系统(如Windows)之上,由专业人员根据各种需要开发。我们平时见到和使用的绝大部分软件均为应用软件,如杀毒软件,文字处理软件,学习软件,游戏软件,上网软件等等。

       ä¸‹å›¾å³ä¸ºä¸€å¥—完整的电脑系统示意框图。

       åˆ°çŽ°åœ¨æˆ‘们会发现,电脑的组成非常象我们人及人的行为:电脑的主机就类似与我们的大脑,因为,我们人是用大脑在思考问题进行运算的,同时我们的大脑还能记忆很多我们所遇见过的和学习过的东西。这也是为什么叫做电脑的原因;电脑的外设就类似与人的眼、耳、四肢等,以及我们用来记录所发生的事情或要做的事情的笔记本。但电脑与人有本质的不同,这就是电脑永远是由人来控制的,是帮助人进行脑力劳动的工具。

VC++ MFC如何获取CPU ID及硬盘的序列号?

       // “获得Intel CPU ID”按钮消息处理函数

       void CIntelCPUIDDlg::OnBtnCPUID()

       {

        unsigned long s1,分时图显示竞价量比源码s2;

        unsigned char vendor_id[]="------------";//CPU提供商ID

        CString str1,str2,str3;

        // 以下为获得CPU ID的汇编语言指令

        _asm // 得到CPU提供商信息

        {

        xor eax,eax // 将eax清0

        cpuid // 获取CPUID的指令

        mov dword ptr vendor_id,ebx

        mov dword ptr vendor_id[+4],edx

        mov dword ptr vendor_id[+8],ecx

        }

        str1.Format("%s",vendor_id);

        _asm // 得到CPU ID的高位

        {

        mov eax,h

        xor edx,edx

        cpuid

        mov s2,eax

        }

        str2.Format("%X-",s2);

        _asm // 得到CPU ID的低位

        {

        mov eax,h

        xor ecx,ecx

        xor edx,edx

        cpuid

        mov s1,edx

        mov s2,ecx

        }

        str3.Format("%X-%X\n",s1,s2);

        str2=str2+str3;

        m_editVendor.SetWindowText(str1);

        m_editCPUID.SetWindowText(str2);

       }

       // GetHDSerial.cpp: implementation of the CGetHDSerial class.

       //

       //////////////////////////////////////////////////////////////////////

       #include "stdafx.h"

       #include "GetHDSerial.h"

       char m_buffer[];

       WORD m_serial[];

       DWORD m_OldInterruptAddress;

       DWORDLONG m_IDTR;

       // 等待硬盘空闲

       static unsigned int WaitHardDiskIdle()

       {

        BYTE byTemp;

       Waiting:

        _asm

        {

        mov dx, 0x1f7

        in al, dx

        cmp al, 0x

        jb Endwaiting

        jmp Waiting

        }

       Endwaiting:

        _asm

        {

        mov byTemp, al

        }

        return byTemp;

       }

       //中断服务程序

       void _declspec( naked )InterruptProcess(void)

       {

        int byTemp;

        int i;

        WORD temp;

        //保存寄存器值

        _asm

        {

        push eax

        push ebx

        push ecx

        push edx

        push esi

        }

        WaitHardDiskIdle();//等待硬盘空闲状态

        _asm

        {

        mov dx, 0x1f6

        mov al, 0xa0

        out dx, al

        }

        byTemp = WaitHardDiskIdle(); //若直接在Ring3级执行等待命令,会进入死循环

        if ((byTemp&0x)!=0x)

        {

        _asm // 恢复中断现场并退出中断服务程序

        {

        pop esi

        pop edx

        pop ecx

        pop ebx

        pop eax

        iretd

        }

        }

        _asm

        {

        mov dx, 0x1f6 //命令端口1f6,选择驱动器0

        mov al, 0xa0

        out dx, al

        inc dx

        mov al, 0xec

        out dx, al //发送读驱动器参数命令

        }

        byTemp = WaitHardDiskIdle();

        if ((byTemp&0x)!=0x)

        {

        _asm // 恢复中断现场并退出中断服务程序

        {

        pop esi

        pop edx

        pop ecx

        pop ebx

        pop eax

        iretd

        }

        }

        //读取硬盘控制器的全部信息

        for (i=0;i<;i++)

        {

        _asm

        {

        mov dx, 0x1f0

        in ax, dx

        mov temp, ax

        }

        m_serial[i] = temp;

        }

        _asm

        {

        pop esi

        pop edx

        pop ecx

        pop ebx

        pop eax

        iretd

        }

       }

       //////////////////////////////////////////////////////////////////////

       // Construction/Destruction

       //////////////////////////////////////////////////////////////////////

       CGetHDSerial::CGetHDSerial()

       {

       }

       CGetHDSerial::~CGetHDSerial()

       {

       }

       // 读取硬盘序列号函数

       char* CGetHDSerial::GetHDSerial()

       {

        m_buffer[0]='\n';

        // 得到当前操作系统版本

        OSVERSIONINFO OSVersionInfo;

        OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

        GetVersionEx( &OSVersionInfo);

        if (OSVersionInfo.dwPlatformId != VER_PLATFORM_WIN_NT)

        {

        // Windows 9x/ME下读取硬盘序列号

        WORD m_wWin9xHDSerial[];

        Win9xReadHDSerial(m_wWin9xHDSerial);

        strcpy (m_buffer, WORDToChar (m_wWin9xHDSerial, , ));

        }

        else

        {

        // Windows NT//XP下读取硬盘序列号

        DWORD m_wWinNTHDSerial[];

        // 判断是否有SCSI硬盘

        if ( ! WinNTReadIDEHDSerial(m_wWinNTHDSerial))

        WinNTReadSCSIHDSerial(m_wWinNTHDSerial);

        strcpy (m_buffer, DWORDToChar (m_wWinNTHDSerial, , ));

        }

        return m_buffer;

       }

       // Windows9X/ME系统下读取硬盘序列号

       void _stdcall CGetHDSerial::Win9xReadHDSerial(WORD * buffer)

       {

        int i;

        for(i=0;i<;i++)

        buffer[i]=0;

        _asm

        {

        push eax

        //获取修改的中断的中断描述符(中断门)地址

        sidt m_IDTR

        mov eax,dword ptr [m_IDTR+h]

        add eax,3*h+h

        cli

        //保存原先的中断入口地址

        push ecx

        mov ecx,dword ptr [eax]

        mov cx,word ptr [eax-h]

        mov dword ptr m_OldInterruptAddress,ecx

        pop ecx

        //设置修改的中断入口地址为新的中断处理程序入口地址

        push ebx

        lea ebx,InterruptProcess

        mov word ptr [eax-h],bx

        shr ebx,h

        mov word ptr [eax+h],bx

        pop ebx

        //执行中断,转到Ring 0(类似CIH病毒原理)

        int 3h

        //恢复原先的中断入口地址

        push ecx

        mov ecx,dword ptr m_OldInterruptAddress

        mov word ptr [eax-h],cx

        shr ecx,h

        mov word ptr [eax+h],cx

        pop ecx

        sti

        pop eax

        }

        for(i=0;i<;i++)

        buffer[i]=m_serial[i];

       }

       // Windows 9x/ME系统下,将字类型(WORD)的硬盘信息转换为字符类型(char)

       char * CGetHDSerial::WORDToChar (WORD diskdata [], int firstIndex, int lastIndex)

       {

        static char string [];

        int index = 0;

        int position = 0;

        // 按照高字节在前,低字节在后的顺序将字数组diskdata 中内容存入到字符串string中

        for (index = firstIndex; index <= lastIndex; index++)

        {

        // 存入字中的高字节

        string [position] = (char) (diskdata [index] / );

        position++;

        // 存入字中的低字节

        string [position] = (char) (diskdata [index] % );

        position++;

        }

        // 添加字符串结束标志

        string [position] = '\0';

        // 删除字符串中空格

        for (index = position - 1; index > 0 && ' ' == string [index]; index--)

        string [index] = '\0';

        return string;

       }

       // Windows NT//XP系统下,将双字类型(DWORD)的硬盘信息转换为字符类型(char)

       char* CGetHDSerial::DWORDToChar (DWORD diskdata [], int firstIndex, int lastIndex)

       {

        static char string [];

        int index = 0;

        int position = 0;

        // 按照高字节在前,低字节在后的顺序将双字中的低字存入到字符串string中

        for (index = firstIndex; index <= lastIndex; index++)

        {

        // 存入低字中的高字节

        string [position] = (char) (diskdata [index] / );

        position++;

        // 存入低字中的低字节

        string [position] = (char) (diskdata [index] % );

        position++;

        }

        // 添加字符串结束标志

        string [position] = '\0';

        // 删除字符串中空格

        for (index = position - 1; index > 0 && ' ' == string [index]; index--)

        string [index] = '\0';

        return string;

       }

       // Windows NT//XP下读取IDE硬盘序列号

       BOOL CGetHDSerial::WinNTReadIDEHDSerial(DWORD * buffer)

       {

        BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];

        BOOL bFlag = FALSE;

        int drive = 0;

        char driveName [];

        HANDLE hPhysicalDriveIOCTL = 0;

        sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive);

        // Windows NT//XP下创建文件需要管理员权限

        hPhysicalDriveIOCTL = CreateFile (driveName,

        GENERIC_READ | GENERIC_WRITE,

        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,

        OPEN_EXISTING, 0, NULL);

        if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)

        {

        GETVERSIONOUTPARAMS VersionParams;

        DWORD cbBytesReturned = 0;

        // 得到驱动器的IO控制器版本

        memset ((void*) &VersionParams, 0, sizeof(VersionParams));

        if(DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_VERSION,

        NULL, 0, &VersionParams,

        sizeof(VersionParams),

        &cbBytesReturned, NULL) )

        {

        if (VersionParams.bIDEDeviceMap > 0)

        {

        BYTE bIDCmd = 0; // IDE或者ATAPI识别命令

        SENDCMDINPARAMS scip;

        // 如果驱动器是光驱,采用命令IDE_ATAPI_IDENTIFY, command,

        // 否则采用命令IDE_ATA_IDENTIFY读取驱动器信息

        bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x)?

        IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;

        memset (&scip, 0, sizeof(scip));

        memset (IdOutCmd, 0, sizeof(IdOutCmd));

        // 获取驱动器信息

        if (WinNTGetIDEHDInfo (hPhysicalDriveIOCTL,

        &scip,

        (PSENDCMDOUTPARAMS)&IdOutCmd,

        (BYTE) bIDCmd,

        (BYTE) drive,

        &cbBytesReturned))

        {

        int m = 0;

        USHORT *pIdSector = (USHORT *)

        ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;

        for (m = 0; m < ; m++)

        buffer[m] = pIdSector [m];

        bFlag = TRUE; // 读取硬盘信息成功

        }

        }

        }

        CloseHandle (hPhysicalDriveIOCTL); // 关闭句柄

        }

        return bFlag;

       }

       // WindowsNT//XP系统下读取SCSI硬盘序列号

       BOOL CGetHDSerial::WinNTReadSCSIHDSerial (DWORD * buffer)

       {

        buffer[0]='\n';

        int controller = 0;

        HANDLE hScsiDriveIOCTL = 0;

        char driveName [];

        sprintf (driveName, "\\\\.\\Scsi%d:", controller);

        // Windows NT//XP下任何权限都可以进行

        hScsiDriveIOCTL = CreateFile (driveName,

        GENERIC_READ | GENERIC_WRITE,

        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,

        OPEN_EXISTING, 0, NULL);

        if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE)

        {

        int drive = 0;

        DWORD dummy;

        for (drive = 0; drive < 2; drive++)

        {

        char buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH];

        SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer;

        SENDCMDINPARAMS *pin =

        (SENDCMDINPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));

        // 准备参数

        memset (buffer, 0, sizeof (buffer));

        p -> HeaderLength = sizeof (SRB_IO_CONTROL);

        p -> Timeout = ;

        p -> Length = SENDIDLENGTH;

        p -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;

        strncpy ((char *) p -> Signature, "SCSIDISK", 8);

        pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;

        pin -> bDriveNumber = drive;

        // 得到SCSI硬盘信息

        if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT,

        buffer,

        sizeof (SRB_IO_CONTROL) +

        sizeof (SENDCMDINPARAMS) - 1,

        buffer,

        sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,

        &dummy, NULL))

        {

        SENDCMDOUTPARAMS *pOut =

        (SENDCMDOUTPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));

        IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer);

        if (pId -> sModelNumber [0])

        {

        int n = 0;

        USHORT *pIdSector = (USHORT *) pId;

        for (n = 0; n < ; n++)

        buffer[n] =pIdSector [n];

        return TRUE; // 读取成功

        }

        }

        }

        CloseHandle (hScsiDriveIOCTL); // 关闭句柄

        }

        return FALSE; // 读取失败

       }

       // Windows NT//XP下读取IDE设备信息

       BOOL CGetHDSerial::WinNTGetIDEHDInfo (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,

        PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,

        PDWORD lpcbBytesReturned)

       {

        // 为读取设备信息准备参数

        pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;

        pSCIP -> irDriveRegs.bFeaturesReg = 0;

        pSCIP -> irDriveRegs.bSectorCountReg = 1;

        pSCIP -> irDriveRegs.bSectorNumberReg = 1;

        pSCIP -> irDriveRegs.bCylLowReg = 0;

        pSCIP -> irDriveRegs.bCylHighReg = 0;

        // 计算驱动器位置

        pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4);

        // 设置读取命令

        pSCIP -> irDriveRegs.bCommandReg = bIDCmd;

        pSCIP -> bDriveNumber = bDriveNum;

        pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;

        // 读取驱动器信息

        return ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_DRIVE_INFO,

        (LPVOID) pSCIP,

        sizeof(SENDCMDINPARAMS) - 1,

        (LPVOID) pSCOP,

        sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,

        lpcbBytesReturned, NULL) );

       }