Page 1 of 1

Detect Pen Drive

Posted: Fri Nov 16, 2018 11:46 am
by PedroAlex
Hello,

xBase 2.0
it is possible to detect if a pen drive is connected and its letter?

Many Thanks,

Re: Detect Pen Drive

Posted: Fri Nov 16, 2018 2:03 pm
by Auge_Ohr
PedroAlex wrote:it is possible to detect if a pen drive is connected and its letter?
hi,

if Pen Drive = USB-Stick -> YES
but it is Windows API so not "build-in"

a USB-Stick is a removeable Media (nType = 2)

Code: Select all

   nType := DriveType( cDrive ) 
   DO CASE
      CASE nType = 0                                        // DRIVE_UNKNOWN
      CASE nType = 1                                        // DRIVE_NO_ROOT_DIR
      CASE nType = 2                                        // DRIVE_REMOVABLE - Floppy
         nAccess := BOr( GENERIC_READ, GENERIC_WRITE )
      CASE nType = 3                                        // DRIVE_FIXED
      CASE nType = 4                                        // DRIVE_REMOTE
      CASE nType = 5                                        // DRIVE_CDROM
         IF UseCDdrives = .T.
            nAccess := GENERIC_READ
         ENDIF
      CASE nType = 6                                        // DRIVE_RAMDISK
      OTHERWISE
         MSGBOX( "can not use Type " + STR( nType ) )
   ENDCASE

* ------------------------- *

FUNCTION DriveType( cDrive )
LOCAL nDriveType, cRoot := cDrive +":\"+ chr(0)
LOCAL nDll := DllLoad("Kernel32.dll")
if nDll != 0
   nDriveType := DllCall(nDll,DLL_STDCALL,"GetDriveTypeA",@cRoot)
   DllUnload( nDll )
endif
RETURN nDriveType

Re: Detect Pen Drive

Posted: Sat Nov 17, 2018 4:31 am
by PedroAlex
Jimmy,
Many thanks for the help
I'll test this code

Re: Detect Pen Drive

Posted: Sat Nov 17, 2018 11:26 am
by PedroAlex
Jimmy,
I am trying to detect the letter of a Pen Drive just plugged into the USB port.
but this is not going well.
The "GetLogicalDriveStringsW" function does not work as expected.
I'm probably passing the parameters wrong.
I'm not in the right truck?

Code: Select all

Procedure Teste_Deteta_PenDrive()
Local nType, nAccess, cDrives := GetDrives()

For x:=1 To Len( cDrives )

	nType := DriveType( SubStr(cDrives,x,1) )

	DO CASE
    	CASE nType = 0                                        // DRIVE_UNKNOWN
    	CASE nType = 1                                        // DRIVE_NO_ROOT_DIR
    	CASE nType = 2                                        // DRIVE_REMOVABLE - Floppy
        	nAccess := BOr( GENERIC_READ, GENERIC_WRITE )
			MsgBox('Floppy')

    	CASE nType = 3                                        // DRIVE_FIXED
    	CASE nType = 4                                        // DRIVE_REMOTE
    	CASE nType = 5                                        // DRIVE_CDROM
        	IF UseCDdrives = .T.
        		nAccess := GENERIC_READ
        	ENDIF
    	CASE nType = 6                                        // DRIVE_RAMDISK
    	OTHERWISE
        	MSGBOX( "can not use Type " + STR( nType ) )
	ENDCASE



Next

Return

* ------------------------- *

FUNCTION DriveType( cDrive )
LOCAL nDriveType, cRoot := cDrive +":\"+ chr(0)
LOCAL nDll := DllLoad("Kernel32.dll")
if nDll != 0
   nDriveType := DllCall(nDll,DLL_STDCALL,"GetDriveTypeA",cRoot)
   DllUnload( nDll )
endif
RETURN nDriveType

* ------------------------- *

FUNCTION GetDrives()
LOCAL nDll := DllLoad("Kernel32.dll"), cDrives, MyDrives:=10, nBuffer[10]
if nDll != 0
   cDrives := DllCall(nDll,DLL_STDCALL,"GetLogicalDriveStringsW",MyDrives, @nBuffer )
   DllUnload( nDll )
endif
RETURN cDrives

