Показать сообщение отдельно
  #7  
Старый 26.09.2007, 13:14
~ SaM ~ ~ SaM ~ вне форума
Начинающий
 
Регистрация: 05.01.2007
Адрес: Днепропетровск
Сообщения: 141
Репутация: 25
Смех

//Часть первая(просто весь код не влазит в одно сообщение)

Код:
uses
    ......, ComCtrls, StdCtrls, SetupAPI, ExtCtrls, Menus;


const
  SetupApiModuleName        = 'cfgmgr32.dll';
  REGSTR_VAL_NODISPLAYCLASS = 'NoDisplayClass';
  CR_SUCCESS                = $00000000;
  DN_HAS_PROBLEM            = $00000400;
  DN_DISABLEABLE            = $00002000;
  DN_NO_SHOW_IN_DM          = $40000000;
  CM_PROB_DISABLED          = $00000016;
  CM_PROB_HARDWARE_DISABLED = $0000001D;

  function CM_Get_DevNode_Status(pulStatus: PULong; pulProblemNumber: PULong;
  dnDevInst: DWord; ulFlags: ULong): DWord; stdcall;
  external SetupApiModuleName name 'CM_Get_DevNode_Status';

type
  TForm1 = class(TForm)
    TreeView: TTreeView;
    ImageList: TImageList;
    MainMenu: TMainMenu;
    mFile: TMenuItem;
    mExit: TMenuItem;
    mChange: TMenuItem;
    mEnableDevice: TMenuItem;
    mDisableDevice: TMenuItem;
    mOptions: TMenuItem;
    mRefreshDisplay: TMenuItem;
    mShowHiddenDevices: TMenuItem;
    mN: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure mExitClick(Sender: TObject);
    procedure mRefreshDisplayClick(Sender: TObject);
    procedure mShowHiddenDevicesClick(Sender: TObject);
    procedure TreeViewChange(Sender: TObject; Node: TTreeNode);
    procedure TreeViewDblClick(Sender: TObject);
    procedure ChangeEnableDevice(Sender: TObject);
    procedure ChangeDisableDevice(Sender: TObject);
  private
 { Private declarations }
    DevInfo: hDevInfo;
    ClassImageListData: TSPClassImageListData;
    ShowHidden: Boolean;
    function IsDisableable(SelectedItem: DWord; hDevInfo: hDevInfo): Boolean;
    function IsDisabled(SelectedItem: DWord; hDevInfo: hDevInfo): Boolean;
    function StateChange(NewState: DWord; SelectedItem: DWord; hDevInfo: hDevInfo): Boolean;
    function GetRegistryProperty(PnPHandle: HDEVINFO;DevData: TSPDevInfoData;
             Prop: DWORD; Buffer: PChar; dwLength: DWord): Boolean;
    function ConstructDeviceName(DeviceInfoSet: hDevInfo;
             DeviceInfoData: TSPDevInfoData; Buffer: PChar; dwLength: DWord): Boolean;
    function IsClassHidden(ClassGuid: TGuid): Boolean;
    function EnumAddDevices(ShowHidden: Boolean; hwndTree: TTreeView; DevInfo: hDevInfo): Boolean;
    function GetClassImageIndex(ClassGuid: TGuid; Index: PInt): Boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;


implementation

{$R *.DFM}

function TForm1.IsDisableable(SelectedItem: DWord; hDevInfo: hDevInfo): Boolean;
var
  DeviceInfoData: TSPDevInfoData;
  Status, Problem: DWord;
begin
  DeviceInfoData.cbSize := SizeOf(TSPDevInfoData);
  if (not SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, DeviceInfoData)) then
  begin
    Result := false;
    exit;
  end;
  if (CM_Get_DevNode_Status(@Status, @Problem, DeviceInfoData.DevInst, 0) <> CR_SUCCESS) then
  begin
    Result := false;
    exit;
  end;
  Result := ((Status and DN_DISABLEABLE = DN_DISABLEABLE) and not (CM_PROB_HARDWARE_DISABLED = Problem));
end;

function TForm1.IsDisabled(SelectedItem: DWord; hDevInfo: hDevInfo): Boolean;
var
  DeviceInfoData: TSPDevInfoData;
  Status, Problem: DWord;
begin
  DeviceInfoData.cbSize := SizeOf(TSPDevInfoData);
  if (not SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, DeviceInfoData)) then
  begin
    Result := false;
    exit;
  end;
  if (CM_Get_DevNode_Status(@Status, @Problem, DeviceInfoData.DevInst, 0) <> CR_SUCCESS) then
  begin
    Result := false;
    exit;
  end;
  Result := ((Status and DN_HAS_PROBLEM = DN_HAS_PROBLEM) and (CM_PROB_DISABLED = Problem));
end;

function TForm1.StateChange(NewState: DWord; SelectedItem: DWord; hDevInfo: hDevInfo): Boolean;
var
  PropChangeParams: TSPPropChangeParams;
  DeviceInfoData: TSPDevInfoData;
begin
  PropChangeParams.ClassInstallHeader.cbSize := SizeOf(TSPClassInstallHeader);
  DeviceInfoData.cbSize := SizeOf(TSPDevInfoData);
  if (not SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, DeviceInfoData)) then
  begin
    Result := false;
    ShowMessage('EnumDeviceInfo');
    exit;
  end;
  PropChangeParams.ClassInstallHeader.InstallFunction := DIF_PROPERTYCHANGE;
  PropChangeParams.Scope := DICS_FLAG_GLOBAL;
  PropChangeParams.StateChange := NewState;
  if (not SetupDiSetClassInstallParams(hDevInfo, @DeviceInfoData,
     PSPClassInstallHeader(@PropChangeParams), SizeOf(PropChangeParams))) then
  begin
    Result := false;
    ShowMessage('SetClassInstallParams');
    exit;
  end;
  if (not SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, @DeviceInfoData)) then
  begin
    Result := false;
    ShowMessage('SetClassInstallParams');
    exit;
  end;
  Result := true;
