MTP:
 * Add Win32 progress callback reporting support


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18355 a1c6a512-1295-4272-9138-f99709370657
diff --git a/utils/MTP/MTP_DLL.dll b/utils/MTP/MTP_DLL.dll
index 3f9b6c7..448dff4 100755
--- a/utils/MTP/MTP_DLL.dll
+++ b/utils/MTP/MTP_DLL.dll
Binary files differ
diff --git a/utils/MTP/MTP_DLL/MTP_DLL.cpp b/utils/MTP/MTP_DLL/MTP_DLL.cpp
index 8d8e250..ffd314a 100644
--- a/utils/MTP/MTP_DLL/MTP_DLL.cpp
+++ b/utils/MTP/MTP_DLL/MTP_DLL.cpp
@@ -12,7 +12,7 @@
 BOOL APIENTRY DllMain( HMODULE hModule,

                        DWORD  ul_reason_for_call,

                        LPVOID lpReserved

-					 )

+                     )

 {

     return TRUE;

 }

diff --git a/utils/MTP/MTP_DLL/MTP_DLL.h b/utils/MTP/MTP_DLL/MTP_DLL.h
index 4535283..ad99014 100644
--- a/utils/MTP/MTP_DLL/MTP_DLL.h
+++ b/utils/MTP/MTP_DLL/MTP_DLL.h
@@ -10,6 +10,8 @@
 #define MTP_DLL_API __declspec(dllimport)

 #endif

 

