|
|
|
@ -40,6 +40,8 @@
|
|
|
|
|
#include <cutils/fs.h>
|
|
|
|
|
#include <cutils/log.h>
|
|
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
#include "Volume.h"
|
|
|
|
|
#include "VolumeManager.h"
|
|
|
|
|
#include "ResponseCode.h"
|
|
|
|
@ -80,6 +82,8 @@ const char *Volume::ASECDIR = "/mnt/asec";
|
|
|
|
|
*/
|
|
|
|
|
const char *Volume::LOOPDIR = "/mnt/obb";
|
|
|
|
|
|
|
|
|
|
const char *Volume::BLKID_PATH = "/system/bin/blkid";
|
|
|
|
|
|
|
|
|
|
static const char *stateToStr(int state) {
|
|
|
|
|
if (state == Volume::State_Init)
|
|
|
|
|
return "Initializing";
|
|
|
|
@ -109,6 +113,8 @@ Volume::Volume(VolumeManager *vm, const fstab_rec* rec, int flags) {
|
|
|
|
|
mVm = vm;
|
|
|
|
|
mDebug = false;
|
|
|
|
|
mLabel = strdup(rec->label);
|
|
|
|
|
mUuid = NULL;
|
|
|
|
|
mUserLabel = NULL;
|
|
|
|
|
mState = Volume::State_Init;
|
|
|
|
|
mFlags = flags;
|
|
|
|
|
mCurrentlyMountedKdev = -1;
|
|
|
|
@ -118,25 +124,8 @@ Volume::Volume(VolumeManager *vm, const fstab_rec* rec, int flags) {
|
|
|
|
|
|
|
|
|
|
Volume::~Volume() {
|
|
|
|
|
free(mLabel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
free(mUuid);
|
|
|
|
|
free(mUserLabel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Volume::setDebug(bool enable) {
|
|
|
|
@ -162,6 +151,46 @@ int Volume::handleBlockEvent(NetlinkEvent *evt) {
|
|
|
|
|
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) {
|
|
|
|
|
char msg[255];
|
|
|
|
|
int oldState = mState;
|
|
|
|
@ -274,7 +303,6 @@ bool Volume::isMountpointMounted(const char *path) {
|
|
|
|
|
fclose(fp);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fclose(fp);
|
|
|
|
@ -413,7 +441,7 @@ int Volume::mountVol() {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protectFromAutorunStupidity();
|
|
|
|
|
extractMetadata(devicePath);
|
|
|
|
|
|
|
|
|
|
if (providesAsec && mountAsecExternal() != 0) {
|
|
|
|
|
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());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setUuid(NULL);
|
|
|
|
|
setUserLabel(NULL);
|
|
|
|
|
setState(Volume::State_Idle);
|
|
|
|
|
mCurrentlyMountedKdev = -1;
|
|
|
|
|
return 0;
|
|
|
|
@ -608,3 +638,55 @@ int Volume::initializeMbr(const char *deviceNode) {
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|