rbutil: reworked device detection, now uses rockbox-info.txt and the patchers to detect the device.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13687 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Dominik Wenger 2007-06-22 18:53:27 +00:00
parent 00cc66c633
commit 69241529ff
4 changed files with 212 additions and 223 deletions

View file

@ -24,74 +24,139 @@
* General autodetection code * General autodetection code
****************************************************/ ****************************************************/
bool ipodpatcherDetect(UsbDeviceInfo* tempdevice)
UsbDeviceInfo detectDevicesViaPatchers()
{ {
UsbDeviceInfo tempdevice; /* use ipodpatcher for ipod detecting */
tempdevice.device_index= 0;
tempdevice.path=wxT("");
tempdevice.status =0;
/* scann for ipods */
struct ipod_t ipod; struct ipod_t ipod;
int n = ipod_scan(&ipod); int n = ipod_scan(&ipod);
if(n == 1) if(n == 1) /* we found an ipod */
{ {
wxString temp(ipod.targetname,wxConvUTF8); wxString temp(ipod.targetname,wxConvUTF8);
int index = gv->plat_bootloadername.Index(temp); // use the bootloader names.. int index = gv->plat_bootloadername.Index(temp); // use the bootloader names..
tempdevice.device_index = index; tempdevice->device_index = index;
tempdevice->status=DEVICEFOUND;
/* find mount point if possible */ /* find mount point if possible */
#if !(defined( __WXMSW__ ) || defined( __DARWIN__)) //linux code #if !(defined( __WXMSW__ ) || defined( __DARWIN__)) //linux code
wxString tmp = resolve_mount_point(wxString(ipod.diskname,wxConvUTF8)+wxT("2")); wxString tmp = resolve_mount_point(wxString(ipod.diskname,wxConvUTF8)+wxT("2"));
if( tmp != wxT("") ) if( tmp != wxT("") )
tempdevice.path = tmp; tempdevice->path = tmp;
#endif #endif
#if defined( __WXMSW__ ) //Windows code return true;
wxString tmp = guess_mount_point();
if( tmp != wxT("") )
tempdevice.path = tmp;
#endif
return tempdevice;
} }
else if (n > 1) else if (n > 1) /* to many ipods */
{ {
tempdevice.status = TOMANYDEVICES; tempdevice->status = TOMANYDEVICES;
return tempdevice; return true;
}
else /* no ipod */
{
return false;
} }
}
bool sansapatcherDetect(UsbDeviceInfo* tempdevice)
{
/* scann for sansas */ /* scann for sansas */
struct sansa_t sansa; struct sansa_t sansa;
int n2 = sansa_scan(&sansa); int n = sansa_scan(&sansa);
if(n2==1) if(n==1)
{ {
tempdevice.device_index = gv->plat_id.Index(wxT("sansae200")); tempdevice->device_index = gv->plat_id.Index(wxT("sansae200"));
tempdevice->status = DEVICEFOUND;
/* find mount point if possible */ /* find mount point if possible */
#if !(defined( __WXMSW__ ) || defined( __DARWIN__)) //linux code #if !(defined( __WXMSW__ ) || defined( __DARWIN__)) //linux code
wxString tmp = resolve_mount_point(wxString(ipod.diskname,wxConvUTF8)+wxT("1")); wxString tmp = resolve_mount_point(wxString(ipod.diskname,wxConvUTF8)+wxT("1"));
if( tmp != wxT("") ) if( tmp != wxT("") )
tempdevice.path = tmp; tempdevice->path = tmp;
#endif #endif
#if defined( __WXMSW__ ) // windows code return true;
wxString tmp = guess_mount_point();
if( tmp != wxT("") )
tempdevice.path = tmp;
#endif
return tempdevice;
} }
else if (n > 1) else if (n > 1)
{ {
tempdevice.status = TOMANYDEVICES; tempdevice->status = TOMANYDEVICES;
return tempdevice; return true;
}
else
{
return false;
}
} }
tempdevice.status = NODEVICE; bool rockboxinfoDetect(wxString filename,UsbDeviceInfo* tempdevice)
return tempdevice; {
wxTextFile rockboxinfo(filename);
rockboxinfo.Open();
wxString line = rockboxinfo.GetFirstLine();
wxString targetstring;
if(line.StartsWith(wxT("Target: "), &targetstring))
{
int index = gv->plat_id.Index(targetstring);
if(index < 0) return false;
tempdevice->device_index = index;
wxString myPath;
if(filename.EndsWith(wxT(".rockbox" PATH_SEP "rockbox-info.txt"),&myPath));
tempdevice->path = myPath;
tempdevice->status = DEVICEFOUND;
return true;
}
else
{
return false;
}
} }
bool detectDevices(UsbDeviceInfo* tempdevice)
{
tempdevice->device_index= 0;
tempdevice->path=wxT("");
tempdevice->status =NODEVICE;
/* try ipodpatcher */
if(ipodpatcherDetect(tempdevice))
{
return true;
}
/* try sansapatcher */
if(sansapatcherDetect(tempdevice))
{
return true;
}
/*try via files on the devices */
wxArrayString mountpoints = getPossibleMountPoints();
for(unsigned int i=0;i<mountpoints.GetCount();i++)
{
if(wxDir::Exists(mountpoints[i]))
{
/*check for rockbox-info.txt */
wxString filename;
filename.Printf("%s" PATH_SEP ".rockbox" PATH_SEP "rockbox-info.txt",mountpoints[i].c_str());
if(wxFile::Exists(filename))
{
if(rockboxinfoDetect(filename,tempdevice))
return true;
}
}
}
return false;
}
/*************************************************** /***************************************************
@ -99,103 +164,37 @@ UsbDeviceInfo detectDevicesViaPatchers()
****************************************************/ ****************************************************/
#if defined( __WXMSW__ ) #if defined( __WXMSW__ )
wxString guess_mount_point() wxArrayString getPossibleMountPoints()
{ {
wxString mountpoint = wxT(""); wxArrayString tempList;
TCHAR szDrvName[33]; tempList.Add(wxT("D:\\"));
DWORD maxDriveSet, curDriveSet; tempList.Add(wxT("E:\\"));
DWORD drive; tempList.Add(wxT("F:\\"));
TCHAR szBuf[300]; tempList.Add(wxT("G:\\"));
HANDLE hDevice; tempList.Add(wxT("H:\\"));
PSTORAGE_DEVICE_DESCRIPTOR pDevDesc; tempList.Add(wxT("I:\\"));
tempList.Add(wxT("J:\\"));
maxDriveSet = GetLogicalDrives(); tempList.Add(wxT("K:\\"));
curDriveSet = maxDriveSet; tempList.Add(wxT("L:\\"));
for ( drive = 0; drive < 32; ++drive ) tempList.Add(wxT("M:\\"));
{ tempList.Add(wxT("N:\\"));
if ( maxDriveSet & (1 << drive) ) tempList.Add(wxT("O:\\"));
{ tempList.Add(wxT("P:\\"));
DWORD temp = 1<<drive; tempList.Add(wxT("Q:\\"));
_stprintf( szDrvName, _T("%c:\\"), 'A'+drive ); tempList.Add(wxT("R:\\"));
switch ( GetDriveType( szDrvName ) ) tempList.Add(wxT("S:\\"));
{ tempList.Add(wxT("T:\\"));
case 0: // The drive type cannot be determined. tempList.Add(wxT("U:\\"));
case 1: // The root directory does not exist. tempList.Add(wxT("V:\\"));
case DRIVE_CDROM: // The drive is a CD-ROM drive. tempList.Add(wxT("W:\\"));
case DRIVE_REMOTE: // The drive is a remote (network) drive. tempList.Add(wxT("X:\\"));
case DRIVE_RAMDISK: // The drive is a RAM disk. tempList.Add(wxT("Y:\\"));
case DRIVE_REMOVABLE: // The drive can be removed from the drive. tempList.Add(wxT("Z:\\"));
break;
case DRIVE_FIXED: // The disk cannot be removed from the drive.
sprintf(szBuf, "\\\\?\\%c:", 'A'+drive);
hDevice = CreateFile(szBuf, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
if (hDevice != INVALID_HANDLE_VALUE)
{
pDevDesc = (PSTORAGE_DEVICE_DESCRIPTOR)new BYTE[sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1];
pDevDesc->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;
return tempList;
} }
/****************************************************************************
* 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 */ #endif /* windows code */
/********************************************************** /**********************************************************
@ -203,7 +202,22 @@ char chFirstDriveFromMask (ULONG unitmask)
*******************************************************/ *******************************************************/
#if !(defined( __WXMSW__ ) || defined( __DARWIN__)) #if !(defined( __WXMSW__ ) || defined( __DARWIN__))
wxArrayString getPossibleMountPoints()
{
wxArrayString tempList;
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 )
{
wxString directory = wxString( dir, wxConvUTF8 );
tempList.Add(directory);
free( dev );
free( dir );
}
fclose( fp );
}
wxString resolve_mount_point( const wxString device ) wxString resolve_mount_point( const wxString device )
{ {
@ -228,4 +242,31 @@ wxString resolve_mount_point( const wxString device )
#endif #endif /* linux code */
/**********************************************************
* MAC code for autodetection
*******************************************************/
#if defined( __DARWIN__)
wxArrayString getPossibleMountPoints()
{
wxArrayString tempList;
wxDir volumes;
if(volumes.Open(wxT("/Volumes")))
{
wxString filename;
bool cont = volumes.GetFirst(&filename, wxEmptyString, wxDIR_DIRS);
while ( cont )
{
tempList.Add(filename);
cont = dir.GetNext(&filename);
}
}
return tempList;
}
#endif /* Mac Code */

View file

@ -29,6 +29,7 @@
#define TOMANYDEVICES 2 #define TOMANYDEVICES 2
#define NODEVICE 1 #define NODEVICE 1
#define DEVICEFOUND 0
struct UsbDeviceInfo struct UsbDeviceInfo
{ {
@ -37,87 +38,24 @@ struct UsbDeviceInfo
int status; int status;
}; };
UsbDeviceInfo detectDevicesViaPatchers();
bool detectDevices(UsbDeviceInfo* tempdevice);
wxArrayString getPossibleMountPoints(); /* this funktion has to be implemented for every OS
/******************************** /********************************
* Windows code for USB Device detection and information * Windows header for USB Device detection and information
**************************************/ **************************************/
#if defined( __WXMSW__ ) #if defined( __WXMSW__ )
#include <dbt.h> // For DeviceChange.
#include <winioctl.h> // 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__ */ #endif /*__WXMSW__ */
/************************************************************************+ /************************************************************************+
*Linux code for autodetection *Linux header for autodetection
**************************************************************************/ **************************************************************************/
@ -131,6 +69,16 @@ wxString resolve_mount_point( const wxString device );
/************************************************************************+
*MAc header for autodetection
**************************************************************************/
#if defined( __DARWIN__)
#endif /* MAc Code */

View file

@ -93,6 +93,8 @@
</Linker> </Linker>
<Unit filename="Makefile" /> <Unit filename="Makefile" />
<Unit filename="archos.ico" /> <Unit filename="archos.ico" />
<Unit filename="autodetection.cpp" />
<Unit filename="autodetection.h" />
<Unit filename="bootloaders.cpp" /> <Unit filename="bootloaders.cpp" />
<Unit filename="bootloaders.h" /> <Unit filename="bootloaders.h" />
<Unit filename="copying.txt" /> <Unit filename="copying.txt" />

View file

@ -439,26 +439,12 @@ void DeviceSelectorCtrl::OnAutoDetect(wxCommandEvent& event)
void DeviceSelectorCtrl::AutoDetect() void DeviceSelectorCtrl::AutoDetect()
{ {
UsbDeviceInfo device;
if(detectDevices(&device))
UsbDeviceInfo device = detectDevicesViaPatchers();
if( device.status == NODEVICE)
{ {
WARN_DIALOG(wxT("No Device detected. (This function currently only works for Ipods and Sansas)."),
wxT("Detecting a Device"));
return;
}
if( device.status == TOMANYDEVICES) if(device.status == DEVICEFOUND)
{
WARN_DIALOG(wxT("More then one device detected, please connect only One"),
wxT("Detecting a Device"));
return;
}
if (device.status == 0 ) /* everything is ok */
{ {
m_deviceCbx->SetValue(gv->plat_name[device.device_index]); m_deviceCbx->SetValue(gv->plat_name[device.device_index]);
gv->curplat=gv->plat_id[device.device_index]; gv->curplat=gv->plat_id[device.device_index];
@ -467,7 +453,19 @@ void DeviceSelectorCtrl::AutoDetect()
{ {
gv->curdestdir = device.path; gv->curdestdir = device.path;
} }
}
else if(device.status == TOMANYDEVICES)
{
WARN_DIALOG(wxT("More then one device detected, please connect only One"),
wxT("Detecting a Device"));
return;
}
}
else
{
WARN_DIALOG(wxT("No Device detected. (This function only works if you have already installed rockbox or if you use a ipod or a sansa)."),
wxT("Detecting a Device"));
return;
} }
} }