-extern "C" {

-__declspec(dllexport) bool send_fw(LPWSTR file, int filesize);

+extern "C"

+{

+__declspec(dllexport) bool send_fw(LPWSTR file, int filesize, void (*callback)(unsigned int progress, unsigned int max));

 }

+
diff --git a/utils/MTP/MTP_DLL/sendfirm_win.cpp b/utils/MTP/MTP_DLL/sendfirm_win.cpp
index e895c02..0861b34 100644
--- a/utils/MTP/MTP_DLL/sendfirm_win.cpp
+++ b/utils/MTP/MTP_DLL/sendfirm_win.cpp
@@ -11,6 +11,26 @@
 #include "sac.h"
 #include "scclient.h"
 
+class CProgressHelper : 
+    public IWMDMProgress
+{
+    void          (*m_callback)(unsigned int progress, unsigned int max);
+    DWORD          m_max_ticks;
+    DWORD          m_cur_ticks;
+    DWORD          m_counter;
+
+public:
+    CProgressHelper( void (*callback)(unsigned int progress, unsigned int max) );
+    ~CProgressHelper();
+    STDMETHOD(Begin)( DWORD dwEstimatedTicks );
+    STDMETHOD(Progress)( DWORD dwTranspiredTicks );
+    STDMETHOD(End)();
+
+    STDMETHOD(QueryInterface) ( REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject );
+    STDMETHOD_(ULONG, AddRef)( void );
+    STDMETHOD_(ULONG, Release)( void );
+};
+
 /*
  * Compilation requirements:
  *
@@ -21,74 +41,66 @@
  *
  */
 extern "C" {
-__declspec(dllexport) bool send_fw(LPWSTR file, int filesize)
+__declspec(dllexport) bool send_fw(LPWSTR file, int filesize, void (*callback)(unsigned int progress, unsigned int max))
 {
     bool return_value = false;
-	HRESULT hr;
-	IComponentAuthenticate* pICompAuth;
-	CSecureChannelClient *m_pSacClient = new CSecureChannelClient;
-	IWMDeviceManager3* m_pIdvMgr = NULL;
+    HRESULT hr;
+    IComponentAuthenticate* pICompAuth;
+    CSecureChannelClient *m_pSacClient = new CSecureChannelClient;
+    IWMDeviceManager3* m_pIdvMgr = NULL;
 
-	/* these are generic keys */
-	BYTE abPVK[] = {0x00};
-	BYTE abCert[] = {0x00};
+    /* these are generic keys */
+    BYTE abPVK[] = {0x00};
+    BYTE abCert[] = {0x00};
 
-	CoInitialize(NULL);
+    CoInitialize(NULL);
 
-	/* get an authentication interface */
-	hr = CoCreateInstance(CLSID_MediaDevMgr, NULL, CLSCTX_ALL ,IID_IComponentAuthenticate, (void **)&pICompAuth);
-	if SUCCEEDED(hr)
-	{
-		/* create a secure channel client certificate */
-		hr = m_pSacClient->SetCertificate(SAC_CERT_V1, (BYTE*) abCert, sizeof(abCert), (BYTE*) abPVK, sizeof(abPVK));
-		if SUCCEEDED(hr)
-		{
-			/* bind the authentication interface to the secure channel client */
-			m_pSacClient->SetInterface(pICompAuth);
+    /* get an authentication interface */
+    hr = CoCreateInstance(CLSID_MediaDevMgr, NULL, CLSCTX_ALL ,IID_IComponentAuthenticate, (void **)&pICompAuth);
+    if SUCCEEDED(hr)
+    {
+        /* create a secure channel client certificate */
+        hr = m_pSacClient->SetCertificate(SAC_CERT_V1, (BYTE*) abCert, sizeof(abCert), (BYTE*) abPVK, sizeof(abPVK));
+        if SUCCEEDED(hr)
+        {
+            /* bind the authentication interface to the secure channel client */
+            m_pSacClient->SetInterface(pICompAuth);
 
-			/* trigger communication */
-			hr = m_pSacClient->Authenticate(SAC_PROTOCOL_V1);                    
-			if SUCCEEDED(hr)
-			{
-				/* get main interface to media device manager */
-				hr = pICompAuth->QueryInterface(IID_IWMDeviceManager2, (void**)&m_pIdvMgr);
-				if SUCCEEDED(hr)
-				{
-					/* enumerate devices... */
-					IWMDMEnumDevice *pIEnumDev;
-					hr = m_pIdvMgr->EnumDevices2(&pIEnumDev);
-					if SUCCEEDED(hr)
+            /* trigger communication */
+            hr = m_pSacClient->Authenticate(SAC_PROTOCOL_V1);                    
+            if SUCCEEDED(hr)
+            {
+                /* get main interface to media device manager */
+                hr = pICompAuth->QueryInterface(IID_IWMDeviceManager2, (void**)&m_pIdvMgr);
+                if SUCCEEDED(hr)
+                {
+                    /* enumerate devices... */
+                    IWMDMEnumDevice *pIEnumDev;
+                    hr = m_pIdvMgr->EnumDevices2(&pIEnumDev);
+                    if SUCCEEDED(hr)
                     {
-						hr = pIEnumDev->Reset(); /* Next will now return the first device */
-						if SUCCEEDED(hr)
+                        hr = pIEnumDev->Reset(); /* Next will now return the first device */
+                        if SUCCEEDED(hr)
                         {
-							IWMDMDevice3* pIDevice;
-							unsigned long ulNumFetched;
-							hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
-							while (SUCCEEDED(hr) && (hr != S_FALSE))
+                            IWMDMDevice3* pIDevice;
+                            unsigned long ulNumFetched;
+                            hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
+                            while (SUCCEEDED(hr) && (hr != S_FALSE))
                             {
-#if 0
-								/* output device name */
-								wchar_t pwsString[256];
-								hr = pIDevice->GetName(pwsString, 256);
-								if SUCCEEDED(hr)
-									wprintf(L"Found device %s\n", pwsString);
-#endif
-
-								/* get storage info */
-								DWORD tempDW;
-								pIDevice->GetType(&tempDW);
-								if (tempDW & WMDM_DEVICE_TYPE_STORAGE)
+                                /* get storage info */
+                                DWORD tempDW;
+                                pIDevice->GetType(&tempDW);
+                                if (tempDW & WMDM_DEVICE_TYPE_STORAGE)
                                 {
-									IWMDMEnumStorage *pIEnumStorage = NULL;
-									IWMDMStorage *pIStorage = NULL;
-									IWMDMStorage3 *pIFileStorage = NULL; 
-									hr = pIDevice->EnumStorage(&pIEnumStorage);
-									if SUCCEEDED(hr)
+                                    IWMDMEnumStorage *pIEnumStorage = NULL;
+                                    IWMDMStorage *pIStorage = NULL;
+                                    IWMDMStorage3 *pIFileStorage = NULL; 
+                                    hr = pIDevice->EnumStorage(&pIEnumStorage);
+                                    if SUCCEEDED(hr)
                                     {
-										pIEnumStorage->Reset();
-										hr = pIEnumStorage->Next(1, (IWMDMStorage **)&pIStorage, &ulNumFetched);
-										while (SUCCEEDED(hr) && (hr != S_FALSE))
+                                        pIEnumStorage->Reset();
+                                        hr = pIEnumStorage->Next(1, (IWMDMStorage **)&pIStorage, &ulNumFetched);
+                                        while (SUCCEEDED(hr) && (hr != S_FALSE))
                                         {
                                             IWMDMStorage3 *pNewStorage;
                                             hr = pIStorage->QueryInterface(IID_IWMDMStorage3, (void **)&pNewStorage);
@@ -113,14 +125,15 @@
                                                         if (SUCCEEDED(hr))
                                                         {
                                                             IWMDMStorage *pNewObject = NULL;
+                                                            CProgressHelper *progress = new CProgressHelper(callback);
 
                                                             hr = pIWMDMStorageControl->Insert3(
-                                                                     WMDM_MODE_BLOCK | WMDM_CONTENT_FILE,
+                                                                     WMDM_MODE_BLOCK | WMDM_CONTENT_FILE | WMDM_MODE_PROGRESS,
                                                                      0,
                                                                      file,
                                                                      NULL,
                                                                      NULL,
-                                                                     NULL,
+                                                                     (callback == NULL ? NULL : (IWMDMProgress*)progress),
                                                                      pIWMDMMetaData,
                                                                      NULL,
                                                                      (IWMDMStorage **)&pNewObject);
@@ -135,27 +148,88 @@
                                                     }
                                                 }
                                             }
-										}
-									}
-									pIEnumStorage->Release();
-								}
+                                        }
+                                    }
+                                    pIEnumStorage->Release();
+                                }
 
-								/* move to next device */
-								if(!return_value)
-									hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
-							}
-							pIEnumDev->Release();
-						}
-						m_pIdvMgr->Release();
-					}
-					pICompAuth->Release();
-				}
-			}
-		}
-	}
+                                /* move to next device */
+                                if(!return_value)
+                                    hr = pIEnumDev->Next(1, (IWMDMDevice **)&pIDevice, &ulNumFetched);
+                            }
+                            pIEnumDev->Release();
+                        }
+                        m_pIdvMgr->Release();
+                    }
+                    pICompAuth->Release();
+                }
+            }
+        }
+    }
 
