Exemple #1
0
void* loadFile(char *filename){
	DirLayout *dir = searchFile(filename);
	UCHAR *start = kmalloc(dir->size);	//コピー先確保
	UCHAR *seek = start;
	int cl_num = dir->head_cluster;
	int limit = dir->size / CLUSTER_SIZE + (dir->size % CLUSTER_SIZE==0?0:1);
	int cnt=1;
	
	if(start == 0)return 0;//mallocできなかった

	while(cl_num != 0xfff){
		if(cnt==INF)return 0;//FATがうまく読めてない
		
		//最後のあまりをコピー
		if(cnt==limit){
			kmemcpy(seek,getClusterAdd(cl_num),dir->size%CLUSTER_SIZE);
			break;
		}
		
		kmemcpy(seek,getClusterAdd(cl_num),CLUSTER_SIZE);
		
		cl_num = getNextCluster(cl_num);
		seek += CLUSTER_SIZE;
		
		cnt++;
	}
/*
	if(filename[0]=='l' && filename[1]=='i'){
		asm volatile("cli");
		asm volatile("mov %0,%%eax"::"r"((int)dir):"eax");
		for(;;)asm volatile("hlt");
	}
*/	
	return start;
}
Exemple #2
0
void  FileBox::getClusterChain(){
  unsigned long int *chain, link, length= 1;

  chain= (unsigned long int*)malloc(sizeof(unsigned long int) * length);
  chain[0]= 0x0FFFFFFF;
  SerialUSB.println(startCluster, DEC); while(3.14);
  link= getNextCluster(startCluster);
  while(link != 0x0FFFFFFF){
    chain[length - 1]= link;
    length++;
    chain= (unsigned long int*)realloc(chain, sizeof(unsigned long int) * length);
    link= getNextCluster(link);
  }

  chainLength= length;
  clusterChain= chain;
}
Exemple #3
0
void FileBox::addLink(){
  unsigned long int freeQ= 0;
  unsigned long int clusterQ= clusterChain[chainLength - 1] + 4;
  freeQ= getNextCluster(clusterQ);
  freeQ &= 0x0FFFFFFF;

  while(freeQ != 0){}
}
Exemple #4
0
/*
 * This function sets the size attribute of a specified directory entry.
 * currentDirCluster is the first cluster of the current directory.
 * targetEntry is the entry to be updated.
 * newBytes is the number of bytes to set as the total size.
 */
