Esempio n. 1
0
/** Destructor, free all memory used by the vqa. */
VQAMovie::~VQAMovie()
{
    delete[] CBF_LookUp;
    delete[] CBP_LookUp;
    delete[] VPT_Table;
    delete[] offsets;
    VFS_Close(vqafile);
}
Esempio n. 2
0
/**
 * \fn void Ext2_Unmount(tVFS_Node *Node)
 * \brief Close a mounted device
 */
void Ext2_Unmount(tVFS_Node *Node)
{
	tExt2_Disk	*disk = Node->ImplPtr;
	
	VFS_Close( disk->FD );
	Inode_ClearCache( disk->CacheID );
	memset(disk, 0, sizeof(tExt2_Disk)+disk->GroupCount*sizeof(tExt2_Group));
	free(disk);
}
Esempio n. 3
0
File: dir.c Progetto: berkus/acess2
/**
 * \fn int VFS_Symlink(const char *Name, const char *Link)
 * \brief Creates a symlink called \a Name to \a Link
 * \param Name	Name of symbolic link
 * \param Link	Destination of symbolic link
 */
int VFS_Symlink(const char *Name, const char *Link)
{
	char	*realLink;
	 int	fp;
	
	ENTER("sName sLink", Name, Link);
	
	// Get absolue path name
	realLink = VFS_GetAbsPath( Link );
	if(!realLink) {
		Log_Warning("VFS", "Path '%s' is badly formed", Link);
		errno = EINVAL;
		LEAVE('i', -1);
		return -1;
	}

	LOG("realLink = '%s'", realLink);

	// Make node
	if( VFS_MkNod(Name, VFS_FFLAG_SYMLINK) != 0 ) {
		Log_Warning("VFS", "Unable to create link node '%s'", Name);
		free(realLink);
		// errno is set by VFS_MkNod
		LEAVE('i', -2);
		return -2;	// Make link node
	}
	
	// Write link address
	fp = VFS_Open(Name, VFS_OPENFLAG_WRITE|VFS_OPENFLAG_NOLINK);
	if( fp == -1 ) {
		Log_Warning("VFS", "Unable to open newly created symlink '%s'", Name);
		free(realLink);
		LEAVE('i', -3);
		return -3;
	}
	VFS_Write(fp, strlen(realLink), realLink);
	VFS_Close(fp);
	
	free(realLink);
	
	LEAVE('i', 1);
	return 1;
}
Esempio n. 4
0
/**
 * \brief Mount a device
 * \param Device	Device string to mount
 * \param MountPoint	Destination for the mount
 * \param Filesystem	Filesystem to use for the mount
 * \param Options		Options to be passed to the filesystem
 * \return -1 on Invalid FS, -2 on No Mem, 0 on success
 * 
 * Mounts the filesystem on \a Device at \a MountPoint using the driver
 * \a Filesystem. The options in the string \a Options is passed to the
 * driver's mount.
 */
