Copy files to an OS shell location?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4747
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Copy files to an OS shell location?

Post by Fangbeast »

Is there any way in PB to be able to copy files to an O/S shell location?

When I plug in my mobile phone and it shows up its internal storage locations, there must be some way to register this in PB for me to be able to use it to copy files to?

Has anyone ever done anything like this?
Amateur Radio, D-STAR/VK3HAF
User avatar
RSBasic
Moderator
Moderator
Posts: 1218
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: Copy files to an OS shell location?

Post by RSBasic »

Fangbeast wrote:I plug in my mobile phone
Do you mean MTP?
This is not possible with PB.
Most MTP-compatible devices are not assigned drive letters; instead, they appear as "devices" in applications such as Windows Explorer. Compared to devices that implement USB mass storage, such devices cannot be accessed programmatically by scripts or normal Windows programs that depend on drive letters.
Image
Image
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4747
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: Copy files to an OS shell location?

Post by Fangbeast »

This is not possible with PB.
There must be some way.
Most MTP-compatible devices are not assigned drive letters; instead, they appear as "devices" in applications such as Windows Explorer. Compared to devices that implement USB mass storage, such devices cannot be accessed programmatically by scripts or normal Windows programs that depend on drive letters.
[/quote]

I understand what the quote is saying but I have a question about that premise. If the device is visible in Windows Explorer and I cut, copy, drag and drop to and from it, what is performing those operations?

Is it Windows Explorer doing it somehow or is the device driver intercepting the actions via a DLL hook of some sort and then performing the actions?

If it is a hook of some sort, it must be possible to hook into it somehow. PB's own ExplorerListGadget and ExplorerTreeGadget are heavily API customised (Ownerdrawn might be the word I am looking for here) as I understand it and anything Windows Explorer can do, PB gadgets might be able to at some stage right?

I live in hope:):)
Amateur Radio, D-STAR/VK3HAF
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: Copy files to an OS shell location?

Post by Dude »

This appears to show a way for Android, but it looks complicated:

https://stackoverflow.com/questions/118 ... mmatically

It has an example of using an "adb" command-line tool to do it:

Code: Select all

C:\Users\Documents>adb push -s HT25ZW127890 test.txt /sdcard/test.txt
So it appears you'd need to install this "adb" tool and use RunProgram() with it.

But I don't know if "adb" is free and/or redistributable, sorry. Check it out, and good luck! :)
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4747
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: Copy files to an OS shell location?

Post by Fangbeast »

It has an example of using an "adb" command-line tool to do it:
Ah yes, I have used adb in the past. You can do some nifty things with it.

Code: Select all

So it appears you'd need to install this "adb" tool and use RunProgram() with it.
That's okay. Every person who owns an android device has access to it (or can)
But I don't know if "adb" is free and/or redistributable, sorry. Check it out, and good luck! :)
Well, that's more than I knew this morning, so thanks. And it will do until something better comes along.

P.s. I think ADB.exe is part of the Android SDK but you can download just the few files needed for those basic jobs. So it is free.
Amateur Radio, D-STAR/VK3HAF
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Copy files to an OS shell location?

Post by infratec »

User avatar
CELTIC88
Enthusiast
Enthusiast
Posts: 154
Joined: Thu Sep 17, 2015 3:39 pm

Re: Copy files to an OS shell location?

Post by CELTIC88 »

for mtp protocol I programmed this code but is not completed...

http://www.purebasic.fr/french/viewtopi ... =1&t=16907

Code: Select all

Interface IPortableDeviceManager Extends IUnknown
  ;'{A1567595-4C2F-4574-A6FA-ECEF917B9A40}'
  
  GetDevices(pPnPDeviceIDs,
             pcPnPDeviceIDs)
  
  RefreshDeviceList()
  
  GetDeviceFriendlyName(pszPnPDeviceID,
                        pDeviceFriendlyName,
                        pcchDeviceFriendlyName)
  
  GetDeviceDescription(pszPnPDeviceID,
                       pDeviceDescription,
                       pcchDeviceDescription)
  
  GetDeviceManufacturer(pszPnPDeviceID,                
                        pDeviceManufacturer,
                        pcchDeviceManufacturer)
  
  GetDeviceProperty(pszPnPDeviceID,
                    pszDevicePropertyName,
                    pData,
                    pcbData,
                    pdwType)
  
  GetPrivateDevices(pPnPDeviceIDs,
                    pcPnPDeviceIDs)
