as3525v2: Move codec into iram freeing 1MB for the audio buffer and also a small...
[kugel-rb.git] / utils / MTP / MTP_DLL / mtp_wrapper.cpp
blobf3a05f3c0c1b6329274e89d1ff23cceccbeb481b
1 /*
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
8 * All rights reserved.
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.
34 #include <windows.h>
35 #include "mswmdm_i.c"
36 #include "mswmdm.h"
37 #include "sac.h"
38 #include "scclient.h"
40 #include "progresshelper.h"
41 #include "MTP_DLL.h"
44 * Compilation requirements:
46 * Download the Windows Media Format 9.5 SDK
47 * Add "c:\wmsdk\wmfsdk95\include,c:\wmsdk\wmfsdk95\wmdm\inc" to your inclusion path
48 * Add "c:\wmsdk\wmfsdk95\lib,c:\wmsdk\wmfsdk95\wmdm\lib" to your library inclusion path
49 * Link to "mssachlp.lib"
53 struct mtp_if {
54 IComponentAuthenticate* pICompAuth;
55 CSecureChannelClient *pSacClient;
56 IWMDeviceManager3* pIdvMgr;
57 bool initialized;
61 extern "C" {
62 static int mtp_init(struct mtp_if* mtp)
64 HRESULT hr;
65 mtp->pSacClient = new CSecureChannelClient;
66 mtp->pIdvMgr = NULL;
67 mtp->initialized = false;
69 /* these are generic keys */
70 BYTE abPVK[] = {0x00};
71 BYTE abCert[] = {0x00};
73 CoInitialize(NULL);
75 /* get an authentication interface */
76 hr = CoCreateInstance(CLSID_MediaDevMgr, NULL, CLSCTX_ALL,
77 IID_IComponentAuthenticate, (void **)&mtp->pICompAuth);
78 if SUCCEEDED(hr)
80 /* create a secure channel client certificate */
81 hr = mtp->pSacClient->SetCertificate(SAC_CERT_V1, (BYTE*) abCert,
82 sizeof(abCert), (BYTE*) abPVK, sizeof(abPVK));
83 if SUCCEEDED(hr)
85 /* bind the authentication interface to the secure channel client */
86 mtp->pSacClient->SetInterface(mtp->pICompAuth);
88 /* trigger communication */
89 hr = mtp->pSacClient->Authenticate(SAC_PROTOCOL_V1);
90 if SUCCEEDED(hr)
92 /* get main interface to media device manager */
93 hr = mtp->pICompAuth->QueryInterface(IID_IWMDeviceManager2,
94 (void**)&mtp->pIdvMgr);
95 if SUCCEEDED(hr)
97 mtp->initialized = true;
102 else {
103 CoUninitialize();
105 return mtp->initialized;
109 static int mtp_close(struct mtp_if* mtp)
111 if(mtp->initialized)
113 mtp->pIdvMgr->Release();
114 mtp->pICompAuth->Release();
115 CoUninitialize();
116 mtp->initialized = false;
118 return 0;
121 MTP_DLL_API int mtp_description(wchar_t* name, wchar_t* manufacturer, DWORD* version)
123 HRESULT hr;
124 int num = 0;
125 struct mtp_if mtp;
126 /* zero mtp structure */
127 memset(&mtp, 0, sizeof(struct mtp_if));
129 /* initialize interface */
130 mtp_init(&mtp);
131 if(mtp.initialized == false) {
132 return -1;
135 /* we now have a media device manager interface... */
136 /* enumerate devices... */
137 IWMDMEnumDevice *pIEnumDev;
138 wchar_t pwsString[256];
139 hr = mtp.pIdvMgr->EnumDevices2(&pIEnumDev);
140 if SUCCEEDED(hr) {
141 hr = pIEnumDev->Reset(); /* Next will now return the first device */
142 if SUCCEEDED(hr) {
143 IWMDMDevice3* pIDevice;
144 unsigned long ulNumFetched;
145 hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
146 while (SUCCEEDED(hr) && (hr != S_FALSE)) {
147 /* output device name */
148 hr = pIDevice->GetName(pwsString, 256);
149 if SUCCEEDED(hr) {
150 wcsncpy_s(name, 256, pwsString, _TRUNCATE);
151 num++;
153 /* device manufacturer */
154 hr = pIDevice->GetManufacturer(pwsString, 256);
155 if SUCCEEDED(hr) {
156 wcsncpy_s(manufacturer, 256, pwsString, _TRUNCATE);
158 /* device version -- optional interface so might fail. */
159 DWORD ver;
160 hr = pIDevice->GetVersion(&ver);
161 if SUCCEEDED(hr) {
162 *version = ver;
164 else {
165 *version = 0;
168 /* move to next device */
169 hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
171 pIEnumDev->Release();
173 mtp_close(&mtp);
175 return (num > 0) ? num : -1;
178 MTP_DLL_API int mtp_sendnk(LPWSTR file, int filesize, void (*callback)(unsigned int progress, unsigned int max))
180 HRESULT hr;
181 bool return_value = false;
182 struct mtp_if mtp;
183 /* zero mtp structure */
184 memset(&mtp, 0, sizeof(struct mtp_if));
186 /* initialize interface */
187 mtp_init(&mtp);
188 if(mtp.initialized == false) {
189 return false;
191 /* enumerate devices... */
192 IWMDMEnumDevice *pIEnumDev;
193 hr = mtp.pIdvMgr->EnumDevices2(&pIEnumDev);
194 if SUCCEEDED(hr)
196 hr = pIEnumDev->Reset(); /* Next will now return the first device */
197 if SUCCEEDED(hr)
199 IWMDMDevice3* pIDevice;
200 unsigned long ulNumFetched;
201 hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
202 while (SUCCEEDED(hr) && (hr != S_FALSE))
204 /* get storage info */
205 DWORD tempDW;
206 pIDevice->GetType(&tempDW);
207 if (tempDW & WMDM_DEVICE_TYPE_STORAGE)
209 IWMDMEnumStorage *pIEnumStorage = NULL;
210 IWMDMStorage *pIStorage = NULL;
211 IWMDMStorage3 *pIFileStorage = NULL;
212 hr = pIDevice->EnumStorage(&pIEnumStorage);
213 if SUCCEEDED(hr)
215 pIEnumStorage->Reset();
216 hr = pIEnumStorage->Next(1, (IWMDMStorage **)&pIStorage, &ulNumFetched);
217 while (SUCCEEDED(hr) && (hr != S_FALSE))
219 IWMDMStorage3 *pNewStorage;
220 hr = pIStorage->QueryInterface(IID_IWMDMStorage3, (void **)&pNewStorage);
221 if SUCCEEDED(hr)
223 IWMDMStorageControl3 *pIWMDMStorageControl;
224 hr = pNewStorage->QueryInterface(IID_IWMDMStorageControl3,
225 (void**)&pIWMDMStorageControl);
226 if SUCCEEDED(hr)
228 IWMDMMetaData *pIWMDMMetaData = NULL;
229 hr = pNewStorage->CreateEmptyMetadataObject(&pIWMDMMetaData);
230 if (SUCCEEDED(hr))
232 DWORD dw = WMDM_FORMATCODE_UNDEFINEDFIRMWARE;
233 hr = pIWMDMMetaData->AddItem(WMDM_TYPE_DWORD, g_wszWMDMFormatCode, (BYTE *)&dw, sizeof(dw));
234 hr = pIWMDMMetaData->AddItem(WMDM_TYPE_STRING, g_wszWMDMFileName, (BYTE *)L"nk.bin", 32);
235 DWORD ow[2];
236 ow[0] = filesize;
237 ow[1] = 0;
238 hr = pIWMDMMetaData->AddItem(WMDM_TYPE_QWORD, g_wszWMDMFileSize, (BYTE *)ow, 2 * sizeof(dw));
239 if (SUCCEEDED(hr))
241 IWMDMStorage *pNewObject = NULL;
242 CProgressHelper *progress = new CProgressHelper(callback);
244 hr = pIWMDMStorageControl->Insert3(
245 WMDM_MODE_BLOCK | WMDM_CONTENT_FILE | WMDM_MODE_PROGRESS,
247 file,
248 NULL,
249 NULL,
250 (callback == NULL ? NULL : (IWMDMProgress*)progress),
251 pIWMDMMetaData,
252 NULL,
253 (IWMDMStorage **)&pNewObject);
255 if(SUCCEEDED(hr)
256 || hr == WMDM_S_NOT_ALL_PROPERTIES_APPLIED
257 || hr == WMDM_S_NOT_ALL_PROPERTIES_RETRIEVED)
259 return_value = true;
260 hr = S_FALSE;
268 pIEnumStorage->Release();
271 /* move to next device */
272 if(!return_value)
273 hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
275 pIEnumDev->Release();
277 mtp_close(&mtp);
279 return return_value ? 1 : 0;