Esempio n. 1
0
/**
 *	@brief	Opens a HANDLE to a Windows Blockdevice or File.
 *
 **/
HANDLE fnOpen(char *strDevName, int nBlockSize) {
	
	struct _DEV_INFO	*ptDevInfo;
	DISK_GEOMETRY_EX	DiskGeo;
	LARGE_INTEGER		li, address;

	BOOL				IOError;
	DWORD				BytesReturned;

	HANDLE				hDisk;
	WCHAR				pWide[MAX_PATH];

	MultiByteToWideChar(CP_ACP, 0, strDevName, -1, pWide, MAX_PATH);
	hDisk = CreateFile(pWide, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING , 0, NULL);

	IOError = GetLastError();

	if(hDisk != INVALID_HANDLE_VALUE) {

		// Dismount volume (allow Vista and Seven write access!)
		IOError = DeviceIoControl(hDisk, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &BytesReturned, NULL);

//		if(IOError) {	// Continue on error! This may be an image file!

			ptDevInfo				= (struct _DEV_INFO *) malloc(sizeof(struct _DEV_INFO));		
			if(GetDriveGeometry(&DiskGeo, hDisk)) {
				ptDevInfo->BlockSize	= DiskGeo.Geometry.BytesPerSector;
				ptDevInfo->DiskSize		= DiskGeo.DiskSize.QuadPart;
				ptDevInfo->hDev			= hDisk;
				ptDevInfo->AccessSem	= FF_CreateSemaphore();

				return (HANDLE) ptDevInfo;
			} else {
				GetFileSizeEx(hDisk, &li);
				address.QuadPart = 0;
				if(!nBlockSize) {
					ptDevInfo->BlockSize	= 512;	// Try to assume the most likely setting!
				} else {
					ptDevInfo->BlockSize	= nBlockSize;
				}
				ptDevInfo->DiskSize		= li.QuadPart;
				ptDevInfo->hDev			= hDisk;
				ptDevInfo->AccessSem	= FF_CreateSemaphore();
				return (HANDLE) ptDevInfo;
			}
		//}
	}

	return (HANDLE) NULL;
}
Esempio n. 2
0
HANDLE fnOpen(char *strDevName, int nBlockSize) {
	
	struct _DEV_INFO *ptDevInfo;
	DISK_GEOMETRY_EX DiskGeo;
	LARGE_INTEGER	li, address;

	HANDLE hDisk;

	hDisk = CreateFile(strDevName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING , 0, NULL);

	if(hDisk) {
		ptDevInfo				= (struct _DEV_INFO *) malloc(sizeof(struct _DEV_INFO));		
		if(GetDriveGeometry(&DiskGeo, hDisk)) {
			ptDevInfo->BlockSize	= DiskGeo.Geometry.BytesPerSector;
			ptDevInfo->DiskSize		= DiskGeo.DiskSize.QuadPart;
			ptDevInfo->hDev			= hDisk;
			ptDevInfo->AccessSem	= FF_CreateSemaphore();

			return (HANDLE) ptDevInfo;
		} else {
			//GetFileSizeEx(hDisk, &li);
			address.QuadPart = 0;
			if(!nBlockSize) {
				ptDevInfo->BlockSize	= 512;
			} else {
				ptDevInfo->BlockSize	= nBlockSize;
			}
			ptDevInfo->DiskSize		= li.QuadPart;
			ptDevInfo->hDev			= hDisk;
			ptDevInfo->AccessSem	= FF_CreateSemaphore();
			return (HANDLE) ptDevInfo;
		}
	}

	return (HANDLE) NULL;
}
Esempio n. 3
0
BLK_DEV_LINUX fnOpen(char *szDeviceName, int nBlockSize) {
	
	BLK_DEV_LINUX	ptDevInfo;

	FILE *pDevice;

	pDevice = fopen(szDeviceName, "rb+");

	if(pDevice) {
		ptDevInfo = (struct _DEV_INFO *) malloc(sizeof(struct _DEV_INFO));

		if(ptDevInfo) {
			ptDevInfo->BlockSize = nBlockSize;
			//ptDevInfo->DiskSize
			ptDevInfo->pDevice = pDevice;
			ptDevInfo->AccessSem = FF_CreateSemaphore();

			return (BLK_DEV_LINUX) ptDevInfo;
		}
	}

	return NULL;
}
Esempio n. 4
0
/**
 *	@public
 *	@brief	Creates an FF_IOMAN object, to initialise FullFAT
 *
 *	@param	pCacheMem		Pointer to a buffer for the cache. (NULL if ok to Malloc).
 *	@param	Size			The size of the provided buffer, or size of the cache to be created. (Must be atleast 2 * BlkSize). Always a multiple of BlkSize.
 *	@param	BlkSize			The block size of devices to be attached. If in doubt use 512.
 *	@param	pError			Pointer to a signed byte for error checking. Can be NULL if not required.
 *	@param	pError			To be checked when a NULL pointer is returned.
 *
 *	@return	Returns a pointer to an FF_IOMAN type object. NULL on Error, check the contents of
 *	@return pError
 **/
FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 BlkSize, FF_ERROR *pError) {

	FF_IOMAN	*pIoman = NULL;
	FF_T_UINT32 *pLong	= NULL;	// Force malloc to malloc memory on a 32-bit boundary.
#ifdef FF_PATH_CACHE
	FF_T_UINT32	i;
#endif

	if(pError) {
		*pError = FF_ERR_NONE;
	}

	if((BlkSize % 512) != 0 || BlkSize == 0) {
		if(pError) {
			*pError = FF_ERR_IOMAN_BAD_BLKSIZE | FF_CREATEIOMAN;
		}
		return NULL;	// BlkSize Size not a multiple of 512 > 0
	}

	if((Size % BlkSize) != 0 || Size == 0 || Size == BlkSize) {  // Size must now be atleast 2 * BlkSize (or a deadlock will occur).
		if(pError) {
			*pError = FF_ERR_IOMAN_BAD_MEMSIZE | FF_CREATEIOMAN;
		}
		return NULL;	// Memory Size not a multiple of BlkSize > 0
	}

	pIoman = (FF_IOMAN *) FF_MALLOC(sizeof(FF_IOMAN));

	if(!pIoman) {		// Ensure malloc() succeeded.
		if(pError) {
			*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
		}
		return NULL;
	}

	memset (pIoman, '\0', sizeof(FF_IOMAN));

	// This is just a bit-mask, to use a byte to keep track of memory.
	// pIoman->MemAllocation = 0x00;	// Unset all allocation identifiers.
	pIoman->pPartition	= (FF_PARTITION  *) FF_MALLOC(sizeof(FF_PARTITION));
	if(!pIoman->pPartition) {
		if(pError) {
			*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
		}
		FF_DestroyIOMAN(pIoman);
		return NULL;
	}
	memset (pIoman->pPartition, '\0', sizeof(FF_PARTITION));

	pIoman->MemAllocation |= FF_IOMAN_ALLOC_PART;	// If succeeded, flag that allocation.
	pIoman->pPartition->LastFreeCluster = 0;
	pIoman->pPartition->PartitionMounted = FF_FALSE;	// This should be checked by FF_Open();
#ifdef FF_PATH_CACHE
	pIoman->pPartition->PCIndex = 0;
	for(i = 0; i < FF_PATH_CACHE_DEPTH; i++) {
		pIoman->pPartition->PathCache[i].DirCluster = 0;
		pIoman->pPartition->PathCache[i].Path[0] = '\0';
/*#ifdef FF_HASH_TABLE_SUPPORT
		pIoman->pPartition->PathCache[i].pHashTable = FF_CreateHashTable();
		pIoman->pPartition->PathCache[i].bHashed = FF_FALSE;
#endif*/
	}
#endif

#ifdef FF_HASH_CACHE
	for(i = 0; i < FF_HASH_CACHE_DEPTH; i++) {
		pIoman->HashCache[i].pHashTable 	= FF_CreateHashTable();
		pIoman->HashCache[i].ulDirCluster 	= 0;
		pIoman->HashCache[i].ulMisses		= 100;
	}
#endif

	pIoman->pBlkDevice	= (FF_BLK_DEVICE *) FF_MALLOC(sizeof(FF_BLK_DEVICE));
	if(!pIoman->pBlkDevice) {	// If succeeded, flag that allocation.
		if(pError) {
			*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
		}
		FF_DestroyIOMAN(pIoman);
		return NULL;
	}
	memset (pIoman->pBlkDevice, '\0', sizeof(FF_BLK_DEVICE));
	pIoman->MemAllocation |= FF_IOMAN_ALLOC_BLKDEV;

	// Make sure all pointers are NULL
	pIoman->pBlkDevice->fnpReadBlocks = NULL;
	pIoman->pBlkDevice->fnpWriteBlocks = NULL;
	pIoman->pBlkDevice->pParam = NULL;

	// Organise the memory provided, or create our own!
	if(pCacheMem) {
		pIoman->pCacheMem = pCacheMem;
	}else {	// No-Cache buffer provided (malloc)
		pLong = (FF_T_UINT32 *) FF_MALLOC(Size);
		pIoman->pCacheMem = (FF_T_UINT8 *) pLong;
		if(!pIoman->pCacheMem) {
			if(pError) {
				*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
			}
			FF_DestroyIOMAN(pIoman);
			return NULL;
		}
		pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFFERS;

	}
	memset (pIoman->pCacheMem, '\0', Size);

	pIoman->BlkSize		 = BlkSize;
	pIoman->CacheSize	 = (FF_T_UINT16) (Size / BlkSize);
	pIoman->FirstFile	 = NULL;
	pIoman->Locks		 = 0;

	/*	Malloc() memory for buffer objects. (FullFAT never refers to a buffer directly
		but uses buffer objects instead. Allows us to provide thread safety.
	*/
	pIoman->pBuffers = (FF_BUFFER *) FF_MALLOC(sizeof(FF_BUFFER) * pIoman->CacheSize);

	if(!pIoman->pBuffers) {
		if(pError) {
			*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
		}
		FF_DestroyIOMAN(pIoman);
		return NULL;	// HT added
	}
	memset (pIoman->pBuffers, '\0', sizeof(FF_BUFFER) * pIoman->CacheSize);

	pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFDESCR;
	FF_IOMAN_InitBufferDescriptors(pIoman);

	// Finally create a Semaphore for Buffer Description modifications.
	pIoman->pSemaphore = FF_CreateSemaphore();

#ifdef FF_BLKDEV_USES_SEM
	pIoman->pBlkDevSemaphore = FF_CreateSemaphore();
#endif

	return pIoman;	// Sucess, return the created object.
}