@ -40,6 +40,8 @@
# include <cutils/fs.h>
# include <cutils/fs.h>
# include <cutils/log.h>
# include <cutils/log.h>
# include <string>
# include "Volume.h"
# include "Volume.h"
# include "VolumeManager.h"
# include "VolumeManager.h"
# include "ResponseCode.h"
# include "ResponseCode.h"
@ -80,6 +82,8 @@ const char *Volume::ASECDIR = "/mnt/asec";
*/
*/
const char * Volume : : LOOPDIR = " /mnt/obb " ;
const char * Volume : : LOOPDIR = " /mnt/obb " ;
const char * Volume : : BLKID_PATH = " /system/bin/blkid " ;
static const char * stateToStr ( int state ) {
static const char * stateToStr ( int state ) {
if ( state = = Volume : : State_Init )
if ( state = = Volume : : State_Init )
return " Initializing " ;
return " Initializing " ;
@ -109,6 +113,8 @@ Volume::Volume(VolumeManager *vm, const fstab_rec* rec, int flags) {
mVm = vm ;
mVm = vm ;
mDebug = false ;
mDebug = false ;
mLabel = strdup ( rec - > label ) ;
mLabel = strdup ( rec - > label ) ;
mUuid = NULL ;
mUserLabel = NULL ;
mState = Volume : : State_Init ;
mState = Volume : : State_Init ;
mFlags = flags ;
mFlags = flags ;
mCurrentlyMountedKdev = - 1 ;
mCurrentlyMountedKdev = - 1 ;
@ -118,25 +124,8 @@ Volume::Volume(VolumeManager *vm, const fstab_rec* rec, int flags) {
Volume : : ~ Volume ( ) {
Volume : : ~ Volume ( ) {
free ( mLabel ) ;
free ( mLabel ) ;
}
free ( mUuid ) ;
free ( mUserLabel ) ;
void Volume : : protectFromAutorunStupidity ( ) {
char filename [ 255 ] ;
snprintf ( filename , sizeof ( filename ) , " %s/autorun.inf " , getMountpoint ( ) ) ;
if ( ! access ( filename , F_OK ) ) {
SLOGW ( " Volume contains an autorun.inf! - removing " ) ;
/*
* Ensure the filename is all lower - case so
* the process killer can find the inode .
* Probably being paranoid here but meh .
*/
rename ( filename , filename ) ;
Process : : killProcessesWithOpenFiles ( filename , 2 ) ;
if ( unlink ( filename ) ) {
SLOGE ( " Failed to remove %s (%s) " , filename , strerror ( errno ) ) ;
}
}
}
}
void Volume : : setDebug ( bool enable ) {
void Volume : : setDebug ( bool enable ) {
@ -162,6 +151,46 @@ int Volume::handleBlockEvent(NetlinkEvent *evt) {
return - 1 ;
return - 1 ;
}
}
void Volume : : setUuid ( const char * uuid ) {
char msg [ 256 ] ;
if ( mUuid ) {
free ( mUuid ) ;
}
if ( uuid ) {
mUuid = strdup ( uuid ) ;
snprintf ( msg , sizeof ( msg ) , " %s %s \" %s \" " , getLabel ( ) ,
getFuseMountpoint ( ) , mUuid ) ;
} else {
mUuid = NULL ;
snprintf ( msg , sizeof ( msg ) , " %s %s " , getLabel ( ) , getFuseMountpoint ( ) ) ;
}
mVm - > getBroadcaster ( ) - > sendBroadcast ( ResponseCode : : VolumeUuidChange , msg ,
false ) ;
}
void Volume : : setUserLabel ( const char * userLabel ) {
char msg [ 256 ] ;
if ( mUserLabel ) {
free ( mUserLabel ) ;
}
if ( userLabel ) {
mUserLabel = strdup ( userLabel ) ;
snprintf ( msg , sizeof ( msg ) , " %s %s \" %s \" " , getLabel ( ) ,
getFuseMountpoint ( ) , mUserLabel ) ;
} else {
mUserLabel = NULL ;
snprintf ( msg , sizeof ( msg ) , " %s %s " , getLabel ( ) , getFuseMountpoint ( ) ) ;
}
mVm - > getBroadcaster ( ) - > sendBroadcast ( ResponseCode : : VolumeUserLabelChange ,
msg , false ) ;
}
void Volume : : setState ( int state ) {
void Volume : : setState ( int state ) {
char msg [ 255 ] ;
char msg [ 255 ] ;
int oldState = mState ;
int oldState = mState ;
@ -274,7 +303,6 @@ bool Volume::isMountpointMounted(const char *path) {
fclose ( fp ) ;
fclose ( fp ) ;
return true ;
return true ;
}
}
}
}
fclose ( fp ) ;
fclose ( fp ) ;
@ -413,7 +441,7 @@ int Volume::mountVol() {
continue ;
continue ;
}
}
protectFromAutorunStupidity( ) ;
extractMetadata( devicePath ) ;
if ( providesAsec & & mountAsecExternal ( ) ! = 0 ) {
if ( providesAsec & & mountAsecExternal ( ) ! = 0 ) {
SLOGE ( " Failed to mount secure area (%s) " , strerror ( errno ) ) ;
SLOGE ( " Failed to mount secure area (%s) " , strerror ( errno ) ) ;
@ -550,6 +578,8 @@ int Volume::unmountVol(bool force, bool revert) {
SLOGI ( " Encrypted volume %s reverted successfully " , getMountpoint ( ) ) ;
SLOGI ( " Encrypted volume %s reverted successfully " , getMountpoint ( ) ) ;
}
}
setUuid ( NULL ) ;
setUserLabel ( NULL ) ;
setState ( Volume : : State_Idle ) ;
setState ( Volume : : State_Idle ) ;
mCurrentlyMountedKdev = - 1 ;
mCurrentlyMountedKdev = - 1 ;
return 0 ;
return 0 ;
@ -608,3 +638,55 @@ int Volume::initializeMbr(const char *deviceNode) {
return rc ;
return rc ;
}
}
/*
* Use blkid to extract UUID and label from device , since it handles many
* obscure edge cases around partition types and formats . Always broadcasts
* updated metadata values .
*/
int Volume : : extractMetadata ( const char * devicePath ) {
int res = 0 ;
std : : string cmd ;
cmd = BLKID_PATH ;
cmd + = " -c /dev/null " ;
cmd + = devicePath ;
FILE * fp = popen ( cmd . c_str ( ) , " r " ) ;
if ( ! fp ) {
ALOGE ( " Failed to run %s: %s " , cmd . c_str ( ) , strerror ( errno ) ) ;
res = - 1 ;
goto done ;
}
char line [ 1024 ] ;
char value [ 128 ] ;
if ( fgets ( line , sizeof ( line ) , fp ) ! = NULL ) {
ALOGD ( " blkid reported: %s " , line ) ;
char * start = strstr ( line , " UUID= " ) + 5 ;
if ( sscanf ( start , " \" %127[^ \" ] \" " , value ) = = 1 ) {
setUuid ( value ) ;
} else {
setUuid ( NULL ) ;
}
start = strstr ( line , " LABEL= " ) + 6 ;
if ( sscanf ( start , " \" %127[^ \" ] \" " , value ) = = 1 ) {
setUserLabel ( value ) ;
} else {
setUserLabel ( NULL ) ;
}
} else {
res = - 1 ;
}
pclose ( fp ) ;
done :
if ( res = = - 1 ) {
setUuid ( NULL ) ;
setUserLabel ( NULL ) ;
}
return res ;
}