EndInterface

Interface  IPortableDevice Extends IUnknown
  ;{625e2df8-6392-4cf0-9ad1-3cfa5f17775c}
  Open(pszPnPDeviceID,
       pClientInfo)
  
  SendCommand(dwFlags.l,
              pParameters,
              ppResults)
  
  Content(ppContent)
  
  Capabilities(ppCapabilities) 
  
  Cancel()
  
  Close()
  
  Advise(dwFlags.l,
         pCallback,
         pParameters,
         ppszCookie)
  
  Unadvise(pszCookie)
  
  GetPnPDeviceID(ppszPnPDeviceID) 
  
EndInterface

Interface IPortableDeviceValues Extends IUnknown
  ;"6848f6f2-3155-4f86-b6f5-263eeeab3143"
  GetCount(pcelt)
  
  GetAt(index.l,
        pKey,
        pValue)
  
  SetValue(key,
           pValue)
  
  GetValue(key,
           pValue)
  
  SetStringValue(key,
                 LPCWSTRValue)
  
  GetStringValue(key,
                 pLPWSTRValue)
  
  SetUnsignedIntegerValue(key,
                          LongValue.l)
  
  GetUnsignedIntegerValue(key,
                          pLongValue)
  
  SetSignedIntegerValue(key,
                        LongValue.l)
  
  GetSignedIntegerValue(key,
                        pLongValue)
  
  SetUnsignedLargeIntegerValue(key,
                               QuadValue.q)
  
  GetUnsignedLargeIntegerValue(key,
                               pQuadValue)
  
  SetSignedLargeIntegerValue(key,
                             QuadValue.q)
  
  GetSignedLargeIntegerValue(key,
                             pQuadValue)
  
  SetFloatValue(key,
                FLOATValue.f)
  
  GetFloatValue(key,
                pFLOATpValue)
  
  SetErrorValue(key,
                HRESULTLongValue.l)
  
  GetErrorValue(key,
                pHRESULTLongValue)
  
  SetKeyValue(key,
              REFPROPERTYKEYValue)
  
  GetKeyValue(key,
              pPROPERTYKEYValue)
  
  SetBoolValue(key,
               BOOLLongValue)
  
  GetBoolValue(key,
               pBOOLLongValue)
  
  SetIUnknownValue(key,
                   pIUnknownValue)
  
  GetIUnknownValue(key,
                   ppIUnknownValue)
  
  SetGuidValue(key,
               REFGUIDValue)
  
  GetGuidValue(key,
               pGUIDValue)
  
  SetBufferValue(key,
                 pValue,
                 cbValue.l)
  
  GetBufferValue(key,
                 ppValue,
                 pcbValue)
  
  SetIPortableDeviceValuesValue(key,
                                pValue)
  
  GetIPortableDeviceValuesValue(key,
                                ppValue)
  
  SetIPortableDevicePropVariantCollectionValue(key,
                                               pValue)
  
  GetIPortableDevicePropVariantCollectionValue(key,
                                               ppValue)
  
  SetIPortableDeviceKeyCollectionValue(key,
                                       pValue)
  
  GetIPortableDeviceKeyCollectionValue(key,
                                       ppValue)
  
  SetIPortableDeviceValuesCollectionValue(key,
                                          pValue)
  
  GetIPortableDeviceValuesCollectionValue(key,
                                          ppValue)
  
  RemoveValue(key)
  
  CopyValuesFromPropertyStore(pStore)
  
  CopyValuesToPropertyStore(pStore)
  
  Clear()
EndInterface

