频道直达 - 专题 - 新闻 - 技巧 - 组网 - 开发 - 安全 - web编程 - 图像 - 操作系统 - 数据库 - 教育 - 旅游 - 健康 - 时尚 - 驱动 - 软件 - 游戏 - 多媒体 - ERP - 讨论组

用Delphi通过SetupAPI.dll列举和停用硬件设备

来源: 作者: 出处:巧巧读书 2007-10-09 进入讨论组

  前天弄的东西,通过SetupAPI.dll列举硬件设备,部分是改自MSDN自带的例子,自己加了显示设备类型名和图标.代码是我一个个加上去的有些乱.

{Setup.pas---从SetupAPI.h里转的一些函数和常量}
unitSetupAPI;
interface
uses
 Windows;
const
 DIGCF_PRESENT=$0002;
 DIGCF_ALLCLASSES=$0004;
 SPDRP_DEVICEDESC=0;
 DIF_PROPERTYCHANGE=18;
 DICS_ENABLE=1;
 DICS_FLAG_GLOBAL=1;
 DICS_DISABLE=2;
type
 HDEVINFO=typeCardinal;
 DI_FUNCTION=typeCardinal;
 
 PSP_DEVINFO_DATA=^SP_DEVINFO_DATA;
 SP_DEVINFO_DATA=record
  cbSize:DWORD;
  ClassGuid:TGUID;
  DevInst:DWORD;
  Reserved:Longint;
 end;
 PSP_CLASSINSTALL_HEADER=^SP_CLASSINSTALL_HEADER;
 SP_CLASSINSTALL_HEADER=record
  cbSize:DWORD;
  InstallFunction:DI_FUNCTION;{(DIFcode)}
 end;
 PSP_PROPCHANGE_PARAMS=^SP_PROPCHANGE_PARAMS;
 SP_PROPCHANGE_PARAMS=record
  ClassInstallHeader:SP_CLASSINSTALL_HEADER;
  StateChange:DWORD;
  Scope:DWORD;
  HwProfile:DWORD;
 end;
 PSP_CLASSIMAGELIST_DATA=^SP_CLASSIMAGELIST_DATA;
 SP_CLASSIMAGELIST_DATA=record
  cbSize:DWORD;
  ImageList:HWND;
  Reserved:DWORD;
 end;
functionSetupDiGetClassDevs(constClassGuid:PGUID;Enumerator:PChar;
 hwndParent:HWND;Flags:DWORD):HDEVINFO;stdcall;
 external'Setupapi.dll'name'SetupDiGetClassDevsA';
functionSetupDiEnumDeviceInfo(DeviceInfoSet:HDEVINFO;MemberIndex:DWORD;
 DeviceInfoData:PSP_DEVINFO_DATA):BOOL;stdcall;
 external'Setupapi.dll'name'SetupDiEnumDeviceInfo';
functionSetupDiGetDeviceRegistryProperty(DeviceInfoSet:HDEVINFO;
 DeviceInfoData:PSP_DEVINFO_DATA;Propertys:DWORD;PropertyRegDataType:PWORD;
 PropertyBuffer:PByte;PropertyBufferSize:DWORD;RequiredSize:PWORD):BOOL;stdcall;
 external'Setupapi.dll'name'SetupDiGetDeviceRegistryPropertyA';
functionSetupDiDestroyDeviceInfoList(DeviceInfoSet:HDEVINFO):BOOL;stdcall;
 external'Setupapi.dll'name'SetupDiDestroyDeviceInfoList';
functionSetupDiClassNameFromGuid(ClassGuid:PGUID;ClassName:PChar;
 ClassNameSize:DWORD;RequiredSize:PDWORD):BOOL;stdcall;
 external'Setupapi.dll'name'SetupDiClassNameFromGuidA';
functionSetupDiSetClassInstallParams(DeviceInfoSet:HDEVINFO;
 DeviceInfoData:PSP_DEVINFO_DATA;ClassInstallParams:PSP_CLASSINSTALL_HEADER;
 ClassInstallParamsSize:DWORD):BOOLstdcall;
 external'Setupapi.dll'name'SetupDiSetClassInstallParamsA';
functionSetupDiCallClassInstaller(InstallFunction:DI_FUNCTION;
 DeviceInfoSet:HDEVINFO;DeviceInfoData:PSP_DEVINFO_DATA):BOOL;stdcall;
 external'Setupapi.dll'name'SetupDiCallClassInstaller';
functionSetupDiGetClassImageList(ClassImageListData:PSP_CLASSIMAGELIST_DATA):BOOL;
 stdcall;external'Setupapi.dll'name'SetupDiGetClassImageList';
functionSetupDiDestroyClassImageList(ClassImageListData:PSP_CLASSIMAGELIST_DATA):
 BOOL;stdcall;external'Setupapi.dll'name'SetupDiDestroyClassImageList';
functionSetupDiGetClassImageIndex(ClassImageListData:PSP_CLASSIMAGELIST_DATA;
 ClassGuid:PGUID;ImageIndex:PINT):BOOL;stdcall;
 external'Setupapi.dll'name'SetupDiGetClassImageIndex';
implementation
end.
{untMain.pas主窗体单元,Uses部分引用上面的pas,
再加1个BUTTON;1个TListView;1个TImageList,定义看代码}
unituntMain;
interface
uses
 Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
 Dialogs,SetupAPI,StdCtrls,ComCtrls,ImgList;
type
 TForm1=class(TForm)
  lv1:TListView;
  btn1:TButton;
  il1:TImageList;
  procedurebtn1Click(Sender:TObject);
 private
  functionGetDeviceClassName(aGUID:TGUID):string;
  {Privatedeclarations}
 public
  {Publicdeclarations}
 end;
var
 Form1:TForm1;
 ClassImageListData:SP_CLASSIMAGELIST_DATA;{设备类型图标结构,全局变量,退出时释放.}
implementation
{$R*.dfm}
procedureTForm1.btn1Click(Sender:TObject);
var
 hDevInfo:Cardinal;
 DeviceInfoData:SP_DEVINFO_DATA;{设备信息结构}
 i:Integer;
 DataT,Buffersize:DWORD;
 Buffer:PAnsiChar;
 List:TListItem;
 index:Integer;
begin
 {获取设备信息句柄}
 lv1.Items.BeginUpdate;
 DriverInfoData.cbSize:=SizeOf(SP_DRVINFO_DATA_A);
 hDevInfo:=SetupDiGetClassDevs(nil,0,0,
  DIGCF_PRESENTorDIGCF_ALLCLASSES);
 ifhDevInfo=INVALID_HANDLE_VALUEthenExit;
 {设备图标数据结构}
 ClassImageListData.cbSize:=SizeOf(SP_CLASSIMAGELIST_DATA);
 {获取设备图标数据}
 ifSetupDiGetClassImageList(@ClassImageListData)then
 begin
  {赋句柄给ImageList}
  il1.Handle:=ClassImageListData.ImageList;
  {TreeView图标指定到ImageList}
  lv1.SmallImages:=il1;
 end;
  
 i:=0;
 Buffersize:=256;
 DeviceInfoData.cbSize:=SizeOf(SP_DEVINFO_DATA);
 GetMem(Buffer,Buffersize);
 {枚举设备信息}
 whileSetupDiEnumDeviceInfo(hDevInfo,i,@DeviceInfoData)do
 begin
  {获取设备信息包括GUID和名称}
  SetupDiGetDeviceRegistryProperty(hDevInfo,@DeviceInfoData,
   SPDRP_DEVICEDESC,@DataT,PByte(Buffer),Buffersize,nil);
  Inc(i);
  List:=lv1.Items.Add;
  {获取制定GUID(设备类型)的图标索引}
  ifSetupDiGetClassImageIndex(@ClassImageListData,
   @DeviceInfoData.ClassGuid,@index)then
   {制定显示图标}
   List.ImageIndex:=index;
  {通过GUID获取设备类型(Class)}
  List.Caption:=GetDeviceClassName(DeviceInfoData.ClassGuid);
  {转换GUID到字符串}
  List.SubItems.Add(GUIDToString(DeviceInfoData.ClassGuid));
  {显示设备名称}
  List.SubItems.Add(Buffer);
  {设备状态}
  ifIsDisableable(i,hDevInfo)then
   List.SubItems.Add('True')
  else
   List.SubItems.Add('False');
  
 end;
 ifBuffer<>nilthenFreeMem(Buffer);
 if(GetLastError()<>NO_ERROR)and
  (GetLastError()<>ERROR_NO_MORE_ITEMS)then
  Exit;
 {释放DeviceInfoData,hDevInfo}
 SetupDiDestroyDeviceInfoList(hDevInfo);
 lv1.Items.EndUpdate;
end;
{最后在退出程序时释放SetupDiDestroyClassImageList(@ClassImageListData);}
{获取设备类型}
functionTForm1.GetDeviceClassName(aGUID:TGUID):string;
var
 ClassName:PChar;
 ClassNameSize:DWORD;
