unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,EjectUSB, StdCtrls;
// EjectUSB http://www.delphitop.com/html/danyuan/3578.html
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Button2: TButton;
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function SafeRemoveUDisk(DriveLetter: Char; bTips:Boolean):Integer;
var
szDevicePath,
szRootPath,
szVolumeAccessPath: array[0..MAX_PATH-1]of char;
DeviceNumber: Integer ;
hVolume: THANDLE;
sdn: STORAGE_DEVICE_NUMBER;
dwBytesReturned: DWORD;
res: Integer ;
DriveType: UINT;
szDosDeviceName: array[0..MAX_PATH-1]of char;
iDevInst, DevInstParent: DEVINST;
Status: ULONG;
ProblemNumber: ULONG;
VetoType: PNP_VETO_TYPE;
VetoNameW: array[0..MAX_PATH-1]of WCHAR;
bSuccess: bool;
tries: Integer ;
begin
// "X:\" -> for GetDriveType
szRootPath := 'X:\';
szRootPath[0] := DriveLetter;
// "X:" -> for QueryDosDevice
szDevicePath := 'X:';
szDevicePath[0] := DriveLetter;
// "\\.\X:" -> to open the volume
szVolumeAccessPath := '\\.\X:';
szVolumeAccessPath[4] := DriveLetter;
DeviceNumber := -1;
hVolume := CreateFile(szVolumeAccessPath, 0,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0);
if (hVolume = INVALID_HANDLE_VALUE) then
begin
Result := 1;
Exit;
end;
res := Integer(DeviceIoControl(hVolume,
IOCTL_STORAGE_GET_DEVICE_NUMBER,
nil, 0, @sdn, sizeof(sdn),
dwBytesReturned, nil));
if ( res>0 ) then
begin
DeviceNumber := sdn.DeviceNumber;
end;
CloseHandle(hVolume);
if ( DeviceNumber = -1 ) then
begin
Result := 1;
Exit;
end;
DriveType := GetDriveType(szRootPath);
// get the dos device name (like \device\floppy0)
// to decide if it's a floppy or not
res := QueryDosDevice(szDevicePath, szDosDeviceName, MAX_PATH);
if ( res=0 ) then
begin
Result := 1;
Exit;
end;
iDevInst := DeviceNumberDrive(DeviceNumber,
DriveType, szDosDeviceName);
if ( iDevInst=0 ) then
begin
Result := 1;
Exit;
end;
Status := 0;
ProblemNumber := 0;
VetoType := PNP_VetoTypeUnknown;
bSuccess := false;
// get drives's parent, e.g. the USB bridge,
// the SATA port, an IDE channel with two drives!
DevInstParent := 0;
res := CM_Get_Parent(DevInstParent, iDevInst, 0);
for tries:=1 to 3 do
begin
// sometimes we need some tries...
VetoNameW[0] := #0;
if bTips then
res := CM_Request_Device_EjectW(DevInstParent,
@VetoType, nil, 0, 0)
else
res := CM_Request_Device_EjectW(DevInstParent,
@VetoType, VetoNameW, MAX_PATH, 0);
bSuccess := ( res=CR_SUCCESS) and
( VetoType=PNP_VetoTypeUnknown );
if ( bSuccess ) then
begin
break;
end;
Sleep(500); // required to give the next tries a chance!
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
SafeRemoveUDisk('H',True); //H是U盘符,可用edit1来传递U盘符
end;
end.