你好,用过U盘的都知道,如果要安全的拔除U盘,必须通过右下的”安全拔下或弹出“的小工具来进行。我现在想自己写一段代码来安全地删除某个usb设备,不知如何下手,请高手赐教。
谢谢。
完整代码如下,在VC6,2000环境下编译通过。
谢谢大家捧场,特别感谢codewarrior(会思考的草)和 holyeagle(一杯清茶)两位朋友,没有你们我肯定解决不了这个问题。另外,也感谢tikomo software(日本),他们的例子让我少走了许多弯路。
谢谢大家,散分了.
#include <tchar.h>
#include <stdio.h>
#include <windows.h>
#include <devguid.h>
#define DWORD_PTR DWORD
#define ULONG_PTR DWORD
extern "C" {
#include "hidsdi.h"
}
// 需加入hid.lib
#include <setupapi.h>
// 需加入setupapi.lib
#include <regstr.h>
#include <winbase.h>
#include <cfgmgr32.h>
// 需要加入cfgmgr32.lib
#include <initguid.h>
//#include <usbiodef.h>
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE,
0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
#define GUID_CLASS_USB_DEVICE GUID_DEVINTERFACE_USB_DEVICE
int main(int argc, _TCHAR* argv[])
{
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
DWORD i;
//--------------------------------------------------------------------------
// 获取设备信息
hDevInfo = SetupDiGetClassDevs((LPGUID)&GUID_CLASS_USB_DEVICE,
0, // Enumerator
0,
DIGCF_PRESENT ¦ DIGCF_DEVICEINTERFACE );
if (hDevInfo == INVALID_HANDLE_VALUE) {
// 查询信息失败
printf("ERROR - SetupDiGetClassDevs()");
return 1;
}
//--------------------------------------------------------------------------
// 枚举每个USB设备
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i=0;SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData);i++)
{
LPTSTR buffer = NULL;
PVOID buffer2 = NULL;
DWORD buffersize = 0;
ULONG len;
CONFIGRET cr;
PNP_VETO_TYPE pnpvietotype;
CHAR vetoname[MAX_PATH];
ULONG ulStatus;
ULONG ulProblemNumber;
cr = CM_Get_DevNode_Status( &ulStatus,
&ulProblemNumber,
DeviceInfoData.DevInst,
0);
if ( CR_SUCCESS == cr ) {
printf("OK - CM_Get_DevNode_Status()[%d]\n", cr);
printf("OK - CM_Get_DevNode_Status() sts [%x]\n", ulStatus);
printf("OK - CM_Get_DevNode_Status() pro [%x]\n", ulProblemNumber);
} else {
printf("ERROR - CM_Get_DevNode_Status()[%d]\n", cr);
printf("ERROR - CM_Get_DevNode_Status()[%d]\n", GetLastError());
}
// DN_DISABLEABLE or DN_REMOVABLE
if ((DN_DISABLEABLE & ulStatus ) != 0 ) {
printf("HAS - DN_DISABLEABLE()[%x]\n", DN_DISABLEABLE & ulStatus);
} else {
continue;
}
if ((DN_REMOVABLE & ulStatus ) != 0 ) {
printf("HAS - DN_REMOVABLE()[%x]\n", DN_REMOVABLE & ulStatus);
} else {
continue;
}
len = MAX_PATH;
// pnpvietotype = PNP_VetoDevice;
cr = CM_Request_Device_Eject(
DeviceInfoData.DevInst,
&pnpvietotype,
vetoname,
len,
0
);
if ( CR_SUCCESS == cr ) {
printf("OK - CM_Request_Device_Eject()[%d]\n", cr);
} else {
printf("ERROR - CM_Request_Device_Eject()[%d]\n", cr);
printf("ERROR - CM_Request_Device_Eject()[%d]\n", GetLastError());
}
}
if ( GetLastError()!=NO_ERROR &&
GetLastError()!=ERROR_NO_MORE_ITEMS )
{
// Insert error handling here.
return 1;
}
// Cleanup
SetupDiDestroyDeviceInfoList(hDevInfo);
return 0;
}
谢谢。
完整代码如下,在VC6,2000环境下编译通过。
谢谢大家捧场,特别感谢codewarrior(会思考的草)和 holyeagle(一杯清茶)两位朋友,没有你们我肯定解决不了这个问题。另外,也感谢tikomo software(日本),他们的例子让我少走了许多弯路。
谢谢大家,散分了.
#include <tchar.h>
#include <stdio.h>
#include <windows.h>
#include <devguid.h>
#define DWORD_PTR DWORD
#define ULONG_PTR DWORD
extern "C" {
#include "hidsdi.h"
}
// 需加入hid.lib
#include <setupapi.h>
// 需加入setupapi.lib
#include <regstr.h>
#include <winbase.h>
#include <cfgmgr32.h>
// 需要加入cfgmgr32.lib
#include <initguid.h>
//#include <usbiodef.h>
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE,
0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
#define GUID_CLASS_USB_DEVICE GUID_DEVINTERFACE_USB_DEVICE
int main(int argc, _TCHAR* argv[])
{
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
DWORD i;
//--------------------------------------------------------------------------
// 获取设备信息
hDevInfo = SetupDiGetClassDevs((LPGUID)&GUID_CLASS_USB_DEVICE,
0, // Enumerator
0,
DIGCF_PRESENT ¦ DIGCF_DEVICEINTERFACE );
if (hDevInfo == INVALID_HANDLE_VALUE) {
// 查询信息失败
printf("ERROR - SetupDiGetClassDevs()");
return 1;
}
//--------------------------------------------------------------------------
// 枚举每个USB设备
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i=0;SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData);i++)
{
LPTSTR buffer = NULL;
PVOID buffer2 = NULL;
DWORD buffersize = 0;
ULONG len;
CONFIGRET cr;
PNP_VETO_TYPE pnpvietotype;
CHAR vetoname[MAX_PATH];
ULONG ulStatus;
ULONG ulProblemNumber;
cr = CM_Get_DevNode_Status( &ulStatus,
&ulProblemNumber,
DeviceInfoData.DevInst,
0);
if ( CR_SUCCESS == cr ) {
printf("OK - CM_Get_DevNode_Status()[%d]\n", cr);
printf("OK - CM_Get_DevNode_Status() sts [%x]\n", ulStatus);
printf("OK - CM_Get_DevNode_Status() pro [%x]\n", ulProblemNumber);
} else {
printf("ERROR - CM_Get_DevNode_Status()[%d]\n", cr);
printf("ERROR - CM_Get_DevNode_Status()[%d]\n", GetLastError());
}
// DN_DISABLEABLE or DN_REMOVABLE
if ((DN_DISABLEABLE & ulStatus ) != 0 ) {
printf("HAS - DN_DISABLEABLE()[%x]\n", DN_DISABLEABLE & ulStatus);
} else {
continue;
}
if ((DN_REMOVABLE & ulStatus ) != 0 ) {
printf("HAS - DN_REMOVABLE()[%x]\n", DN_REMOVABLE & ulStatus);
} else {
continue;
}
len = MAX_PATH;
// pnpvietotype = PNP_VetoDevice;
cr = CM_Request_Device_Eject(
DeviceInfoData.DevInst,
&pnpvietotype,
vetoname,
len,
0
);
if ( CR_SUCCESS == cr ) {
printf("OK - CM_Request_Device_Eject()[%d]\n", cr);
} else {
printf("ERROR - CM_Request_Device_Eject()[%d]\n", cr);
printf("ERROR - CM_Request_Device_Eject()[%d]\n", GetLastError());
}
}
if ( GetLastError()!=NO_ERROR &&
GetLastError()!=ERROR_NO_MORE_ITEMS )
{
// Insert error handling here.
return 1;
}
// Cleanup
SetupDiDestroyDeviceInfoList(hDevInfo);
return 0;
}
var
ghDevInfo : HDEVINFO;
gDeviceInfoData : SP_DEVINFO_DATA;
vetoname : array[0..MAX_PATH] of CHAR;
pnpvietotype : TPnpVetoType;
ulStatus : ULONG;
ulProblemNumber : ULONG;
i : Integer;
len : ULONG;
dwRc : DWORD;
begin
// USB?
//  HDEVINFO 
ghDevInfo := SetupDiGetClassDevs( @GUID_CLASS_USB_DEVICE,
nil, // Enumerator
0,
DIGCF_PRESENT or DIGCF_DEVICEINTERFACE ); if (ghDevInfo = nil) then begin // INVALID_HANDLE_VALUE
// ?
ShowMessage('ERROR - SetupDiGetClassDevs()');
Exit;
end
else begin
//
ShowMessage('SUCCESS - SetupDiGetClassDevs()');
end; // ?
gDeviceInfoData.cbSize := sizeof(SP_DEVINFO_DATA);
i := 0;
while( true = SetupDiEnumDeviceInfo(ghDevInfo, i, gDeviceInfoData) ) do begin ShowMessage('SUCCESS - SetupDiEnumDeviceInfo()' + ' count=' + IntToStr(i)); dwRc := CM_Get_DevNode_Status( @ulStatus,
@ulProblemNumber,
gDeviceInfoData.DevInst,
0); if ( CR_SUCCESS = dwRc ) then begin
ShowMessage('SUCCESS - CM_Get_DevNode_Status()['+ IntToStr(dwRc) + ']');
end
else begin
ShowMessage('SUCCESS - CM_Get_DevNode_Status()['+ IntToStr(dwRc) + ']');
end; if ((DN_DISABLEABLE and ulStatus ) <> 0 ) then begin
ShowMessage('HAS - DN_DISABLEABLE['+ IntToHex(DN_DISABLEABLE and ulStatus, 8) + ']');
end
else begin
continue;
end; if ((DN_REMOVABLE and ulStatus ) <> 0 ) then begin
ShowMessage('HAS - DN_REMOVABLE['+ IntToHex(DN_REMOVABLE and ulStatus, 8) + ']');
end
else begin
continue;
end; len := MAX_PATH;
dwRc := CM_Request_Device_Eject( gDeviceInfoData.DevInst,
pnpvietotype,
vetoname,
len,
0); if ( CR_SUCCESS = dwRc ) then begin
ShowMessage('SUCCESS - CM_Request_Device_Eject()['+ IntToStr(dwRc) + ']');
end
else begin
ShowMessage('ERROR - CM_Request_Device_Eject()['+ IntToStr(dwRc) + ']');
end;
i := i + 1;
end;
// Cleanup
if ( LongBool(0) <> SetupDiDestroyDeviceInfoList(ghDevInfo) ) then begin
//
ShowMessage('SUCCESS - SetupDiDestroyDeviceInfoList()');
end
else begin
// ?
ShowMessage('ERROR - SetupDiDestroyDeviceInfoList()');
ShowMessage('GetLastError()[' + IntToHex(GetLastError(),8) + ']');
// CM_Get_DevNode_Status()
// GetLastError() = 0 
// 
end;end;
CM_Get_DevNode_Status 這個函數都沒有翻譯!!!要自己做進去!我翻了一半, 先copy段別人的給你!!
不過, 我現在還沒有 cfgmgr32 的pascal 聲明, 還要找下!
var
hDevInfo : HDEVINFO;
DeviceInfoData : SP_DEVINFO_DATA;
i : DWORD;
tempchar : pchar;
buffer : LPTSTR;
PVOID buffer2 : PVOID ; //以下几个类同!
vetoname : array[0..MAX_PATH] of char ;
DWORD buffersize := 0;
ULONG len;
CONFIGRET cr;
PNP_VETO_TYPE pnpvietotype;
ULONG ulStatus;
ULONG ulProblemNumber;
begin
//--------------------------------------------------------------------------
// 获取设备信息
hDevInfo := SetupDiGetClassDevs((LPGUID)@GUID_CLASS_USB_DEVICE,
0, // Enumerator
0,
DIGCF_PRESENT @brvbar; DIGCF_DEVICEINTERFACE );
if (hDevInfo = INVALID_HANDLE_VALUE) begin
// 查询信息失败
tempchar :='ERROR - SetupDiGetClassDevs()';
writebuf(tempchar,length(tempchar));
result := 1;
end;
//--------------------------------------------------------------------------
// 枚举每个USB设备
DeviceInfoData.cbSize := sizeof(SP_DEVINFO_DATA);
for i := 0 to SetupDiEnumDeviceInfo(hDevInfo, i, @DeviceInfoData) do
begin
buffer := NULL;
buffer2 := NULL;
buffersize := 0;
cr := CM_Get_DevNode_Status( @ulStatus,
@ulProblemNumber,
DeviceInfoData.DevInst,
0);
if ( CR_SUCCESS = cr ) begin
printf("OK - CM_Get_DevNode_Status()[%d]\n", cr);
printf("OK - CM_Get_DevNode_Status() sts [%x]\n", ulStatus);
printf("OK - CM_Get_DevNode_Status() pro [%x]\n", ulProblemNumber);
end; else begin
printf("ERROR - CM_Get_DevNode_Status()[%d]\n", cr);
printf("ERROR - CM_Get_DevNode_Status()[%d]\n", GetLastError());
end;
// DN_DISABLEABLE or DN_REMOVABLE
if ((DN_DISABLEABLE @ ulStatus ) <> 0 ) begin
printf("HAS - DN_DISABLEABLE()[%x]\n", DN_DISABLEABLE @ ulStatus);
end; else begin
continue;
end;
if ((DN_REMOVABLE @ ulStatus ) <> 0 ) begin
printf("HAS - DN_REMOVABLE()[%x]\n", DN_REMOVABLE @ ulStatus);
end; else begin
continue;
end;
len := MAX_PATH;
// pnpvietotype := PNP_VetoDevice;
cr := CM_Request_Device_Eject(
DeviceInfoData.DevInst,
@pnpvietotype,
vetoname,
len,
0
);
if ( CR_SUCCESS = cr ) begin
printf("OK - CM_Request_Device_Eject()[%d]\n", cr);
end; else begin
printf("ERROR - CM_Request_Device_Eject()[%d]\n", cr);
printf("ERROR - CM_Request_Device_Eject()[%d]\n", GetLastError());
end;
end;
if ( GetLastError()<>NO_ERROR and
GetLastError()<>ERROR_NO_MORE_ITEMS )
begin
// Insert error handling here.
result := 1;
end;
// Cleanup
SetupDiDestroyDeviceInfoList(hDevInfo);
result := 0;
end;
tempchar :='ERROR - SetupDiGetClassDevs()';
writebuf(tempchar,length(tempchar)); 写!
use cfg, cfgmgr32, SetupApi, usbiodef;
怎么没有这个单元呢?
我收到500分後, 發給你!! 呵呵, 不好意思, 最近需要分!!
dnDevInst: DWord; ulFlags: ULong): DWord; stdcall;
external SetupApiModuleName name 'CM_Get_DevNode_Status';先頂住!!
http://community.csdn.net/Expert/topic/3222/3222369.xml?temp=.6579248
http://community.csdn.net/Expert/topic/3220/3220703.xml?temp=.1812555
http://community.csdn.net/Expert/topic/3222/3222364.xml?temp=.1745264
还有本贴100分!
VCToDelphi(VC);
}
http://community.csdn.net/Expert/topic/3222/3222369.xml?temp=.6579248
http://community.csdn.net/Expert/topic/3220/3220703.xml?temp=.1812555
http://community.csdn.net/Expert/topic/3222/3222364.xml?temp=.1745264 版主可以把上面的贴子转为‘技术得分’么?谢谢。
http://community.csdn.net/Expert/topic/3222/3222369.xml?temp=.6579248
http://community.csdn.net/Expert/topic/3220/3220703.xml?temp=.1812555
http://community.csdn.net/Expert/topic/3222/3222364.xml?temp=.1745264 版主可以把上面的贴子转为‘技术得分’么?谢谢。
而不能 DICS_START或者DICS_STOP?
麻烦你了。
http://www.yeahware.com/download/eject.zip
选择Show hidden device后在USB Mass Storage Device处就是Eject了!!!
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';
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, PChar(’Eject OK (Veto: ' + VetoName + ')'), 'Vetoed', MB_OK); 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;
http://community.csdn.net/Expert/topic/3223/3223796.xml?temp=1.796901E-03
不好意思,只能给你100分了,500分已经给->(aiirii(ari-爱的眼睛)
散分中...
http://community.csdn.net/Expert/topic/3223/3223822.xml?temp=.8752558
没问题,加上本贴都有200了:)ARI比较热心的,虽然他没能100%解决问题,他愿意给你翻译代码,这个我可做不到了
http://lysoft.7u7.netBTW:
我最喜欢Delphi搞接近DDK的东西的:)
非常感谢!
明天上午把这个贴子结掉。
可是我已经答应给aiirii(ari-爱的眼睛),500分了。
不好意思!
提交到FAQ吧:)
不会这个都不行吧:(
我就解决了,要早点看见这个贴就好了:(除了弹出U盘,还包括有U盘插入/移除的检测和U盘ID的读取把U盘用于安全领域,就需要这样的
唉, 什麼都要快!! ly_liuyang(Liu Yang) ( ) 才在沒頭腦的那個貼說 分沒用, 你不要,
到這裹又搶了我200分啊, 200分!!! 我....
這個問題我已經解決了90%了!!就是差這麼一會!!!
yangs1295118971(杨姬轩) 你不要介意, 開個玩笑而已!
那个贴子,结不了贴,你有没有办法处理?或者怎么能找到版主呢?To aiirii(ari-爱的眼睛):
还是要谢谢你,今天才真正认识你。原来只是经常听说你的大名。
那个Eject原代码是有Bug的,修正如下添加
function TForm1.GetDevInfo(var hDevInfo: hDevInfo): boolean;
begin
// Get a handle to all devices in all classes present on system
hDevInfo := SetupDiGetClassDevs(nil, nil, 0, DIGCF_PRESENT or DIGCF_ALLCLASSES);
Result := hDevInfo <> Pointer(INVALID_HANDLE_VALUE);
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.mRefreshDisplayClick(Sender: TObject);
begin
if not GetDevInfo(DevInfo) then
begin
ShowMessage('GetClassDevs');
exit;
end;
EnumAddDevices(ShowHidden, TreeView, DevInfo);
end; 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');
exit;
end;
EnumAddDevices(ShowHidden, TreeView, DevInfo);
end;哈哈,这回就OK了
我才不会很着紧呢》yangs1295118971(杨姬轩)只说认识ARI,怎么就没我份?!!》ARI,你都算厉害了,对于资源的搜集真是同我有得比哦,佩服!真心讲的!不过我不只是收集,还会去处理的,修改别人的Code和VCL我是最在行的:)什么时候加上你的QQ有空Q你?
不好意思,我刚才是不是说错话了,真的很对不起! 因为CSDN还才少来的。
我的QQ是:3241106
兩位如果有興趣, 都來可加我! 注明 csdn 比較好!沒什麼了, 分數的, 我們都是上萬了的人, 不會太在乎百半分的!
一爭反而顯得我小氣了!
extern "C" {
#include "hidsdi.h"
}
为什么要这样呢?
各位大侠!