summaryrefslogtreecommitdiff
path: root/utils/MTP/MTP_DLL
diff options
context:
space:
mode:
Diffstat (limited to 'utils/MTP/MTP_DLL')
-rw-r--r--utils/MTP/MTP_DLL/MTP_DLL.h13
-rw-r--r--utils/MTP/MTP_DLL/MTP_DLL.vcproj29
-rw-r--r--utils/MTP/MTP_DLL/mtp_wrapper.cpp284
-rw-r--r--utils/MTP/MTP_DLL/progresshelper.cpp104
-rw-r--r--utils/MTP/MTP_DLL/progresshelper.h52
-rw-r--r--utils/MTP/MTP_DLL/sendfirm_win.cpp260
6 files changed, 463 insertions, 279 deletions
diff --git a/utils/MTP/MTP_DLL/MTP_DLL.h b/utils/MTP/MTP_DLL/MTP_DLL.h
index eeee72a87b..2793c936e1 100644
--- a/utils/MTP/MTP_DLL/MTP_DLL.h
+++ b/utils/MTP/MTP_DLL/MTP_DLL.h
@@ -1,10 +1,21 @@
1
2#ifndef MTP_DLL_H
3#define MTP_DLL_H
4
1#ifdef MTP_DLL_EXPORTS 5#ifdef MTP_DLL_EXPORTS
2#define MTP_DLL_API __declspec(dllexport) 6#define MTP_DLL_API __declspec(dllexport)
3#else 7#else
4#define MTP_DLL_API __declspec(dllimport) 8#define MTP_DLL_API __declspec(dllimport)
5#endif 9#endif
6 10
11#ifdef __cplusplus
7extern "C" 12extern "C"
8{ 13{
9 __declspec(dllexport) bool send_fw(LPWSTR file, int filesize, void (*callback)(unsigned int progress, unsigned int max)); 14#endif
15MTP_DLL_API int mtp_sendnk(LPWSTR file, int filesize, void (*callback)(unsigned int progress, unsigned int max));
16MTP_DLL_API int mtp_description(wchar_t* name, wchar_t* manufacturer, DWORD* version);
17#ifdef __cplusplus
10} 18}
19#endif
20
21#endif
diff --git a/utils/MTP/MTP_DLL/MTP_DLL.vcproj b/utils/MTP/MTP_DLL/MTP_DLL.vcproj
index 3d7fa43475..644e2e445e 100644
--- a/utils/MTP/MTP_DLL/MTP_DLL.vcproj
+++ b/utils/MTP/MTP_DLL/MTP_DLL.vcproj
@@ -1,7 +1,7 @@
1<?xml version="1.0" encoding="Windows-1252"?> 1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject 2<VisualStudioProject
3 ProjectType="Visual C++" 3 ProjectType="Visual C++"
4 Version="8,00" 4 Version="8.00"
5 Name="MTP_DLL" 5 Name="MTP_DLL"
6 ProjectGUID="{C7A39A2D-2ADF-40A3-A9A5-0DF4509B761B}" 6 ProjectGUID="{C7A39A2D-2ADF-40A3-A9A5-0DF4509B761B}"
7 RootNamespace="MTP_DLL" 7 RootNamespace="MTP_DLL"
@@ -170,6 +170,7 @@
170 /> 170 />
171 <Tool 171 <Tool
172 Name="VCPostBuildEventTool" 172 Name="VCPostBuildEventTool"
173 CommandLine="echo Copying $(TargetName) dll / lib to ..&#x0D;&#x0A;copy /Y &quot;$(InputDir)$(ConfigurationName)\$(TargetFileName)&quot; &quot;$(InputDir)..\&quot;&#x0D;&#x0A;copy /Y &quot;$(InputDir)$(ConfigurationName)\$(TargetName).lib&quot; &quot;$(InputDir)..\&quot;"
173 /> 174 />
174 </Configuration> 175 </Configuration>
175 </Configurations> 176 </Configurations>
@@ -186,24 +187,12 @@
186 > 187 >
187 </File> 188 </File>
188 <File 189 <File
189 RelativePath=".\sendfirm_win.cpp" 190 RelativePath=".\mtp_wrapper.cpp"
191 >
192 </File>
193 <File
194 RelativePath=".\progresshelper.cpp"
190 > 195 >
191 <FileConfiguration
192 Name="Debug|Win32"
193 >
194 <Tool
195 Name="VCCLCompilerTool"
196 UsePrecompiledHeader="0"
197 />
198 </FileConfiguration>
199 <FileConfiguration
200 Name="Release|Win32"
201 >
202 <Tool
203 Name="VCCLCompilerTool"
204 UsePrecompiledHeader="0"
205 />
206 </FileConfiguration>
207 </File> 196 </File>
208 <File 197 <File
209 RelativePath=".\stdafx.cpp" 198 RelativePath=".\stdafx.cpp"
@@ -236,6 +225,10 @@
236 > 225 >
237 </File> 226 </File>
238 <File 227 <File
228 RelativePath=".\progresshelper.h"
229 >
230 </File>
231 <File
239 RelativePath=".\stdafx.h" 232 RelativePath=".\stdafx.h"
240 > 233 >
241 </File> 234 </File>
diff --git a/utils/MTP/MTP_DLL/mtp_wrapper.cpp b/utils/MTP/MTP_DLL/mtp_wrapper.cpp
new file mode 100644
index 0000000000..f444a59631
--- /dev/null
+++ b/utils/MTP/MTP_DLL/mtp_wrapper.cpp
@@ -0,0 +1,284 @@
1/*
2 * Windows MTP Firmware Uploading Implementation
3 *
4 * Based on http://opensource.creative.com/mtp_xfer.html
5 * Edited by Maurus Cuelenaere for Rockbox
6 *
7 * Copyright (c) 2009, Maurus Cuelenaere
8 * All rights reserved.
9 *
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.
20 *
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.
31 */
32
33
34#include "stdafx.h"
35
36#include <windows.h>
37#include "mswmdm_i.c"
38#include "mswmdm.h"
39#include "sac.h"
40#include "scclient.h"
41
42#include "progresshelper.h"
43#include "MTP_DLL.h"
44
45/*
46 * Compilation requirements:
47 *
48 * Download the Windows Media Format 9.5 SDK
49 * Add "c:\wmsdk\wmfsdk95\include,c:\wmsdk\wmfsdk95\wmdm\inc" to your inclusion path
50 * Add "c:\wmsdk\wmfsdk95\lib,c:\wmsdk\wmfsdk95\wmdm\lib" to your library inclusion path
51 * Link to "mssachlp.lib"
52 *
53 */
54
55struct mtp_if {
56 IComponentAuthenticate* pICompAuth;
57 CSecureChannelClient *pSacClient;
58 IWMDeviceManager3* pIdvMgr;
59 bool initialized;
60};
61
62
63extern "C" {
64static int mtp_init(struct mtp_if* mtp)
65{
66 HRESULT hr;
67 mtp->pSacClient = new CSecureChannelClient;
68 mtp->pIdvMgr = NULL;
69 mtp->initialized = false;
70
71 /* these are generic keys */
72 BYTE abPVK[] = {0x00};
73 BYTE abCert[] = {0x00};
74
75 CoInitialize(NULL);
76
77 /* get an authentication interface */
78 hr = CoCreateInstance(CLSID_MediaDevMgr, NULL, CLSCTX_ALL,
79 IID_IComponentAuthenticate, (void **)&mtp->pICompAuth);
80 if SUCCEEDED(hr)
81 {
82 /* create a secure channel client certificate */
83 hr = mtp->pSacClient->SetCertificate(SAC_CERT_V1, (BYTE*) abCert,
84 sizeof(abCert), (BYTE*) abPVK, sizeof(abPVK));
85 if SUCCEEDED(hr)
86 {
87 /* bind the authentication interface to the secure channel client */
88 mtp->pSacClient->SetInterface(mtp->pICompAuth);
89
90 /* trigger communication */
91 hr = mtp->pSacClient->Authenticate(SAC_PROTOCOL_V1);
92 if SUCCEEDED(hr)
93 {
94 /* get main interface to media device manager */
95 hr = mtp->pICompAuth->QueryInterface(IID_IWMDeviceManager2,
96 (void**)&mtp->pIdvMgr);
97 if SUCCEEDED(hr)
98 {
99 mtp->initialized = true;
100 }
101 }
102 }
103 }
104 else {
105 CoUninitialize();
106 }
107 return mtp->initialized;
108}
109
110
111static int mtp_close(struct mtp_if* mtp)
112{
113 if(mtp->initialized)
114 {
115 mtp->pIdvMgr->Release();
116 mtp->pICompAuth->Release();
117 CoUninitialize();
118 mtp->initialized = false;
119 }
120 return 0;
121}
122
123__declspec(dllexport) int mtp_description(wchar_t* name, wchar_t* manufacturer, DWORD* version)
124{
125 HRESULT hr;
126 int num = 0;
127 struct mtp_if mtp;
128 /* zero mtp structure */
129 memset(&mtp, 0, sizeof(struct mtp_if));
130
131 /* initialize interface */
132 mtp_init(&mtp);
133 if(mtp.initialized == false) {
134 return -1;
135 }
136
137 /* we now have a media device manager interface... */
138 /* enumerate devices... */
139 IWMDMEnumDevice *pIEnumDev;
140 wchar_t pwsString[256];
141 hr = mtp.pIdvMgr->EnumDevices2(&pIEnumDev);
142 if SUCCEEDED(hr) {
143 hr = pIEnumDev->Reset(); /* Next will now return the first device */
144 if SUCCEEDED(hr) {
145 IWMDMDevice3* pIDevice;
146 unsigned long ulNumFetched;
147 hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
148 while (SUCCEEDED(hr) && (hr != S_FALSE)) {
149 /* output device name */
150 hr = pIDevice->GetName(pwsString, 256);
151 if SUCCEEDED(hr) {
152 wcsncpy_s(name, 256, pwsString, _TRUNCATE);
153 num++;
154 }
155 /* device manufacturer */
156 hr = pIDevice->GetManufacturer(pwsString, 256);
157 if SUCCEEDED(hr) {
158 wcsncpy_s(manufacturer, 256, pwsString, _TRUNCATE);
159 }
160 /* device version -- optional interface so might fail. */
161 DWORD ver;
162 hr = pIDevice->GetVersion(&ver);
163 if SUCCEEDED(hr) {
164 *version = ver;
165 }
166 else {
167 *version = 0;
168 }
169
170 /* move to next device */
171 hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
172 }
173 pIEnumDev->Release();
174 }
175 mtp_close(&mtp);
176 }
177 return (num > 0) ? num : -1;
178}
179
180__declspec(dllexport) int mtp_sendnk(LPWSTR file, int filesize, void (*callback)(unsigned int progress, unsigned int max))
181{
182 HRESULT hr;
183 bool return_value = false;
184 struct mtp_if mtp;
185 /* zero mtp structure */
186 memset(&mtp, 0, sizeof(struct mtp_if));
187
188 /* initialize interface */
189 mtp_init(&mtp);
190 if(mtp.initialized == false) {
191 return false;
192 }
193 /* enumerate devices... */
194 IWMDMEnumDevice *pIEnumDev;
195 hr = mtp.pIdvMgr->EnumDevices2(&pIEnumDev);
196 if SUCCEEDED(hr)
197 {
198 hr = pIEnumDev->Reset(); /* Next will now return the first device */
199 if SUCCEEDED(hr)
200 {
201 IWMDMDevice3* pIDevice;
202 unsigned long ulNumFetched;
203 hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
204 while (SUCCEEDED(hr) && (hr != S_FALSE))
205 {
206 /* get storage info */
207 DWORD tempDW;
208 pIDevice->GetType(&tempDW);
209 if (tempDW & WMDM_DEVICE_TYPE_STORAGE)
210 {
211 IWMDMEnumStorage *pIEnumStorage = NULL;
212 IWMDMStorage *pIStorage = NULL;
213 IWMDMStorage3 *pIFileStorage = NULL;
214 hr = pIDevice->EnumStorage(&pIEnumStorage);
215 if SUCCEEDED(hr)
216 {
217 pIEnumStorage->Reset();
218 hr = pIEnumStorage->Next(1, (IWMDMStorage **)&pIStorage, &ulNumFetched);
219 while (SUCCEEDED(hr) && (hr != S_FALSE))
220 {
221 IWMDMStorage3 *pNewStorage;
222 hr = pIStorage->QueryInterface(IID_IWMDMStorage3, (void **)&pNewStorage);
223 if SUCCEEDED(hr)
224 {
225 IWMDMStorageControl3 *pIWMDMStorageControl;
226 hr = pNewStorage->QueryInterface(IID_IWMDMStorageControl3,
227 (void**)&pIWMDMStorageControl);
228 if SUCCEEDED(hr)
229 {
230 IWMDMMetaData *pIWMDMMetaData = NULL;
231 hr = pNewStorage->CreateEmptyMetadataObject(&pIWMDMMetaData);
232 if (SUCCEEDED(hr))
233 {
234 DWORD dw = WMDM_FORMATCODE_UNDEFINEDFIRMWARE;
235 hr = pIWMDMMetaData->AddItem(WMDM_TYPE_DWORD, g_wszWMDMFormatCode, (BYTE *)&dw, sizeof(dw));
236 hr = pIWMDMMetaData->AddItem(WMDM_TYPE_STRING, g_wszWMDMFileName, (BYTE *)L"nk.bin", 32);
237 DWORD ow[2];
238 ow[0] = filesize;
239 ow[1] = 0;
240 hr = pIWMDMMetaData->AddItem(WMDM_TYPE_QWORD, g_wszWMDMFileSize, (BYTE *)ow, 2 * sizeof(dw));
241 if (SUCCEEDED(hr))
242 {
243 IWMDMStorage *pNewObject = NULL;
244 CProgressHelper *progress = new CProgressHelper(callback);
245
246 hr = pIWMDMStorageControl->Insert3(
247 WMDM_MODE_BLOCK | WMDM_CONTENT_FILE | WMDM_MODE_PROGRESS,
248 0,
249 file,
250 NULL,
251 NULL,
252 (callback == NULL ? NULL : (IWMDMProgress*)progress),
253 pIWMDMMetaData,
254 NULL,
255 (IWMDMStorage **)&pNewObject);
256
257 if(SUCCEEDED(hr)
258 || hr == WMDM_S_NOT_ALL_PROPERTIES_APPLIED
259 || hr == WMDM_S_NOT_ALL_PROPERTIES_RETRIEVED)
260 {
261 return_value = true;
262 hr = S_FALSE;
263 }
264 }
265 }
266 }
267 }
268 }
269 }
270 pIEnumStorage->Release();
271 }
272
273 /* move to next device */
274 if(!return_value)
275 hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
276 }
277 pIEnumDev->Release();
278 }
279 mtp_close(&mtp);
280 }
281 return return_value ? 1 : 0;
282}
283
284} \ No newline at end of file
diff --git a/utils/MTP/MTP_DLL/progresshelper.cpp b/utils/MTP/MTP_DLL/progresshelper.cpp
new file mode 100644
index 0000000000..a8aac365c5
--- /dev/null
+++ b/utils/MTP/MTP_DLL/progresshelper.cpp
@@ -0,0 +1,104 @@
1/*
2 * Windows MTP Firmware Uploading Implementation
3 *
4 * Based on http://opensource.creative.com/mtp_xfer.html
5 * Edited by Maurus Cuelenaere for Rockbox
6 *
7 * Copyright (c) 2009, Maurus Cuelenaere
8 * All rights reserved.
9 *
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.
20 *
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.
31 */
32
33#include "stdafx.h"
34
35#include <windows.h>
36#include "mswmdm_i.c"
37#include "mswmdm.h"
38#include "sac.h"
39#include "scclient.h"
40
41#include "progresshelper.h"
42
43
44
45
46CProgressHelper::CProgressHelper( void (*callback)(unsigned int progress, unsigned int max) )
47{
48 m_cur_ticks = 0;
49 m_max_ticks = 0;
50 m_counter = 0;
51
52 m_callback = callback;
53}
54
55CProgressHelper::~CProgressHelper()
56{
57}
58
59HRESULT CProgressHelper::Begin( DWORD dwEstimatedTicks )
60{
61 m_max_ticks = dwEstimatedTicks;
62
63 return S_OK;
64}
65
66HRESULT CProgressHelper::Progress( DWORD dwTranspiredTicks )
67{
68 m_cur_ticks = dwTranspiredTicks;
69
70 if(m_callback != NULL)
71 m_callback(m_cur_ticks, max(m_max_ticks, m_cur_ticks));
72
73 return S_OK;
74}
75
76HRESULT CProgressHelper::End()
77{
78 m_cur_ticks = m_max_ticks;
79
80 return S_OK;
81}
82
83HRESULT CProgressHelper::QueryInterface( REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject )
84{
85 if(riid == IID_IWMDMProgress || riid == IID_IUnknown)
86 {
87 *ppvObject = this;
88 return S_OK;
89 }
90 else
91 {
92 *ppvObject = NULL;
93 return E_NOINTERFACE;
94 }
95}
96
97ULONG CProgressHelper::AddRef()
98{
99 return m_counter++;
100}
101ULONG CProgressHelper::Release()
102{
103 return m_counter--;
104}
diff --git a/utils/MTP/MTP_DLL/progresshelper.h b/utils/MTP/MTP_DLL/progresshelper.h
new file mode 100644
index 0000000000..ac54095520
--- /dev/null
+++ b/utils/MTP/MTP_DLL/progresshelper.h
@@ -0,0 +1,52 @@
1/*
2 * Windows MTP Firmware Uploading Implementation
3 *
4 * Based on http://opensource.creative.com/mtp_xfer.html
5 * Edited by Maurus Cuelenaere for Rockbox
6 *
7 * Copyright (c) 2009, Maurus Cuelenaere
8 * All rights reserved.
9 *
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.
20 *
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.
31 */
32
33class CProgressHelper :
34 public IWMDMProgress
35{
36 void (*m_callback)(unsigned int progress, unsigned int max);
37 DWORD m_max_ticks;
38 DWORD m_cur_ticks;
39 DWORD m_counter;
40
41public:
42 CProgressHelper( void (*callback)(unsigned int progress, unsigned int max) );
43 ~CProgressHelper();
44 STDMETHOD(Begin)( DWORD dwEstimatedTicks );
45 STDMETHOD(Progress)( DWORD dwTranspiredTicks );
46 STDMETHOD(End)();
47
48 STDMETHOD(QueryInterface) ( REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject );
49 STDMETHOD_(ULONG, AddRef)( void );
50 STDMETHOD_(ULONG, Release)( void );
51};
52
diff --git a/utils/MTP/MTP_DLL/sendfirm_win.cpp b/utils/MTP/MTP_DLL/sendfirm_win.cpp
deleted file mode 100644
index 6f9cf24e93..0000000000
--- a/utils/MTP/MTP_DLL/sendfirm_win.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
1/*
2 * Windows MTP Firmware Uploading Implementation
3 *
4 * Based on http://opensource.creative.com/mtp_xfer.html
5 * Edited by Maurus Cuelenaere for Rockbox
6 *
7 * Copyright (c) 2009, Maurus Cuelenaere
8 * All rights reserved.
9 *
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.
20 *
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.
31 */
32
33#include <windows.h>
34#include "mswmdm_i.c"
35#include "mswmdm.h"
36#include "sac.h"
37#include "scclient.h"
38
39class CProgressHelper :
40 public IWMDMProgress
41{
42 void (*m_callback)(unsigned int progress, unsigned int max);
43 DWORD m_max_ticks;
44 DWORD m_cur_ticks;
45 DWORD m_counter;
46
47public:
48 CProgressHelper( void (*callback)(unsigned int progress, unsigned int max) );
49 ~CProgressHelper();
50 STDMETHOD(Begin)( DWORD dwEstimatedTicks );
51 STDMETHOD(Progress)( DWORD dwTranspiredTicks );
52 STDMETHOD(End)();
53
54 STDMETHOD(QueryInterface) ( REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject );
55 STDMETHOD_(ULONG, AddRef)( void );
56 STDMETHOD_(ULONG, Release)( void );
57};
58
59/*
60 * Compilation requirements:
61 *
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"
66 *
67 */
68extern "C" {
69__declspec(dllexport) bool send_fw(LPWSTR file, int filesize, void (*callback)(unsigned int progress, unsigned int max))
70{
71 bool return_value = false;
72 HRESULT hr;
73 IComponentAuthenticate* pICompAuth;
74 CSecureChannelClient *m_pSacClient = new CSecureChannelClient;
75 IWMDeviceManager3* m_pIdvMgr = NULL;
76
77 /* these are generic keys */
78 BYTE abPVK[] = {0x00};
79 BYTE abCert[] = {0x00};
80
81 CoInitialize(NULL);
82
83 /* get an authentication interface */
84 hr = CoCreateInstance(CLSID_MediaDevMgr, NULL, CLSCTX_ALL ,IID_IComponentAuthenticate, (void **)&pICompAuth);
85 if SUCCEEDED(hr)
86 {
87 /* create a secure channel client certificate */
88 hr = m_pSacClient->SetCertificate(SAC_CERT_V1, (BYTE*) abCert, sizeof(abCert), (BYTE*) abPVK, sizeof(abPVK));
89 if SUCCEEDED(hr)
90 {
91 /* bind the authentication interface to the secure channel client */
92 m_pSacClient->SetInterface(pICompAuth);
93
94 /* trigger communication */
95 hr = m_pSacClient->Authenticate(SAC_PROTOCOL_V1);
96 if SUCCEEDED(hr)
97 {
98 /* get main interface to media device manager */
99 hr = pICompAuth->QueryInterface(IID_IWMDeviceManager2, (void**)&m_pIdvMgr);
100 if SUCCEEDED(hr)
101 {
102 /* enumerate devices... */
103 IWMDMEnumDevice *pIEnumDev;
104 hr = m_pIdvMgr->EnumDevices2(&pIEnumDev);
105 if SUCCEEDED(hr)
106 {
107 hr = pIEnumDev->Reset(); /* Next will now return the first device */
108 if SUCCEEDED(hr)
109 {
110 IWMDMDevice3* pIDevice;
111 unsigned long ulNumFetched;
112 hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
113 while (SUCCEEDED(hr) && (hr != S_FALSE))
114 {
115 /* get storage info */
116 DWORD tempDW;
117 pIDevice->GetType(&tempDW);
118 if (tempDW & WMDM_DEVICE_TYPE_STORAGE)
119 {
120 IWMDMEnumStorage *pIEnumStorage = NULL;
121 IWMDMStorage *pIStorage = NULL;
122 IWMDMStorage3 *pIFileStorage = NULL;
123 hr = pIDevice->EnumStorage(&pIEnumStorage);
124 if SUCCEEDED(hr)
125 {
126 pIEnumStorage->Reset();
127 hr = pIEnumStorage->Next(1, (IWMDMStorage **)&pIStorage, &ulNumFetched);
128 while (SUCCEEDED(hr) && (hr != S_FALSE))
129 {
130 IWMDMStorage3 *pNewStorage;
131 hr = pIStorage->QueryInterface(IID_IWMDMStorage3, (void **)&pNewStorage);
132 if SUCCEEDED(hr)
133 {
134 IWMDMStorageControl3 *pIWMDMStorageControl;
135 hr = pNewStorage->QueryInterface(IID_IWMDMStorageControl3,
136 (void**)&pIWMDMStorageControl);
137 if SUCCEEDED(hr)
138 {
139 IWMDMMetaData *pIWMDMMetaData = NULL;
140 hr = pNewStorage->CreateEmptyMetadataObject(&pIWMDMMetaData);
141 if (SUCCEEDED(hr))
142 {
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);
146 DWORD ow[2];
147 ow[0] = filesize;
148 ow[1] = 0;
149 hr = pIWMDMMetaData->AddItem(WMDM_TYPE_QWORD, g_wszWMDMFileSize, (BYTE *)ow, 2 * sizeof(dw));
150 if (SUCCEEDED(hr))
151 {
152 IWMDMStorage *pNewObject = NULL;
153 CProgressHelper *progress = new CProgressHelper(callback);
154
155 hr = pIWMDMStorageControl->Insert3(
156 WMDM_MODE_BLOCK | WMDM_CONTENT_FILE | WMDM_MODE_PROGRESS,
157 0,
158 file,
159 NULL,
160 NULL,
161 (callback == NULL ? NULL : (IWMDMProgress*)progress),
162 pIWMDMMetaData,
163 NULL,
164 (IWMDMStorage **)&pNewObject);
165
166 if(SUCCEEDED(hr) || hr == WMDM_S_NOT_ALL_PROPERTIES_APPLIED
167 || hr == WMDM_S_NOT_ALL_PROPERTIES_RETRIEVED)
168 {
169 return_value = true;
170 hr = S_FALSE;
171 }
172 }
173 }
174 }
175 }
176 }
177 }
178 pIEnumStorage->Release();
179 }
180
181 /* move to next device */
182 if(!return_value)
183 hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
184 }
185 pIEnumDev->Release();
186 }
187 m_pIdvMgr->Release();
188 }
189 pICompAuth->Release();
190 }
191 }
192 }
193 }
194
195 CoUninitialize();
196
197 return return_value;
198}
199}
200
201
202CProgressHelper::CProgressHelper( void (*callback)(unsigned int progress, unsigned int max) )
203{
204 m_cur_ticks = 0;
205 m_max_ticks = 0;
206 m_counter = 0;
207
208 m_callback = callback;
209}
210
211CProgressHelper::~CProgressHelper()
212{
213}
214
215HRESULT CProgressHelper::Begin( DWORD dwEstimatedTicks )
216{
217 m_max_ticks = dwEstimatedTicks;
218
219 return S_OK;
220}
221
222HRESULT CProgressHelper::Progress( DWORD dwTranspiredTicks )
223{
224 m_cur_ticks = dwTranspiredTicks;
225
226 if(m_callback != NULL)
227 m_callback(m_cur_ticks, max(m_max_ticks, m_cur_ticks));
228
229 return S_OK;
230}
231
232HRESULT CProgressHelper::End()
233{
234 m_cur_ticks = m_max_ticks;
235
236 return S_OK;
237}
238
239HRESULT CProgressHelper::QueryInterface( REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject )
240{
241 if(riid == IID_IWMDMProgress || riid == IID_IUnknown)
242 {
243 *ppvObject = this;
244 return S_OK;
245 }
246 else
247 {
248 *ppvObject = NULL;
249 return E_NOINTERFACE;
250 }
251}
252
253ULONG CProgressHelper::AddRef()
254{
255 return m_counter++;
256}
257ULONG CProgressHelper::Release()
258{
259 return m_counter--;
260}