summaryrefslogtreecommitdiff
path: root/utils/MTP/MTP_DLL/mtp_wrapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/MTP/MTP_DLL/mtp_wrapper.cpp')
-rw-r--r--utils/MTP/MTP_DLL/mtp_wrapper.cpp284
1 files changed, 284 insertions, 0 deletions
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