关于识别及控制硬盘和USB等外设的一些问题?请提供思路或是相关资料,谢谢

时间:2023-02-20 22:13:10
在98,2000,me,NT下,
1.我编程时怎么知道哪一个是“我的电脑”:例如:我的桌面上有包含C:,D:的“我的电脑”,另外我新建了一个文件夹,也叫“我的电脑”,编程时如何区别两者?利用注册表中的GUID?如何利用GUID?
2.我自己的程序怎么像操作系统那样能够随时知道USB外设或是其他硬件连通还是断开,类似这样的实时监控要利用什么方法做?消息循环?
3.像虚拟光驱,USB硬盘这类东西装到电脑上后会自动分到F:,G:之类的盘符,那么我如何知道哪个盘符对应哪个设备,如:我安装了两个不同的虚拟光驱软件和两个不同的USB硬盘,结果出现了四个盘符:F:,G:,H:,I:,随着我插入USB硬盘的次序不同,这四个盘符的对应关系也会变化,那么我在编程时如何知道某一个盘符就是我想要的那一个呢?是不是要利用设备驱动之类的方法?

另外最好能做到98,2000,me,NT兼容,比如说我试着用注册表中的GUID方法来解决,可发现98和2000放置驱动程序GUID的位置不一样,还有听说2000不支持VxD

请提供思路或是相关资料,谢谢

22 个解决方案

#1


help

#2


up一下

#3


1、既然98、NT不一样,你把每一个都找出准确位置。程序头加上一段宏,根据操作系统版本,定义不同的常量值。
2、一点思路:在98下,拿掉USB没有提示,在ME下,有提示,你可以跟踪一下,看看调用的是什么。资料没有,笨方法,假如知道容量,可以穷举盘符,比较容量

#4


up

#5


UP

#6


no_limit(一切反动派都是纸老虎) :
穷举盘符是好办法,可如果两个USB容量相同就不行了

#7


1、可以用GetDesktopFolder来得到指向桌面的IShellFolder,然后用IShellFolder的EnumObjects来得到桌面上的所有对象,然后就可以得到每个对象的所有属性,你自然就可以知道哪个是文件夹,哪个是真的“我的电脑”了。
2、做一个死循环的线程不断去查就好了。
3、用GetDriveType可以区分cdrom和usb盘,不知道你要区分到什么程度?如果要再详细的信息的话,可以再查一下与IShellFolder相关的函数和信息。

#8


kicku():
我是在用GetDesktopFolder来得到指向桌面的IShellFolder,然后用IShellFolder的EnumObjects来得到桌面上的所有对象,然后就可以得到每个对象的所有属性,可我还是不知道该怎么区分,属性中没有这项功能
死循环的线程不断去查-----操作系统是这样做的吗?
GetDriveType可以区分cdrom和usb盘,但是如何知道哪一个盘符是cdrom,哪一个盘符是usb盘???

#9


up

#10


UP

#11


// shellfolder.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <comdef.h>
#include <atlbase.h>
#include <objbase.h>
#include <shlobj.h>
#include <stdio.h>
#include <shlwapi.h>

int main(int argc, char* argv[])
{
CoInitialize(NULL);
USES_CONVERSION;
IShellFolder* pDesktop;
IEnumIDList* pIdList;
ITEMIDLIST* pItemList;
STRRET strRet;
LPSTR str;
HRESULT hr;
ULONG rgf;

hr = SHGetDesktopFolder(&pDesktop);
hr = pDesktop->EnumObjects(NULL, SHCONTF_FOLDERS, &pIdList);
while(pIdList->Next(1, &pItemList, NULL) != S_FALSE) {
hr = pDesktop->GetDisplayNameOf(pItemList, SHGDN_NORMAL, &strRet);
if (strRet.uType == STRRET_WSTR) {
str = W2A(strRet.pOleStr);
} else if (strRet.uType == STRRET_CSTR) {
str = strRet.cStr;
}
printf("%s\n", str);
rgf = SFGAO_FILESYSTEM;
hr = pDesktop->GetAttributesOf(1, (LPCITEMIDLIST *)(&pItemList), &rgf);
if (rgf & SFGAO_FILESYSTEM) {
printf("\tIt's a folder!\n");
}
}
CoTaskMemFree(pItemList);
pIdList->Release();
pDesktop->Release();
CoUninitialize();
return 0;
}

#12


kicku():
你写的这段代码与我提的问题无关阿?
你这段代码只是遍历了桌面,然后把桌面的对象的显示名称打出来,如果是文件夹的话则打印这是文件夹。
我研究了一下,下述代码可以解答我的第一个问题:
LPITEMIDLIST    lph,lph1=0;
                SHGetSpecialFolderLocation(hwnd,CSIDL_DRIVES,&lph);
HRESULT hres=lpsf->CompareIDs(0,lph,lpi);
hres如果是零,表示他是真正的我的电脑
现在第2,3个问题还是不会。

#13


UP,学习

#14


你不是只要区分是“我的电脑”还是一个文件夹么?那我的程序就可以了啊..... ;-)

第二个问题,就用一个死循环吧,没问题的。

第三个问题,先用GetLogicDrives得到当前系统里所有的盘符,然后用一个循环,一个一个GetDriveType试吧....很快的....

#15