Interface  IPortableDeviceContent Extends IUnknown
  ;6a96ed84-7c73-4480-9938-bf5af477d426
  EnumObjects(dwFlags.l,
              pszParentObjectID,
              pFilter,
              ppEnum)
  
  Properties(ppProperties)
  
  Transfer(ppResources)
  
  CreateObjectWithPropertiesOnly(pValues,
                                 ppszObjectID)
  
  CreateObjectWithPropertiesAndData(pValues,
                                    ppData,
                                    pdwOptimalWriteBufferSize,
                                    ppszCookie)
  
  Delete(dwOptions.l,
         pObjectIDs,
         ppResults)
  
  GetObjectIDsFromPersistentUniqueIDs(pPersistentUniqueIDs,
                                      ppObjectIDs)
  
  Cancel()
  
  Move(pObjectIDs,
       pszDestinationFolderObjectID,
       ppResults)
  
  Copy(pObjectIDs,
       pszDestinationFolderObjectID,
       ppResults)
  
EndInterface

Interface IEnumPortableDeviceObjectIDs Extends IUnknown
  ;10ece955-cf41-4728-bfa0-41eedf1bbf19
Next(cObjects.l,
     pObjIDs,
     pcFetched)

Skip(cObjects.l)

Reset()

Clone(ppEnum)

Cancel()
EndInterface

Interface IPortableDeviceProperties Extends IUnknown
  ;"7f6d695c-03df-4439-a809-59266beee3a6"
  GetSupportedProperties(pszObjectID,
                         ppKeys)
  
  GetPropertyAttributes(pszObjectID,
                        Key,
                        ppAttributes)
  
  GetValues(pszObjectID,
            pKeys,
            ppValues)
  
  SetValues(pszObjectID,
            pValues,
            ppResults)
  
  Delete(pszObjectID,
         pKeys)
  
  Cancel()
  
EndInterface

Interface IPortableDeviceKeyCollection Extends IUnknown
  ;"dada2357-e0ad-492e-98db-dd61c53ba353"
  GetCount(pcElems)
  
  GetAt(dwIndex.l,
        pKey)
  
  Add(Key)
  
  Clear()
  
  RemoveAt(dwIndex.l)
EndInterface
      
Macro CoInitialize()
  CoInitializeEx_(0, 0)
EndMacro

Macro CoUninitialize()
  CoUninitialize_()
EndMacro

Macro FAILED(hr)
  hr < 0
EndMacro

Macro SUCCEEDED(hr)
  hr = 0
EndMacro

Macro DEFINE_PROPERTYKEY(Nm,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12)
  Nm:
  Data.l   p1
  Data.w   p2,p3
  Data.b   p4,p5,p6,p7,p8,p9,p10,p11,p12
EndMacro

Macro DEFINE_DEVSVCPROPKEY(Nm,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12)
  DEFINE_PROPERTYKEY(Nm,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12)
EndMacro

Macro DEFINE_GUID(IID, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11) 
    IID: 
    Data.l Data1 
    Data.w Data2, Data3 
    Data.b Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11 
EndMacro

Macro CompareGuid(Guid1,Guid2)
  CompareMemory(Guid1,Guid2,SizeOf(Guid)) > 0
EndMacro

Global CLIENT_NAME.s="WPD Sample Application"
Global CLIENT_MAJOR_VER=1
Global CLIENT_MINOR_VER=0
Global CLIENT_REVISION=2

Global WPD_DEVICE_OBJECT_ID.s = "DEVICE" 
Global NUM_OBJECTS_TO_REQUEST=10