int VFS_Mount(const char *Device, const char *MountPoint, const char *Filesystem, const char *Options)
{
	tVFS_Mount	*mnt, *parent_mnt;
	tVFS_Driver	*fs;
	 int	deviceLen = strlen(Device);
	 int	mountLen = strlen(MountPoint);
	 int	argLen = strlen(Options);
	
	// Get the filesystem
	if( Filesystem && Filesystem[0] )
	{
		fs = VFS_GetFSByName(Filesystem);
		if(!fs) {
			Log_Warning("VFS", "VFS_Mount - Unknown FS Type '%s'", Filesystem);
			return -ENOENT;
		}
	}
	else
	{
		int fd = VFS_Open(Device, VFS_OPENFLAG_READ);
		if( fd == -1 ) {
			Log_Warning("VFS", "VFS_Mount - Unable to open '%s' for autodetect", Device);
			return -ENOENT;
		}
		
		tVFS_Driver	*bestfs = NULL;
		 int	bestrank = 0, rank;
		for( fs = gVFS_Drivers; fs; fs = fs->Next )
		{
			if(!fs->Detect)	continue ;
			rank = fs->Detect(fd);
			if(!rank)	continue ;
			if(!bestfs || rank > bestrank) {
				bestfs = fs;
				bestrank = rank;
			}
		}
		VFS_Close(fd);
		if( bestfs == NULL ) {
			Log_Warning("VFS", "VFS_Mount - Filesystem autodetection failed");
			return -1;
		}
		
		fs = bestfs;
	}
	
	// Validate the mountpoint target
	// - Only if / is mounted
	if( gVFS_Mounts )
	{
		tVFS_Node *mpnode = VFS_ParsePath(MountPoint, NULL, &parent_mnt);
		if( !mpnode ) {
			Log_Warning("VFS", "VFS_Mount - Mountpoint '%s' does not exist", MountPoint);
			return -1;
		}
		if( mpnode->Type->Close )
			mpnode->Type->Close(mpnode);
		if( parent_mnt->RootNode == mpnode ) {
			Log_Warning("VFS", "VFS_Mount - Attempt to mount over '%s' (%s)",
				MountPoint, parent_mnt->MountPoint);
			return -1;
		}
	}
	
	// Create mount information
	mnt = malloc( sizeof(tVFS_Mount)+deviceLen+1+mountLen+1+argLen+1 );
	if(!mnt) {
		ASSERT(parent_mnt->OpenHandleCount > 0);
		parent_mnt->OpenHandleCount --;
		return -2;
	}

	// HACK: Forces VFS_ParsePath to fall back on root  
	if(mountLen == 1 && MountPoint[0] == '/')
		mnt->MountPointLen = 0;
	else
		mnt->MountPointLen = mountLen;
	
	// Fill Structure
	mnt->Filesystem = fs;
	mnt->OpenHandleCount = 0;
	
	mnt->Device = &mnt->StrData[0];
	memcpy( mnt->Device, Device, deviceLen+1 );
	
	mnt->MountPoint = &mnt->StrData[deviceLen+1];
	memcpy( mnt->MountPoint, MountPoint, mountLen+1 );
	
	mnt->Options = &mnt->StrData[deviceLen+1+mountLen+1];
	memcpy( mnt->Options, Options, argLen+1 );
	
	// Parse options string
	char	*str = mnt->Options;
	 int	nArg = 0;
	do {
		nArg ++;
	} while( (str = strchr(str, ',')) );

	char	*args[nArg + 1];
	str = mnt->Options;
	nArg = 0;
	do {
		args[nArg++] = str;
		str = strchr(str, ',');
		if(str)	*str = '\0';
	} while( str );
	args[nArg] = 0;	// NULL terminal
	
	// Initialise Volume
	mnt->RootNode = fs->InitDevice(Device, (const char **)args);
	if(!mnt->RootNode) {
		free(mnt);
		ASSERT(parent_mnt->OpenHandleCount>0);
		parent_mnt->OpenHandleCount --;
		return -2;
	}

	// Repair the options string
	while( nArg -- > 1 )
		args[nArg][-1] = ',';

	mnt->Identifier = giVFS_NextMountIdent++;
	#if 0
	// Ensure identifiers don't repeat
	// - Only a problem if there have been 4 billion mounts
	while( giVFS_NextMountIdent == 0 || VFS_GetMountByIdent(giVFS_NextMountIdent) )
		giVFS_NextMountIdent ++;
	#endif
	
	// Set root
	if(!gVFS_RootMount)	gVFS_RootMount = mnt;
	
	// Add to mount list
	RWLock_AcquireWrite( &glVFS_MountList );
	{
		mnt->Next = NULL;
		if(gVFS_Mounts) {
			tVFS_Mount	*tmp;
			for( tmp = gVFS_Mounts; tmp->Next; tmp = tmp->Next );
			tmp->Next = mnt;
		}
		else {
			gVFS_Mounts = mnt;
		}
	}
	RWLock_Release( &glVFS_MountList );
	
	Log_Log("VFS", "Mounted '%s' to '%s' ('%s')", Device, MountPoint, fs->Name);
	
	VFS_UpdateMountFile();
	
	return 0;
}
Esempio n. 5
0
/**
 \brief Initializes a device to be read by by the driver
 \param Device	String - Device to read from
 \param Options	NULL Terminated array of option strings
 \return Root Node
*/
tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options)
{
	tExt2_Disk	*disk = NULL;
	 int	fd;
	 int	groupCount;
	tExt2_SuperBlock	sb;
	
	ENTER("sDevice pOptions", Device, Options);
	
	// Open Disk
	fd = VFS_Open(Device, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE);		//Open Device
	if(fd == -1) {
		Log_Warning("EXT2", "Unable to open '%s'", Device);
		LEAVE('n');
		return NULL;
	}
	
	// Read Superblock at offset 1024
	VFS_ReadAt(fd, 1024, 1024, &sb);	// Read Superblock
	
	// Sanity Check Magic value
	if(sb.s_magic != 0xEF53) {
		Log_Warning("EXT2", "Volume '%s' is not an EXT2 volume (0x%x != 0xEF53)",
			Device, sb.s_magic);
		goto _error;
	}

	if( sb.s_blocks_per_group < MIN_BLOCKS_PER_GROUP ) {
		Log_Warning("Ext2", "Blocks per group is too small (%i < %i)",
			sb.s_blocks_per_group, MIN_BLOCKS_PER_GROUP);
		goto _error;
	}	

	// Get Group count
	groupCount = DivUp(sb.s_blocks_count, sb.s_blocks_per_group);
	LOG("groupCount = %i", groupCount);
	
	// Allocate Disk Information
	disk = malloc(sizeof(tExt2_Disk) + sizeof(tExt2_Group)*groupCount);
	if(!disk) {
		Log_Warning("EXT2", "Unable to allocate disk structure");
		goto _error;
	}
	disk->FD = fd;
	memcpy(&disk->SuperBlock, &sb, 1024);
	disk->GroupCount = groupCount;
	
	// Get an inode cache handle
	disk->CacheID = Inode_GetHandle(NULL);
	
	// Get Block Size
	if( sb.s_log_block_size > MAX_BLOCK_LOG_SIZE ) {
		Log_Warning("Ext2", "Block size (log2) too large (%i > %i)",
			sb.s_log_block_size, MAX_BLOCK_LOG_SIZE);
		goto _error;
	}
	disk->BlockSize = 1024 << sb.s_log_block_size;
	LOG("Disk->BlockSie = 0x%x (1024 << %i)", disk->BlockSize, sb.s_log_block_size);
	
	// Read Group Information
	LOG("sb,s_first_data_block = %x", sb.s_first_data_block);
	VFS_ReadAt(
		disk->FD,
		sb.s_first_data_block * disk->BlockSize + 1024,
		sizeof(tExt2_Group)*groupCount,
		disk->Groups
		);
	
	LOG("Block Group 0");
	LOG(".bg_block_bitmap = 0x%x", disk->Groups[0].bg_block_bitmap);
	LOG(".bg_inode_bitmap = 0x%x", disk->Groups[0].bg_inode_bitmap);
	LOG(".bg_inode_table = 0x%x", disk->Groups[0].bg_inode_table);
	LOG("Block Group 1");
	LOG(".bg_block_bitmap = 0x%x", disk->Groups[1].bg_block_bitmap);
	LOG(".bg_inode_bitmap = 0x%x", disk->Groups[1].bg_inode_bitmap);
	LOG(".bg_inode_table = 0x%x", disk->Groups[1].bg_inode_table);
	
	// Get root Inode
	Ext2_int_ReadInode(disk, 2, &disk->RootInode);
	
	// Create Root Node
	memset(&disk->RootNode, 0, sizeof(tVFS_Node));
	disk->RootNode.Inode = 2;	// Root inode ID
	disk->RootNode.ImplPtr = disk;	// Save disk pointer
	disk->RootNode.Size = -1;	// Fill in later (on readdir)
	disk->RootNode.Flags = VFS_FFLAG_DIRECTORY;

	disk->RootNode.Type = &gExt2_DirType;
	
	// Complete root node
	disk->RootNode.UID = disk->RootInode.i_uid;
	disk->RootNode.GID = disk->RootInode.i_gid;
	disk->RootNode.NumACLs = 1;
	disk->RootNode.ACLs = &gVFS_ACL_EveryoneRW;
	
	#if DEBUG
	LOG("inode.i_size = 0x%x", disk->RootInode.i_size);
	LOG("inode.i_block[0] = 0x%x", disk->RootInode.i_block[0]);
	#endif
	
	LEAVE('p', &disk->RootNode);
	return &disk->RootNode;
_error:
	if( disk )
		free(disk);
	VFS_Close(fd);
	LEAVE('n');
	return NULL;
}