Link to home
Start Free TrialLog in
Avatar of Clyde24
Clyde24

asked on

Using MTP (Media Transfer Protocol) with Delphi

Hi,

There seems to be very little documentation about how to use MTP (Media Transfer Protocol) with Delphi.

I need to be able to talk to a WPD (Windows portable device) which can only be accessed via MTP. In theory this should be possible using the Microsoft Windows Portable device api.

In need to be able to:

1. Indentify the device
2. Read files from the device
3. Write files to the device
4. Remove files from the device

Code snippets to do each is what I need

Thanks.
Avatar of Sinisa Vuk
Sinisa Vuk
Flag of Croatia image

I made small example with functionality you requested. I test it using sd card but should work with other devices. I don't know what is your device. I import PortableDeviceApi 1.0 type library (included in example) and add some buttons to list devices, copy, delete files.

In source there are few links related to this, but here are few other:
http://www.chblog.ch/TitusKoty/83954/WPD+with+Dephi%3B+Getting+Events+from+a+digital+camera.html
http://dotnet.dzone.com/articles/windows-portable-devices-0

Most of them are using c#,Delphi is not so popular :-)
mtp.zip
Avatar of Clyde24
Clyde24

ASKER

I tried compiling your test project but I get several compile errors (I am using Delphi 2010)

User generated image
Uh, I'm using XE3 to make this. I will try to use older one to make new example.
Here is newer version ported to Delphi 2007. Should work on D2010.
mtp2.zip
Avatar of Clyde24

ASKER

Yes, that compiles fine in Delphi 2010 - Thanks.

All options work for any USB drive I have connected, but not for  the MTP device (I have a camera connected)

The list devices option correctly identifies the camera

User generated image
However, no files show when you take the option List files on device. There are definitely files and folders on the Camera because you can view them using Windows explorer.

USB drives show as a drive letter so I don't need to speak to them using MTP, I can just do normal file copy, delete etc. You can't use standard file commands on a MTP device in Delphi, so that is the whole reason I need the code to work with MTP devices.

To give you an idea, this is how the MTP camera shows up in Windows explorer - notice how it does not have a drive letter assigned to it.

User generated image
Do you have a Camera or Music player you can test with?
I'm don't have mtp compatible camera, but my guess is that camera have dual mode. One is for image capture and second is for access memory card. I think that you should start second mode and file will appear.

I build extended example with logging. Please run it and post log you will get. In time i'll try to get some cannon to test it.
mtp3.zip
Avatar of Clyde24

ASKER

sDevId := Trim(Copy(sDevId, Pos('\\?', sDevId), Length(sDevId)));

Open in new window


This line throws the following compile error

[DCC Error] mtp_main.pas(1378): E2251 Ambiguous overloaded call to 'Pos'

So I commented out those lines and got it to compile. Here is the log when I run it (the first device is the camera):

+++++ List portable devices +++++
Devices found: 3
Connected: \\?\usb#vid_04a9&pid_3184#2b7655da496c450599a492698723f17f#{6ac27878-a6fa-4155-ba85-f98f491d4f33}
Dev. Functional Categories Count: 1
Dev. Functional Category: WPD_FUNCTIONAL_CATEGORY_STORAGE
Functional Category Objects Count: 1
Functional Category Object: s10001
Content Types Count: 6
Content Type: WPD_CONTENT_TYPE_IMAGE
Content Type: WPD_CONTENT_TYPE_AUDIO
Content Type: WPD_CONTENT_TYPE_VIDEO
Content Type: WPD_CONTENT_TYPE_DOCUMENT
Content Type: WPD_CONTENT_TYPE_UNSPECIFIED
Content Type: WPD_CONTENT_TYPE_FOLDER
Supported Commands Count: 45
Supported Command: WPD_CATEGORY_OBJECT_ENUMERATION (2)
Supported Command: WPD_CATEGORY_OBJECT_ENUMERATION (3)
Supported Command: WPD_CATEGORY_OBJECT_ENUMERATION (4)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (2)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (4)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (6)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (3)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (2)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (3)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (4)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (5)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (7)
Supported Command: WPD_CATEGORY_CAPABILITIES (2)
Supported Command: WPD_CATEGORY_CAPABILITIES (3)
Supported Command: WPD_CATEGORY_CAPABILITIES (4)
Supported Command: WPD_CATEGORY_CAPABILITIES (5)
Supported Command: WPD_CATEGORY_CAPABILITIES (6)
Supported Command: WPD_CATEGORY_CAPABILITIES (7)
Supported Command: WPD_CATEGORY_CAPABILITIES (8)
Supported Command: WPD_CATEGORY_CAPABILITIES (9)
Supported Command: WPD_CATEGORY_CAPABILITIES (10)
Supported Command: WPD_CATEGORY_CAPABILITIES (11)
Supported Command: {4D545058-1A2E-4106-A357-771E0819FC56} (11)
Supported Command: {4D545058-1A2E-4106-A357-771E0819FC56} (18)
Supported Command: {4D545058-1A2E-4106-A357-771E0819FC56} (12)
Supported Command: {4D545058-1A2E-4106-A357-771E0819FC56} (13)
Supported Command: {4D545058-1A2E-4106-A357-771E0819FC56} (14)
Supported Command: {4D545058-1A2E-4106-A357-771E0819FC56} (15)
Supported Command: {4D545058-1A2E-4106-A357-771E0819FC56} (16)
Supported Command: {4D545058-1A2E-4106-A357-771E0819FC56} (17)
Supported Command: {B520E0C2-41DF-4EBD-93E7-5B99C101932F} (11)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (7)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (2)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (3)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (4)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (5)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (6)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (5)
Supported Command: WPD_CATEGORY_STORAGE (2)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES_BULK (2)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES_BULK (3)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES_BULK (4)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES_BULK (5)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES_BULK (6)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES_BULK (7)
Connected: \\?\wpdbusenumroot#umb#2&37c186b&0&storage#volume#_??_usbstor#disk&ven_lexar&prod_jumpdrive&rev_1.00#09020000001575698394&0##{6ac27878-a6fa-4155-ba85-f98f491d4f33}
Dev. Functional Categories Count: 1
Dev. Functional Category: WPD_FUNCTIONAL_CATEGORY_STORAGE
Functional Category Objects Count: 1
Functional Category Object: H:\
Content Types Count: 6
Content Type: WPD_CONTENT_TYPE_UNSPECIFIED
Content Type: WPD_CONTENT_TYPE_FOLDER
Content Type: WPD_CONTENT_TYPE_AUDIO
Content Type: WPD_CONTENT_TYPE_VIDEO
Content Type: WPD_CONTENT_TYPE_IMAGE
Content Type: WPD_CONTENT_TYPE_CONTACT
Supported Commands Count: 32
Supported Command: WPD_CATEGORY_OBJECT_ENUMERATION (2)
Supported Command: WPD_CATEGORY_OBJECT_ENUMERATION (3)
Supported Command: WPD_CATEGORY_OBJECT_ENUMERATION (4)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (7)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (2)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (3)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (4)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (5)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (6)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (2)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (4)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (6)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (5)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (3)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (7)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (2)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (3)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (4)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (5)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (6)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (7)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (8)
Supported Command: WPD_CATEGORY_CAPABILITIES (2)
Supported Command: WPD_CATEGORY_CAPABILITIES (3)
Supported Command: WPD_CATEGORY_CAPABILITIES (4)
Supported Command: WPD_CATEGORY_CAPABILITIES (10)
Supported Command: WPD_CATEGORY_CAPABILITIES (11)
Supported Command: WPD_CATEGORY_CAPABILITIES (5)
Supported Command: WPD_CATEGORY_CAPABILITIES (6)
Supported Command: WPD_CATEGORY_CAPABILITIES (7)
Supported Command: WPD_CATEGORY_CAPABILITIES (8)
Supported Command: WPD_CATEGORY_CAPABILITIES (9)
Connected: \\?\wpdbusenumroot#umb#2&37c186b&0&storage#volume#_??_usbstor#disk&ven_sandisk&prod_cruzer_micro&rev_6.51#0001d87121702c7d&0##{6ac27878-a6fa-4155-ba85-f98f491d4f33}
Dev. Functional Categories Count: 1
Dev. Functional Category: WPD_FUNCTIONAL_CATEGORY_STORAGE
Functional Category Objects Count: 1
Functional Category Object: X:\
Content Types Count: 6
Content Type: WPD_CONTENT_TYPE_UNSPECIFIED
Content Type: WPD_CONTENT_TYPE_FOLDER
Content Type: WPD_CONTENT_TYPE_AUDIO
Content Type: WPD_CONTENT_TYPE_VIDEO
Content Type: WPD_CONTENT_TYPE_IMAGE
Content Type: WPD_CONTENT_TYPE_CONTACT
Supported Commands Count: 32
Supported Command: WPD_CATEGORY_OBJECT_ENUMERATION (2)
Supported Command: WPD_CATEGORY_OBJECT_ENUMERATION (3)
Supported Command: WPD_CATEGORY_OBJECT_ENUMERATION (4)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (7)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (2)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (3)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (4)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (5)
Supported Command: WPD_CATEGORY_OBJECT_MANAGEMENT (6)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (2)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (4)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (6)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (5)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (3)
Supported Command: WPD_CATEGORY_OBJECT_PROPERTIES (7)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (2)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (3)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (4)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (5)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (6)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (7)
Supported Command: WPD_CATEGORY_OBJECT_RESOURCES (8)
Supported Command: WPD_CATEGORY_CAPABILITIES (2)
Supported Command: WPD_CATEGORY_CAPABILITIES (3)
Supported Command: WPD_CATEGORY_CAPABILITIES (4)
Supported Command: WPD_CATEGORY_CAPABILITIES (10)
Supported Command: WPD_CATEGORY_CAPABILITIES (11)
Supported Command: WPD_CATEGORY_CAPABILITIES (5)
Supported Command: WPD_CATEGORY_CAPABILITIES (6)
Supported Command: WPD_CATEGORY_CAPABILITIES (7)
Supported Command: WPD_CATEGORY_CAPABILITIES (8)
Supported Command: WPD_CATEGORY_CAPABILITIES (9)

Open in new window

Avatar of Clyde24

ASKER

OK, I changed

sDevId := Trim(Copy(sDevId, Pos('\\?', sDevId), Length(sDevId)));

to

sDevId := Trim(Copy(sDevId, Pos(widestring('\\?'), sDevId), Length(sDevId)));

Now it compiles OK

When I select the camera and click on "list first level of device" I see:

 User generated image
In Windows explorer when I click on the Portable device/Camera shows as:

User generated image
When I double mouse click on s10001 I see:

User generated image
When I double mouse click on the "Removeable drive" in Windows explorer I see:

User generated image
If I double click on o80000 I see:

User generated image
In Windows explorer if double mouse click on the "DCIM" folder I see :

User generated image
If I double mouse click on o1900000 I see:

User generated image
The 189 objects listed equates to the number of images I have in my camera in the 100CANON folder

User generated image
The corresponding list in Windows explorer looks like:

User generated image
Using the "copy from device" button seems to copy the file to my computer OK (but with the wrong file name). Using "Copy to device" results in error.

User generated image
Avatar of Clyde24

ASKER

Using "Copy to device" results in error.

This is understandable as I can't copy a file from my computer to the camera via Windows explorer:

User generated image
So I don't think that is a problem.

I am only using my camera as a test as it is the only MTP device I own. The application I am writing (for other people) is to send waypoints to a GPSr, and it does support writing files to the device. The actual GPSr is a Garmin Monterra - an android based GPSr unit which only supports MTP for sending/receiving files (you can't make it appear as a removeable drive).

BTW, clicking on the "list all files on device (slow)" shows:

User generated image
And the log is:

+++++ List all files on device (slow) +++++
Connected: \\?\usb#vid_04a9&pid_3184#2b7655da496c450599a492698723f17f#{6ac27878-a6fa-4155-ba85-f98f491d4f33}
Device root: DEVICE
WPD_OBJECT_PARENT_ID: 
WPD_OBJECT_NAME: Canon DIGITAL IXUS 80 IS
WPD_OBJECT_PERSISTENT_UNIQUE_ID: DEVICE
WPD_OBJECT_FORMAT: {30010000-AE6C-4804-98BA-C57B46965FE7}
WPD_OBJECT_CONTENT_TYPE: {99ED0160-17FF-4C44-9D98-1D7A6F941921}
Enumerate: DEVICE
Enum count: 1
Go deep...
WPD_OBJECT_PARENT_ID: DEVICE
WPD_OBJECT_NAME: Removable storage
WPD_OBJECT_PERSISTENT_UNIQUE_ID: SID-{10001,,2028601344}
WPD_OBJECT_FORMAT: {30010000-AE6C-4804-98BA-C57B46965FE7}
WPD_OBJECT_CONTENT_TYPE: {99ED0160-17FF-4C44-9D98-1D7A6F941921}
Enumerate: s10001
Enum count: 2
Go deep...
WPD_OBJECT_PARENT_ID: s10001
WPD_OBJECT_NAME: DCIM
WPD_OBJECT_PERSISTENT_UNIQUE_ID: {00080000-0000-0000-0000-000000000000}
WPD_OBJECT_FORMAT: {30010000-AE6C-4804-98BA-C57B46965FE7}
WPD_OBJECT_CONTENT_TYPE: {27E2E392-A111-48E0-AB0C-E17705A05F85}
Enumerate: o80000
Enum count: 1
Go deep...
WPD_OBJECT_PARENT_ID: o80000
WPD_OBJECT_NAME: 100CANON
WPD_OBJECT_PERSISTENT_UNIQUE_ID: {01900000-0000-0000-0000-000000000000}
WPD_OBJECT_FORMAT: {30010000-AE6C-4804-98BA-C57B46965FE7}
WPD_OBJECT_CONTENT_TYPE: {27E2E392-A111-48E0-AB0C-E17705A05F85}
Enumerate: o1900000
Enum count: 189
Go deep...
WPD_OBJECT_PARENT_ID: s10001
WPD_OBJECT_NAME: SNDR
WPD_OBJECT_PERSISTENT_UNIQUE_ID: {10080000-0000-0000-0000-000000000000}
WPD_OBJECT_FORMAT: {30010000-AE6C-4804-98BA-C57B46965FE7}
WPD_OBJECT_CONTENT_TYPE: {27E2E392-A111-48E0-AB0C-E17705A05F85}
Enumerate: o10080000
Enum count: 1
Go deep...
WPD_OBJECT_PARENT_ID: o10080000
WPD_OBJECT_NAME: 100CANON
WPD_OBJECT_PERSISTENT_UNIQUE_ID: {11900000-0000-0000-0000-000000000000}
WPD_OBJECT_FORMAT: {30010000-AE6C-4804-98BA-C57B46965FE7}
WPD_OBJECT_CONTENT_TYPE: {27E2E392-A111-48E0-AB0C-E17705A05F85}
Enumerate: o11900000
Enum count: 1

Open in new window

With new example you should see real names. But this is not important. If you want to use gps device - then try to connect it and show logs here. This device have another set of supported commands under different functional category than storage device. Thing that this is not like send/receive files (similar to camera control)
mtp4.zip
Avatar of Clyde24

ASKER

Thanks.

I am waiting on feedback from a Monterra user and will report back when I get it.

However, in the mean time, just a few observations/issues

1. Please change your copy of the program so I don't get the "DCC Error] mtp_main.pas(1378): E2251 Ambiguous overloaded call to 'Pos'" message when I try to compile (see my post above on how I fixed it)

2. When I select the "Copy from device" button. The dialog correctly shows the file name but the actual file created is the object ID (with no extension).

3. When selecting the "copy to device" button, which folder does the file get created it? Another words, how do I specify which folder this file should go to?

Thanks
Clyde
Avatar of Clyde24

ASKER

I had a user run the MTP demo program with the Garmin Monterra connected. Unfortunately it did not go well. The log says "devices found: 1" but nothing else works.

User generated image
Avatar of Clyde24

ASKER

... also here is a screenshot of how the Monterra GPS shows up in windows explorer

User generated image
I've requested that this question be deleted for the following reason:

Not enough information to confirm an answer.
Avatar of Clyde24

ASKER

Please do not close. I am hoping Sinisa Vuk can add more code to help track down why the Monterra will not work. As can be seen from the log the code recognizes the device is connected but there are no more details. I am hoping extra code can be added to determine what the problem is.
I was very busy lately .... In a meanwhile I modified example to avoid your problems.
About Montera - maybe is wrong mtp driver installed. I go through lots of sites and found that some devices have really a problem with that.
http://www.anythingbutipod.com/forum/showthread.php?t=37339
http://code.google.com/p/clementine-player/wiki/PortableDevices
https://motorola-global-portal.custhelp.com/app/answers/detail/a_id/90460/action/auth
...
Try it...
mtp5.zip
Avatar of Clyde24

ASKER

I have had 4 users test this with exactly the same result. I don't believe the problem is USB drive associated as all 4 can drag and drop files etc using Windows explorer.

Unfortunately the result is the same as before. The demo program recognizes that there is one device connected but no more information is shownUser generated image
Try modified version which will show more info when getting device info. This may help to continue.

Alternatively you can change iDevCount := 0 to iDevCount := 1 in Button1Click event.

        // Determine how many WPD devices are connected
        iDevCount := 1;
        if PMan.GetDevices(PWideChar(nil^), iDevCount) = S_OK then
        begin
...

Open in new window

mtp6.zip
Avatar of Clyde24

ASKER

Unfortunately  the results are the same with modified version (no extra information shown at all), and when changing iDevCount := 1
This is very strange. Did you test with other devices (like real usb memory)?
Try even more detailed example. There should be more log lines.
mtp7.zip
Avatar of Clyde24

ASKER

Unfortunately still no joy. Memory drives work OK but not the Monterra.
What log looks like?
Avatar of Clyde24

ASKER

+++++ List portable devices +++++
Devices found: 1
Prepare dev. list
Call: GetDevices
Result = 0
We are more closer .... :-)
Try another example and show me log.
mtp8.zip
Avatar of Clyde24

ASKER

Picture of log:

User generated image
Again ... much closer.....
mtp9.zip
Avatar of Clyde24

ASKER

Yes! We are getting much closer - nearly there!

This time the test user was able to see the device in the demo. He could copy files FROM the Monterra and also delete files FROM the Monterra, bad sadly both the "Copy to device" and "Copy to spec. folder" ended with the error message dialog ("Error!" and "Cannot locate destination folder!" respectively).

So it would appear the only issue to be resolved now is copying files to the unit. I have attached the log so you can see how far the copy got before throwing the error. Perhaps more more logging/error checking is needed find out why the copy is not working?
log.txt
ASKER CERTIFIED SOLUTION
Avatar of Sinisa Vuk
Sinisa Vuk
Flag of Croatia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Clyde24

ASKER

log.txt attached
log.txt
As I can see - problem is that "Copy to device" mode doesn't know destination folder. Is destination folder empty? Keep noticed that this app is very restrictive demo. It uses at least one file (object) in folder to get information about destination folder. You can stop at upper level and select ("browned" item) folder where you want to copy file.
Same thing for "Copy to spec. folder" - make sure that you enter valid (relative) path....
Send screenshot with folders/state when you want to do copy to device....
Avatar of Clyde24

ASKER

Sorry, it was user error - so everything seems to be working fine now! Thanks!!!!

I will accept your answer shortly and award the points.

However, I suspect I will have other related questions as I want to massage your code for my specific application.

For this I will start a new question(s) but just wanted to know how best to phrase the title so you will see it and respond. Could you please let me know.

It makes sense that you would be the one to answer as the questions will almost certainly be related to code you have written in the Mtp_Demo project

Thanks
Clyde
when I'm not so busy (at work :-) ... I go to EE very often. Just put MTP somewhere in title. Put latest examle (mtp10.zip) as attachment to question and maybe link to this question. I suggest to look for comments in code and links too. Because there is no Delphi examples/topics about this I'm trying to learn myself too. Hope you will get into too.
I assume you want to build own projest at last.
@sinisav: Your sample code is excellent.  I was wondering if I may repost it to stackoverflow.com as many people do not have Expert Exchange access.
Hi!
thanks for asking. You may repost to stack.... Unfortunately, I have very little time.... This comes very complex now. Maybe you can put my referral link to EE too :-) if someone found it useful and comes to EE for membership .....
http://rdsrc.us/lhshJT
A message has been sent to some additional experts asking them to review your question. We will check back again to see if you are getting the help you need.

This request included Experts from Delphi Programming.
Roadrunner email