关于识别及控制硬盘和USB等外设的一些问题?请提供思路或是相关资料,谢谢 1、既然98、NT不一样,你把每一个都找出准确位置。程序头加上一段宏,根据操作系统版本,定义不同的常量值。2、一点思路:在98下,拿掉USB没有提示,在ME下,有提示,你可以跟踪一下,看看调用的是什么。资料没有,笨方法,假如知道容量,可以穷举盘符,比较容量 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 no_limit(一切反动派都是纸老虎) :穷举盘符是好办法,可如果两个USB容量相同就不行了 1、可以用GetDesktopFolder来得到指向桌面的IShellFolder,然后用IShellFolder的EnumObjects来得到桌面上的所有对象,然后就可以得到每个对象的所有属性,你自然就可以知道哪个是文件夹,哪个是真的“我的电脑”了。2、做一个死循环的线程不断去查就好了。3、用GetDriveType可以区分cdrom和usb盘,不知道你要区分到什么程度?如果要再详细的信息的话,可以再查一下与IShellFolder相关的函数和信息。 kicku():我是在用GetDesktopFolder来得到指向桌面的IShellFolder,然后用IShellFolder的EnumObjects来得到桌面上的所有对象,然后就可以得到每个对象的所有属性,可我还是不知道该怎么区分,属性中没有这项功能死循环的线程不断去查-----操作系统是这样做的吗?GetDriveType可以区分cdrom和usb盘,但是如何知道哪一个盘符是cdrom,哪一个盘符是usb盘??? // 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;} kicku():你写的这段代码与我提的问题无关阿?你这段代码只是遍历了桌面,然后把桌面的对象的显示名称打出来,如果是文件夹的话则打印这是文件夹。我研究了一下,下述代码可以解答我的第一个问题:LPITEMIDLIST lph,lph1=0; SHGetSpecialFolderLocation(hwnd,CSIDL_DRIVES,&lph); HRESULT hres=lpsf->CompareIDs(0,lph,lpi); hres如果是零,表示他是真正的我的电脑现在第2,3个问题还是不会。 你不是只要区分是“我的电脑”还是一个文件夹么?那我的程序就可以了啊..... ;-)第二个问题,就用一个死循环吧,没问题的。第三个问题,先用GetLogicDrives得到当前系统里所有的盘符,然后用一个循环,一个一个GetDriveType试吧....很快的.... 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了 2、首先,task manager看不到线程。然后......只要是程序就会被杀死啊,用service倒是杀不死,可是服务可以停掉啊。只要用户有管理员的权限,想不让你运行还不简单啊? kicku() :第二个问题也有方法了,设备发生变化时windows会发出WM_DEVICECHANGE消息,哈哈哈....这样三个问题就都解决了,多谢帮忙。 (代码分为两部分放上来)通常情况下,我们通过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; } 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; } } 特别提示上面的程序可以获得银盘的序号和特别标示功能如S.M.A.T.P等的参数但是必须在WIN2000,WINXP操作系统上实现 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: //////////////////////////////////////////////////////////////////////////// ////////////////////////////////////// hDevice = CreateFile( DriveToOpen, // device interface name GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode NULL, // lpSecurityAttributes OPEN_EXISTING, // dwCreationDistribution 0, // dwFlagsAndAttributes NULL // hTemplateFile ); // query the info query.PropertyId = StorageDeviceProperty; query.QueryType = PropertyStandardQuery; status = DeviceIoControl( hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof( STORAGE_PROPERTY_QUERY ), &outBuf, 512, &returnedLength, NULL ); devDesc = (PSTORAGE_DEVICE_DESCRIPTOR) outBuf; //////////////////////////////////////////////////////////////////////////// ////////////////////////////////////// On Win9x you enumerate all the drives using the SetupDi interfaces: //////////////////////////////////////////////////////////////////////////// ////////////////////////////////////// // // Create a Device Information Set with all present devices. // DeviceInfoSet = SetupDiGetClassDevs( (LPGUID)&GUID_DEVCLASS_DISKDRIVE, 0, 0, DIGCF_PRESENT ); // // Enumerate through all Devices. // DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for( i=0; SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData); i++ ) { SetupDiGetDeviceRegistryProperty( DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, &DataT, (PBYTE)buffer, buffersize, &buffersize ); 另:你的主页很好,向你学习 > 设备发生变化时windows会发出WM_DEVICECHANGE消息,哈哈哈....这么牛?这都有消息?我一直以为要注册个回调才能得到这样的通知呢...... ;-) 如果将opengl中的绕一轴旋转分解到绕xyz3个不同轴的旋转中去? VC 对话框上添加超连接动态图片 如何将菜单栏的菜单及其菜单项字体变大?十万火急! 高分求vCard的解析类 vc6的编译问题 各位xdjm提供几个数据结构、算法源码的网址。小第需要一个简单公式计算的代码,算法 请问如何在com的服务器端实现一个对话框, 怎样得到winXP的API列表和详细解释(中英文皆可)。 来这里的有几个是非计算机专业的 ? 有什么好的访问数据库的技术 关于VC++中系统目录配置的问题? 请教如何在满足某一条件时改变列表视图里光标条为其它颜色?
穷举盘符是好办法,可如果两个USB容量相同就不行了
2、做一个死循环的线程不断去查就好了。
3、用GetDriveType可以区分cdrom和usb盘,不知道你要区分到什么程度?如果要再详细的信息的话,可以再查一下与IShellFolder相关的函数和信息。
我是在用GetDesktopFolder来得到指向桌面的IShellFolder,然后用IShellFolder的EnumObjects来得到桌面上的所有对象,然后就可以得到每个对象的所有属性,可我还是不知道该怎么区分,属性中没有这项功能
死循环的线程不断去查-----操作系统是这样做的吗?
GetDriveType可以区分cdrom和usb盘,但是如何知道哪一个盘符是cdrom,哪一个盘符是usb盘???
//#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;
}
你写的这段代码与我提的问题无关阿?
你这段代码只是遍历了桌面,然后把桌面的对象的显示名称打出来,如果是文件夹的话则打印这是文件夹。
我研究了一下,下述代码可以解答我的第一个问题:
LPITEMIDLIST lph,lph1=0;
SHGetSpecialFolderLocation(hwnd,CSIDL_DRIVES,&lph);
HRESULT hres=lpsf->CompareIDs(0,lph,lpi);
hres如果是零,表示他是真正的我的电脑
现在第2,3个问题还是不会。
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了
首先,task manager看不到线程。
然后......
只要是程序就会被杀死啊,用service倒是杀不死,可是服务可以停掉啊。只要用户有管理员的权限,想不让你运行还不简单啊?
第二个问题也有方法了,设备发生变化时windows会发出WM_DEVICECHANGE消息,哈哈哈....
这样三个问题就都解决了,多谢帮忙。
通常情况下,我们通过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;
}
{ 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;
}
}
上面的程序可以获得银盘的序号和特别标示功能
如S.M.A.T.P等的参数但是必须在WIN2000,WINXP操作系统上实现
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:
////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////
hDevice = CreateFile(
DriveToOpen, //
device interface name
GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
NULL, // lpSecurityAttributes
OPEN_EXISTING, // dwCreationDistribution
0, // dwFlagsAndAttributes
NULL // hTemplateFile
);
// query the info
query.PropertyId = StorageDeviceProperty;
query.QueryType = PropertyStandardQuery;
status = DeviceIoControl(
hDevice,
IOCTL_STORAGE_QUERY_PROPERTY,
&query,
sizeof( STORAGE_PROPERTY_QUERY ),
&outBuf,
512,
&returnedLength,
NULL
);
devDesc = (PSTORAGE_DEVICE_DESCRIPTOR) outBuf;
////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////
On Win9x you enumerate all the drives using the SetupDi interfaces:
////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////
//
// Create a Device Information Set with all present devices.
//
DeviceInfoSet = SetupDiGetClassDevs(
(LPGUID)&GUID_DEVCLASS_DISKDRIVE,
0,
0,
DIGCF_PRESENT
);
//
// Enumerate through all Devices.
//
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for( i=0; SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData); i++ )
{
SetupDiGetDeviceRegistryProperty(
DeviceInfoSet,
&DeviceInfoData,
SPDRP_HARDWAREID,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize
);
另:你的主页很好,向你学习