Sync files with phone via MTP(?)

Just starting out? Need help? Post your questions and find answers here.
AZJIO
Addict
Addict
Posts: 2175
Joined: Sun May 14, 2017 1:48 am

Sync files with phone via MTP(?)

Post by AZJIO »

I had an old direct USB phone and used my file sync software. There was no need to copy all the files, but only the changed ones, it was fast. When buying a new phone, which had advantages in Internet speed and page display, I had to give up synchronization and other minor little things. Now I again have a desire to understand, since the explorer sees the size and date of the file, but the request for this data is much slower. This is not critical, since overwriting all files will take more time than reading this data. But the problem is how do I make a request for files if the device does not have a drive letter. Do I need to use WinAPI and \\.\PhysicalDrive1?

I tried FreeFileSync, it performed synchronization without any problems in the form in which I needed, that is, comparison only by file size, type "mirror", that is, it repeats what is on the computer and outputs logs quite well about what has been done.
User avatar
jacdelad
Addict
Addict
Posts: 2003
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Sync files with phone via MTP(?)

Post by jacdelad »

RSBasic created an MTP module long ago, maybe this helps: http://forums.purebasic.com/german/view ... hp?t=31465
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Sync files with phone via MTP(?)

Post by Kwai chang caine »

Thanks at you two for the subject and the link 8)
That works fine here with my old phone NOTE2
I don't know this MDP protocol and it's possible to communicate with Phone without ADB :shock:

But, i have not understand something, the DLL are compiled with the Github source code "Bassman2/MediaDevices" or i can found the last version already compiled elsewhere ?
ImageThe happiness is a road...
Not a destination
AZJIO
Addict
Addict
Posts: 2175
Joined: Sun May 14, 2017 1:48 am

Re: Sync files with phone via MTP(?)

Post by AZJIO »

there the sources are written in C, but compiled as a dll so that there is access in any programming language. thanks for the finished module, I wanted to answer later so that I could have a recursive example of searching for files and make my own help file. I had to save the code in utf8, then it worked, because there was a problem of the Russian language in the name of the root folder.
AZJIO
Addict
Addict
Posts: 2175
Joined: Sun May 14, 2017 1:48 am

Re: Sync files with phone via MTP(?)

Post by AZJIO »

Recursive file search

Code: Select all

;1.0.3.0

EnableExplicit

Global PBEx_MTP

#PBEx_MTP_Type_File = 1
#PBEx_MTP_Type_Directory = 2
#PBEx_MTP_DeviceType_Generic = 0
#PBEx_MTP_DeviceType_Camera = 1
#PBEx_MTP_DeviceType_MediaPlayer = 2
#PBEx_MTP_DeviceType_Phone = 3
#PBEx_MTP_DeviceType_Video = 4
#PBEx_MTP_DeviceType_PersonalInformationManager = 5
#PBEx_MTP_DeviceType_AudioRecorder = 6

CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
	PBEx_MTP = OpenLibrary(#PB_Any, "PB.Ex_MTP_x86.dll")
CompilerElseIf #PB_Compiler_Processor = #PB_Processor_x64
	PBEx_MTP = OpenLibrary(#PB_Any, "PB.Ex_MTP_x64.dll")
CompilerEndIf

If PBEx_MTP
	Prototype ExamineMTP(ErrorOutput)
	Global ExamineMTP.ExamineMTP = GetFunction(PBEx_MTP, "ExamineMTP")
	Prototype NextMTPEntry(ErrorOutput)
	Global NextMTPEntry.NextMTPEntry = GetFunction(PBEx_MTP, "NextMTPEntry")
	Prototype FinishMTP(ErrorOutput)
	Global FinishMTP.FinishMTP = GetFunction(PBEx_MTP, "FinishMTP")
	Prototype MTPEntryName(Output, ErrorOutput)
	Global MTPEntryName.MTPEntryName = GetFunction(PBEx_MTP, "MTPEntryName")
	Prototype OpenMTP(ID, DeviceName.p-Unicode, ErrorOutput)
	Global OpenMTP.OpenMTP = GetFunction(PBEx_MTP, "OpenMTP")
	Prototype CloseMTP(ID, ErrorOutput)
	Global CloseMTP.CloseMTP = GetFunction(PBEx_MTP, "CloseMTP")
	Prototype IsMTP(ID, ErrorOutput)
	Global IsMTP.IsMTP = GetFunction(PBEx_MTP, "IsMTP")
	Prototype ExamineMTPDirectory(ID, ErrorOutput)
	Global ExamineMTPDirectory.ExamineMTPDirectory = GetFunction(PBEx_MTP, "ExamineMTPDirectory")
	Prototype FinishMTPDirectory(ID, ErrorOutput)
	Global FinishMTPDirectory.FinishMTPDirectory = GetFunction(PBEx_MTP, "FinishMTPDirectory")
	Prototype NextMTPDirectoryEntry(ID, ErrorOutput)
	Global NextMTPDirectoryEntry.NextMTPDirectoryEntry = GetFunction(PBEx_MTP, "NextMTPDirectoryEntry")
	Prototype MTPDirectoryEntryName(ID, Output, ErrorOutput)
	Global MTPDirectoryEntryName.MTPDirectoryEntryName = GetFunction(PBEx_MTP, "MTPDirectoryEntryName")
	Prototype SetMTPDirectory(ID, DirectoryPath.p-Unicode, ErrorOutput)
	Global SetMTPDirectory.SetMTPDirectory = GetFunction(PBEx_MTP, "SetMTPDirectory")
	Prototype GetMTPDirectory(ID, Output, ErrorOutput)
	Global GetMTPDirectory.GetMTPDirectory = GetFunction(PBEx_MTP, "GetMTPDirectory")
	Prototype MTPDirectoryEntryType(ID, ErrorOutput)
	Global MTPDirectoryEntryType.MTPDirectoryEntryType = GetFunction(PBEx_MTP, "MTPDirectoryEntryType")
	Prototype ReceiveMTPFile(ID, RemoteFileName.p-Unicode, FileName.p-Unicode, ErrorOutput)
	Global ReceiveMTPFile.ReceiveMTPFile = GetFunction(PBEx_MTP, "ReceiveMTPFile")
	Prototype MTPDirectoryEntrySize(ID, ErrorOutput)
	Global MTPDirectoryEntrySize.MTPDirectoryEntrySize = GetFunction(PBEx_MTP, "MTPDirectoryEntrySize")
	Prototype MTPDirectoryEntryDate(ID, ErrorOutput)
	Global MTPDirectoryEntryDate.MTPDirectoryEntryDate = GetFunction(PBEx_MTP, "MTPDirectoryEntryDate")
	Prototype GetMTPDescription(ID, Output, ErrorOutput)
	Global GetMTPDescription.GetMTPDescription = GetFunction(PBEx_MTP, "GetMTPDescription")
	Prototype GetMTPDeviceID(ID, Output, ErrorOutput)
	Global GetMTPDeviceID.GetMTPDeviceID = GetFunction(PBEx_MTP, "GetMTPDeviceID")
	Prototype GetMTPDeviceType(ID, ErrorOutput)
	Global GetMTPDeviceType.GetMTPDeviceType = GetFunction(PBEx_MTP, "GetMTPDeviceType")
	Prototype GetMTPFirmwareVersion(ID, Output, ErrorOutput)
	Global GetMTPFirmwareVersion.GetMTPFirmwareVersion = GetFunction(PBEx_MTP, "GetMTPFirmwareVersion")
	Prototype GetMTPFriendlyName(ID, Output, ErrorOutput)
	Global GetMTPFriendlyName.GetMTPFriendlyName = GetFunction(PBEx_MTP, "GetMTPFriendlyName")
	Prototype GetMTPManufacturer(ID, Output, ErrorOutput)
	Global GetMTPManufacturer.GetMTPManufacturer = GetFunction(PBEx_MTP, "GetMTPManufacturer")
	Prototype GetMTPModel(ID, Output, ErrorOutput)
	Global GetMTPModel.GetMTPModel = GetFunction(PBEx_MTP, "GetMTPModel")
	Prototype GetMTPPnPDeviceID(ID, Output, ErrorOutput)
	Global GetMTPPnPDeviceID.GetMTPPnPDeviceID = GetFunction(PBEx_MTP, "GetMTPPnPDeviceID")
	Prototype GetMTPSerialNumber(ID, Output, ErrorOutput)
	Global GetMTPSerialNumber.GetMTPSerialNumber = GetFunction(PBEx_MTP, "GetMTPSerialNumber")
	
EndIf

Global Output$ = Space(1024)
Global ErrorOutput$ = Space(128)
Global DeviceName$

;List all devices to determine the device name.
If ExamineMTP(@ErrorOutput$)
  While NextMTPEntry(@ErrorOutput$)
    MTPEntryName(@Output$, @ErrorOutput$)
    DeviceName$ = Output$
  Wend
EndIf

; 	
; 	;Get device information
; 	GetMTPFriendlyName(1, @Output$, @ErrorOutput$)
; 	Debug "Friendly name: " + Output$
; 	GetMTPManufacturer(1, @Output$, @ErrorOutput$)
; 	Debug "Manufacturer: " + Output$
; 	GetMTPFirmwareVersion(1, @Output$, @ErrorOutput$)
; 	Debug "Firmware version: " + Output$
; 	GetMTPPnPDeviceID(1, @Output$, @ErrorOutput$)
; 	Debug "PnPDeviceID: " + Output$
; 	


; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Procedure FileSearch(id, List Files.s(), dir.s)
	Protected NewList CurDir.s()
	SetMTPDirectory(id, dir, @ErrorOutput$)
	
	If ExamineMTPDirectory(id, @ErrorOutput$)
		While NextMTPDirectoryEntry(id, @ErrorOutput$)
			MTPDirectoryEntryName(id, @Output$, @ErrorOutput$)
			If MTPDirectoryEntryType(id, @ErrorOutput$) = #PBEx_MTP_Type_Directory And AddElement(CurDir())
				CurDir() = dir + "\" + Output$
			ElseIf MTPDirectoryEntryType(id, @ErrorOutput$) = #PBEx_MTP_Type_File And AddElement(Files())
				Files() = dir + "\" + Output$
			EndIf
		Wend
	EndIf
	
	ForEach CurDir()
		FileSearch(id, Files(), CurDir())
	Next
EndProcedure

Define NewList Files.s()
Define id = 1
If Asc(DeviceName$) And OpenMTP(id, DeviceName$, @ErrorOutput$)
	FileSearch(id, Files(), "\Internal Storage\Movies")
	CloseMTP(id, @ErrorOutput$)
Else
	Debug ErrorOutput$
EndIf

ForEach Files()
	Debug Files()
Next

CloseLibrary(PBEx_MTP)
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Sync files with phone via MTP(?)

Post by Kwai chang caine »

AZJIO wrote:there the sources are written in C, but compiled as a dll so that there is access in any programming language.
Thanks for your explanation 8)

Your recursive research works perfect here :wink:
Thanks a lot AZJIO for your sharing and this very nice and useful subject 8)
ImageThe happiness is a road...
Not a destination
AZJIO
Addict
Addict
Posts: 2175
Joined: Sun May 14, 2017 1:48 am