-	CoUninitialize();
+    CoUninitialize();
 
-	return return_value;
+    return return_value;
 }
 }
+
+
+CProgressHelper::CProgressHelper( void (*callback)(unsigned int progress, unsigned int max) )
+{
+    m_cur_ticks = 0;
+    m_max_ticks = 0;
+    m_counter = 0;
+
+    m_callback = callback;
+}
+
+CProgressHelper::~CProgressHelper()
+{
+}
+
+HRESULT CProgressHelper::Begin( DWORD dwEstimatedTicks )
+{
+    m_max_ticks = dwEstimatedTicks;
+
+    return S_OK;
+}
+
+HRESULT CProgressHelper::Progress( DWORD dwTranspiredTicks )
+{
+    m_cur_ticks = dwTranspiredTicks;
+
+    if(m_callback != NULL)
+        m_callback(m_cur_ticks, max(m_max_ticks, m_cur_ticks));
+
+    return S_OK;
+}
+
+HRESULT CProgressHelper::End()
+{
+    m_cur_ticks = m_max_ticks;
+
+    return S_OK;
+}
+
+HRESULT CProgressHelper::QueryInterface( REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject )
+{
+    if(riid == IID_IWMDMProgress || riid == IID_IUnknown)
+    {
+        *ppvObject = this;
+        return S_OK;
+    }
+    else
+    {
+        *ppvObject = NULL;
+        return E_NOINTERFACE;
+    }
+}
+
+ULONG CProgressHelper::AddRef()
+{
+    return m_counter++;
+}
+ULONG CProgressHelper::Release()
+{
+    return m_counter--;
+}
diff --git a/utils/MTP/MTP_DLL/stdafx.h b/utils/MTP/MTP_DLL/stdafx.h
index a13982c..1734058 100644
--- a/utils/MTP/MTP_DLL/stdafx.h
+++ b/utils/MTP/MTP_DLL/stdafx.h
@@ -7,23 +7,23 @@
 

 // Modify the following defines if you have to target a platform prior to the ones specified below.

 // Refer to MSDN for the latest info on corresponding values for different platforms.