Procedure.l EnumerateAllDevices(List ListDevisId.s())
  
  pnpDeviceIDCount.l   
  deviceManager.IPortableDeviceManager
  
  hr = CoCreateInstance_(?CLSID_PortableDeviceManager, 
                         0, 
                         #CLSCTX_INPROC_SERVER, 
                         ?IID_IPortableDeviceManager,@deviceManager);     
  
  If (FAILED(hr))
    Debug "Failed to CoCreateInstance CLSID_PortableDeviceManager"
    ProcedureReturn -1
  EndIf
  
  hr = deviceManager\GetDevices(0, @pnpDeviceIDCount)
  If (FAILED(hr))                       
    Debug  "Failed to get number of devices on the system"
    deviceManager\Release()
    ProcedureReturn -1  
  EndIf
  
  Debug " Windows Portable Device(s) found on the system n=° (" +Str(pnpDeviceIDCount)+ ")"
  
  If pnpDeviceIDCount > 0
    ;     pnpDeviceIDs=AllocateMemory(SizeOf(integer)*pnpDeviceIDCount)
    Dim pnpDeviceIDs.i(pnpDeviceIDCount)  ;
    retrievedDeviceIDCount = pnpDeviceIDCount 
    hr = deviceManager\GetDevices(@pnpDeviceIDs(0), @retrievedDeviceIDCount); 
    If (SUCCEEDED(hr)) 
      S.s{124}
      sl=124
      For index = 0 To retrievedDeviceIDCount -1
        
        AddElement(ListDevisId())
        ListDevisId()=PeekS(pnpDeviceIDs(index))
        
        Debug "ID: " + ListDevisId() 
        deviceManager\GetDeviceFriendlyName(pnpDeviceIDs(index),@s,@sl)
        Debug S
        S="":sl=124
        deviceManager\GetDeviceDescription(pnpDeviceIDs(index),@s,@sl)
        Debug S
        S="":sl=124
        deviceManager\GetDeviceManufacturer(pnpDeviceIDs(index),@s,@sl)
        Debug S
        
        CoTaskMemFree_(pnpDeviceIDs(index))
      Next 
      
    EndIf
  EndIf
  
  deviceManager\Release()
  
  ProcedureReturn pnpDeviceIDCount
EndProcedure 


Procedure GetClientInformation()
  clientInformation.IPortableDeviceValues
  hr = CoCreateInstance_(?CLSID_PortableDeviceValues,
                         0,
                         #CLSCTX_INPROC_SERVER,
                         ?IID_IPortableDeviceValues, @clientInformation);
  
  If (SUCCEEDED(hr))
    hr = clientInformation\SetStringValue(?WPD_CLIENT_NAME, @CLIENT_NAME);
    If (FAILED(hr))
      Debug "! Failed to set WPD_CLIENT_NAME"
      ProcedureReturn -1
    EndIf
    
    hr = clientInformation\SetUnsignedIntegerValue(?WPD_CLIENT_MAJOR_VERSION, CLIENT_MAJOR_VER);
    If (FAILED(hr))
      Debug "! Failed to set WPD_CLIENT_MAJOR_VERSION"
    EndIf
    
    hr = clientInformation\SetUnsignedIntegerValue(?WPD_CLIENT_MINOR_VERSION, CLIENT_MINOR_VER);
    If (FAILED(hr))
      Debug "! Failed to set WPD_CLIENT_MINOR_VERSION"
    EndIf
    
    hr = clientInformation\SetUnsignedIntegerValue(?WPD_CLIENT_REVISION, CLIENT_REVISION);
    If (FAILED(hr))
      Debug "! Failed to set WPD_CLIENT_REVISION"
    EndIf
    
    hr = clientInformation\SetUnsignedIntegerValue(?WPD_CLIENT_SECURITY_QUALITY_OF_SERVICE, SECURITY_IMPERSONATION);
    If (FAILED(hr))
      Debug "! Failed to set WPD_CLIENT_SECURITY_QUALITY_OF_SERVICE"
    EndIf
    
    ProcedureReturn clientInformation
  Else
    Debug "! Failed to CoCreateInstance CLSID_PortableDeviceValues"
  EndIf
EndProcedure

Procedure WrapObject(properties.IPortableDeviceProperties , objectId)
  keys.IPortableDeviceKeyCollection ;
  Debug properties\GetSupportedProperties(objectId, @keys);
  
  values.IPortableDeviceValues ;
  Debug properties\GetValues(objectId, keys, @values);
  
  name.i;    
  Debug Hex(values\GetStringValue(?PKEY_GenericObj_Name, @name))
  
  Debug name
;   CallDebugger
  
  contentType.Guid;
  values\GetGuidValue(?WPD_OBJECT_CONTENT_TYPE, @contentType);
  
  folderType = ?WPD_CONTENT_TYPE_FOLDER
  functionalType = ?WPD_CONTENT_TYPE_FUNCTIONAL_OBJECT
    
  If CompareGuid(contentType,folderType) Or CompareGuid(contentType,functionalType)
    Debug "IS dir"
  Else
    Debug "IS file"
  EndIf
EndProcedure

Procedure RecursiveEnumerate(objectID, content.IPortableDeviceContent)
  properties.IPortableDeviceProperties
  enumObjectIDs.IEnumPortableDeviceObjectIDs
  content\Properties(@properties)

  hr = content\EnumObjects(0,
                           objectID,
                           0,
                           @enumObjectIDs);
  
  If (FAILED(hr))
    Debug "! Failed to get IEnumPortableDeviceObjectIDs from IPortableDeviceContent"
  Else
    
    Repeat
      numFetched.l = 0;
      objectIDi.i
      
      hr = enumObjectIDs\Next(1, 
                              @objectIDi,           
                              @numFetched);        
      If numFetched > 0
        
        Debug PeekS(objectIDi)
;         CallDebugger
          WrapObject(properties , objectIDi)
          
          RecursiveEnumerate(objectIDi, content);
          CoTaskMemFree_(objectIDi)             ;
          
      EndIf
    Until numFetched=0
    
    enumObjectIDs\Release()
  EndIf
EndProcedure

Procedure EnumerateAllContent(device.IPortableDevice)
  content.IPortableDeviceContent
  hr= device\Content(@content)
  If (FAILED(hr))
    Debug "! Failed to get IPortableDeviceContent from IPortableDevice"
  Else
    
    RecursiveEnumerate(@WPD_DEVICE_OBJECT_ID, content)
    content\Release()
    
  EndIf
EndProcedure

Procedure ChooseDevice(nDevis)
  
  clientInformation.IPortableDeviceValues 
  device.IPortableDevice
  
  NewList  ListDevisId.s()
  If EnumerateAllDevices(ListDevisId()) > 0
    ForEach ListDevisId()
      If ListIndex(ListDevisId()) = nDevis
        Break
      EndIf
    Next
    
    clientInformation = GetClientInformation()
    
    If clientInformation
      
      hr = CoCreateInstance_(?CLSID_PortableDeviceFTM,
                             0,
                             #CLSCTX_INPROC_SERVER,
                             ?IID_IPortableDevice,@device)
      If (SUCCEEDED(hr))
        Did.s{124}= ListDevisId()
        hr =  device\Open(@Did,clientInformation)
        ;         #define E_ACCESSDENIED ((HRESULT)0x80070005L)
        
        If hr = $80070005
          clientInformation\SetUnsignedIntegerValue(?WPD_CLIENT_DESIRED_ACCESS, #GENERIC_READ)
          hr =  device\Open(@Did,clientInformation)
        EndIf
        
        clientInformation\Release()
        clientInformation=0
        
        If (FAILED(hr))
          Debug "! Failed to Open the device"
        Else
          ;To be continued ;)
          Debug "- The device successfully opened"
          
          ProcedureReturn device
          
        EndIf
        
        device\Release();
      Else
        Debug "! Failed to CoCreateInstance CLSID_PortableDeviceFTM"
      EndIf
      If clientInformation
        clientInformation\Release()
      EndIf
    Else
      Debug "! Failed to CoCreateInstance CLSID_PortableDeviceValues"
    EndIf
  EndIf
  
EndProcedure

CoInitialize()

device.IPortableDevice=ChooseDevice(0)
If device
  EnumerateAllContent(device)
  
EndIf
CoUninitialize()

