una rastro quitar programa pendrive para memoria formatear eliminar duro disco directo dejar cómo como borrar acceso delphi usb

delphi - rastro - programa para eliminar virus de acceso directo



¿Cómo puedo eliminar un disco flash USB programáticamente usando Delphi? (3)

Esto no expulsa la unidad, pero vacía los búferes de la unidad y hace que sea seguro eliminarla. Requiere derechos administrativos bajo Vista y superior (y XP si se ejecuta como un usuario con derechos limitados, IIRC). Probablemente debería intentarlo ... para asegurarse de que se llama a CloseHandle ; Lo dejo como un ejercicio para el lector, ya que el formato de código es ajustado aquí sin desplazamiento horizontal. :-)

unit USBDriveFlush; interface uses Windows; type // Taken from JEDI JwaWinIoctl PSTORAGE_HOTPLUG_INFO = ^STORAGE_HOTPLUG_INFO; {$EXTERNALSYM PSTORAGE_HOTPLUG_INFO} _STORAGE_HOTPLUG_INFO = record Size: DWORD; // version MediaRemovable: BOOLEAN; // ie. zip, jaz, cdrom, mo, etc. vs hdd MediaHotplug: BOOLEAN; // ie. does the device succeed a lock // even though its not lockable media? DeviceHotplug: BOOLEAN; // ie. 1394, USB, etc. WriteCacheEnableOverride: BOOLEAN; // This field should not be // relied upon because it is no longer used end; {$EXTERNALSYM _STORAGE_HOTPLUG_INFO} STORAGE_HOTPLUG_INFO = _STORAGE_HOTPLUG_INFO; {$EXTERNALSYM STORAGE_HOTPLUG_INFO} TStorageHotplugInfo = STORAGE_HOTPLUG_INFO; PStorageHotplugInfo = PSTORAGE_HOTPLUG_INFO; function FlushUSBDrive(const Drive: string): Boolean; implementation function FlushUSBDrive(const Drive: string): Boolean; var shpi : TStorageHotplugInfo; retlen : DWORD; //unneeded, but deviceiocontrol expects it h : THandle; begin Result := False; h := CreateFile(PChar(''//./' + Drive), 0, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); if h <> INVALID_HANDLE_VALUE then begin shpi.Size := SizeOf(shpi); if DeviceIoControl(h, IOCTL_STORAGE_GET_HOTPLUG_INFO, nil, 0, @shpi, SizeOf(shpi), retlen, nil) then begin //shpi now has the existing values, so you can check to //see if the device is already hot-pluggable if not shpi.DeviceHotplug then begin shpi.DeviceHotplug:= True; //Need to use correct administrator security privilages here //otherwise it''ll just give ''access is denied'' error Result := DeviceIoControl(h, IOCTL_STORAGE_SET_HOTPLUG_INFO, @shpi, SizeOf(shpi), nil, 0, retlen, nil); end; end; CloseHandle(h); end; end;

Uso de muestra:

if FlushUSBDrive(''G:'') then ShowMessage(''Safe to remove USB drive G:'') else ShowMessage(''Flush of drive G: failed!'' + SysErrorMessage(GetLastError()));

¿Cómo puedo detectar y eliminar un disco flash USB programáticamente usando Delphi?

He visto algunos de los ejemplos en este sitio web, pero carecen de una explicación clara sobre cómo hacerlo.

¡Por favor los ejemplos realmente ayudarán!


La clave para eliminar una unidad USB es utilizar la función CM_Request_Device_Eject ,

Consulte esta aplicación de delphi de muestra, basada en este artículo How to Prepare a USB Drive for Safe Removal y que utiliza la JEDI API Library & Security Code Library