void setFileSize(FILE *fileImgPtr, unsigned int currentDirCluster,
                unsigned char *targetEntry, int newSize) {

  unsigned char entry[32];
  unsigned int nextCluster;

  // Break the file's size into 4 characters.
  unsigned char sizeA = (newSize & 0xFF000000) >> 24;
  unsigned char sizeB = (newSize & 0x00FF0000) >> 16;
  unsigned char sizeC = (newSize & 0x0000FF00) >> 8;
  unsigned char sizeD = (newSize & 0x000000FF);

  nextCluster = currentDirCluster;

  // Loop until the end of cluster chain is reached or the entry is found.
  do {
    // Seek to the cluster's first sector.
    fseek(fileImgPtr, (getSector(nextCluster) * fsMetadata[BYTES_PER_SECTOR]),
          SEEK_SET);

    // Loop once for each directory entry that can fit in the sector.
    for(int i = 0; i < 16; ++i) {
      // Read in a directory entry.
      for(int j = 0; j < 32; ++j) {
        entry[j] = getc(fileImgPtr);
      }

      // If the entry is a long name entry, do not add it.
      if((entry[11] | 0xF0) == 0xFF)
        continue;
      // If the entry is empty, do not add it.
      if(entry[0] == 0xE5)
        continue;
      // If the entry is free, and is the last entry, end the entire function.
      if(entry[0] == 0x00)
        return;

      // Compare the directory entries. If they have the same first cluster
      // numbers, they are the same entry.
      if(targetEntry[20] == entry[20] && targetEntry[21] == entry[21] &&
        targetEntry[26] == entry[26] && targetEntry[27] == entry[27]) {
        // This is the entry whose size we want to update.
        // Move the file pointer back 4 bytes and write the new size.
        fseek(fileImgPtr, -4, SEEK_CUR);
        putc(sizeD, fileImgPtr);
        putc(sizeC, fileImgPtr);
        putc(sizeB, fileImgPtr);
        putc(sizeA, fileImgPtr);

        return;
      }
    }

    // If next cluster not EOC, set next cluster to next cluster in chain.
    nextCluster = getNextCluster(fileImgPtr, nextCluster);
  } while(nextCluster < EOCMIN);
}
Exemple #5
0
//指定アドレスにファイルをロード
void* loadFileToMem(void *add,char *filename){
	DirLayout *dir = searchFile(filename);
	UCHAR *start = add;	//コピー先確保
	UCHAR *seek = start;
	int cl_num = dir->head_cluster;
	int limit = dir->size / CLUSTER_SIZE + (dir->size % CLUSTER_SIZE==0?0:1);
	int cnt=1;
	if(start == 0)return 0;//mallocできなかった

	while(cl_num != 0xfff){
		if(cnt==INF)return 0;//FATがうまく読めてない
		
		//最後のあまりをコピー
		if(cnt==limit){
			kmemcpy(seek,getClusterAdd(cl_num),dir->size%CLUSTER_SIZE);
			break;
		}
		kmemcpy(seek,getClusterAdd(cl_num),CLUSTER_SIZE);
		cl_num = getNextCluster(cl_num);
		seek += CLUSTER_SIZE;
		cnt++;
	}
	return start;
}
Exemple #6
0
/**
 * Creates a file (creates the directory entry for a file) for optimized write.
 * After this function returns successfully, it should be possible to do optimized
 * writes on the file starting at the beginning.
 * No checks are done against duplicate file name, and no clusters are allocated.
 * File space is allocated during write operations.
 *
 * @param[in] fs Filesystem structure.
 * @param[in] dir Directory structure.
 * @param[out] fileOpt Output optimized file structure.
 * @param[in] name File name, up to 8 characters.
 * @param[in] ext File extension, up to 3 characters.
 * @retval 1 Success
 * @retval -1 Error creating file
 * @retval -2 SD Card Error
 * @retval -128 General error
 */
int8_t FAT32_CreateFileOpt(FAT32FS *fs, FAT32Directory *dir, FAT32FileOpt *file, char *name, char *ext) {
	uint32_t currentCluster = dir->directoryTableAvailableCluster;
	fs_addr_t currentLBA = dir->directoryTableAvailableLBA;
	uint8_t clusterOffset = dir->directoryTableAvailableClusterOffset;	// block number within the cluster

	fs_length_t iii = 0;

	DBG_DATA_printf("Starting cluster = 0x%08lx", currentCluster);

	// Search for an empty file
	while (1) {
		if (BLOCK_SIZE != SD_SPI_ReadSingleBlock(fs->card, currentLBA, file->directoryTableBlockData)) {
			DBG_printf("Error creating file (SD Read error on LBA = 0x%08lx).", currentLBA);
			return -2;			// Sanity check: Not reading the correct number of bytes
		}
		DBG_DATA_printf("Read Directory Table LBA = 0x%08lx", currentLBA)

		// Search Directory Table for desired entry
		for (iii = 0; iii < fs->bytesPerSector; iii += 32) {
			DBG_SPAM_printf("Searching record '%8.8s.%3.3s'.", file->directoryTableBlockData + iii, file->directoryTableBlockData + iii + 8);

			if (file->directoryTableBlockData[iii] == 0x00 || file->directoryTableBlockData[iii] == 0xe5) {	// Available entry
				DBG_printf("Available entry found.");

				// Update directory structure with new end
				dir->directoryTableAvailableCluster = currentCluster;
				dir->directoryTableAvailableClusterOffset = clusterOffset;
				dir->directoryTableAvailableLBA = currentLBA;

				FATCreateDirectoryTableEntry(file->directoryTableBlockData+iii, name, ext);

				// Fill out file structure

				strncpy((char *) file->name, (char*)file->directoryTableBlockData+iii, 8);
				strncpy((char *) file->ext, (char*)file->directoryTableBlockData+iii+8, 3);

				file->fs = fs;

				file->directoryTableLBA = currentLBA;
				file->directoryTableBlockOffset = iii;
				file->directoryTableDirty = 0;

				file->startCluster = 0;
				file->size = 0;

				file->previousFATBlockData = file->previousFATData;
				file->currentFATBlockData = file->currentFATData;

				file->previousFATBlockOffset = 0;
				file->previousFATDirty = 0;
				file->previousFileSize = 0;

				file->currentCluster = 0;
				file->currentLBA = 0;
				file->position = 0;

				file->currentOperation = FILE_OP_None;
				file->nextOperation = FILE_OP_WritingDataIdle;

				file->dataBuffer[0] = SD_DMA_GetBuffer(0);
				if (file->dataBuffer[0] == NULL) {
					DBG_ERR_printf("Error allocating DMA buffer 0");
					return -128;
				}
				file->dataBuffer[1] = SD_DMA_GetBuffer(1);
				if (file->dataBuffer[1] == NULL) {
					DBG_ERR_printf("Error allocating DMA buffer 1");
					return -128;
				}
				file->fsBuffer = SD_DMA_GetBuffer(2);
				if (file->fs == NULL) {
					DBG_ERR_printf("Error allocating DMA FS buffer");
					return -128;
				}
				file->dataBufferWrite = 0;
				file->dataBufferFill = 0;
				file->dataBufferNumFilled = 0;
				file->dataBufferPos = 0;

				file->overflowBufferBegin = 0;
				file->overflowBufferEnd = 0;
				file->overflowBufferSize = 0;

				FAT32_InitializeFileFAT(file);

				SD_SPI_WriteSingleBlock(fs->card, file->directoryTableLBA, file->directoryTableBlockData);
				file->directoryTableDirty = 0;

				SD_SPI_WriteSingleBlock(fs->card, file->currentFATLBA, file->currentFATBlockData);
				file->currentFATAllocated = 0;

				FAT32_FillFSInformationSector(file);
				SD_SPI_WriteSingleBlock(fs->card, fs->FS_info_LBA, file->fsBuffer);
				file->fs->fsInfoDirty = 0;


				return 1;
			}
		}

		// Advance to next block
		clusterOffset++;
		if (clusterOffset >= fs->sectorsPerCluster) {	// End of cluster
			currentCluster = getNextCluster(fs, currentCluster);
			DBG_DATA_printf("Next cluster = 0x%08lx", currentCluster);
			// Sanity check: ensure Directory Table cluster is valid
			if (currentCluster >= 0xF0000000) {
				DBG_printf("Error creating file (searched past end of Directory Table Cluster).");
				return -1;
			}
			currentLBA = GetClusterLBA(fs, currentCluster);
			clusterOffset = 0;
		} else {	// Advance to next block within cluster
			currentLBA++;
		}
	}
}
Exemple #7
0
void listfiles(struct BootEntry* b,char* diskpath,char* lpath)
{
	//find the sector num of root directory
	unsigned int rootcluster =  b->BPB_RootClus;	
	unsigned int rootsectornum = b->BPB_RsvdSecCnt + b->BPB_NumFATs * b->BPB_FATSz32 + rootcluster -2;
	unsigned int rootaddress = rootsectornum * b->BPB_BytsPerSec;		
	//Now you know the address, first read directory Entries
	//Here, i represents layer. 
	int i=1;
	unsigned int currentcluster =rootcluster;
		
	//we need address for the starting point of the folder
	unsigned int address = rootaddress;
	unsigned int current_address;
	//start with root
	current_address = lseek(devicefd, rootaddress, SEEK_SET);
	//find the directory
 	while(tokens[i-1][0]!='\0'){
		//assume you have reached layer i-1. Start with layer 0, i.e. root
		//so, try to match tokens[i-1] in the directory tokens[i-2]. Or -1 as root.  
		strcat(tokens[i-1],"/");
		while(1)
		{
			struct DirEntry *entry = malloc(sizeof(struct DirEntry));
			//read the device entry and advance.	
			read(devicefd, entry, sizeof(struct DirEntry));
			current_address = lseek(devicefd, 0,SEEK_CUR); 
			if(current_address>(cluster_to_address(currentcluster+1)))
			{
				//look for next cluster. go to fat table.
				currentcluster = getNextCluster(currentcluster);
				read(devicefd, entry, sizeof(struct DirEntry));	
			}
			//check if it is LNF
			while(entry->DIR_Attr == 0x0f)
			{
				read(devicefd, entry, sizeof(struct DirEntry));
				if(current_address>cluster_to_address(currentcluster+1))
				{
					currentcluster = getNextCluster(currentcluster);
					read(devicefd, entry, sizeof(struct DirEntry));
				//look for next cluster. go to fat table.
				}
			}
			//check if it is directory
			if(entry->DIR_Attr != 0x10)
			{
				free(entry);
				continue;
			}
			//now, time to test name!
			char *name = getName(entry->DIR_Name,entry->DIR_Attr);	
			//check if you got it
			if(strcmp(name,tokens[i-1])==0)
			{ 
				//got it. Now, seek to that place
				currentcluster = get_cluster_from_directory_entry(entry);	
				current_address = cluster_to_address(currentcluster);
				lseek(devicefd,current_address,SEEK_SET);  
				free(entry);
				free(name);
				break;
			}
			free(entry);
			free(name);
		}
		//in root, find that one
// 		printf("tokens[%d]: %s\n",i-1,tokens[i-1]);	

		i++;

 	}	
		//Now you have found the place to start searching
		int count = 1;
 		while(1)
 		{	
			//allocate new directory entry
			struct DirEntry *entry = malloc(sizeof(struct DirEntry));
			//read the device entry and advance.	
			read(devicefd, entry, sizeof(struct DirEntry));
			current_address = lseek(devicefd, 0,SEEK_CUR); 
			if(current_address>(cluster_to_address(currentcluster+1)))
			{
				//look for next cluster. go to fat table.
				currentcluster = getNextCluster(currentcluster);
				if(currentcluster == -1)	
					exit(EXIT_SUCCESS);
				read(devicefd, entry, sizeof(struct DirEntry));	
			}
			if(entry->DIR_Attr == 0x00)
			{
				break;
			}
			//check if it is LNF
			while(entry->DIR_Attr == 0x0f)
			{
				read(devicefd, entry, sizeof(struct DirEntry));
				if(current_address>cluster_to_address(currentcluster+1))
				{
					currentcluster = getNextCluster(currentcluster);
					if(currentcluster == -1)
						exit(EXIT_SUCCESS);
					read(devicefd, entry, sizeof(struct DirEntry));
				//look for next cluster. go to fat table.
				}
			}
			//now, we reach the normal portion
			//here, a is the address of cluster 
			//starting cluster num
			long unsigned int starting_cluster = get_cluster_from_directory_entry(entry); 		
			char *name = getName(entry->DIR_Name,entry->DIR_Attr);	
			//order, name, file size, starting cluster
			printf("%d, %s, %lu, %ld\n", count, name, entry->DIR_FileSize, starting_cluster);
			count++;
			//lseek(devicefd, 32, SEEK_CUR);
			free(name);
			free(entry);

 		}
		close(devicefd);

	

}
Exemple #8
0
void recoverfiles(char* r_targetpath,char* o_outputpath,struct BootEntry* b)
{
	//find the sector num of root directory
	unsigned long filesize = -1;
	unsigned int rootcluster =  b->BPB_RootClus;	
	unsigned int rootsectornum = b->BPB_RsvdSecCnt + b->BPB_NumFATs * b->BPB_FATSz32 + rootcluster -2;
	unsigned int rootaddress = rootsectornum * b->BPB_BytsPerSec;		
	//Now you know the address, first read directory Entries
	//Here, i represents layer. 
	int i=1;
	unsigned int currentcluster =rootcluster;
	//we need address for the starting point of the folder
	unsigned int address = rootaddress;
	unsigned int current_address;
	//start with root
	current_address = lseek(devicefd, rootaddress, SEEK_SET);
	//find the directory
	//use i, but not i-1. Assures find the one before file
 	while(rtokens[i][0]!='\0')
	{
		//assume you have reached layer i-1. Start with layer 0, i.e. root
		//so, try to match tokens[i-1] in the directory tokens[i-2]. Or -1 as root.  
		strcat(rtokens[i-1],"/");
		while(1)
		{
			struct DirEntry *entry = malloc(sizeof(struct DirEntry));
			//read the device entry and advance.	
			read(devicefd, entry, sizeof(struct DirEntry));
			current_address = lseek(devicefd, 0,SEEK_CUR); 
			if(current_address>(cluster_to_address(currentcluster+1)))
			{
				//look for next cluster. go to fat table.
				currentcluster = getNextCluster(currentcluster);
				read(devicefd, entry, sizeof(struct DirEntry));	
			}
			//check if it is LNF
			while(entry->DIR_Attr == 0x0f)
			{
				read(devicefd, entry, sizeof(struct DirEntry));
				if(current_address>cluster_to_address(currentcluster+1))
				{
					currentcluster = getNextCluster(currentcluster);
					read(devicefd, entry, sizeof(struct DirEntry));
				//look for next cluster. go to fat table.
				}
			}
			//check if it is directory
			if(entry->DIR_Attr != 0x10)
			{
				free(entry);
				continue;
			}
			//now, time to test name!
			char *name = getName(entry->DIR_Name,entry->DIR_Attr);	
			//check if you got it. 
			if(strcmp(name,rtokens[i-1])==0)
			{ 
				//got it. Now, seek to that place
				currentcluster = get_cluster_from_directory_entry(entry);	
				current_address = cluster_to_address(currentcluster);
				lseek(devicefd,current_address,SEEK_SET);  
				free(entry);
				free(name);
				break;
			}
			free(entry);
			free(name);
		}
		//in root, find that one
		i++;
 	}	
	//Now, you have reached the directory set containing the file. Search in this directory to get the file.	
	char copy_of_file[1024];
	strcpy(copy_of_file, rtokens[i-1]);
	copy_of_file[0] = '?';
	int emptyflag = 0;
	//printf("%s\n",rtokens[i-1]);
	while(1)
	{
		struct DirEntry *entry = malloc(sizeof(struct DirEntry));
		//read the device entry and advance.	
		read(devicefd, entry, sizeof(struct DirEntry));
		current_address = lseek(devicefd, 0,SEEK_CUR); 
		if(current_address>(cluster_to_address(currentcluster+1)))
		{
			//look for next cluster. go to fat table.
			currentcluster = getNextCluster(currentcluster);
			
			if(currentcluster == -1)
			{
				printf("%s: error - file not found\n",rtokens[i-1]);
				exit(EXIT_FAILURE);
			}
			read(devicefd, entry, sizeof(struct DirEntry));	
		}
		//check if it is LNF
		while(entry->DIR_Attr == 0x0f)
		{
			read(devicefd, entry, sizeof(struct DirEntry));
			if(current_address>cluster_to_address(currentcluster+1))
			{
				currentcluster = getNextCluster(currentcluster);
				if(currentcluster == -1)
				{
					printf("%s: error - file not found\n",rtokens[i-1]);
					exit(EXIT_FAILURE);
				}
				read(devicefd, entry, sizeof(struct DirEntry));
			//look for next cluster. go to fat table.
			}
		}
		//check if it is directory. If yes, skip it. We want file.
		if(entry->DIR_Attr == 0x10)
		{
			free(entry);
			continue;
		}
		//now, time to test name!
		char *name = getName(entry->DIR_Name,entry->DIR_Attr);	
		//check if you got it. 
		if(strcmp(name,copy_of_file)==0)
		{ 
			//got it. Now, seek to that place
			currentcluster = get_cluster_from_directory_entry(entry);	
			current_address = cluster_to_address(currentcluster);
			//check if file is empty
			if((currentcluster!=0)&&(checkCurrentCluster(currentcluster)!=0))
			{
				printf("%s: error - fail to recover\n",rtokens[i-1]);	
				exit(EXIT_FAILURE);
			}
			if(currentcluster == 0)
			{
				emptyflag = 1;
			}
			printf("%s: recovered\n",rtokens[i-1]);
			filesize = entry->DIR_FileSize;
			printf("file size:%lu\n",filesize);
			lseek(devicefd,current_address,SEEK_SET);  
			free(entry);
			free(name);
			break;
		}
		free(entry);
		free(name);
	}
	//Now, you are at the file cluster. Do recovery!
	FILE *out =NULL;
	char buf[filesize];
	//if not able to open
	if(!(out=fopen(o_outputpath,"w+")))
	{
		printf("%s: failed to open\n",rtokens[i-1]);
		exit(EXIT_FAILURE);
	}
	//Copy the Content to the file
	//write one by one	
	read(devicefd, buf,filesize);
	fwrite(buf,1,filesize,out);
	fclose(out);
	exit(EXIT_SUCCESS);	
}