end;

function TForm1.GetClassImageIndex(ClassGuid: TGuid; Index: PInt): Boolean;
begin
  Result := SetupDiGetClassImageIndex(ClassImageListData, ClassGuid, Index^);
end;

function TForm1.GetRegistryProperty(PnPHandle: hDevInfo; DevData: TSPDevInfoData; Prop: DWord; Buffer: PChar; dwLength: DWord): Boolean;
var
  aBuffer: array[0..256] of Char;
begin
  dwLength := 0;
  aBuffer[0] := #0;
  SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, Prop, Prop, PBYTE(@aBuffer[0]), SizeOf(aBuffer), dwLength);
  StrCopy(Buffer, aBuffer);
  Result := Buffer^ <> #0;
end;

function TForm1.ConstructDeviceName(DeviceInfoSet: hDevInfo;
         DeviceInfoData: TSPDevInfoData; Buffer: PChar; dwLength: DWord): Boolean;
const
  UnknownDevice = '<Unknown Device>';
begin
  if (not GetRegistryProperty(DeviceInfoSet, DeviceInfoData, SPDRP_FRIENDLYNAME, Buffer, dwLength)) then
  begin
    if (not GetRegistryProperty(DeviceInfoSet, DeviceInfoData, SPDRP_DEVICEDESC, Buffer, dwLength)) then
    begin
      if (not GetRegistryProperty(DeviceInfoSet, DeviceInfoData, SPDRP_CLASS, Buffer, dwLength)) then
      begin
        if (not GetRegistryProperty(DeviceInfoSet, DeviceInfoData, SPDRP_CLASSGUID, Buffer, dwLength)) then
        begin
          dwLength := DWord(SizeOf(UnknownDevice));
          Buffer := Pointer(LocalAlloc(LPTR, Cardinal(dwLength)));
          StrCopy(Buffer, UnknownDevice);
        end;
      end;
    end;
  end;
  Result := true;
end;

function TForm1.IsClassHidden(ClassGuid: TGuid): Boolean;
var
  bHidden: Boolean;
  hKeyClass: HKey;
begin
  bHidden := false;
  hKeyClass := SetupDiOpenClassRegKey(@ClassGuid, KEY_READ);
  if (hKeyClass <> 0) then
  begin
    bHidden := (RegQueryValueEx(hKeyClass, REGSTR_VAL_NODISPLAYCLASS, nil, nil, nil, nil) = ERROR_SUCCESS);
    RegCloseKey(hKeyClass);
  end;
  Result := bHidden;
end;

function TForm1.EnumAddDevices(ShowHidden: Boolean; hwndTree: TTreeView; DevInfo: hDevInfo): Boolean;
var
  i, Status, Problem: DWord;
  pszText: PChar;
  DeviceInfoData: TSPDevInfoData;
  iImage: Integer;
begin
  TTreeView(hWndTree).Items.BeginUpdate;
  DeviceInfoData.cbSize := SizeOf(TSPDevInfoData);
  TTreeView(hWndTree).Items.Clear;
  i := 0;
  while SetupDiEnumDeviceInfo(DevInfo, i, DeviceInfoData) do
  begin
    inc(i);
    if (CM_Get_DevNode_Status(@Status, @Problem, DeviceInfoData.DevInst, 0) <> CR_SUCCESS) then
    begin
      ShowMessage('CM_Get_DevNode_Status :: uenable.pas');
      break;
    end;
    if (not (ShowHidden or not(Boolean(Status and DN_NO_SHOW_IN_DM) or IsClassHidden(DeviceInfoData.ClassGuid)))) then
    begin
      break;
    end;
    GetMem(pszText, 256);
    try
      ConstructDeviceName(DevInfo, DeviceInfoData, pszText, DWord(nil));
      if (GetClassImageIndex(DeviceInfoData.ClassGuid, @iImage)) then
      begin
        with TTreeView(hWndTree).Items.AddObject(nil, pszText, nil) do
        begin
          TTreeView(hWndTree).Items[i-1].ImageIndex := iImage;
          TTreeView(hWndTree).Items[i-1].SelectedIndex := iImage;
        end;
        if (Problem = CM_PROB_DISABLED) then // Красный (X)
        begin
            TTreeView(hWndTree).Items[i-1].OverlayIndex := IDI_DISABLED_OVL - IDI_CLASSICON_OVERLAYFIRST;
        end else
        begin
          if (Boolean(Problem)) then // Желтый (!)
          begin
              TTreeView(hWndTree).Items[i-1].OverlayIndex := IDI_PROBLEM_OVL - IDI_CLASSICON_OVERLAYFIRST;
          end;
        end;
        if (Status and DN_NO_SHOW_IN_DM = DN_NO_SHOW_IN_DM) then 
        begin
          TTreeView(hWndTree).Items[i-1].Cut := true;
        end;
      end;
    finally
      FreeMem(pszText);
    end;
  end;
  TTreeView(hWndTree).Items.EndUpdate;
  Result := true;
end;
Ответить с цитированием