Re: Sync files with phone via MTP(?)

Post by AZJIO »

Phone-MTP
While testing the examples, I ran into 3 problems:
1. File date always returns 0
2. GetMTPFriendlyName() returns an empty string.
3. The author added 3 functions (CreateMTPDirectory, DeleteMTPDirectory, DeleteMTPFile), which are not in the example.
4. Some GetMTPDeviceID-GetMTPPnPDeviceID, MTPEntryName-GetMTPDescription-GetMTPModel functions return the same values. But perhaps it depends on the device, on what values ​​the manufacturer has entered there.

Code: Select all

  Prototype CreateMTPDirectory(ID, CreateFolder.p-Unicode, ErrorOutput)
  Global CreateMTPDirectory.CreateMTPDirectory = GetFunction(PBEx_MTP, "CreateMTPDirectory")
  Prototype DeleteMTPDirectory(ID, DeleteFolder.p-Unicode, ErrorOutput)
  Global DeleteMTPDirectory.DeleteMTPDirectory = GetFunction(PBEx_MTP, "DeleteMTPDirectory")
  Prototype DeleteMTPFile(ID, DeleteFile.p-Unicode, ErrorOutput)
  Global DeleteMTPFile.DeleteMTPFile = GetFunction(PBEx_MTP, "DeleteMTPFile")
  
  
	CreateMTPDirectory(1, "\Internal Storage\Movies\New", @ErrorOutput$)
	DeleteMTPDirectory(1, "\Internal Storage\Movies\New", @ErrorOutput$)
	DeleteMTPFile(1, "\Internal Storage\Movies\New.txt", @ErrorOutput$)
  
Post Reply