Pictureflow: Don't show the playback control one targets that can't have playback...
[kugel-rb.git] / utils / MTP / MTP_DLL / sendfirm_win.cpp
blob6f9cf24e93d4eac916cf8ff03fb35d4c397621f9
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.
33 #include <windows.h>
34 #include "mswmdm_i.c"
35 #include "mswmdm.h"
36 #include "sac.h"
37 #include "scclient.h"
39 class CProgressHelper :
40 public IWMDMProgress
42 void (*m_callback)(unsigned int progress, unsigned int max);
43 DWORD m_max_ticks;
44 DWORD m_cur_ticks;
45 DWORD m_counter;
47 public:
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)();
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"
68 extern "C" {
69 __declspec(dllexport) bool send_fw(LPWSTR file, int filesize, void (*callback)(unsigned int progress, unsigned int max))
71 bool return_value = false;
72 HRESULT hr;
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};
81 CoInitialize(NULL);
83 /* get an authentication interface */
84 hr = CoCreateInstance(CLSID_MediaDevMgr, NULL, CLSCTX_ALL ,IID_IComponentAuthenticate, (void **)&pICompAuth);
85 if SUCCEEDED(hr)
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)
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);
96 if SUCCEEDED(hr)
98 /* get main interface to media device manager */
99 hr = pICompAuth->QueryInterface(IID_IWMDeviceManager2, (void**)&m_pIdvMgr);
100 if SUCCEEDED(hr)
102 /* enumerate devices... */
103 IWMDMEnumDevice *pIEnumDev;
104 hr = m_pIdvMgr->EnumDevices2(&pIEnumDev);
105 if SUCCEEDED(hr)
107 hr = pIEnumDev->Reset(); /* Next will now return the first device */
108 if SUCCEEDED(hr)
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 */
116 DWORD tempDW;
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);
124 if SUCCEEDED(hr)
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);
132 if SUCCEEDED(hr)
134 IWMDMStorageControl3 *pIWMDMStorageControl;
135 hr = pNewStorage->QueryInterface(IID_IWMDMStorageControl3,
136 (void**)&pIWMDMStorageControl);
137 if SUCCEEDED(hr)
139 IWMDMMetaData *pIWMDMMetaData = NULL;
140 hr = pNewStorage->CreateEmptyMetadataObject(&pIWMDMMetaData);
141 if (SUCCEEDED(hr))
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))
152 IWMDMStorage *pNewObject = NULL;
153 CProgressHelper *progress = new CProgressHelper(callback);
155 hr = pIWMDMStorageControl->Insert3(
156 WMDM_MODE_BLOCK | WMDM_CONTENT_FILE | WMDM_MODE_PROGRESS,
158 file,
159 NULL,
160 NULL,
161 (callback == NULL ? NULL : (IWMDMProgress*)progress),
162 pIWMDMMetaData,
163 NULL,
164 (IWMDMStorage **)&pNewObject);
166 if(SUCCEEDED(hr) || hr == WMDM_S_NOT_ALL_PROPERTIES_APPLIED
167 || hr == WMDM_S_NOT_ALL_PROPERTIES_RETRIEVED)
169 return_value = true;
170 hr = S_FALSE;
178 pIEnumStorage->Release();
181 /* move to next device */
182 if(!return_value)
183 hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
185 pIEnumDev->Release();
187 m_pIdvMgr->Release();
189 pICompAuth->Release();
195 CoUninitialize();
197 return return_value;
202 CProgressHelper::CProgressHelper( void (*callback)(unsigned int progress, unsigned int max) )
204 m_cur_ticks = 0;
205 m_max_ticks = 0;
206 m_counter = 0;
208 m_callback = callback;
211 CProgressHelper::~CProgressHelper()
215 HRESULT CProgressHelper::Begin( DWORD dwEstimatedTicks )
217 m_max_ticks = dwEstimatedTicks;
219 return S_OK;
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));
229 return S_OK;
232 HRESULT CProgressHelper::End()
234 m_cur_ticks = m_max_ticks;
236 return S_OK;
239 HRESULT CProgressHelper::QueryInterface( REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject )
241 if(riid == IID_IWMDMProgress || riid == IID_IUnknown)
243 *ppvObject = this;
244 return S_OK;
246 else
248 *ppvObject = NULL;
249 return E_NOINTERFACE;
253 ULONG CProgressHelper::AddRef()
255 return m_counter++;
257 ULONG CProgressHelper::Release()
259 return m_counter--;