Re: Detect Pen Drive

Posted: Sat Nov 17, 2018 11:56 am
by Auge_Ohr
PedroAlex wrote: I am trying to detect the letter of a Pen Drive just plugged into the USB port.
but this is not going well.
it does not detect when you plugin some Device ...

you need to get WM_DEVICECHANGE Message and look for DBT_DEVICEARRIVAL / DBT_DEVICEREMOVECOMPLETE.

PedroAlex wrote: The "GetLogicalDriveStringsW" function does not work as expected.
I'm probably passing the parameters wrong.
I'm not in the right truck?
a API Function with "W" on End are Unicode.
try this to get Drives

Code: Select all

FUNCTION AvailDrives( lFloppy )
LOCAL cDrive  := UPPER( CurDrive() )
LOCAL aDrives := { cDrive }
LOCAL cCurdir := CURDIR()
LOCAL bError  := ERRORBLOCK( { | oErr | DriveError( oErr, aDrives ) } )
LOCAL i, nStart

   DEFAULT lFloppy TO .F.
   IF lFloppy
      nStart := 1
   ELSE
      nStart := 3                                           // without Floppy A: / B:
   ENDIF

   FOR i := nStart TO 26
      BEGIN SEQUENCE
         Curdrive( CHR( 64 + i ) )
         CURDIR()
         IF ASCAN( aDrives, UPPER( CurDrive() ) ) == 0
            AADD( aDrives, UPPER( Curdrive() ) )
         ENDIF
      ENDSEQUENCE
   NEXT

   CurDrive( cDrive )
   CURDIR( cdrive + ":\" + cCurdir )
   ERRORBLOCK( bError )
RETURN ASORT( aDrives )

Re: Detect Pen Drive

Posted: Sun Nov 18, 2018 5:56 pm
by Auge_Ohr

Re: Detect Pen Drive

Posted: Tue Nov 20, 2018 9:27 am
by PedroAlex
Hi Jimmy

this code works fine for me.
this way I can detect Pendrives ( removable drives ) conected.

Code: Select all

FUNCTION AvailPenDrives( lFloppy )
LOCAL aDrives := {}
LOCAL i, nStart

DEFAULT lFloppy TO .F.
IF lFloppy
	nStart := 1
ELSE
	nStart := 3                                           // without Floppy A: / B:
ENDIF

FOR i := nStart TO 26
	BEGIN SEQUENCE
	IF IsDriveReady( CHR( 64 + i ) ) == 0                  // Is drive ready ?
		IF DriveType( CHR( 64 + i ) ) == 2                 // DRIVE_REMOVABLE - Floppy, PenDrive
    		IF ASCAN( aDrives, UPPER( CHR( 64 + i ) ) ) == 0
    			AADD( aDrives, UPPER( CHR( 64 + i ) ) )
    		ENDIF
		ENDIF
	ENDIF
	ENDSEQUENCE
NEXT

Dc_ArrayView( ASORT( aDrives ) )
RETURN ASORT( aDrives )

* ------------------------- *

FUNCTION IsDriveReady( cDrive )                   // Is drive ready ?
LOCAL nReturn   := 0
LOCAL cOldDrive := CurDrive()                     // save current drive
LOCAL bError    := ErrorBlock( {|e| Break(e) } )
LOCAL oError

BEGIN SEQUENCE

    CurDrive( cDrive )                            // change drive
    CurDir( cDrive )                              // read current directory

RECOVER USING oError                              // error has occurred

    IF oError:osCode == DRIVE_NOT_READY
       nReturn := -1                              // drive not ready
    ELSE
       nReturn := -2                              // drive not available
    ENDIF                                         // or invalid

ENDSEQUENCE

ErrorBlock( bError )                              // reset error code block
CurDrive( cOldDrive )                             // and drive

RETURN nReturn

* ------------------------- *

FUNCTION DriveType( cDrive )
LOCAL nDriveType, cRoot := cDrive +":\"+ chr(0)
LOCAL nDll := DllLoad("Kernel32.dll")
if nDll != 0
   nDriveType := DllCall(nDll,DLL_STDCALL,"GetDriveTypeA",cRoot)
   DllUnload( nDll )
endif
RETURN nDriveType


Thanks for your help