kicku() :
1.如果“我的电脑”被改名了,或是英文版的“my computer”,那你这招就不灵了。我要的是真正的“我的电脑”,不论任何情况都能被程序认出,我研究的那段代码可以做到:
     LPITEMIDLIST    lph,lph1=0;
     SHGetSpecialFolderLocation(hwnd,CSIDL_DRIVES,&lph);
     HRESULT hres=lpsf->CompareIDs(0,lph,lpi);  //lpi是传过来的要比较的LPITEMIDLIST,如果hres等于0,那么lpi所代表的就是真正的“我的电脑”
2.辅助线程死循环,那么辅助线程被杀死(比如用2000的任务管理器)怎么办?
3.GetDriveType只能获得磁盘的简单信息,我要的是跟驱动相关的信息,我研究了一下,确实是利用GUID来解决,主要利用函数SetupDiGetDeviceRegistryProperty把磁盘的GUID读出来,不管它放在注册表的那个位置,然后一比较就OK了

#16


2、
首先,task manager看不到线程。
然后......
只要是程序就会被杀死啊,用service倒是杀不死,可是服务可以停掉啊。只要用户有管理员的权限,想不让你运行还不简单啊?

#17


kicku() :
第二个问题也有方法了,设备发生变化时windows会发出WM_DEVICECHANGE消息,哈哈哈....
这样三个问题就都解决了,多谢帮忙。

#18


(代码分为两部分放上来)
通常情况下,我们通过0XEC命令对IDE端口进行监测.获取硬盘信息. 
一般情况下,我们就写个VXD或者DRIVER来完成.但是现在,通过MS的S.M.A.R.T.接口,我们可以直接从RING3调用API DeviceIoControl()来获取硬盘信息.下面乃是我的例程: 
另外,也有编译好的版本供大家平时使用.欢迎下载. 
*注:在WIN98SE,WINDOWS ME中,S.M.A.R.T并不缺省安装.请将SMARTVSD.VXD拷贝到%SYSTEM%\IOSUBSYS目录下. 
在WINDOWS2000下,由于非ADMINISTRATORS组的用户对硬盘连GENERIC_READ的权限也没有,所以请以ADMINISTRATOR登录后使用. 
/*+++ 
HDID.CPP 
Written by Lu Lin 
http://lu0.126.com 
2000.11.3 
---*/ 
#include <windows.h> 
#include <iostream.h> 
#include <stdio.h> 

#define DFP_GET_VERSION 0x00074080 
#define DFP_SEND_DRIVE_COMMAND 0x0007c084 
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088 

#pragma pack(1) 
typedef struct _GETVERSIONOUTPARAMS { 
BYTE bVersion;  // Binary driver version. 
BYTE bRevision;  // Binary driver revision. 
BYTE bReserved;  // Not used. 
BYTE bIDEDeviceMap; // Bit map of IDE devices. 
DWORD fCapabilities; // Bit mask of driver capabilities. 
DWORD dwReserved[4]; // For future use. 
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS; 

typedef struct _IDEREGS { 
BYTE bFeaturesReg;  // Used for specifying SMART "commands". 
BYTE bSectorCountReg; // IDE sector count register 
BYTE bSectorNumberReg; // IDE sector number register 
BYTE bCylLowReg;  // IDE low order cylinder value 
BYTE bCylHighReg;  // IDE high order cylinder value 
BYTE bDriveHeadReg;  // IDE drive/head register 
BYTE bCommandReg;  // Actual IDE command. 
BYTE bReserved;  // reserved for future use.  Must be zero. 
} IDEREGS, *PIDEREGS, *LPIDEREGS; 

typedef struct _SENDCMDINPARAMS { 
DWORD cBufferSize;  // Buffer size in bytes 
IDEREGS irDriveRegs;  // Structure with drive register values. 
BYTE bDriveNumber;  // Physical drive number to send 
      // command to (0,1,2,3). 
BYTE bReserved[3];  // Reserved for future expansion. 
DWORD dwReserved[4];  // For future use. 
//BYTE  bBuffer[1];  // Input buffer. 
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS; 

typedef struct _DRIVERSTATUS { 
BYTE bDriverError;  // Error code from driver, 
      // or 0 if no error. 
BYTE bIDEStatus;  // Contents of IDE Error register. 
      // Only valid when bDriverError 
      // is SMART_IDE_ERROR. 
BYTE bReserved[2];  // Reserved for future expansion. 
DWORD dwReserved[2];  // Reserved for future expansion. 
} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS; 

typedef struct _SENDCMDOUTPARAMS { 
DWORD    cBufferSize;  // Size of bBuffer in bytes 
DRIVERSTATUS DriverStatus;  // Driver status structure. 
BYTE  bBuffer[512];  // Buffer of arbitrary length 
        // in which to store the data read from the drive. 
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS; 

typedef struct _IDSECTOR { 
USHORT wGenConfig; 
USHORT wNumCyls; 
USHORT wReserved; 
USHORT wNumHeads; 
USHORT wBytesPerTrack; 
USHORT wBytesPerSector; 
USHORT wSectorsPerTrack; 
USHORT wVendorUnique[3]; 
CHAR sSerialNumber[20]; 
USHORT wBufferType; 
USHORT wBufferSize; 
USHORT wECCSize; 
CHAR sFirmwareRev[8]; 
CHAR sModelNumber[40]; 
USHORT wMoreVendorUnique; 
USHORT wDoubleWordIO; 
USHORT wCapabilities; 
USHORT wReserved1; 
USHORT wPIOTiming; 
USHORT wDMATiming; 
USHORT wBS; 
USHORT wNumCurrentCyls; 
USHORT wNumCurrentHeads; 
USHORT wNumCurrentSectorsPerTrack; 
ULONG ulCurrentSectorCapacity; 
USHORT wMultSectorStuff; 
ULONG ulTotalAddressableSectors; 
USHORT wSingleWordDMA; 
USHORT wMultiWordDMA; 
BYTE bReserved[128]; 
} IDSECTOR, *PIDSECTOR; 

/*+++ 
Global vars 
---*/ 
GETVERSIONOUTPARAMS vers; 
SENDCMDINPARAMS in; 
SENDCMDOUTPARAMS out; 
HANDLE h; 
DWORD i; 
BYTE j; 

void CopyRight(){ 
cerr<<endl<<"HDD identifier v1.0 for WIN95/98/Me/NT/2000. written by Lu Lin"<<endl; 
cerr<<"For more information, please visit Inside Programming: http://lu0.126.com"<<endl; 
cerr<<"2000.11.3"<<endl<<endl; 
}

#19


VOID ChangeByteOrder(PCHAR szString, USHORT uscStrSize) 


USHORT i; 
CHAR temp; 
for (i = 0; i < uscStrSize; i+=2) 

temp = szString[i]; 
szString[i] = szString[i+1]; 
szString[i+1] = temp; 



void DetectIDE(BYTE bIDEDeviceMap){ 
if (bIDEDeviceMap&1){ 
if (bIDEDeviceMap&16){ 
  cout<<"ATAPI device is attached to primary controller, drive 0."<<endl; 
}else{ 
  cout<<"IDE device is attached to primary controller, drive 0."<<endl; 


if (bIDEDeviceMap&2){ 
if (bIDEDeviceMap&32){ 
  cout<<"ATAPI device is attached to primary controller, drive 1."<<endl; 
}else{ 
  cout<<"IDE device is attached to primary controller, drive 1."<<endl; 


if (bIDEDeviceMap&4){ 
if (bIDEDeviceMap&64){ 
  cout<<"ATAPI device is attached to secondary controller, drive 0."<<endl; 
}else{ 
  cout<<"IDE device is attached to secondary controller, drive 0."<<endl; 


if (bIDEDeviceMap&8){ 
if (bIDEDeviceMap&128){ 
  cout<<"ATAPI device is attached to secondary controller, drive 1."<<endl; 
}else{ 
  cout<<"IDE device is attached to secondary controller, drive 1."<<endl; 




void hdid9x(){ 
ZeroMemory(&vers,sizeof(vers)); 
//We start in 95/98/Me 
h=CreateFile("\\\\.\\Smartvsd",0,0,0,CREATE_NEW,0,0); 
if (!h){ 
cout<<"open smartvsd.vxd failed"<<endl; 
exit(0); 


if (!DeviceIoControl(h,DFP_GET_VERSION,0,0,&vers,sizeof(vers),&i,0)){ 
cout<<"DeviceIoControl failed:DFP_GET_VERSION"<<endl; 
CloseHandle(h); 
return; 

//If IDE identify command not supported, fails 
if (!(vers.fCapabilities&1)){ 
cout<<"Error: IDE identify command not supported."; 
CloseHandle(h); 
return; 

//Display IDE drive number detected 
DetectIDE(vers.bIDEDeviceMap); 
//Identify the IDE drives 
for (j=0;j<4;j++){ 
PIDSECTOR phdinfo; 
char s[41]; 

ZeroMemory(&in,sizeof(in)); 
ZeroMemory(&out,sizeof(out)); 
if (j&1){ 
  in.irDriveRegs.bDriveHeadReg=0xb0; 
}else{ 
  in.irDriveRegs.bDriveHeadReg=0xa0; 

if (vers.fCapabilities&(16>>j)){ 
  //We don't detect a ATAPI device. 
  cout<<"Drive "<<(int)(j+1)<<" is a ATAPI device, we don't detect it"<<endl; 
  continue; 
}else{ 
  in.irDriveRegs.bCommandReg=0xec; 

in.bDriveNumber=j; 
in.irDriveRegs.bSectorCountReg=1; 
in.irDriveRegs.bSectorNumberReg=1; 
in.cBufferSize=512; 
if (!DeviceIoControl(h,DFP_RECEIVE_DRIVE_DATA,&in,sizeof(in),&out,sizeof(out),&i,0)){ 
  cout<<"DeviceIoControl failed:DFP_RECEIVE_DRIVE_DATA"<<endl; 
  CloseHandle(h); 
  return; 

phdinfo=(PIDSECTOR)out.bBuffer; 
memcpy(s,phdinfo->sModelNumber,40); 
s[40]=0; 
ChangeByteOrder(s,40); 
cout<<endl<<"Module Number:"<<s<<endl; 
memcpy(s,phdinfo->sFirmwareRev,8); 
s[8]=0; 
ChangeByteOrder(s,8); 
cout<<"\tFirmware rev:"<<s<<endl; 
memcpy(s,phdinfo->sSerialNumber,20); 
s[20]=0; 
ChangeByteOrder(s,20); 
cout<<"\tSerial Number:"<<s<<endl; 
cout<<"\tCapacity:"<<phdinfo->ulTotalAddressableSectors/2/1024<<"M"<<endl<<endl; 


//Close handle before quit 
CloseHandle(h); 
CopyRight(); 



void hdidnt(){ 
char hd[80]; 
PIDSECTOR phdinfo; 
char s[41]; 

ZeroMemory(&vers,sizeof(vers)); 
//We start in NT/Win2000 
for (j=0;j<4;j++){ 
sprintf(hd,"\\\\.\\PhysicalDrive%d",j); 
h=CreateFile(hd,GENERIC_READ|GENERIC_WRITE, 
  FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0); 
if (!h){ 
  continue; 

if (!DeviceIoControl(h,DFP_GET_VERSION,0,0,&vers,sizeof(vers),&i,0)){ 
  CloseHandle(h); 
  continue; 

//If IDE identify command not supported, fails 
if (!(vers.fCapabilities&1)){ 
  cout<<"Error: IDE identify command not supported."; 
  CloseHandle(h); 
  return; 

//Identify the IDE drives 
ZeroMemory(&in,sizeof(in)); 
ZeroMemory(&out,sizeof(out)); 
if (j&1){ 
  in.irDriveRegs.bDriveHeadReg=0xb0; 
}else{ 
  in.irDriveRegs.bDriveHeadReg=0xa0; 

if (vers.fCapabilities&(16>>j)){ 
  //We don't detect a ATAPI device. 
cout<<"Drive "<<(int)(j+1)<<" is a ATAPI device, we don't detect it"<<endl; 
  continue; 
}else{ 
  in.irDriveRegs.bCommandReg=0xec; 

in.bDriveNumber=j; 
in.irDriveRegs.bSectorCountReg=1; 
in.irDriveRegs.bSectorNumberReg=1; 
in.cBufferSize=512; 
if (!DeviceIoControl(h,DFP_RECEIVE_DRIVE_DATA,&in,sizeof(in),&out,sizeof(out),&i,0)){ 
  cout<<"DeviceIoControl failed:DFP_RECEIVE_DRIVE_DATA"<<endl; 
  CloseHandle(h); 
  return; 

phdinfo=(PIDSECTOR)out.bBuffer; 
memcpy(s,phdinfo->sModelNumber,40); 
s[40]=0; 
ChangeByteOrder(s,40); 
cout<<endl<<"Module Number:"<<s<<endl; 
memcpy(s,phdinfo->sFirmwareRev,8); 
s[8]=0; 
ChangeByteOrder(s,8); 
cout<<"\tFirmware rev:"<<s<<endl; 
memcpy(s,phdinfo->sSerialNumber,20); 
s[20]=0; 
ChangeByteOrder(s,20); 
cout<<"\tSerial Number:"<<s<<endl; 
cout<<"\tCapacity:"<<phdinfo->ulTotalAddressableSectors/2/1024<<"M"<<endl<<endl; 
CloseHandle(h); 

CopyRight(); 


void main(){ 
OSVERSIONINFO VersionInfo; 

ZeroMemory(&VersionInfo,sizeof(VersionInfo)); 
VersionInfo.dwOSVersionInfoSize=sizeof(VersionInfo); 
GetVersionEx(&VersionInfo); 

switch (VersionInfo.dwPlatformId){ 
case VER_PLATFORM_WIN32s: 
cout<<"Win32s is not supported by this programm."<<endl; 
return; 
case VER_PLATFORM_WIN32_WINDOWS: 
hdid9x(); 
return; 
case VER_PLATFORM_WIN32_NT: 
hdidnt(); 
return; 

}

#20


特别提示
上面的程序可以获得银盘的序号和特别标示功能
如S.M.A.T.P等的参数

但是必须在WIN2000,WINXP操作系统上实现

#21


baoch110(来自北方的包子) :
    2000不支持VxD吧?
    利用下述方法也可以获得硬盘的相关信息:
    主要就是两个函数,一个是你说的DeviceIoControl(),另一个是SetupDiGetDeviceRegistryProperty
    //////////////////////////////////////////////////////////////////////////// 
////////////////////////////////////// 
On Win2k you open the root device for each drive letter (DriveToOpen="C:", 
"D:", etc.) 
Then do the following to get the scsi disk id: 
//////////////////////////////////////////////////////////////////////////// 
////////////////////////////////////// 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hDevice = CreateFile( 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DriveToOpen,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 
device interface name 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GENERIC_READ | GENERIC_WRITE,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // dwDesiredAccess 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // lpSecurityAttributes 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OPEN_EXISTING,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // dwCreationDistribution 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // dwFlagsAndAttributes 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // hTemplateFile 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ); 
&nbsp;&nbsp;&nbsp;&nbsp; // query the info 
&nbsp;&nbsp;&nbsp; query.PropertyId = StorageDeviceProperty; 
&nbsp;&nbsp;&nbsp; query.QueryType = PropertyStandardQuery; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = DeviceIoControl( 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hDevice, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IOCTL_STORAGE_QUERY_PROPERTY, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &query, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof( STORAGE_PROPERTY_QUERY ), 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &outBuf, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 512, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &returnedLength, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ); 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; devDesc = (PSTORAGE_DEVICE_DESCRIPTOR) outBuf; 
//////////////////////////////////////////////////////////////////////////// 
////////////////////////////////////// 
On Win9x you enumerate all the drives using the SetupDi interfaces: 
//////////////////////////////////////////////////////////////////////////// 
////////////////////////////////////// 
&nbsp;&nbsp;&nbsp; // 
&nbsp;&nbsp;&nbsp; // Create a Device Information Set with all present devices. 
&nbsp;&nbsp;&nbsp; // 
&nbsp;&nbsp;&nbsp; DeviceInfoSet = SetupDiGetClassDevs( 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (LPGUID)&GUID_DEVCLASS_DISKDRIVE, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DIGCF_PRESENT 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ); 
&nbsp;&nbsp;&nbsp; // 
&nbsp;&nbsp;&nbsp; //&nbsp; Enumerate through all Devices. 
&nbsp;&nbsp;&nbsp; // 
&nbsp;&nbsp;&nbsp; DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 
&nbsp;&nbsp;&nbsp; for( i=0; SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData); i++ ) 
&nbsp;&nbsp;&nbsp; { 
SetupDiGetDeviceRegistryProperty( 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DeviceInfoSet, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &DeviceInfoData, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SPDRP_HARDWAREID, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &DataT, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (PBYTE)buffer, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffersize, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &buffersize 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ); 
另:你的主页很好,向你学习

#22


> 设备发生变化时windows会发出WM_DEVICECHANGE消息,哈哈哈....

这么牛?这都有消息?我一直以为要注册个回调才能得到这样的通知呢...... ;-)

#1


help

#2


up一下

#3


1、既然98、NT不一样,你把每一个都找出准确位置。程序头加上一段宏,根据操作系统版本,定义不同的常量值。
2、一点思路:在98下,拿掉USB没有提示,在ME下,有提示,你可以跟踪一下,看看调用的是什么。资料没有,笨方法,假如知道容量,可以穷举盘符,比较容量

#4


up

#5


UP

#6


no_limit(一切反动派都是纸老虎) :
穷举盘符是好办法,可如果两个USB容量相同就不行了

#7


1、可以用GetDesktopFolder来得到指向桌面的IShellFolder,然后用IShellFolder的EnumObjects来得到桌面上的所有对象,然后就可以得到每个对象的所有属性,你自然就可以知道哪个是文件夹,哪个是真的“我的电脑”了。
2、做一个死循环的线程不断去查就好了。
3、用GetDriveType可以区分cdrom和usb盘,不知道你要区分到什么程度?如果要再详细的信息的话,可以再查一下与IShellFolder相关的函数和信息。

#8


kicku():
我是在用GetDesktopFolder来得到指向桌面的IShellFolder,然后用IShellFolder的EnumObjects来得到桌面上的所有对象,然后就可以得到每个对象的所有属性,可我还是不知道该怎么区分,属性中没有这项功能
死循环的线程不断去查-----操作系统是这样做的吗?
GetDriveType可以区分cdrom和usb盘,但是如何知道哪一个盘符是cdrom,哪一个盘符是usb盘???

#9


up

#10


UP

#11


// shellfolder.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <comdef.h>
#include <atlbase.h>
#include <objbase.h>
#include <shlobj.h>
#include <stdio.h>
#include <shlwapi.h>

int main(int argc, char* argv[])
{
CoInitialize(NULL);
USES_CONVERSION;
IShellFolder* pDesktop;
IEnumIDList* pIdList;
ITEMIDLIST* pItemList;
STRRET strRet;
LPSTR str;
HRESULT hr;
ULONG rgf;

hr = SHGetDesktopFolder(&pDesktop);
hr = pDesktop->EnumObjects(NULL, SHCONTF_FOLDERS, &pIdList);
while(pIdList->Next(1, &pItemList, NULL) != S_FALSE) {
hr = pDesktop->GetDisplayNameOf(pItemList, SHGDN_NORMAL, &strRet);
if (strRet.uType == STRRET_WSTR) {
str = W2A(strRet.pOleStr);
} else if (strRet.uType == STRRET_CSTR) {
str = strRet.cStr;
}
printf("%s\n", str);
rgf = SFGAO_FILESYSTEM;
hr = pDesktop->GetAttributesOf(1, (LPCITEMIDLIST *)(&pItemList), &rgf);
if (rgf & SFGAO_FILESYSTEM) {
printf("\tIt's a folder!\n");
}
}
CoTaskMemFree(pItemList);
pIdList->Release();
pDesktop->Release();
CoUninitialize();
return 0;
}

#12


kicku():
你写的这段代码与我提的问题无关阿?
你这段代码只是遍历了桌面,然后把桌面的对象的显示名称打出来,如果是文件夹的话则打印这是文件夹。
我研究了一下,下述代码可以解答我的第一个问题:
LPITEMIDLIST    lph,lph1=0;
                SHGetSpecialFolderLocation(hwnd,CSIDL_DRIVES,&lph);
HRESULT hres=lpsf->CompareIDs(0,lph,lpi);
hres如果是零,表示他是真正的我的电脑
现在第2,3个问题还是不会。

#13


UP,学习

#14


你不是只要区分是“我的电脑”还是一个文件夹么?那我的程序就可以了啊..... ;-)

第二个问题,就用一个死循环吧,没问题的。

第三个问题,先用GetLogicDrives得到当前系统里所有的盘符,然后用一个循环,一个一个GetDriveType试吧....很快的....

#15


kicku() :
1.如果“我的电脑”被改名了,或是英文版的“my computer”,那你这招就不灵了。我要的是真正的“我的电脑”,不论任何情况都能被程序认出,我研究的那段代码可以做到:
     LPITEMIDLIST    lph,lph1=0;
     SHGetSpecialFolderLocation(hwnd,CSIDL_DRIVES,&lph);
     HRESULT hres=lpsf->CompareIDs(0,lph,lpi);  //lpi是传过来的要比较的LPITEMIDLIST,如果hres等于0,那么lpi所代表的就是真正的“我的电脑”
2.辅助线程死循环,那么辅助线程被杀死(比如用2000的任务管理器)怎么办?
3.GetDriveType只能获得磁盘的简单信息,我要的是跟驱动相关的信息,我研究了一下,确实是利用GUID来解决,主要利用函数SetupDiGetDeviceRegistryProperty把磁盘的GUID读出来,不管它放在注册表的那个位置,然后一比较就OK了

#16


2、
首先,task manager看不到线程。
然后......
只要是程序就会被杀死啊,用service倒是杀不死,可是服务可以停掉啊。只要用户有管理员的权限,想不让你运行还不简单啊?

#17


kicku() :
第二个问题也有方法了,设备发生变化时windows会发出WM_DEVICECHANGE消息,哈哈哈....
这样三个问题就都解决了,多谢帮忙。

#18


(代码分为两部分放上来)
通常情况下,我们通过0XEC命令对IDE端口进行监测.获取硬盘信息. 
一般情况下,我们就写个VXD或者DRIVER来完成.但是现在,通过MS的S.M.A.R.T.接口,我们可以直接从RING3调用API DeviceIoControl()来获取硬盘信息.下面乃是我的例程: 
另外,也有编译好的版本供大家平时使用.欢迎下载. 
*注:在WIN98SE,WINDOWS ME中,S.M.A.R.T并不缺省安装.请将SMARTVSD.VXD拷贝到%SYSTEM%\IOSUBSYS目录下. 
在WINDOWS2000下,由于非ADMINISTRATORS组的用户对硬盘连GENERIC_READ的权限也没有,所以请以ADMINISTRATOR登录后使用. 
/*+++ 
HDID.CPP 
Written by Lu Lin 
http://lu0.126.com 
2000.11.3 
---*/ 
#include <windows.h> 
#include <iostream.h> 
#include <stdio.h> 

#define DFP_GET_VERSION 0x00074080 
#define DFP_SEND_DRIVE_COMMAND 0x0007c084 
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088 

#pragma pack(1) 
typedef struct _GETVERSIONOUTPARAMS { 
BYTE bVersion;  // Binary driver version. 
BYTE bRevision;  // Binary driver revision. 
BYTE bReserved;  // Not used. 
BYTE bIDEDeviceMap; // Bit map of IDE devices. 
DWORD fCapabilities; // Bit mask of driver capabilities. 
DWORD dwReserved[4]; // For future use. 
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS; 

typedef struct _IDEREGS { 
BYTE bFeaturesReg;  // Used for specifying SMART "commands". 
BYTE bSectorCountReg; // IDE sector count register 
BYTE bSectorNumberReg; // IDE sector number register 
BYTE bCylLowReg;  // IDE low order cylinder value 
BYTE bCylHighReg;  // IDE high order cylinder value 
BYTE bDriveHeadReg;  // IDE drive/head register 
BYTE bCommandReg;  // Actual IDE command. 
BYTE bReserved;  // reserved for future use.  Must be zero. 
} IDEREGS, *PIDEREGS, *LPIDEREGS; 

typedef struct _SENDCMDINPARAMS { 
DWORD cBufferSize;  // Buffer size in bytes 
IDEREGS irDriveRegs;  // Structure with drive register values. 
BYTE bDriveNumber;  // Physical drive number to send 
      // command to (0,1,2,3). 
BYTE bReserved[3];  // Reserved for future expansion. 
DWORD dwReserved[4];  // For future use. 
//BYTE  bBuffer[1];  // Input buffer. 
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS; 

typedef struct _DRIVERSTATUS { 
BYTE bDriverError;  // Error code from driver, 
      // or 0 if no error. 
BYTE bIDEStatus;  // Contents of IDE Error register. 
      // Only valid when bDriverError 
      // is SMART_IDE_ERROR. 
BYTE bReserved[2];  // Reserved for future expansion. 
DWORD dwReserved[2];  // Reserved for future expansion. 
} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS; 

typedef struct _SENDCMDOUTPARAMS { 
DWORD    cBufferSize;  // Size of bBuffer in bytes 
DRIVERSTATUS DriverStatus;  // Driver status structure. 
BYTE  bBuffer[512];  // Buffer of arbitrary length 
        // in which to store the data read from the drive. 
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS; 

typedef struct _IDSECTOR { 
USHORT wGenConfig; 
USHORT wNumCyls; 
USHORT wReserved; 
USHORT wNumHeads; 
USHORT wBytesPerTrack; 
USHORT wBytesPerSector; 
USHORT wSectorsPerTrack; 
USHORT wVendorUnique[3]; 
CHAR sSerialNumber[20]; 
USHORT wBufferType; 
USHORT wBufferSize; 
USHORT wECCSize; 
CHAR sFirmwareRev[8]; 
CHAR sModelNumber[40]; 
USHORT wMoreVendorUnique; 
USHORT wDoubleWordIO; 
USHORT wCapabilities; 
USHORT wReserved1; 
USHORT wPIOTiming; 
USHORT wDMATiming; 
USHORT wBS; 
USHORT wNumCurrentCyls; 
USHORT wNumCurrentHeads; 
USHORT wNumCurrentSectorsPerTrack; 
ULONG ulCurrentSectorCapacity; 
USHORT wMultSectorStuff; 
ULONG ulTotalAddressableSectors; 
USHORT wSingleWordDMA; 
USHORT wMultiWordDMA; 
BYTE bReserved[128]; 
} IDSECTOR, *PIDSECTOR; 

/*+++ 
Global vars 
---*/ 
GETVERSIONOUTPARAMS vers; 
SENDCMDINPARAMS in; 
SENDCMDOUTPARAMS out; 
HANDLE h; 
DWORD i; 
BYTE j; 

void CopyRight(){ 
cerr<<endl<<"HDD identifier v1.0 for WIN95/98/Me/NT/2000. written by Lu Lin"<<endl; 
cerr<<"For more information, please visit Inside Programming: http://lu0.126.com"<<endl; 
cerr<<"2000.11.3"<<endl<<endl; 
}

#19


VOID ChangeByteOrder(PCHAR szString, USHORT uscStrSize) 


USHORT i; 
CHAR temp; 
for (i = 0; i < uscStrSize; i+=2) 

temp = szString[i]; 
szString[i] = szString[i+1]; 
szString[i+1] = temp; 



void DetectIDE(BYTE bIDEDeviceMap){ 
if (bIDEDeviceMap&1){ 
if (bIDEDeviceMap&16){ 
  cout<<"ATAPI device is attached to primary controller, drive 0."<<endl; 
}else{ 
  cout<<"IDE device is attached to primary controller, drive 0."<<endl; 


if (bIDEDeviceMap&2){ 
if (bIDEDeviceMap&32){ 
  cout<<"ATAPI device is attached to primary controller, drive 1."<<endl; 
}else{ 
  cout<<"IDE device is attached to primary controller, drive 1."<<endl; 


if (bIDEDeviceMap&4){ 
if (bIDEDeviceMap&64){ 
  cout<<"ATAPI device is attached to secondary controller, drive 0."<<endl; 
}else{ 
  cout<<"IDE device is attached to secondary controller, drive 0."<<endl; 


if (bIDEDeviceMap&8){ 
if (bIDEDeviceMap&128){ 
  cout<<"ATAPI device is attached to secondary controller, drive 1."<<endl; 
}else{ 
  cout<<"IDE device is attached to secondary controller, drive 1."<<endl; 




void hdid9x(){ 
ZeroMemory(&vers,sizeof(vers)); 
//We start in 95/98/Me 
h=CreateFile("\\\\.\\Smartvsd",0,0,0,CREATE_NEW,0,0); 
if (!h){ 
cout<<"open smartvsd.vxd failed"<<endl; 
exit(0); 


if (!DeviceIoControl(h,DFP_GET_VERSION,0,0,&vers,sizeof(vers),&i,0)){ 
cout<<"DeviceIoControl failed:DFP_GET_VERSION"<<endl; 
CloseHandle(h); 
return; 

//If IDE identify command not supported, fails 
if (!(vers.fCapabilities&1)){ 
cout<<"Error: IDE identify command not supported."; 
CloseHandle(h); 
return; 

//Display IDE drive number detected 
DetectIDE(vers.bIDEDeviceMap); 
//Identify the IDE drives 
for (j=0;j<4;j++){ 
PIDSECTOR phdinfo; 
char s[41]; 

ZeroMemory(&in,sizeof(in)); 
ZeroMemory(&out,sizeof(out)); 
if (j&1){ 
  in.irDriveRegs.bDriveHeadReg=0xb0; 
}else{ 
  in.irDriveRegs.bDriveHeadReg=0xa0; 

if (vers.fCapabilities&(16>>j)){ 
  //We don't detect a ATAPI device. 
  cout<<"Drive "<<(int)(j+1)<<" is a ATAPI device, we don't detect it"<<endl; 
  continue; 
}else{ 
  in.irDriveRegs.bCommandReg=0xec; 

in.bDriveNumber=j; 
in.irDriveRegs.bSectorCountReg=1; 
in.irDriveRegs.bSectorNumberReg=1; 
in.cBufferSize=512; 
if (!DeviceIoControl(h,DFP_RECEIVE_DRIVE_DATA,&in,sizeof(in),&out,sizeof(out),&i,0)){ 
  cout<<"DeviceIoControl failed:DFP_RECEIVE_DRIVE_DATA"<<endl; 
  CloseHandle(h); 
  return; 

phdinfo=(PIDSECTOR)out.bBuffer; 
memcpy(s,phdinfo->sModelNumber,40); 
s[40]=0; 
ChangeByteOrder(s,40); 
cout<<endl<<"Module Number:"<<s<<endl; 
memcpy(s,phdinfo->sFirmwareRev,8); 
s[8]=0; 
ChangeByteOrder(s,8); 
cout<<"\tFirmware rev:"<<s<<endl; 
memcpy(s,phdinfo->sSerialNumber,20); 
s[20]=0; 
ChangeByteOrder(s,20); 
cout<<"\tSerial Number:"<<s<<endl; 
cout<<"\tCapacity:"<<phdinfo->ulTotalAddressableSectors/2/1024<<"M"<<endl<<endl; 


//Close handle before quit 
CloseHandle(h); 
CopyRight(); 



void hdidnt(){ 
char hd[80]; 
PIDSECTOR phdinfo; 
char s[41]; 

ZeroMemory(&vers,sizeof(vers)); 
//We start in NT/Win2000 
for (j=0;j<4;j++){ 
sprintf(hd,"\\\\.\\PhysicalDrive%d",j); 
h=CreateFile(hd,GENERIC_READ|GENERIC_WRITE, 
  FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0); 
if (!h){ 
  continue; 

if (!DeviceIoControl(h,DFP_GET_VERSION,0,0,&vers,sizeof(vers),&i,0)){ 
  CloseHandle(h); 
  continue; 

//If IDE identify command not supported, fails 
if (!(vers.fCapabilities&1)){ 
  cout<<"Error: IDE identify command not supported."; 
  CloseHandle(h); 
  return; 

//Identify the IDE drives 
ZeroMemory(&in,sizeof(in)); 
ZeroMemory(&out,sizeof(out)); 
if (j&1){ 
  in.irDriveRegs.bDriveHeadReg=0xb0; 
}else{ 
  in.irDriveRegs.bDriveHeadReg=0xa0; 

if (vers.fCapabilities&(16>>j)){ 
  //We don't detect a ATAPI device. 
cout<<"Drive "<<(int)(j+1)<<" is a ATAPI device, we don't detect it"<<endl; 
  continue; 
}else{ 
  in.irDriveRegs.bCommandReg=0xec; 

in.bDriveNumber=j; 
in.irDriveRegs.bSectorCountReg=1; 
in.irDriveRegs.bSectorNumberReg=1; 
in.cBufferSize=512; 
if (!DeviceIoControl(h,DFP_RECEIVE_DRIVE_DATA,&in,sizeof(in),&out,sizeof(out),&i,0)){ 
  cout<<"DeviceIoControl failed:DFP_RECEIVE_DRIVE_DATA"<<endl; 
  CloseHandle(h); 
  return; 

phdinfo=(PIDSECTOR)out.bBuffer; 
memcpy(s,phdinfo->sModelNumber,40); 
s[40]=0; 
ChangeByteOrder(s,40); 
cout<<endl<<"Module Number:"<<s<<endl; 
memcpy(s,phdinfo->sFirmwareRev,8); 
s[8]=0; 
ChangeByteOrder(s,8); 
cout<<"\tFirmware rev:"<<s<<endl; 
memcpy(s,phdinfo->sSerialNumber,20); 
s[20]=0; 
ChangeByteOrder(s,20); 
cout<<"\tSerial Number:"<<s<<endl; 
cout<<"\tCapacity:"<<phdinfo->ulTotalAddressableSectors/2/1024<<"M"<<endl<<endl; 
CloseHandle(h); 

CopyRight(); 


void main(){ 
OSVERSIONINFO VersionInfo; 

ZeroMemory(&VersionInfo,sizeof(VersionInfo)); 
VersionInfo.dwOSVersionInfoSize=sizeof(VersionInfo); 
GetVersionEx(&VersionInfo); 

switch (VersionInfo.dwPlatformId){ 
case VER_PLATFORM_WIN32s: 
cout<<"Win32s is not supported by this programm."<<endl; 
return; 
case VER_PLATFORM_WIN32_WINDOWS: 
hdid9x(); 
return; 
case VER_PLATFORM_WIN32_NT: 
hdidnt(); 
return; 

}

#20


特别提示
上面的程序可以获得银盘的序号和特别标示功能
如S.M.A.T.P等的参数

但是必须在WIN2000,WINXP操作系统上实现

#21


baoch110(来自北方的包子) :
    2000不支持VxD吧?
    利用下述方法也可以获得硬盘的相关信息:
    主要就是两个函数,一个是你说的DeviceIoControl(),另一个是SetupDiGetDeviceRegistryProperty
    //////////////////////////////////////////////////////////////////////////// 
////////////////////////////////////// 
On Win2k you open the root device for each drive letter (DriveToOpen="C:", 
"D:", etc.) 
Then do the following to get the scsi disk id: 
//////////////////////////////////////////////////////////////////////////// 
////////////////////////////////////// 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hDevice = CreateFile( 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DriveToOpen,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 
device interface name 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GENERIC_READ | GENERIC_WRITE,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // dwDesiredAccess 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // lpSecurityAttributes 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OPEN_EXISTING,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // dwCreationDistribution 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // dwFlagsAndAttributes 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // hTemplateFile 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ); 
&nbsp;&nbsp;&nbsp;&nbsp; // query the info 
&nbsp;&nbsp;&nbsp; query.PropertyId = StorageDeviceProperty; 
&nbsp;&nbsp;&nbsp; query.QueryType = PropertyStandardQuery; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = DeviceIoControl( 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hDevice, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IOCTL_STORAGE_QUERY_PROPERTY, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &query, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof( STORAGE_PROPERTY_QUERY ), 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &outBuf, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 512, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &returnedLength, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ); 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; devDesc = (PSTORAGE_DEVICE_DESCRIPTOR) outBuf; 
//////////////////////////////////////////////////////////////////////////// 
////////////////////////////////////// 
On Win9x you enumerate all the drives using the SetupDi interfaces: 
//////////////////////////////////////////////////////////////////////////// 
////////////////////////////////////// 
&nbsp;&nbsp;&nbsp; // 
&nbsp;&nbsp;&nbsp; // Create a Device Information Set with all present devices. 
&nbsp;&nbsp;&nbsp; // 
&nbsp;&nbsp;&nbsp; DeviceInfoSet = SetupDiGetClassDevs( 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (LPGUID)&GUID_DEVCLASS_DISKDRIVE, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DIGCF_PRESENT 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ); 
&nbsp;&nbsp;&nbsp; // 
&nbsp;&nbsp;&nbsp; //&nbsp; Enumerate through all Devices. 
&nbsp;&nbsp;&nbsp; // 
&nbsp;&nbsp;&nbsp; DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 
&nbsp;&nbsp;&nbsp; for( i=0; SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData); i++ ) 
&nbsp;&nbsp;&nbsp; { 
SetupDiGetDeviceRegistryProperty( 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DeviceInfoSet, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &DeviceInfoData, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SPDRP_HARDWAREID, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &DataT, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (PBYTE)buffer, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffersize, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &buffersize 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ); 
另:你的主页很好,向你学习

#22


> 设备发生变化时windows会发出WM_DEVICECHANGE消息,哈哈哈....

这么牛?这都有消息?我一直以为要注册个回调才能得到这样的通知呢...... ;-)