DataSection
  CLSID_PortableDeviceManager:
  ;       "{0af10cec-2ecd-4b92-9581-34f6ae0637f3}"
  Data.l $0af10cec
  Data.w $2ecd,$4b92
  Data.b $95,$81,$34,$f6,$ae,$06,$37,$f3
  IID_IPortableDeviceManager:
  ;       "{a1567595-4c2f-4574-a6fa-ecef917b9a40}"
  Data.l $a1567595
  Data.w $4c2f,$4574
  Data.b $a6,$fa,$ec,$ef,$91,$7b,$9a,$40
  
  CLSID_PortableDeviceFTM:
  ;       "{f7c0039a-4762-488a-b4b3-760ef9a1ba9b}"
  Data.l $f7c0039a
  Data.w $4762,$488a
  Data.b $b4,$b3,$76,$0e,$f9,$a1,$ba,$9b
  
  IID_IPortableDevice:
  ;       "{625e2df8-6392-4cf0-9ad1-3cfa5f17775c}"
  Data.l $625e2df8
  Data.w $6392,$4cf0
  Data.b $9a,$d1,$3c,$fa,$5f,$17,$77,$5c
  
  CLSID_PortableDeviceValues:
  ;"0c15d503-d017-47ce-9016-7b3f978721cc"
  Data.l $0c15d503
  Data.w $d017,$47ce
  Data.b $90,$16,$7b,$3f,$97,$87,$21,$cc
  
  IID_IPortableDeviceValues:
  ;"6848f6f2-3155-4f86-b6f5-263eeeab3143"
  Data.l $6848f6f2
  Data.w $3155,$4f86
  Data.b $b6,$f5,$26,$3e,$ee,$ab,$31,$43
  
  ;   IID_IPortableDeviceContent
  ;   ;6a96ed84-7c73-4480-9938-bf5af477d426
  ;   Data.l $6a96ed84
  ;   Data.w $7c73,$4480
  ;   Data.b $99,$38,$bf,$5a,$f4,$77,$d4,$26
  
  DEFINE_PROPERTYKEY( WPD_CLIENT_NAME , $204D9F0C, $2292, $4080, $9F, $42, $40, $66, $4E, $70, $F8, $59 , 2 );
  
  DEFINE_PROPERTYKEY( WPD_CLIENT_MAJOR_VERSION , $204D9F0C, $2292, $4080, $9F, $42, $40, $66, $4E, $70, $F8, $59 , 3 );
  
  DEFINE_PROPERTYKEY( WPD_CLIENT_MINOR_VERSION , $204D9F0C, $2292, $4080, $9F, $42, $40, $66, $4E, $70, $F8, $59 , 4 );
  
  DEFINE_PROPERTYKEY( WPD_CLIENT_REVISION , $204D9F0C, $2292, $4080, $9F, $42, $40, $66, $4E, $70, $F8, $59 , 5 );
  
  DEFINE_PROPERTYKEY( WPD_CLIENT_SECURITY_QUALITY_OF_SERVICE , $204D9F0C, $2292, $4080, $9F, $42, $40, $66, $4E, $70, $F8, $59 , 8 );
  
  DEFINE_PROPERTYKEY( WPD_CLIENT_DESIRED_ACCESS , $204D9F0C, $2292, $4080, $9F, $42, $40, $66, $4E, $70, $F8, $59 , 9 );
  
  DEFINE_PROPERTYKEY( WPD_OBJECT_CONTENT_TYPE , $EF6B490D, $5CD8, $437A, $AF, $FC, $DA, $8B, $60, $EE, $4A, $3C , 7 );

  DEFINE_DEVSVCPROPKEY(PKEY_GenericObj_Name,$EF6B490D, $5CD8, $437A, $AF, $FC, $DA, $8B, $60, $EE, $4A, $3C, 4); 
  
  DEFINE_GUID(WPD_CONTENT_TYPE_FOLDER, $27E2E392, $A111, $48E0, $AB, $0C, $E1, $77, $05, $A0, $5F, $85 );
  
  DEFINE_GUID(WPD_CONTENT_TYPE_FUNCTIONAL_OBJECT, $99ED0160, $17FF, $4C44, $9D, $98, $1D, $7A, $6F, $94, $19, $21 )
  
EndDataSection
interested in Cybersecurity..
Post Reply