⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb.pas

📁 给定偏移地址和大小,实现对USB块设备(如U盘)的读写
💻 PAS
字号:
unit USB;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

{const}
const
    SECTOR_SIZE = 512;
    SECTRO_SHFT = 9;
    RETRY_TIMES     = 3;

type
  TUSB = class(TObject)
  private
    { Private declarations }
    Fopen : Boolean;
    FileName : array [0..20] of Char;
    m_hDevice : THandle;
    USB_thread: THandle;
    procedure SetOpen(const Enable : Boolean);
    function  SectorRead(lpBuffer: PChar; dwIndex: DWORD; dwCount: DWORD): boolean;
    function  SectorWrite(lpBuffer: PChar; dwIndex: DWORD; dwCount: DWORD): boolean;
    function  connect: boolean;
  protected

  public
    { Public declarations }

    constructor Create();
    destructor Destroy;
    property Open : Boolean
      		read FOpen write SetOpen default false;
    procedure set_driver(driver : Char);
    function  SectorRead_retry(lpBuffer: PChar; dwIndex: DWORD; dwCount: DWORD): boolean;
    function  SectorWrite_retry(lpBuffer: PChar; dwIndex: DWORD; dwCount: DWORD): boolean;
  end;

var
    CriticalSection: TRTLCriticalSection;
    USB_valid :boolean = false;
    USB_Driver : Char;

procedure USB_Watch_Thread(Ptr:Pointer);stdcall;
procedure MemCopy(dst: PChar; src: PChar; num:integer);
procedure MemSet(dst: PChar; src: Char; num:integer);


implementation
uses unit1;

procedure MemCopy(dst: PChar; src: PChar; num:integer);
var
    i:integer;
begin
	for i := 0 to (num-1) do begin
    	dst[i] := src[i];
    end;
end;

procedure MemSet(dst: PChar; src: Char; num:integer);
var
    i:integer;
begin
	for i := 0 to (num-1) do begin
    	dst[i] := src;
    end;
end;

constructor TUSB.Create();
begin
    Fopen := False;
    m_hDevice := INVALID_HANDLE_VALUE;
    FileName := '\\.\Z:';
    InitializeCriticalSection(CriticalSection);
end;

destructor TUSB.Destroy;
begin
    CloseHandle(m_hDevice);
    DeleteCriticalSection(CriticalSection);
end;

procedure TUSB.set_driver(driver : Char );
begin
    filename[4] := driver;
end;

procedure TUSB.SetOpen(const Enable : Boolean);
var
    i :integer;
    dwLDMap : DWORD;
begin
    if(Enable = true) then begin
	    dwLDMap := GetLogicalDrives();
        i := integer(filename[4]) - integer('A');
        if ((dwLDMap and (1 shl i)) <> 0) then begin
            if(connect = true) then exit;
		end;
        m_hDevice := INVALID_HANDLE_VALUE;
        Fopen := false;
        MessageBox(0,'Can Open USB Device, please check it!',nil,mb_OK);
    end
    else begin
        if(Fopen = true) then begin
            TerminateThread(USB_thread,0);
            CloseHandle(USB_thread);
            CloseHandle(m_hDevice);
            Fopen := false;
        end;
    end;
end;

function  TUSB.SectorRead(lpBuffer: PChar;dwIndex: DWORD; dwCount :DWORD): boolean;
var
    dwSize, dwBytes : DWORD;
begin
    result := false;
    if (m_hDevice = INVALID_HANDLE_VALUE) then exit;

	if (SetFilePointer(m_hDevice, dwIndex shl SECTRO_SHFT, nil, FILE_BEGIN) <> (dwIndex shl SECTRO_SHFT)) then exit;

	dwSize := (dwCount shl SECTRO_SHFT);
	if ((not ReadFile(m_hDevice, lpBuffer^, dwSize, dwBytes, nil)) or (dwBytes < dwSize)) then exit;

	result := true;
end;

function  TUSB.SectorWrite(lpBuffer: PChar;dwIndex: DWORD; dwCount :DWORD): boolean;
var
    dwSize, dwBytes : DWORD;
begin
    result := false;
    if (m_hDevice = INVALID_HANDLE_VALUE) then exit;

	if (SetFilePointer(m_hDevice, dwIndex shl SECTRO_SHFT, nil, FILE_BEGIN) <> (dwIndex shl SECTRO_SHFT)) then exit;

	dwSize := (dwCount shl SECTRO_SHFT);
	if ((not WriteFile(m_hDevice, lpBuffer^, dwSize, dwBytes, nil)) or (dwBytes < dwSize)) then exit;

	result := true;
end;

function  TUSB.SectorRead_retry(lpBuffer: PChar;dwIndex: DWORD; dwCount :DWORD): boolean;
var
    retry_times : integer;
begin
    result := true;

    retry_times := 1;
    for retry_times := 1 to RETRY_TIMES do begin
        if (SectorRead(lpBuffer, dwIndex, dwCount) = true) then exit;
        sleep(10);
    end;

    result := false;
end;

function  TUSB.SectorWrite_retry(lpBuffer: PChar;dwIndex: DWORD; dwCount :DWORD): boolean;
var
    retry_times : integer;
begin
    result := true;

    retry_times := 1;
    for retry_times := 1 to RETRY_TIMES do begin
        if (SectorWrite(lpBuffer, dwIndex, dwCount) = true) then exit;
        sleep(10);
    end;

    result := false;

end;

function  TUSB.connect: boolean;
var
     i: integer;
     TheadID: DWORD;
begin
    result := false;

    m_hDevice := CreateFile(FileName, GENERIC_READ or GENERIC_WRITE,
				    0, nil, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING,0);
    if (m_hDevice <> INVALID_HANDLE_VALUE) then begin
            USB_Driver := FileName[4];
            USB_valid  := true;
            USB_thread := CreateThread(nil,0,@USB_Watch_Thread,nil,0,TheadID);
            if(USB_thread = 0) then begin
                MessageBox(0,'Can Not Create USB Thread!',nil,mb_OK);
                USB_valid  := false;
                CloseHandle(USB_thread);
                CloseHandle(m_hDevice);
                exit;
            end;
            setupcomm(m_hDevice,10240,4096);
            Fopen := true;
            result := true;
            exit;
    end;
    CloseHandle(m_hDevice);
end;

procedure USB_Watch_Thread(Ptr:Pointer);stdcall; // USB监视插拔线程
var
    i: integer;
    dwLDMap : DWORD;
begin
    while(true) do begin
        dwLDMap := GetLogicalDrives();
        i := 1 shl (integer(USB_Driver) - integer('A'));
        if ((dwLDMap and i) <>0 )  then begin
            USB_valid := true;
            end
        else begin
            if(USB_valid = true) then begin
                MessageBox(0,'USB Line is dropped!',nil,mb_OK);
                USB_valid := false;
                end;
        end;
        sleep(1000);
    end;
end;



end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -