Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternatives to WPD/WIA on Windows XP?

WPD does not work correctly on Windows XP (SP1 if that matters), even if Microsoft states it does.

Problem with WPD:

IPortableDeviceManager.GetDevices call does not find any devices on Win XP while it finds all connected cameras on Windows 7.

A few other people had this same problem with WPD not working on XP, no solution: 1 2

I have decided to reimplement the functionality using WIA.

Problem with WIA automation/WIA interfaces:

  • WIA automation offers only silly dialogs when interacting with the camera - I need to rather do this from code
  • Programming against WIA interfaces is recommended to achieve lower level tasks with WIA. I have not found any samples how to use WIA interfaces from C# (also found some indication that this is not possible at all or at least very hard to do)

Thus I have looked at WIA 2.0 (wrapper around wiaaut.dll):

  • I am getting HRESULT 0x80210006 (WIA_ERROR_BUSY) for the first time and then HRESULT E_FAIL all the time on Win XP while on Windows 7 the same code works without a problem.

I am getting out of options here... Can you recommend an alternative to provide the following features for cameras connected to the computer that works on Windows XP?

  • sends a notification that a picture was taken
  • allows to download the recently taken picture from the camera
like image 793
Marek Avatar asked Feb 26 '23 23:02

Marek


1 Answers

Microsoft claim that WPD and MTP are supported on XP with WMP11 installed, and indeed this is the case!

However by default on XP a camera device will most likely load the PTP driver stack instead. You can check this by looking at the Driver Details page from Device Manager, Properties, Driver tab, where you should see:

  • C:\Windows\System32\ptpusb.dll
  • C:\Windows\System32\ptpusd.dll

That is, unless your camera vendor has thoughtfully supplied a custom WPD compatible INF file for your device on XP. Most haven't, probably due to the reliance on WMP10/11.

However it is relatively easy to create your own custom INF to enable MTP, and details for this are given in the Microsoft Media Transfer Protocol Porting Kit in the mtpdev.chm help file under section "Providing a Custom INF File for an MTP Device".

However the detail there seem somewhat incomplete, and there is further information to be had about the sections required in the comments of C:\Windows\Inf\WpdMtp.inf installed with Windows Media Player 11:

;;******************************************************************************
;; The following are to be used in vendor specific "Includes" and "Needs" sections.
;; Specifically, the INF should contain:
;;
;; [DDInstall]
;; Include = wpdmtp.inf
;; Needs   = WPD.MTP
;;
;; [DDInstall.hw]
;; Include = wpdmtp.inf
;; Needs   = WPD.MTP.Registration       <- includes all default legacy API and autoplay registration for the device
;;  - OR - 
;; Needs   = WPD.MTP.RegistrationBasic  <- only do minimum registration, no legacy API or autoplay
;;
;; [DDInstall.Services]
;; Include = wpdmtp.inf
;; Needs   = WPD.MTP.Services
;;
;; [DDInstall.CoInstallers]
;; Include = wpdmtp.inf
;; Needs = WPD.MTP.CoInstallers
;;
;; [DDInstall.Wdf]
;; Include = wpdmtp.inf
;; Needs = WPD.MTP.Wdf
;; UmdfServiceOrder=WpdMtpDriver
;;
;;******************************************************************************

For example, for a Nikon D90, the following INF file can be created:

[Version]
Signature="$WINDOWS NT$"
Class=WPD
ClassGUID={EEC5AD98-8080-425f-922A-DABF3DE3F69A}
Provider=%Provider%
DriverVer=02/22/2006,5.2.5326.4762

[Manufacturer]
%MfgName%=Nikon

[Nikon]
%Nikon.DeviceDesc%=Nikon_MTP, USB\VID_04B0&PID_0421

[Nikon_MTP]
Include = wpdmtp.inf
Needs   = WPD.MTP

[Nikon_MTP.hw]
Include = wpdmtp.inf
Needs   = WPD.MTP.RegistrationBasic

[Nikon_MTP.Services]
Include = wpdmtp.inf
Needs   = WPD.MTP.Services

[Nikon_MTP.CoInstallers]
Include = wpdmtp.inf
Needs   = WPD.MTP.CoInstallers

[Nikon_MTP.Wdf]
Include = wpdmtp.inf
Needs   = WPD.MTP.Wdf
UmdfServiceOrder=WpdMtpDriver

[Strings]
Nikon.DeviceDesc       = "Nikon D90 MTP Device"
MfgName                 = "Nikon"
Provider                = "Nikon"

To support different devices change, or add additional items, under the [Nikon] section with the correct PID and VID for your device. You can find these in Device Manager on the Details tab by selecting "Hadrware Ids" from the drop down. You'll probably also want to change all the references to "Nikon" if your camera is from a different manufacturer.

Once you have created your INF file in notepad, save under an appropriate name, for example NikonD90.INF. Then:

  • In Windows Device Manager right click the camera device and "Update Driver".
  • Select "No, not this time" when Windows asks to search Windows Update.
  • Select "Install from a list or specific location (Advanced)".
  • Select "Don't search, I will choose the drive to install".
  • Click "Have Disk".
  • Click "Browser" and navigate to the folder where you saved the INF file created above.
  • Select the INF file and it should install the MTP drivers.

Now in Device manager you should see that the camera device has moved from "Imaging Devices" and is now displayed under "Portable Devices" instead. Also on the driver details you should see the following files indicating that the generic WPD MTP class drivers are being used (instead of PTP previously):

  • C:\Windows\System32\wpdusb.dll
  • C:\Windows\System32\wudfrd.dll

You should now be able to successfully enumerate your MTP device using IPortableDeviceManager.GetDevices and use all of the other API functions to send custom MTP commands. See the MSDN posts by dimeby8 for details.

The above solution allows you to build applications with a common API that work on Windows XP through Windows 7 in either 32 or 64 bit with no code changes.

like image 161
pcbbc Avatar answered Mar 07 '23 20:03

pcbbc