-#ifndef WINVER				// Allow use of features specific to Windows XP or later.

-#define WINVER 0x0501		// Change this to the appropriate value to target other versions of Windows.

+#ifndef WINVER                // Allow use of features specific to Windows XP or later.

+#define WINVER 0x0501        // Change this to the appropriate value to target other versions of Windows.

 #endif

 

-#ifndef _WIN32_WINNT		// Allow use of features specific to Windows XP or later.                   

-#define _WIN32_WINNT 0x0501	// Change this to the appropriate value to target other versions of Windows.

-#endif						

+#ifndef _WIN32_WINNT        // Allow use of features specific to Windows XP or later.                   

+#define _WIN32_WINNT 0x0501    // Change this to the appropriate value to target other versions of Windows.

+#endif                        

 

-#ifndef _WIN32_WINDOWS		// Allow use of features specific to Windows 98 or later.

+#ifndef _WIN32_WINDOWS        // Allow use of features specific to Windows 98 or later.

 #define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.

 #endif

 

-#ifndef _WIN32_IE			// Allow use of features specific to IE 6.0 or later.

-#define _WIN32_IE 0x0600	// Change this to the appropriate value to target other versions of IE.

+#ifndef _WIN32_IE            // Allow use of features specific to IE 6.0 or later.

+#define _WIN32_IE 0x0600    // Change this to the appropriate value to target other versions of IE.

 #endif

 

-#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers

+#define WIN32_LEAN_AND_MEAN        // Exclude rarely-used stuff from Windows headers

 // Windows Header Files:

 #include <windows.h>

 

diff --git a/utils/MTP/sendfirm_win.c b/utils/MTP/sendfirm_win.c
index e605d47..c16a7ab 100644
--- a/utils/MTP/sendfirm_win.c
+++ b/utils/MTP/sendfirm_win.c
@@ -28,7 +28,7 @@
 #include <wchar.h>

 #include <stdbool.h>

 

-extern __declspec(dllimport) bool send_fw(LPWSTR file, int filesize);

+extern __declspec(dllimport) bool send_fw(LPWSTR file, int filesize, void (*callback)(unsigned int progress, unsigned int max));

 

 void usage(void)

 {

@@ -37,9 +37,9 @@
 

 int filesize(char* filename)

 {

-	FILE* fd;

+    FILE* fd;

     int tmp;

-	fd = fopen(filename, "r");

+    fd = fopen(filename, "r");

     if(fd == NULL)

     {

         fprintf(stderr, "Error while opening %s!\n", filename);

@@ -47,10 +47,17 @@
     }

     fseek(fd, 0, SEEK_END);

     tmp = ftell(fd);

-	fclose(fd);

+    fclose(fd);

     return tmp;

 }

 

+void callback(unsigned int progress, unsigned int max)

+{

+    unsigned int normalized = progress*1000/max;

+    printf("Progress: %d.%d%%\r", normalized/10, normalized%10);

+    fflush(stdout);

+}

+

 int main(int argc, char **argv)

 {

     if (argc < 2)

@@ -69,7 +76,7 @@
     

     fprintf(stdout, "Sending firmware...\n");

     

-    if(send_fw(tmp, filesize(argv[1])))

+    if(send_fw(tmp, filesize(argv[1]), &callback))

         fprintf(stdout, "Firmware sent successfully!\n");

     else

         fprintf(stdout, "Error occured during sending!\n");