IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

[USB] Ejection d'un disque [FAQ]


Sujet :

API, COM et SDKs Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 593
    Billets dans le blog
    65
    Par défaut [USB] Ejection d'un disque
    Avant de réinventer la roue, et apres avoir chercher dans FAQ et FORUMS
    quelqu'un a t'il réussi de façon fiable (WINDOWS version Diverses) à éjecter un disque USB sans qu'il y-ait opération d'un utilisateur ?

    Shell Command s'abstenir

    Merci pour toute piste , avant de m'y atteler sérieusement


  2. #2
    Membre éprouvé Avatar de defluc
    Homme Profil pro
    Architecte
    Inscrit en
    Mai 2002
    Messages
    1 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 383
    Par défaut
    Salut

    Je n'ai pas de lecteur USB, mais pour un lecteur interne, ce qui suit fonctionne.

    Pour ouvrir le lecteur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mciSendString('Set cdaudio door open wait', nil, 0, handle);
    Pour fermer le lecteur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mciSendString('Set cdaudio door closed wait', nil, 0, handle);
    NB : Ne pas oublier d'ajouter MMSystem dans la clause Use

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 593
    Billets dans le blog
    65
    Par défaut suite de mes cogitations
    j'ai décidé de m'y attelé

    pour éjecter un CD pas de problème par contre pour un disque USB

    en cherchant à droite et à gauche forums VB,C etc ... tous les codes que je trouve font en gros la même chose , et ceux que j'ai transposé aussi
    le lecteur USB est peut-être déconnecté mais WIN XP (ma machine de test)
    le connait toujours si je clique sur l'icone de retrait du périhérique donc

    toutefois pour faire bonne mesure voici une partie de mon code
    constantes trouvé dans l'excellente Win32 API de JEDI
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
     
    TYPE
      PPREVENT_MEDIA_REMOVAL = ^PREVENT_MEDIA_REMOVAL;
      PREVENT_MEDIA_REMOVAL = RECORD
        PreventMediaRemoval: WordBool;
      END;
     
    CONST
    FILE_DEVICE_FILE_SYSTEM = $00000009;
    FILE_ANY_ACCESS = 0;
    FILE_SPECIAL_ACCESS = FILE_ANY_ACCESS;
    FILE_READ_ACCESS    = $0001;           // file & pipe
    FILE_WRITE_ACCESS   = $0002;           // file & pipe
     
    METHOD_BUFFERED = 0;
     
    FILE_DEVICE_DISK                = $00000007;
    FILE_DEVICE_MASS_STORAGE        = $0000002d;
     
    IOCTL_STORAGE_BASE = FILE_DEVICE_MASS_STORAGE;
    FSCTL_LOCK_VOLUME = ((FILE_DEVICE_FILE_SYSTEM shl 16) or (FILE_ANY_ACCESS shl 14) or (6 shl 2) or METHOD_BUFFERED);
    FSCTL_UNLOCK_VOLUME =((FILE_DEVICE_FILE_SYSTEM shl 16) or (FILE_ANY_ACCESS shl 14) or (7 shl 2) or METHOD_BUFFERED);
    FSCTL_DISMOUNT_VOLUME =((FILE_DEVICE_FILE_SYSTEM shl 16) or (FILE_ANY_ACCESS shl 14) or (8 shl 2) or METHOD_BUFFERED);
    IOCTL_STORAGE_MEDIA_REMOVAL = ((IOCTL_STORAGE_BASE shl 16) or (FILE_READ_ACCESS shl 14) or ($0201 shl 2) or METHOD_BUFFERED);
    IOCTL_STORAGE_EJECT_MEDIA = ((IOCTL_STORAGE_BASE shl 16) or (FILE_READ_ACCESS shl 14) or ($0202 shl 2) or METHOD_BUFFERED);
    IOCTL_DISK_BASE = FILE_DEVICE_DISK;
    IOCTL_DISK_EJECT_MEDIA = (
        (IOCTL_DISK_BASE shl 16) or (FILE_READ_ACCESS shl 14) or
        ($0202 shl 2) or METHOD_BUFFERED);
    IOCTL_DISK_MEDIA_REMOVAL = (
        (IOCTL_DISK_BASE shl 16) or (FILE_READ_ACCESS shl 14) or
        ($0201 shl 2) or METHOD_BUFFERED);
    Partie de Code Test (Lecteur = 'G:');
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    R:=GetDriveType(lecteur);
    Case R of
      DRIVE_UNKNOWN : ShowMessage('Inconnu');
      DRIVE_NO_ROOT_DIR : ShowMessage('Inconnu');
      DRIVE_REMOVABLE :begin
     
                        {C'est ici que ça se passe}
     
                       H:=CreateFile('\\.\'+Lecteur,GENERIC_READ,FILE_SHARE_READ OR FILE_SHARE_WRITE,
                                      nil,OPEN_EXISTING,0,0);
                       if H= INVALID_HANDLE_VALUE then ShowMessage('Erreur Handle')
                       else begin
                          DeviceIoControl(H,FSCTL_LOCK_VOLUME,nil,0,nil,0,cb,nil);
    DeviceIoControl(H,FSCTL_DISMOUNT_VOLUME,nil,0,nil,0,cb,nil);
    MRBuffer.PreventMediaRemoval := False; //<- a ne pas oublier :oops: 
    PMRBuffer:=@MRBuffer;                   
    DeviceIoControl(H,IOCTL_DISK_MEDIA_REMOVAL,nil,0,nil,0,cb,nil);
     
                          DeviceIoControl(H,IOCTL_DISK_EJECT_MEDIA , nil, 0,nil,0, cb, nil);
                          CloseHandle(H);
                       end;
                       end;
      DRIVE_FIXED : ShowMessage('Fixe');
      DRIVE_REMOTE : ShowMessage('Réseau');
      DRIVE_CDROM : begin
                       H:=CreateFile('\\.\'+Lecteur,GENERIC_READ,FILE_SHARE_READ OR FILE_SHARE_WRITE,
                                      nil,OPEN_EXISTING,0,0);
                       if H= INVALID_HANDLE_VALUE then ShowMessage('Erreur Handle')
                       else begin
                          DeviceIoControl(H,FSCTL_LOCK_VOLUME,nil,0,nil,0,cb,nil);
                          DeviceIoControl(H,FSCTL_DISMOUNT_VOLUME,nil,0,nil,0,cb,nil);
                          DeviceIoControl(H,IOCTL_STORAGE_EJECT_MEDIA , nil, 0,nil,0, cb, nil);
                          CloseHandle(H);
                       end;
                    end;
      DRIVE_RAMDISK : ShowMessage('RAM');
    else showmessage('Erreur : ');
    end;

    si quelqu'un à une idée je suis preneur

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 593
    Billets dans le blog
    65
    Par défaut je savais bien qu'il ne fallait pas réinventer la roue
    Eureka !! j'étais parti sur une 'mauvaise piste'

    en fouillant bien dans "l'excellente Win32 API de JEDI" (je me répete ? )
    tout y était . En fait c'est dans la partie Setup&ConfigManager qu'il fallait chercher.

    je ne sais pas si j'aurais le temps de faire un tri dans tout ça pour faire un code
    suffisamment concis et ne nécessitant pas tous les sources de JEDI

    toutefois si d'autres personnes veulent obtenir le résultat je me ferais un plaisir
    de laisser le code de mon test

    et bon devpt

  5. #5
    Rédacteur
    Avatar de evarisnea
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Juin 2005
    Messages
    1 957
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 957
    Par défaut


    Citation Envoyé par SergioMaster
    toutefois si d'autres personnes veulent obtenir le résultat je me ferais un plaisir
    de laisser le code de mon test
    moi je suis preneur
    et si en plus tu écrivais un joli tuto là dessus ce serait nickel !

  6. #6
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 593
    Billets dans le blog
    65
    Par défaut
    Citation Envoyé par evarisnea
    si en plus tu écrivais un joli tuto là dessus ce serait nickel !
    Ouais, bon je suis pas très écrivain pour l'instant .

    le code est certainement à toiletter !!! et là pour l'instant je n'ai pas vraiment le temps . Il vient de me tomber 3 demandes sérieuses et urgentes (pour hier)

    voilà pour l'instant mes cogitations tests (clé en 'H:')


    la form ne contient qu' un bouton

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    unit EjectUSBOk;
     
    interface
     
    uses Windows, Classes, Graphics, Forms, Controls, StdCtrls;
     
    type
      TMainForm = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      MainForm: TMainForm;
     
    implementation
     
    uses   Cfg, CfgMgr32, SetupApi, JwaWinBase;
     
    {$R *.dfm}
     
    procedure TMainForm.Button1Click(Sender: TObject);
    var
      VetoType: PNP_VETO_TYPE;
      DriveName,DriveInstance : String;
      inst : DEVINST;
      function GetVolumeNameForVolumeMountPointString(Name: string): string;
      var
        Volume: array [0..MAX_PATH] of Char;
      begin
        FillChar(Volume[0], SizeOf(Volume), 0);
        GetVolumeNameForVolumeMountPoint(PChar(Name), @Volume[0], SizeOf(Volume));
      Result := Volume;
      end;
      function GetDeviceID(Inst: DEVINST): string;
      var
        Buffer: PChar;
        Size: ULONG;
      begin
        CM_Get_Device_ID_Size(Size, Inst, 0);
      // Required! See DDK help for CM_Get_Device_ID
        Inc(Size);
        Buffer := AllocMem(Size * SizeOf(WCHAR));
        CM_Get_Device_ID(Inst, Buffer, Size, 0);
        Result := Buffer;
        FreeMem(Buffer);
      end;
      function GetDriveInstanceID(MountPointName: string; var DeviceInst: DEVINST): Boolean;
      const
        GUID_DEVINTERFACE_VOLUME: TGUID = '{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}';
      var
        StorageGUID: TGUID;
        PnPHandle: HDEVINFO;
        DevData: TSPDevInfoData;
        DeviceInterfaceData: TSPDeviceInterfaceData;
        FunctionClassDeviceData: PSPDeviceInterfaceDetailData;
        Success: LongBool;
        Devn: Integer;
        BytesReturned: DWORD;
        Inst: DEVINST;
        S, FileName, MountName, DevID: string;
      begin
        Result := False;
        DeviceInst := 0;
       // enumerate all volumes
       StorageGUID := GUID_DEVINTERFACE_VOLUME;
       PnPHandle := SetupDiGetClassDevs(@StorageGUID, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
       if PnPHandle = Pointer(INVALID_HANDLE_VALUE) then
         Exit;
       Devn := 0;
       repeat
        DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData);
        Success := SetupDiEnumDeviceInterfaces(PnPHandle, nil, StorageGUID, Devn, DeviceInterfaceData);
        if Success then
        begin
          DevData.cbSize := SizeOf(DevData);
          BytesReturned := 0;
          SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, nil, 0, BytesReturned, @DevData);
          if (BytesReturned <> 0) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
          begin
            FunctionClassDeviceData := AllocMem(BytesReturned);
            try
              FunctionClassDeviceData.cbSize := SizeOf(TSPDeviceInterfaceDetailData);
              if SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData,
                FunctionClassDeviceData, BytesReturned, BytesReturned, @DevData) then
              begin
                FileName := PChar(@FunctionClassDeviceData.DevicePath[0]);
                // get the grandparent DevNode which is the "bus" device
                // like "USB". This is the DevNode for CM_Request_Device_Eject and
                // several other useful operations
                Inst := DevData.DevInst;
                CM_Get_Parent(Inst, Inst, 0);
                CM_Get_Parent(Inst, Inst, 0);
                DevID := GetDeviceID(Inst);
     
                // no need in this example to check for USB only
                // if ExtractBus(DevID) = 'USB' then
                begin
                  S := '\';
                  S := Pchar(@FunctionClassDeviceData.DevicePath) + S;
                  MountName := GetVolumeNameForVolumeMountPointString(S);
                  if MountName = MountPointName then
                  begin
                    DeviceInst := Inst;
                    Result := True;
                    Exit;
                  end;
                end;
              end;
            finally
              FreeMem(FunctionClassDeviceData);
            end;
          end;
        end;
        Inc(Devn);
        until not Success;
        SetupDiDestroyDeviceInfoList(PnPHandle);
      end;
    begin
    DriveName:='H:\';
    if GetDriveType(Pchar(DriveName)) = DRIVE_REMOVABLE then
     begin
      DriveInstance:=GetVolumeNameForVolumeMountPointString(DriveName);
      GetDriveInstanceID(DriveInstance, Inst);
      VetoType := 0;
      CM_Request_Device_Eject(inst,@VetoType, nil, 0, 0);
     end;
    end;
     
    procedure TMainForm.FormCreate(Sender: TObject);
    begin
    LoadSetupApi;
    LoadConfigManagerApi;
    end;
     
    procedure TMainForm.FormDestroy(Sender: TObject);
    begin
    UnloadConfigManagerApi;
    UnloadSetupApi;
    end;
     
    end.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 01/09/2009, 16h31
  2. Ejecter disque dur usb
    Par maloups dans le forum Composants
    Réponses: 4
    Dernier message: 27/08/2007, 13h52
  3. Réponses: 2
    Dernier message: 29/03/2007, 15h45
  4. Quel est le nom des dIsques dur usb dans /dev
    Par MrEddy dans le forum Administration système
    Réponses: 5
    Dernier message: 19/10/2004, 21h06
  5. Monter un disque dur USB
    Par Iced Earth dans le forum Matériel
    Réponses: 5
    Dernier message: 13/01/2003, 22h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo