function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): BOOL; stdcall; external 'Setupapi.dll' name 'SetupDiDestroyDeviceInfoList';
function SetupDiClassNameFromGuid(ClassGuid: PGUID; ClassName: PChar; ClassNameSize: DWORD; RequiredSize: PDWORD): BOOL; stdcall; external 'Setupapi.dll' name 'SetupDiClassNameFromGuidA';
function SetupDiSetClassInstallParams(DeviceInfoSet: HDEVINFO ; DeviceInfoData: PSP_DEVINFO_DATA; ClassInstallParams: PSP_CLASSINSTALL_HEADER; ClassInstallParamsSize: DWORD): BOOL stdcall; external 'Setupapi.dll' name 'SetupDiSetClassInstallParamsA';
function SetupDiCallClassInstaller(InstallFunction: DI_FUNCTION; DeviceInfoSet: HDEVINFO; DeviceInfoData: PSP_DEVINFO_DATA): BOOL; stdcall; external 'Setupapi.dll' name 'SetupDiCallClassInstaller';
function SetupDiGetClassImageList(ClassImageListData: PSP_CLASSIMAGELIST_DATA): BOOL; stdcall; external 'Setupapi.dll' name 'SetupDiGetClassImageList';
function SetupDiDestroyClassImageList(ClassImageListData: PSP_CLASSIMAGELIST_DATA): BOOL; stdcall; external 'Setupapi.dll' name 'SetupDiDestroyClassImageList';
function SetupDiGetClassImageIndex(ClassImageListData: PSP_CLASSIMAGELIST_DATA; ClassGuid: PGUID; ImageIndex: PINT): BOOL; stdcall; external 'Setupapi.dll' name 'SetupDiGetClassImageIndex';
type TForm1 = class(TForm) lv1: TListView; btn1: TButton; il1: TImageList; procedure btn1Click(Sender: TObject); private function GetDeviceClassName(aGUID: TGUID): string; { Private declarations } public { Public declarations } end;
var Form1: TForm1; ClassImageListData: SP_CLASSIMAGELIST_DATA; {设备类型图标结构,全局变量,退出时释放.}
implementation
{$R *.dfm}
procedure TForm1.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_PRESENT or DIGCF_ALLCLASSES); if hDevInfo = INVALID_HANDLE_VALUE then Exit; { 设备图标数据结构 } ClassImageListData.cbSize := SizeOf(SP_CLASSIMAGELIST_DATA); { 获取设备图标数据 } if SetupDiGetClassImageList(@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); { 枚举设备信息 } while SetupDiEnumDeviceInfo(hDevInfo, i, @DeviceInfoData) do begin
end; if Buffer <> nil then FreeMem(Buffer); if (GetLastError() <> NO_ERROR) and (GetLastError() <> ERROR_NO_MORE_ITEMS) then Exit; { 释放 DeviceInfoData, hDevInfo } SetupDiDestroyDeviceInfoList(hDevInfo); lv1.Items.EndUpdate; end;
{ 获取设备类型 } function TForm1.GetDeviceClassName(aGUID: TGUID): string; var ClassName: PChar; ClassNameSize: DWORD; begin ClassNameSize := 0; GetMem(ClassName, ClassNameSize); { 利用GUID返回设备类型名 } while not SetupDiClassNameFromGuid(@aGUID, ClassName, ClassNameSize, @ClassNameSize) do begin if GetLastError() = ERROR_INSUFFICIENT_BUFFER then begin if ClassName <> nil then FreeMem(ClassName); GetMem(ClassName, ClassNameSize); end else Break; end; Result := ClassName; if ClassName <> nil then FreeMem(ClassName); end;
end.
{设备禁用的代码,是从网上改些一个C++代码的,还没来得及加注解,先看着,以后加.}
function ChangeDeviceState(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); if not SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, @DeviceInfoData) then Exit;
// Set the PropChangeParams structure. PropChangeParams.ClassInstallHeader.cbSize := SizeOf(SP_CLASSINSTALL_HEADER); PropChangeParams.ClassInstallHeader.InstallFunction := DIF_PROPERTYCHANGE; PropChangeParams.Scope := DICS_FLAG_GLOBAL; PropChangeParams.StateChange := NewStatus;
if not SetupDiSetClassInstallParams(hDevInfo, @DeviceInfoData, PSP_CLASSINSTALL_HEADER(@PropChangeParams), SizeOf(PropChangeParams)) then Exit;
// Call the ClassInstaller and perform the change. if not SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, @DeviceInfoData) then Exit;
Result := True; end;
function ControlDisk(nStatus, nIndex: Integer): Boolean; var Guid: TGUID ; GUIDString: string; hDevInfo: Cardinal; i: DWORD; DeviceInfoData: SP_DEVINFO_DATA; begin Result := False; if (nStatus = -1) then Exit;
i := 0; while SetupDiEnumDeviceInfo(hDevInfo, i, @DeviceInfoData) do begin if nStatus = 1 then Result := ChangeDeviceState(hDevInfo, DICS_ENABLE, i) else if nStatus = 2 then Result := ChangeDeviceState(hDevInfo, DICS_DISABLE, i); Inc(i); end;
SetupDiDestroyDeviceInfoList(hDevInfo); end;
{ 调用如下: 禁用光驱: if ControlDisk(DICS_DISABLE, 1) then ShowMessage('成功禁用!'); }
{ 启用光驱: if ControlDisk(DICS_ENABLE, 1) then ShowMessage('启用成功!'); }