2 * Windows MTP Firmware Uploading Implementation
4 * Based on http://opensource.creative.com/mtp_xfer.html
5 * Edited by Maurus Cuelenaere for Rockbox
7 * Copyright (c) 2009, Maurus Cuelenaere
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * * Neither the name of the <organization> nor the
18 * names of its contributors may be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY MAURUS CUELENAERE ''AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL MAURUS CUELENAERE BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 class CProgressHelper
:
42 void (*m_callback
)(unsigned int progress
, unsigned int max
);
48 CProgressHelper( void (*callback
)(unsigned int progress
, unsigned int max
) );
50 STDMETHOD(Begin
)( DWORD dwEstimatedTicks
);
51 STDMETHOD(Progress
)( DWORD dwTranspiredTicks
);
54 STDMETHOD(QueryInterface
) ( REFIID riid
, void __RPC_FAR
*__RPC_FAR
*ppvObject
);
55 STDMETHOD_(ULONG
, AddRef
)( void );
56 STDMETHOD_(ULONG
, Release
)( void );
60 * Compilation requirements:
62 * Download the Windows Media Format 9.5 SDK
63 * Add "c:\wmsdk\wmfsdk95\include,c:\wmsdk\wmfsdk95\wmdm\inc" to your inclusion path
64 * Add "c:\wmsdk\wmfsdk95\lib,c:\wmsdk\wmfsdk95\wmdm\lib" to your library inclusion path
65 * Link to "mssachlp.lib"
69 __declspec(dllexport
) bool send_fw(LPWSTR file
, int filesize
, void (*callback
)(unsigned int progress
, unsigned int max
))
71 bool return_value
= false;
73 IComponentAuthenticate
* pICompAuth
;
74 CSecureChannelClient
*m_pSacClient
= new CSecureChannelClient
;
75 IWMDeviceManager3
* m_pIdvMgr
= NULL
;
77 /* these are generic keys */
78 BYTE abPVK
[] = {0x00};
79 BYTE abCert
[] = {0x00};
83 /* get an authentication interface */
84 hr
= CoCreateInstance(CLSID_MediaDevMgr
, NULL
, CLSCTX_ALL
,IID_IComponentAuthenticate
, (void **)&pICompAuth
);
87 /* create a secure channel client certificate */
88 hr
= m_pSacClient
->SetCertificate(SAC_CERT_V1
, (BYTE
*) abCert
, sizeof(abCert
), (BYTE
*) abPVK
, sizeof(abPVK
));
91 /* bind the authentication interface to the secure channel client */
92 m_pSacClient
->SetInterface(pICompAuth
);
94 /* trigger communication */
95 hr
= m_pSacClient
->Authenticate(SAC_PROTOCOL_V1
);
98 /* get main interface to media device manager */
99 hr
= pICompAuth
->QueryInterface(IID_IWMDeviceManager2
, (void**)&m_pIdvMgr
);
102 /* enumerate devices... */
103 IWMDMEnumDevice
*pIEnumDev
;
104 hr
= m_pIdvMgr
->EnumDevices2(&pIEnumDev
);
107 hr
= pIEnumDev
->Reset(); /* Next will now return the first device */
110 IWMDMDevice3
* pIDevice
;
111 unsigned long ulNumFetched
;
112 hr
= pIEnumDev
->Next(1, (IWMDMDevice
**)&pIDevice
, &ulNumFetched
);
113 while (SUCCEEDED(hr
) && (hr
!= S_FALSE
))
115 /* get storage info */
117 pIDevice
->GetType(&tempDW
);
118 if (tempDW
& WMDM_DEVICE_TYPE_STORAGE
)
120 IWMDMEnumStorage
*pIEnumStorage
= NULL
;
121 IWMDMStorage
*pIStorage
= NULL
;
122 IWMDMStorage3
*pIFileStorage
= NULL
;
123 hr
= pIDevice
->EnumStorage(&pIEnumStorage
);
126 pIEnumStorage
->Reset();
127 hr
= pIEnumStorage
->Next(1, (IWMDMStorage
**)&pIStorage
, &ulNumFetched
);
128 while (SUCCEEDED(hr
) && (hr
!= S_FALSE
))
130 IWMDMStorage3
*pNewStorage
;
131 hr
= pIStorage
->QueryInterface(IID_IWMDMStorage3
, (void **)&pNewStorage
);
134 IWMDMStorageControl3
*pIWMDMStorageControl
;
135 hr
= pNewStorage
->QueryInterface(IID_IWMDMStorageControl3
,
136 (void**)&pIWMDMStorageControl
);
139 IWMDMMetaData
*pIWMDMMetaData
= NULL
;
140 hr
= pNewStorage
->CreateEmptyMetadataObject(&pIWMDMMetaData
);
143 DWORD dw
= WMDM_FORMATCODE_UNDEFINEDFIRMWARE
;
144 hr
= pIWMDMMetaData
->AddItem(WMDM_TYPE_DWORD
, g_wszWMDMFormatCode
, (BYTE
*)&dw
, sizeof(dw
));
145 hr
= pIWMDMMetaData
->AddItem(WMDM_TYPE_STRING
, g_wszWMDMFileName
, (BYTE
*)L
"nk.bin", 32);
149 hr
= pIWMDMMetaData
->AddItem(WMDM_TYPE_QWORD
, g_wszWMDMFileSize
, (BYTE
*)ow
, 2 * sizeof(dw
));
152 IWMDMStorage
*pNewObject
= NULL
;
153 CProgressHelper
*progress
= new CProgressHelper(callback
);
155 hr
= pIWMDMStorageControl
->Insert3(
156 WMDM_MODE_BLOCK
| WMDM_CONTENT_FILE
| WMDM_MODE_PROGRESS
,
161 (callback
== NULL
? NULL
: (IWMDMProgress
*)progress
),
164 (IWMDMStorage
**)&pNewObject
);
166 if(SUCCEEDED(hr
) || hr
== WMDM_S_NOT_ALL_PROPERTIES_APPLIED
167 || hr
== WMDM_S_NOT_ALL_PROPERTIES_RETRIEVED
)
178 pIEnumStorage
->Release();
181 /* move to next device */
183 hr
= pIEnumDev
->Next(1, (IWMDMDevice
**)&pIDevice
, &ulNumFetched
);
185 pIEnumDev
->Release();
187 m_pIdvMgr
->Release();
189 pICompAuth
->Release();
202 CProgressHelper::CProgressHelper( void (*callback
)(unsigned int progress
, unsigned int max
) )
208 m_callback
= callback
;
211 CProgressHelper::~CProgressHelper()
215 HRESULT
CProgressHelper::Begin( DWORD dwEstimatedTicks
)
217 m_max_ticks
= dwEstimatedTicks
;
222 HRESULT
CProgressHelper::Progress( DWORD dwTranspiredTicks
)
224 m_cur_ticks
= dwTranspiredTicks
;
226 if(m_callback
!= NULL
)
227 m_callback(m_cur_ticks
, max(m_max_ticks
, m_cur_ticks
));
232 HRESULT
CProgressHelper::End()
234 m_cur_ticks
= m_max_ticks
;
239 HRESULT
CProgressHelper::QueryInterface( REFIID riid
, void __RPC_FAR
*__RPC_FAR
*ppvObject
)
241 if(riid
== IID_IWMDMProgress
|| riid
== IID_IUnknown
)
249 return E_NOINTERFACE
;
253 ULONG
CProgressHelper::AddRef()
257 ULONG
CProgressHelper::Release()