http://www.delphi2007.net/DelphiAPI/html/delphi_20061202153021130.html
请问各位如何用Delphi控制U盘的安全拔出????已经有源代码,但是不知道如何控制指定的U盘
那个帖看见了,这个帖还没人来,我蹭分先
嘻嘻~
你不是已经有源代码了吗?
就在一个消息处理函数(wndpro),拦截了U盘拔出和插入的消息,然后就可以自己添加一些语句来记录。
具体修改不懂!!帮帮我好吗???我把代码发上!!
const
CfgMgr32ModuleName = 'cfgmgr32.dll';
SetupApiModuleName = 'SetupApi.dll';
REGSTR_VAL_NODISPLAYCLASS = 'NoDisplayClass';
CR_SUCCESS = $00000000;
CR_REMOVE_VETOED = $00000017;
DN_HAS_PROBLEM = $00000400;
DN_DISABLEABLE = $00002000;
DN_REMOVABLE = $00004000;
DN_NO_SHOW_IN_DM = $40000000;
CM_PROB_DISABLED = $00000016;
CM_PROB_HARDWARE_DISABLED = $0000001D;
type
_PNP_VETO_TYPE = (
PNP_VetoTypeUnknown,
PNP_VetoLegacyDevice,
PNP_VetoPendingClose,
PNP_VetoWindowsApp,
PNP_VetoWindowsService,
PNP_VetoOutstandingOpen,
PNP_VetoDevice,
PNP_VetoDriver,
PNP_VetoIllegalDeviceRequest,
PNP_VetoInsufficientPower,
PNP_VetoNonDisableable,
PNP_VetoLegacyDriver
);
PNP_VETO_TYPE = _PNP_VETO_TYPE;
PPNP_VETO_TYPE = ^_PNP_VETO_TYPE;
TPNPVetoType = _PNP_VETO_TYPE;
PPNPVetoType = PPNP_VETO_TYPE;
function CM_Get_DevNode_Status(pulStatus: PULong; pulProblemNumber: PULong;
dnDevInst: DWord; ulFlags: ULong): DWord; stdcall;
external CfgMgr32ModuleName name 'CM_Get_DevNode_Status';
function CM_Request_Device_Eject(dnDevInst: DWord; out pVetoType: TPNPVetoType;
pszVetoName: PChar; ulNameLength: ULong; ulFlags: ULong): DWord; stdcall;
external SetupApiModuleName name 'CM_Request_Device_EjectA';
type
TForm1 = class(TForm)
TreeView: TTreeView;
ImageList: TImageList;
MainMenu1: TMainMenu;
Eject1: TMenuItem;
Exit1: TMenuItem;
Change1: TMenuItem;
ShowHidden1: TMenuItem;
EjectDriver1: TMenuItem;
Exit2: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure ShowHidden1Click(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure EjectDriver1Click(Sender: TObject);
procedure Exit2Click(Sender: TObject);
procedure TreeViewClick(Sender: TObject);
private
DevInfo: hDevInfo;
ClassImageListData: TSPClassImageListData;
ShowHidden: Boolean;
function EnumAddDevices(ShowHidden: Boolean; hwndTree: TTreeView; DevInfo: hDevInfo): Boolean;
function IsClassHidden(ClassGuid: TGuid): 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 GetClassImageIndex(ClassGuid: TGuid; Index: PInt): Boolean;
function GetDevInfo(var hDevInfo: hDevInfo): boolean;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function TForm1.GetDevInfo(var hDevInfo: hDevInfo): boolean;
begin
if (assigned(DevInfo)) then
begin
SetupDiDestroyDeviceInfoList(DevInfo);
SetupDiDestroyClassImageList(ClassImageListData);
end;
// Get a handle to all devices in all classes present on system
DevInfo := SetupDiGetClassDevs(nil, nil, 0, DIGCF_PRESENT or DIGCF_ALLCLASSES);
if (DevInfo = Pointer(INVALID_HANDLE_VALUE)) then
begin
ShowMessage('GetClassDevs');
exit;
end;
// Get the Images for all classes, and bind to the TreeView
ClassImageListData.cbSize := SizeOf(TSPClassImageListData);
if (not SetupDiGetClassImageList(ClassImageListData)) then
begin
ShowMessage('GetClassImageList');
exit;
end;
ImageList.Handle := ClassImageListData.ImageList;
TreeView.Images := ImageList;
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 = '
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);
// Clean off all the items in a TreeView.
TTreeView(hWndTree).Items.Clear;
i := 0;
// Enumerate though all the devices.
while SetupDiEnumDeviceInfo(DevInfo, i, DeviceInfoData) do
begin
inc(i);
// Should we display this device, or move onto the next one.
if (CM_Get_DevNode_Status(@Status, @Problem, DeviceInfoData.DevInst, 0) <> CR_SUCCESS) then
begin
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
// Get a friendly name for the device.
ConstructDeviceName(DevInfo, DeviceInfoData, pszText, DWord(nil));
// Try to get an icon index for this device.
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 // red (X)
begin
TTreeView(hWndTree).Items[i-1].OverlayIndex := IDI_DISABLED_OVL - IDI_CLASSICON_OVERLAYFIRST;
end else
begin
if (Boolean(Problem)) then // yellow (!)
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 // Greyed out
begin
TTreeView(hWndTree).Items[i-1].Cut := true;
end;
end;
finally
FreeMem(pszText);
end;
end;
TTreeView(hWndTree).Items.EndUpdate;
Result := true;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
if (not LoadSetupAPI) then
begin
ShowMessage('Could not load SetupAPI.dll');
exit;
end;
DevInfo := nil;
ShowHidden := false;
// Get a handle to all devices in all classes present on system
if not GetDevInfo(DevInfo) then
begin
ShowMessage('GetClassDevs');
exit;
end;
// Get the Images for all classes, and bind to the TreeView
ClassImageListData.cbSize := SizeOf(TSPClassImageListData);
if (not SetupDiGetClassImageList(ClassImageListData)) then
begin
ShowMessage('GetClassImageList');
exit;
end;
ImageList.Handle := ClassImageListData.ImageList;
TreeView.Images := ImageList;
// Add the devices to the TreeView window.
EnumAddDevices(ShowHidden, TreeView, DevInfo);
end;
procedure TForm1.EjectDriver1Click(Sender: TObject);
var
DeviceInfoData: TSPDevInfoData;
Status, Problem: DWord;
VetoType: TPNPVetoType;
VetoName: array[0..256] of Char;
begin
DeviceInfoData.cbSize := SizeOf(TSPDevInfoData);
// Get a handle to the Selected Item.
if (not SetupDiEnumDeviceInfo(DevInfo, TreeView.Selected.Index, DeviceInfoData)) then
begin
exit;
end;
if (CM_Get_DevNode_Status(@Status, @Problem, DeviceInfoData.DevInst, 0) <> CR_SUCCESS) then
begin
exit;
end;
VetoName[0] := #0;
case CM_Request_Device_Eject(DeviceInfoData.DevInst, VetoType, @VetoName, SizeOf(VetoName), 0) of
CR_SUCCESS:
begin
MessageBox(Handle, 'Successful to eject the Device', 'Done', MB_OK);
if not GetDevInfo(DevInfo) then
begin
ShowMessage('GetClassDevs');
end;
EnumAddDevices(ShowHidden, TreeView, DevInfo);
end;
CR_REMOVE_VETOED:
begin
MessageBox(Handle, PChar('Failed to eject the Device (Veto: ' + VetoName + ')'), 'Vetoed', MB_OK);
end;
else
begin
MessageBox(Handle, PChar('Failed to eject the Device (' + SysErrorMessage(GetLastError) + ')'), 'Failure', MB_OK);
end;
end;
end;
procedure TForm1.ShowHidden1Click(Sender: TObject);
begin
ShowHidden := not ShowHidden;
EnumAddDevices(ShowHidden, TreeView, DevInfo);
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
canclose:=application.MessageBox('你真的要退出吗?','系统提示',mb_yesno+MB_ICONQUESTION)=idyes ;
if canclose then
begin
Application.Terminate;
end;
end;
procedure TForm1.Exit2Click(Sender: TObject);
begin
Close;
end;
end.
ly_liuyang(Liu Yang LYSoft http://lysoft.7u7.net)
大牛都灌水,。。。