begin
 ClassNameSize:=0;
 GetMem(ClassName,ClassNameSize);
 {利用GUID返回设备类型名}
 whilenotSetupDiClassNameFromGuid(@aGUID,ClassName,ClassNameSize,
  @ClassNameSize)do
 begin
  ifGetLastError()=ERROR_INSUFFICIENT_BUFFERthen
  begin
   ifClassName<>nilthenFreeMem(ClassName);
   GetMem(ClassName,ClassNameSize);
  endelse
   Break;
 end;
 Result:=ClassName;
 ifClassName<>nilthenFreeMem(ClassName);
end;
end.
{设备禁用的代码,是从网上改些一个C++代码的,还没来得及加注解,先看着,以后加.}
functionChangeDeviceState(hDevInfo:HDEVINFO;NewStatus:DWORD;
 SelectedItem:DWORD):Boolean;
var
 PropChangeParams:SP_PROPCHANGE_PARAMS;
 DeviceInfoData:SP_DEVINFO_DATA;
begin
 Result:=False;
 DeviceInfoData.cbSize:=SizeOf(SP_DEVINFO_DATA);
 ifnotSetupDiEnumDeviceInfo(hDevInfo,SelectedItem,@DeviceInfoData)thenExit;
 //SetthePropChangeParamsstructure.
 PropChangeParams.ClassInstallHeader.cbSize:=SizeOf(SP_CLASSINSTALL_HEADER);
 PropChangeParams.ClassInstallHeader.InstallFunction:=DIF_PROPERTYCHANGE;
 PropChangeParams.Scope:=DICS_FLAG_GLOBAL;
 PropChangeParams.StateChange:=NewStatus;
 ifnotSetupDiSetClassInstallParams(hDevInfo,@DeviceInfoData,
  PSP_CLASSINSTALL_HEADER(@PropChangeParams),SizeOf(PropChangeParams))then
  Exit;
 //CalltheClassInstallerandperformthechange.
 ifnotSetupDiCallClassInstaller(DIF_PROPERTYCHANGE,hDevInfo,
  @DeviceInfoData)then
  Exit;
 Result:=True;
end;
functionControlDisk(nStatus,nIndex:Integer):Boolean;
var
 Guid:TGUID;
 GUIDString:string;
 hDevInfo:Cardinal;
 i:DWORD;
 DeviceInfoData:SP_DEVINFO_DATA;
begin
 Result:=False;
 if(nStatus=-1)thenExit;
 ZeroMemory(@Guid,sizeof(TGUID));
 casenIndexof
  0://0代表软驱
   GUIDString:='{4D36E980-E325-11CE-BFC1-08002BE10318}';
  1://1代表光驱
   GUIDString:='{4D36E965-E325-11CE-BFC1-08002BE10318}';
  2://2代表USB
   GUIDString:='{36FC9E60-C465-11CF-8056-444553540000}';
 end;
 Guid:=StringToGUID(GUIDString);
 hDevInfo:=SetupDiGetClassDevs(@Guid,nil,HWND(nil),DIGCF_PRESENT);
 if(hDevInfo=INVALID_HANDLE_VALUE)thenExit;
 ZeroMemory(@DeviceInfoData,SizeOf(SP_DEVINFO_DATA));
 DeviceInfoData.cbSize:=SizeOf(SP_DEVINFO_DATA);
 i:=0;
 whileSetupDiEnumDeviceInfo(hDevInfo,i,@DeviceInfoData)do
 begin
  ifnStatus =1then
   Result:=ChangeDeviceState(hDevInfo,DICS_ENABLE,i)
  elseifnStatus=2then
   Result:=ChangeDeviceState(hDevInfo,DICS_DISABLE,i);
  Inc(i);
 end;
 SetupDiDestroyDeviceInfoList(hDevInfo);
end;
{调用如下:禁用光驱:ifControlDisk(DICS_DISABLE,1)thenShowMessage('成功禁用!');}
{启用光驱:ifControlDisk(DICS_ENABLE,1)thenShowMessage('启用成功!');}
{注意USB要调用2次ControlDisk(DICS_ENABLE,2)才能完成启用.}

  本文出处:http://moufer.blogdriver.com/moufer/1200678.html

收藏地址:http://www.qqread.com/delphi/d352249.html 更多文章 更多内容请看无线设备专题专题,或进入讨论组讨论。
收藏此文】【 】【打印】【关闭
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
巧巧读书宗旨
相关专题
讨论组问题推荐
站内各频道最新更新文档
站内最新制作专题
热门关键字导读
Photoshop教 程照片处理 照片制作 PS快捷键 抠图
计 算 机 故 障XP系统修复
艺 术 与 设 计设计 流媒体 设计欣赏 边框
计 算 机 安 全ARP
站内频道文章精选
巧巧电脑频道编辑信箱  告诉我们您想看的专题或文章