From 994e1a778f1a3a62b94347985108dd80cb07084f Mon Sep 17 00:00:00 2001 From: domonoky Date: Sun, 17 Jun 2007 20:15:18 +0000 Subject: [PATCH] rbutil: Add quessing of the Drive letter via Windows API, also restructuring for future Device detection via pid and vid. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13655 a1c6a512-1295-4272-9138-f99709370657 --- rbutil/autodetection.cpp | 231 +++++++++++++++++++++++++++++++++++++++++++++++ rbutil/autodetection.h | 142 +++++++++++++++++++++++++++++ rbutil/rbutilCtrls.cpp | 81 +++++------------ rbutil/rbutilFrm.cpp | 17 ++-- 4 files changed, 401 insertions(+), 70 deletions(-) create mode 100644 rbutil/autodetection.cpp create mode 100644 rbutil/autodetection.h diff --git a/rbutil/autodetection.cpp b/rbutil/autodetection.cpp new file mode 100644 index 000000000..1d85d961b --- /dev/null +++ b/rbutil/autodetection.cpp @@ -0,0 +1,231 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * Module: rbutil + * File: autodetection.cpp + * + * Copyright (C) 2008 Dominik Wenger + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "autodetection.h" +#include "bootloaders.h" +/*************************************************** +* General autodetection code +****************************************************/ + + +UsbDeviceInfo detectDevicesViaPatchers() +{ + UsbDeviceInfo tempdevice; + tempdevice.device_index= 0; + tempdevice.path=wxT(""); + tempdevice.status =0; + + /* scann for ipods */ + + struct ipod_t ipod; + int n = ipod_scan(&ipod); + if(n == 1) + { + wxString temp(ipod.targetname,wxConvUTF8); + int index = gv->plat_bootloadername.Index(temp); // use the bootloader names.. + tempdevice.device_index = index; + /* find mount point if possible */ +#if !(defined( __WXMSW__ ) || defined( __DARWIN__)) //linux code + wxString tmp = resolve_mount_point(wxString(ipod.diskname,wxConvUTF8)+wxT("2")); + if( tmp != wxT("") ) + tempdevice.path = tmp; +#endif +#if defined( __WXMSW__ ) //Windows code + wxString tmp = guess_mount_point(); + if( tmp != wxT("") ) + tempdevice.path = tmp; +#endif + return tempdevice; + } + else if (n > 1) + { + tempdevice.status = TOMANYDEVICES; + return tempdevice; + } + + /* scann for sansas */ + struct sansa_t sansa; + int n2 = sansa_scan(&sansa); + if(n2==1) + { + tempdevice.device_index = gv->plat_id.Index(wxT("sansae200")); + /* find mount point if possible */ +#if !(defined( __WXMSW__ ) || defined( __DARWIN__)) //linux code + wxString tmp = resolve_mount_point(wxString(ipod.diskname,wxConvUTF8)+wxT("1")); + if( tmp != wxT("") ) + tempdevice.path = tmp; +#endif +#if defined( __WXMSW__ ) // windows code + wxString tmp = guess_mount_point(); + if( tmp != wxT("") ) + tempdevice.path = tmp; +#endif + return tempdevice; + } + else if (n > 1) + { + tempdevice.status = TOMANYDEVICES; + return tempdevice; + } + + + tempdevice.status = NODEVICE; + return tempdevice; + +} + + + + +/*************************************************** +* Windows code for autodetection +****************************************************/ +#if defined( __WXMSW__ ) + +wxString guess_mount_point() +{ + wxString mountpoint = wxT(""); + TCHAR szDrvName[33]; + DWORD maxDriveSet, curDriveSet; + DWORD drive; + TCHAR szBuf[300]; + HANDLE hDevice; + PSTORAGE_DEVICE_DESCRIPTOR pDevDesc; + + maxDriveSet = GetLogicalDrives(); + curDriveSet = maxDriveSet; + for ( drive = 0; drive < 32; ++drive ) + { + if ( maxDriveSet & (1 << drive) ) + { + DWORD temp = 1<Size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1; + + if(GetDisksProperty(hDevice, pDevDesc)) + { + if(pDevDesc->BusType == BusTypeUsb) + { + mountpoint.Printf(wxT("%c:\\"), chFirstDriveFromMask(temp)); + } + } + delete pDevDesc; + CloseHandle(hDevice); + } + break; + } + } + } + return mountpoint; + +} + + + +/**************************************************************************** +* FUNCTION: GetDisksProperty(HANDLE hDevice, PSTORAGE_DEVICE_DESCRIPTOR pDevDesc) +* PURPOSE: get the info of specified device +*****************************************************************************/ +BOOL GetDisksProperty(HANDLE hDevice, PSTORAGE_DEVICE_DESCRIPTOR pDevDesc) +{ + STORAGE_PROPERTY_QUERY Query; // input param for query + DWORD dwOutBytes; // IOCTL output length + BOOL bResult; // IOCTL return val + + // specify the query type + Query.PropertyId = StorageDeviceProperty; + Query.QueryType = PropertyStandardQuery; + + // Query using IOCTL_STORAGE_QUERY_PROPERTY + bResult = ::DeviceIoControl(hDevice, // device handle + IOCTL_STORAGE_QUERY_PROPERTY, // info of device property + &Query, sizeof(STORAGE_PROPERTY_QUERY), // input data buffer + pDevDesc, pDevDesc->Size, // output data buffer + &dwOutBytes, // out's length + (LPOVERLAPPED)NULL); + + return bResult; +} + +/********************************************* +* Converts the driveMask to a drive letter +*******************************************/ +char chFirstDriveFromMask (ULONG unitmask) +{ + + char i; + for (i = 0; i < 26; ++i) + { + if (unitmask & 0x1) + break; + unitmask = unitmask >> 1; + } + return (i + 'A'); +} +#endif /* windows code */ + +/********************************************************** +* Linux code for autodetection +*******************************************************/ +#if !(defined( __WXMSW__ ) || defined( __DARWIN__)) + + + +wxString resolve_mount_point( const wxString device ) +{ + FILE *fp = fopen( "/proc/mounts", "r" ); + if( !fp ) return wxT(""); + char *dev, *dir; + while( fscanf( fp, "%as %as %*s %*s %*s %*s", &dev, &dir ) != EOF ) + { + if( wxString( dev, wxConvUTF8 ) == device ) + { + wxString directory = wxString( dir, wxConvUTF8 ); + free( dev ); + free( dir ); + return directory; + } + free( dev ); + free( dir ); + } + fclose( fp ); + return wxT(""); +} + + + +#endif diff --git a/rbutil/autodetection.h b/rbutil/autodetection.h new file mode 100644 index 000000000..dc2d7d249 --- /dev/null +++ b/rbutil/autodetection.h @@ -0,0 +1,142 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * Module: rbutil + * File: autodetection.h + * + * Copyright (C) 2008 Dominik Wenger + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef AUTODETECTION_H_INCLUDED +#define AUTODETECTION_H_INCLUDED + + +/************************************** +* General code for USB Device detection +***************************************/ +#include "rbutil.h" + +#define TOMANYDEVICES 2 +#define NODEVICE 1 + +struct UsbDeviceInfo +{ + int device_index; + wxString path; + int status; +}; + +UsbDeviceInfo detectDevicesViaPatchers(); + + +/******************************** +* Windows code for USB Device detection and information +**************************************/ + +#if defined( __WXMSW__ ) + +#include // For DeviceChange. +#include // For DeviceIOCtl. + +// IOCTL control code +#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS) + +//// The following structures all can find at MSDN. +// enumeration type specifies the various types of storage buses +typedef enum _STORAGE_BUS_TYPE { + BusTypeUnknown = 0x00, + BusTypeScsi, + BusTypeAtapi, + BusTypeAta, + BusType1394, + BusTypeSsa, + BusTypeFibre, + BusTypeUsb, + BusTypeRAID, + BusTypeMaxReserved = 0x7F +} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE; +// retrieve the storage device descriptor data for a device. +typedef struct _STORAGE_DEVICE_DESCRIPTOR { + ULONG Version; + ULONG Size; + UCHAR DeviceType; + UCHAR DeviceTypeModifier; + BOOLEAN RemovableMedia; + BOOLEAN CommandQueueing; + ULONG VendorIdOffset; + ULONG ProductIdOffset; + ULONG ProductRevisionOffset; + ULONG SerialNumberOffset; + STORAGE_BUS_TYPE BusType; + ULONG RawPropertiesLength; + UCHAR RawDeviceProperties[1]; + +} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR; +// retrieve the properties of a storage device or adapter. +typedef enum _STORAGE_QUERY_TYPE { + PropertyStandardQuery = 0, + PropertyExistsQuery, + PropertyMaskQuery, + PropertyQueryMaxDefined + +} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE; + +// retrieve the properties of a storage device or adapter. +typedef enum _STORAGE_PROPERTY_ID { + StorageDeviceProperty = 0, + StorageAdapterProperty, + StorageDeviceIdProperty + +} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID; +// retrieve the properties of a storage device or adapter. +typedef struct _STORAGE_PROPERTY_QUERY { + STORAGE_PROPERTY_ID PropertyId; + STORAGE_QUERY_TYPE QueryType; + UCHAR AdditionalParameters[1]; + +} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY; + + +wxString guess_mount_point(); + +BOOL GetDisksProperty(HANDLE hDevice, PSTORAGE_DEVICE_DESCRIPTOR pDevDesc); +char chFirstDriveFromMask (ULONG unitmask); + +#endif /*__WXMSW__ */ + + +/************************************************************************+ +*Linux code for autodetection +**************************************************************************/ + + +#if !(defined( __WXMSW__ ) || defined( __DARWIN__)) + +wxString resolve_mount_point( const wxString device ); + + +#endif /* Linux Code */ + + + + + + + + + + + + +#endif diff --git a/rbutil/rbutilCtrls.cpp b/rbutil/rbutilCtrls.cpp index 1e80e7bea..887f2e7fb 100644 --- a/rbutil/rbutilCtrls.cpp +++ b/rbutil/rbutilCtrls.cpp @@ -1,6 +1,7 @@ #include "rbutilCtrls.h" #include "bootloaders.h" +#include "autodetection.h" ///////////////////////////////////////////////////////////// //// Controls @@ -435,79 +436,39 @@ void DeviceSelectorCtrl::OnAutoDetect(wxCommandEvent& event) AutoDetect(); } -#if !(defined( __WXMSW__ ) || defined( __DARWIN__)) -wxString resolve_mount_point( const wxString device ) -{ - FILE *fp = fopen( "/proc/mounts", "r" ); - if( !fp ) return wxT(""); - char *dev, *dir; - while( fscanf( fp, "%as %as %*s %*s %*s %*s", &dev, &dir ) != EOF ) - { - if( wxString( dev, wxConvUTF8 ) == device ) - { - wxString directory = wxString( dir, wxConvUTF8 ); - free( dev ); - free( dir ); - return directory; - } - free( dev ); - free( dir ); - } - fclose( fp ); - return wxT(""); -} -#endif void DeviceSelectorCtrl::AutoDetect() { - struct ipod_t ipod; - int n = ipod_scan(&ipod); - if(n == 1) - { - wxString temp(ipod.targetname,wxConvUTF8); - int index = gv->plat_bootloadername.Index(temp); // use the bootloader names.. - m_deviceCbx->SetValue(gv->plat_name[index]); - gv->curplat=gv->plat_id[index]; - -#if !(defined( __WXMSW__ ) || defined( __DARWIN__)) - wxString tmp = resolve_mount_point(wxString(ipod.diskname,wxConvUTF8)+wxT("2")); - if( tmp != wxT("") ) - gv->curdestdir = tmp; -#endif - return; - } - else if (n > 1) + + + UsbDeviceInfo device = detectDevicesViaPatchers(); + + if( device.status == NODEVICE) { - WARN_DIALOG(wxT("More then one Ipod device detected, please connect only One"), + WARN_DIALOG(wxT("No Device detected. (This function currently only works for Ipods and Sansas)."), wxT("Detecting a Device")); return; } - struct sansa_t sansa; - int n2 = sansa_scan(&sansa); - if(n2==1) + if( device.status == TOMANYDEVICES) { - int index = gv->plat_id.Index(wxT("sansae200")); - m_deviceCbx->SetValue(gv->plat_name[index]); - gv->curplat=gv->plat_id[index]; - -#if !(defined( __WXMSW__ ) || defined( __DARWIN__)) - wxString tmp = resolve_mount_point(wxString(sansa.diskname,wxConvUTF8)+wxT("1")); - if( tmp != wxT("") ) - gv->curdestdir = tmp; -#endif - return; - } - else if (n2 > 1) - { - WARN_DIALOG(wxT("More then one Sansa device detected, please connect only One"), + WARN_DIALOG(wxT("More then one device detected, please connect only One"), wxT("Detecting a Device")); return; + } - WARN_DIALOG(wxT("No Device detected. (This function currently only works for Ipods and Sansas)."), - wxT("Detecting a Device")); - return; + if (device.status == 0 ) /* everything is ok */ + { + m_deviceCbx->SetValue(gv->plat_name[device.device_index]); + gv->curplat=gv->plat_id[device.device_index]; + + if(device.path != wxT("")) + { + gv->curdestdir = device.path; + } + + } } diff --git a/rbutil/rbutilFrm.cpp b/rbutil/rbutilFrm.cpp index cd68ec86a..0dc85c09b 100644 --- a/rbutil/rbutilFrm.cpp +++ b/rbutil/rbutilFrm.cpp @@ -96,8 +96,6 @@ void rbutilFrm::CreateGUIControls(void) myDeviceSelector->setDefault(); WxBoxSizer0->Add(myDeviceSelector,0,wxGROW|wxALL,5); - - wxNotebook* tabwindow = new wxNotebook(mainPanel,wxID_ANY); WxBoxSizer0->Add(tabwindow,1,wxGROW|wxALL,5); @@ -130,7 +128,7 @@ void rbutilFrm::CreateGUIControls(void) wxBitmap BootloaderInstallButton (tools2_3d_xpm); WxBitmapButton4 = new wxBitmapButton(installpage, ID_BOOTLOADER_BTN, BootloaderInstallButton, wxPoint(0,0), wxSize(64,54), - wxRAISED_BORDER | wxBU_AUTODRAW); + wxRAISED_BORDER | wxBU_AUTODRAW, wxDefaultValidator,wxT("Bootloader Installation")); WxBitmapButton4->SetToolTip(wxT("Click here to install the Rockbox bootloader")); WxFlexGridSizer1->Add(WxBitmapButton4, 0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxALL,5); @@ -147,7 +145,7 @@ void rbutilFrm::CreateGUIControls(void) WxBitmapButton1 = new wxBitmapButton(installpage, ID_INSTALL_BTN, WxBitmapButton1_BITMAP, wxPoint(0,0), wxSize(64,54), wxRAISED_BORDER | wxBU_AUTODRAW, wxDefaultValidator, - wxT("WxBitmapButton1")); + wxT("Rockbox Installation")); WxBitmapButton1->SetToolTip(wxT("Click here to install Rockbox")); WxFlexGridSizer1->Add(WxBitmapButton1,0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxALL,5); @@ -177,7 +175,7 @@ void rbutilFrm::CreateGUIControls(void) wxBitmap FontInstallButton (fonts_3d_xpm); WxBitmapButton3 = new wxBitmapButton(themepage, ID_FONT_BTN, FontInstallButton, wxPoint(0,0), wxSize(64,54), - wxRAISED_BORDER | wxBU_AUTODRAW); + wxRAISED_BORDER | wxBU_AUTODRAW,wxDefaultValidator, wxT("Font installation")); WxBitmapButton3->SetToolTip(wxT("Click here to install the most up to date " "Rockbox fonts.")); WxFlexGridSizer2->Add(WxBitmapButton3, 0, @@ -194,7 +192,7 @@ void rbutilFrm::CreateGUIControls(void) wxBitmap ThemesInstallButton (themes_3d_xpm); WxBitmapButton5 = new wxBitmapButton(themepage, ID_THEMES_BTN, ThemesInstallButton, wxPoint(0,0), wxSize(64,54), - wxRAISED_BORDER | wxBU_AUTODRAW); + wxRAISED_BORDER | wxBU_AUTODRAW,wxDefaultValidator, wxT("Theme installation")); WxBitmapButton5->SetToolTip(wxT("Click here to install themes for Rockbox.")); WxFlexGridSizer2->Add(WxBitmapButton5, 0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxALL,5); @@ -208,7 +206,7 @@ void rbutilFrm::CreateGUIControls(void) wxBitmap DoomInstallButton (doom_3d_xpm); WxBitmapButton6 = new wxBitmapButton(themepage, ID_DOOM_BTN, DoomInstallButton, wxPoint(0,0), wxSize(64,54), - wxRAISED_BORDER | wxBU_AUTODRAW); + wxRAISED_BORDER | wxBU_AUTODRAW,wxDefaultValidator, wxT("Freedoom installation")); WxBitmapButton6->SetToolTip(wxT("Click here to install the freedoom wad files.")); WxFlexGridSizer2->Add(WxBitmapButton6, 0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxALL,5); @@ -238,8 +236,7 @@ void rbutilFrm::CreateGUIControls(void) wxBitmap WxBitmapButton2_BITMAP (uninstall_3d_xpm); WxBitmapButton2 = new wxBitmapButton(uninstallpage, ID_REMOVE_BTN, WxBitmapButton2_BITMAP, wxPoint(0,0), wxSize(64,54), - wxRAISED_BORDER | wxBU_AUTODRAW, wxDefaultValidator, - wxT("WxBitmapButton2")); + wxRAISED_BORDER | wxBU_AUTODRAW,wxDefaultValidator, wxT("Rockbox uninstallation")); WxBitmapButton2->SetToolTip(wxT("Click here to uninstall Rockbox")); WxFlexGridSizer3->Add(WxBitmapButton2,0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxALL,5); @@ -253,7 +250,7 @@ void rbutilFrm::CreateGUIControls(void) WxBitmapButton4 = new wxBitmapButton(uninstallpage, ID_BOOTLOADERREMOVE_BTN, WxBitmapButton4_BITMAP, wxPoint(0,0), wxSize(64,54), wxRAISED_BORDER | wxBU_AUTODRAW, wxDefaultValidator, - wxT("WxBitmapButton4")); + wxT("Bootloader uninstallation")); WxBitmapButton4->SetToolTip(wxT("Click here to uninstall the Bootloader")); WxFlexGridSizer3->Add(WxBitmapButton4,0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxALL,5); -- 2.11.4.GIT