{$APPTYPE CONSOLE} {$R *.res} uses JwaWinIoctl, Cfg, CfgMgr32, SetupApi, Windows, SysUtils; function GetDrivesDevInstByDeviceNumber(DeviceNumber : LONG; DriveType : UINT; szDosDeviceName: PChar) : DEVINST; var StorageGUID : TGUID; IsFloppy : Boolean; hDevInfo : SetupApi.HDEVINFO; dwIndex : DWORD; res : BOOL; pspdidd : PSPDeviceInterfaceDetailData; spdid : SP_DEVICE_INTERFACE_DATA; spdd : SP_DEVINFO_DATA; dwSize : DWORD; hDrive : THandle; sdn : STORAGE_DEVICE_NUMBER; dwBytesReturned : DWORD; begin Result:=0; IsFloppy := pos(''//Floppy'', szDosDeviceName)>0; // who knows a better way? case DriveType of DRIVE_REMOVABLE: if ( IsFloppy ) then StorageGUID := GUID_DEVINTERFACE_FLOPPY else StorageGUID := GUID_DEVINTERFACE_DISK; DRIVE_FIXED: StorageGUID := GUID_DEVINTERFACE_DISK; DRIVE_CDROM: StorageGUID := GUID_DEVINTERFACE_CDROM; else exit end; // Get device interface info set handle for all devices attached to system hDevInfo := SetupDiGetClassDevs(@StorageGUID, nil, 0, DIGCF_PRESENT OR DIGCF_DEVICEINTERFACE); if (NativeUInt(hDevInfo) <> INVALID_HANDLE_VALUE) then try // Retrieve a context structure for a device interface of a device information set dwIndex := 0; //PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf; spdid.cbSize := SizeOf(spdid); while true do begin res := SetupDiEnumDeviceInterfaces(hDevInfo, nil, StorageGUID, dwIndex, spdid); if not res then break; dwSize := 0; SetupDiGetDeviceInterfaceDetail(hDevInfo, @spdid, nil, 0, dwSize, nil); // check the buffer size if ( dwSize<>0) then begin pspdidd := AllocMem(dwSize); try pspdidd.cbSize := SizeOf(TSPDeviceInterfaceDetailData); ZeroMemory(@spdd, sizeof(spdd)); spdd.cbSize := SizeOf(spdd); res := SetupDiGetDeviceInterfaceDetail(hDevInfo, @spdid, pspdidd, dwSize, dwSize, @spdd); if res then begin // open the disk or cdrom or floppy hDrive := CreateFile(pspdidd.DevicePath, 0, FILE_SHARE_READ OR FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); if ( hDrive <> INVALID_HANDLE_VALUE ) then try // get its device number dwBytesReturned := 0; res := DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, nil, 0, @sdn, sizeof(sdn), dwBytesReturned, nil); if res then begin if ( DeviceNumber = sdn.DeviceNumber) then begin // match the given device number with the one of the current device Result:= spdd.DevInst; exit; end; end; finally CloseHandle(hDrive); end; end; finally FreeMem(pspdidd); end; end; Inc(dwIndex); end; finally SetupDiDestroyDeviceInfoList(hDevInfo); end; end; procedure EjectUSB(const DriveLetter:char); var szRootPath, szDevicePath : PChar; szVolumeAccessPath : PChar; hVolume : THandle; DeviceNumber : LONG; sdn : STORAGE_DEVICE_NUMBER; dwBytesReturned : DWORD; res : BOOL; resCM : Cardinal; DriveType : UINT; szDosDeviceName : array [0..MAX_PATH-1] of Char; DevInst : CfgMgr32.DEVINST; VetoType : PNP_VETO_TYPE; VetoName : array [0..MAX_PATH-1] of WCHAR; bSuccess : Boolean; DevInstParent : CfgMgr32.DEVINST; tries : Integer; begin szRootPath := PChar(DriveLetter+'':/'); szDevicePath := PChar(DriveLetter+'':''); szVolumeAccessPath := PChar(Format(''//./%s:'',[DriveLetter])); DeviceNumber:=-1; // open the storage volume hVolume := CreateFile(szVolumeAccessPath, 0, FILE_SHARE_READ OR FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); if (hVolume <> INVALID_HANDLE_VALUE) then try //get the volume''s device number dwBytesReturned := 0; res := DeviceIoControl(hVolume, IOCTL_STORAGE_GET_DEVICE_NUMBER, nil, 0, @sdn, SizeOf(sdn), dwBytesReturned, nil); if res then DeviceNumber := sdn.DeviceNumber; finally CloseHandle(hVolume); end; if DeviceNumber=-1 then exit; // get the drive type which is required to match the device numbers correctely DriveType := GetDriveType(szRootPath); // get the dos device name (like /device/floppy0) to decide if it''s a floppy or not - who knows a better way? QueryDosDevice(szDevicePath, szDosDeviceName, MAX_PATH); // get the device instance handle of the storage volume by means of a SetupDi enum and matching the device number DevInst := GetDrivesDevInstByDeviceNumber(DeviceNumber, DriveType, szDosDeviceName); if ( DevInst = 0 ) then exit; 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; resCM := CM_Get_Parent(DevInstParent, DevInst, 0); for tries:=0 to 3 do // sometimes we need some tries... begin FillChar(VetoName[0], SizeOf(VetoName), 0); // CM_Query_And_Remove_SubTree doesn''t work for restricted users //resCM = CM_Query_And_Remove_SubTree(DevInstParent, &VetoType, VetoNameW, MAX_PATH, CM_REMOVE_NO_RESTART); // CM_Query_And_Remove_SubTreeA is not implemented under W2K! //resCM = CM_Query_And_Remove_SubTree(DevInstParent, NULL, NULL, 0, CM_REMOVE_NO_RESTART); // with messagebox (W2K, Vista) or balloon (XP) resCM := CM_Request_Device_Eject(DevInstParent, @VetoType, @VetoName[0], Length(VetoName), 0); resCM := CM_Request_Device_Eject(DevInstParent,nil, nil, 0, 0); // optional -> shows messagebox (W2K, Vista) or balloon (XP) bSuccess := (resCM=CR_SUCCESS) and (VetoType=PNP_VetoTypeUnknown); if ( bSuccess ) then break; Sleep(500); // required to give the next tries a chance! end; if ( bSuccess ) then Writeln(''Success'') else Writeln(''Failed''); end; begin try LoadSetupApi; LoadConfigManagerApi; EjectUSB(''F''); except on E: Exception do Writeln(E.ClassName, '': '', E.Message); end; Readln; end.


Esta es una traducción rápida y sucia de este código de muestra para eliminar una unidad, de support.microsoft.com. Sin embargo, funciona solo para usuarios con permisos de administrador en mi sistema.

Para obtener más información sobre cómo trabajar con dispositivos USB, en general, siga el enlace en esta respuesta por concept03 .

function OpenVolume(ADrive: char): THandle; var RootName, VolumeName: string; AccessFlags: DWORD; begin RootName := ADrive + '':/'; (* ''/''' // keep SO syntax highlighting working *) case GetDriveType(PChar(RootName)) of DRIVE_REMOVABLE: AccessFlags := GENERIC_READ or GENERIC_WRITE; DRIVE_CDROM: AccessFlags := GENERIC_READ; else Result := INVALID_HANDLE_VALUE; exit; end; VolumeName := Format(''//./%s:'', [ADrive]); Result := CreateFile(PChar(VolumeName), AccessFlags, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); if Result = INVALID_HANDLE_VALUE then RaiseLastWin32Error; end; function LockVolume(AVolumeHandle: THandle): boolean; const LOCK_TIMEOUT = 10 * 1000; // 10 Seconds LOCK_RETRIES = 20; LOCK_SLEEP = LOCK_TIMEOUT div LOCK_RETRIES; // #define FSCTL_LOCK_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS) FSCTL_LOCK_VOLUME = (9 shl 16) or (0 shl 14) or (6 shl 2) or 0; var Retries: integer; BytesReturned: Cardinal; begin for Retries := 1 to LOCK_RETRIES do begin Result := DeviceIoControl(AVolumeHandle, FSCTL_LOCK_VOLUME, nil, 0, nil, 0, BytesReturned, nil); if Result then break; Sleep(LOCK_SLEEP); end; end; function DismountVolume(AVolumeHandle: THandle): boolean; const // #define FSCTL_DISMOUNT_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS) FSCTL_DISMOUNT_VOLUME = (9 shl 16) or (0 shl 14) or (8 shl 2) or 0; var BytesReturned: Cardinal; begin Result := DeviceIoControl(AVolumeHandle, FSCTL_DISMOUNT_VOLUME, nil, 0, nil, 0, BytesReturned, nil); if not Result then RaiseLastWin32Error; end; function PreventRemovalOfVolume(AVolumeHandle: THandle; APreventRemoval: boolean): boolean; const // #define IOCTL_STORAGE_MEDIA_REMOVAL CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS) IOCTL_STORAGE_MEDIA_REMOVAL = ($2d shl 16) or (1 shl 14) or ($201 shl 2) or 0; type TPreventMediaRemoval = record PreventMediaRemoval: BOOL; end; var BytesReturned: Cardinal; PMRBuffer: TPreventMediaRemoval; begin PMRBuffer.PreventMediaRemoval := APreventRemoval; Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_MEDIA_REMOVAL, @PMRBuffer, SizeOf(TPreventMediaRemoval), nil, 0, BytesReturned, nil); if not Result then RaiseLastWin32Error; end; function AutoEjectVolume(AVolumeHandle: THandle): boolean; const // #define IOCTL_STORAGE_EJECT_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS) IOCTL_STORAGE_EJECT_MEDIA = ($2d shl 16) or (1 shl 14) or ($202 shl 2) or 0; var BytesReturned: Cardinal; begin Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_EJECT_MEDIA, nil, 0, nil, 0, BytesReturned, nil); if not Result then RaiseLastWin32Error; end; function EjectVolume(ADrive: char): boolean; var VolumeHandle: THandle; begin Result := FALSE; // Open the volume VolumeHandle := OpenVolume(ADrive); if VolumeHandle = INVALID_HANDLE_VALUE then exit; try // Lock and dismount the volume if LockVolume(VolumeHandle) and DismountVolume(VolumeHandle) then begin // Set prevent removal to false and eject the volume if PreventRemovalOfVolume(VolumeHandle, FALSE) then AutoEjectVolume(VolumeHandle); end; finally // Close the volume so other processes can use the drive CloseHandle(VolumeHandle); end; end; procedure TForm1.Button1Click(Sender: TObject); begin EjectVolume(''E''); end;