int cp_cmd(int argc, char **argv, FF_ENVIRONMENT *pEnv) { FF_IOMAN *pIoman = pEnv->pIoman; FF_FILE *fSource, *fDest; FF_ERROR Error; FF_T_INT8 path[FF_MAX_PATH]; FF_T_UINT8 copybuf[COPY_BUFFER_SIZE]; FF_T_SINT32 BytesRead; //LARGE_INTEGER ticksPerSecond; //LARGE_INTEGER start_ticks, end_ticks, cputime; float transferRate = 0; //QueryPerformanceFrequency(&ticksPerSecond); if(argc == 3) { if(strstr(argv[1], "*") || strstr(argv[2], "*")) { return wildcopy(argc, argv, pEnv); } ProcessPath(path, argv[1], pEnv); fSource = FF_Open(pIoman, path, FF_MODE_READ, &Error); if(fSource) { ProcessPath(path, argv[2], pEnv); fDest = FF_Open(pIoman, path, FF_GetModeBits("w"), &Error); if(fDest) { // Do the copy //QueryPerformanceCounter(&start_ticks); //QueryPerformanceCounter(&end_ticks); do{ BytesRead = FF_Read(fSource, COPY_BUFFER_SIZE, 1, (FF_T_UINT8 *)copybuf); FF_Write(fDest, BytesRead, 1, (FF_T_UINT8 *) copybuf); //QueryPerformanceCounter(&end_ticks); //cputime.QuadPart = end_ticks.QuadPart - start_ticks.QuadPart; //time = ((float)cputime.QuadPart/(float)ticksPerSecond.QuadPart); //transferRate = (fSource->FilePointer / time) / 1024; //cons_printf("%f% - %10ld Bytes Copied, %f Kb/S\r", ((float)((float)fSource->FilePointer/(float)fSource->Filesize) * 100), fSource->FilePointer, transferRate); }while(BytesRead > 0); //cons_printf("%f% - %10ld Bytes Copied, %f Kb/S\n", ((float)((float)fSource->FilePointer/(float)fSource->Filesize) * 100), fSource->FilePointer, transferRate); FF_Close(fSource); FF_Close(fDest); } else { FF_Close(fSource); cons_printf("Could not open destination file - %s\n", FF_GetErrMessage(Error)); } } else { cons_printf("Could not open source file - %s\n", FF_GetErrMessage(Error)); } } else { cons_printf("Usage: %s [source file] [destination file]\n", argv[0]); } return 0; }
int mkfile_cmd(int argc, char **argv, FF_ENVIRONMENT *pEnv) { FF_FILE *f; FF_T_UINT32 Bytes; FF_T_UINT32 BytesWritten = 0; FF_T_UINT32 ElementSize = 0, Elements = 0, Multiplier = 0; FF_T_UINT8 IntBuffer[4096*4]; // 16Kb of Integers! FF_T_UINT32 i = 0, x; FF_T_INT8 path[FF_MAX_PATH]; FF_ERROR Error; FF_T_UINT64 TicksPerSecond, TicksStart, TicksEnd, Ticks; float transferRate = 0.0, time; TicksPerSecond = FFTerm_GetTickRate(pEnv->pConsole); if(argc == 5) { sscanf(argv[1], "%lu", &ElementSize); /*if(!ElementSize) { printf("Invalid Element Size!\n"); return 0; }*/ sscanf(argv[2], "%lu", &Elements); /*if(!Elements) { printf("Invalid Number of Elements\n"); return 0; }*/ sscanf(argv[3], "%lu", &Multiplier); /*if(!Multiplier) { printf("Invalid Multiplier\n"); return 0; }*/ Bytes = ElementSize * Elements * Multiplier; printf("Creating file of size %lu Bytes (%0.2f MB) (%0.3f GB)\n", Bytes, (float)((float)Bytes / 1048576.0), (float)(((float)Bytes / 1048576.0)/1024.0)); ProcessPath(path, argv[4], pEnv); f = FF_Open(pEnv->pIoman, path, FF_GetModeBits("wb"), &Error); if(f) { while(Bytes) { for(x = 0; x < 4096*4; x++) { IntBuffer[x] = (FF_T_UINT8)i++; } TicksStart = FFTerm_GetTicks(pEnv->pConsole); if(Bytes >= (4096 * 4)) { BytesWritten += 4096 * 4; Bytes -= FF_Write(f, 1, 4096 * 4, (FF_T_UINT8 *) IntBuffer); } else { BytesWritten += Bytes; Bytes -= FF_Write(f, 1, Bytes, (FF_T_UINT8 *) IntBuffer); } TicksEnd = FFTerm_GetTicks(pEnv->pConsole); Ticks += (TicksEnd - TicksStart); time = ((float)Ticks/(float)TicksPerSecond); transferRate = (BytesWritten / time) / 1024; printf("Written %0.2f MB (%7.2f KB/s)\r", (float) ((float)BytesWritten / 1048576.0), transferRate); } printf("Written %0.2f MB (%7.2f KB/s)\n", (float) ((float)BytesWritten / 1048576.0), transferRate); FF_Close(f); } else { printf("Error opening file: %s\n", FF_GetErrMessage(Error)); } } else { printf("Generates a File filled with 32-bit integers.\n\n"); printf("Usage: %s [Element Size] [Elements] [Multiplier] [filename]\n\n", argv[0]); printf("E.g. a 1Mb File, \tFullFAT\\>%s 1024\t 1024\t 1\t 1m.dat\n", argv[0]); printf("E.g. a 2Mb File, \tFullFAT\\>%s 1024\t 1024\t 2\t 2m.dat\n", argv[0]); printf("E.g. a 10Mb File, \tFullFAT\\>%s 1024\t 1024\t 10\t 10m.dat\n", argv[0]); printf("E.g. a 100Mb File, \tFullFAT\\>%s 1024\t 1024\t 100\t 100m.dat\n\n", argv[0]); } return 0; }
int more_cmd(int argc, char **argv, FF_ENVIRONMENT *pEnv) { FF_FILE *f; FF_ERROR Error; FF_T_SINT32 c; FF_T_INT8 path[FF_MAX_PATH]; if(argc == 2) { ProcessPath(path, argv[1], pEnv); f = FF_Open(pEnv->pIoman, path, FF_MODE_READ, &Error); if(f) { printf("//---------- START OF FILE\n"); while(!FF_isEOF(f)) { c = FF_GetC(f); if(c >= 0) { printf("%c", (FF_T_INT8) c); } else { printf("Error while reading file: %s\n", FF_GetErrMessage(c)); FF_Close(f); return -3; } } printf("\n//---------- END OF FILE\n"); FF_Close(f); } else { printf("Could not open file: %s\n", FF_GetErrMessage(Error)); return -2; } } else { printf("Usage: %s [filename]\n", argv[0]); } return 0; }
/* This isn't a command, but rather a simple copy function designed to aid wildCard copying. */ int filecopy(const char *src, const char *dest, FF_ENVIRONMENT *pEnv) { FF_IOMAN *pIoman = pEnv->pIoman; FF_ERROR Error; FF_FILE *fSource, *fDest; FF_T_UINT8 copybuf[COPY_BUFFER_SIZE]; FF_T_SINT32 BytesRead; //LARGE_INTEGER ticksPerSecond; //LARGE_INTEGER start_ticks, end_ticks, cputime, ostart, oend; float transferRate = 0; //int ticks; //QueryPerformanceFrequency(&ticksPerSecond); //QueryPerformanceCounter(&ostart); fSource = FF_Open(pIoman, src, FF_MODE_READ, &Error); //QueryPerformanceCounter(&oend); //ticks = (int) (oend.QuadPart - ostart.QuadPart); //cons_printf("Source: Open took %d\n", ticks); if(fSource) { //QueryPerformanceCounter(&ostart); fDest = FF_Open(pIoman, dest, FF_GetModeBits("w"), &Error); //QueryPerformanceCounter(&oend); //ticks = (int) (oend.QuadPart - ostart.QuadPart); //cons_printf("Dest: Open took %d\n", ticks); if(fDest) { // Do the copy //QueryPerformanceCounter(&start_ticks); do{ BytesRead = FF_Read(fSource, COPY_BUFFER_SIZE, 1, (FF_T_UINT8 *)copybuf); FF_Write(fDest, BytesRead, 1, (FF_T_UINT8 *) copybuf); //QueryPerformanceCounter(&end_ticks); //cputime.QuadPart = end_ticks.QuadPart - start_ticks.QuadPart; //time = ((float)cputime.QuadPart/(float)ticksPerSecond.QuadPart); //transferRate = (fSource->FilePointer / time) / 1024; cons_printf("%3.0f%% - %10ld Bytes Copied, %7.2f Kb/S\r", ((float)((float)fSource->FilePointer/(float)fSource->Filesize) * 100), fSource->FilePointer, transferRate); }while(BytesRead > 0); cons_printf("%3.0f%% - %10ld Bytes Copied, %7.2f Kb/S\n", ((float)((float)fSource->FilePointer/(float)fSource->Filesize) * 100), fSource->FilePointer, transferRate); FF_Close(fSource); FF_Close(fDest); } else { FF_Close(fSource); cons_printf("Could not open destination file - %s\n", FF_GetErrMessage(Error)); } } else { if(Error == FF_ERR_FILE_OBJECT_IS_A_DIR) { return FF_ERR_FILE_OBJECT_IS_A_DIR; } cons_printf("Could not open source file - %s\n", FF_GetErrMessage(Error)); } return 0; }
static BT_ERROR fullfat_file_cleanup(BT_HANDLE hFile) { BT_FF_FILE *pFile = (BT_FF_FILE *) hFile; FF_Close(pFile->pFile); return BT_ERR_NONE; }
FF_ERROR FF_RmFile(FF_IOMAN *pIoman, const FF_T_INT8 *path) { FF_FILE *pFile; FF_ERROR Error = 0; FF_T_UINT8 EntryBuffer[32]; pFile = FF_Open(pIoman, path, FF_MODE_READ, &Error); if(!pFile) { return Error; // File in use or File not found! } pFile->FileDeleted = FF_TRUE; FF_lockFAT(pIoman); // Lock the FAT so its thread-safe. { FF_UnlinkClusterChain(pIoman, pFile->ObjectCluster, 0); // 0 to delete the entire chain! } FF_unlockFAT(pIoman); // Edit the Directory Entry! (So it appears as deleted); FF_lockDIR(pIoman); { FF_RmLFNs(pIoman, pFile->DirCluster, pFile->DirEntry); FF_FetchEntry(pIoman, pFile->DirCluster, pFile->DirEntry, EntryBuffer); EntryBuffer[0] = 0xE5; FF_PushEntry(pIoman, pFile->DirCluster, pFile->DirEntry, EntryBuffer); } FF_unlockDIR(pIoman); FF_FlushCache(pIoman); FF_Close(pFile); // Free the file pointer resources return 0; }
int killthread_cmd(int argc, char **argv, FF_ENVIRONMENT *pEnv) { THREAD hThread; int threadID; if(!pEnv) { return 0; } if(argc == 2) { sscanf(argv[1], "%d", &threadID); hThread = GetThread(threadID); if(hThread) { /*TerminateThread(hThread->hThread, &dwExitCode);*/ hThread->tKill = FF_TRUE; while(!hThread->isDead); FF_Close(hThread->pFile); CloseHandle(hThread->hThread); RemoveThread(hThread); } } else { printf("Usage: %s [Thread ID]\n", argv[0]); } return 0; }
VOID NTAPI FatDeleteFcb(IN PFAT_IRP_CONTEXT IrpContext, IN PFCB Fcb) { DPRINT("FatDeleteFcb %p\n", Fcb); if (Fcb->OpenCount != 0) { DPRINT1("Trying to delete FCB with OpenCount %d\n", Fcb->OpenCount); ASSERT(FALSE); } if ((Fcb->Header.NodeTypeCode == FAT_NTC_DCB) || (Fcb->Header.NodeTypeCode == FAT_NTC_ROOT_DCB)) { /* Make sure it's a valid deletion */ ASSERT(Fcb->Dcb.DirectoryFileOpenCount == 0); ASSERT(IsListEmpty(&Fcb->Dcb.ParentDcbList)); ASSERT(Fcb->Dcb.DirectoryFile == NULL); } else { /* Free locks */ FsRtlUninitializeFileLock(&Fcb->Fcb.Lock); FsRtlUninitializeOplock(&Fcb->Fcb.Oplock); } /* Release any possible filter contexts */ FsRtlTeardownPerStreamContexts(&Fcb->Header); /* Remove from parents queue */ if (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB) { RemoveEntryList(&(Fcb->ParentDcbLinks)); } /* Free FullFAT handle */ if (Fcb->FatHandle) FF_Close(Fcb->FatHandle); /* Remove from the splay table */ if (FlagOn(Fcb->State, FCB_STATE_HAS_NAMES)) FatRemoveNames(IrpContext, Fcb); /* Free file name buffers */ if (Fcb->Header.NodeTypeCode != FAT_NTC_ROOT_DCB) { if (Fcb->FullFileName.Buffer) ExFreePool(Fcb->FullFileName.Buffer); } if (Fcb->ExactCaseLongName.Buffer) ExFreePool(Fcb->ExactCaseLongName.Buffer); /* Free this FCB, finally */ ExFreePool(Fcb); }
int createthread_cmd(int argc, char **argv, FF_ENVIRONMENT *pEnv) { THREAD hThread = (THREAD) malloc(sizeof(struct _IO_THREAD)); THREAD hThreadList = g_ThreadList; FF_T_INT8 Path[FF_MAX_PATH]; FF_ERROR Error; if(argc == 2) { if(hThread) { hThread->isDead = FF_FALSE; hThread->pNext = NULL; hThread->nThreadBytes = 0; hThread->nThreadNum = 0; hThread->tKill = FF_FALSE; ProcessPath(Path, argv[1], pEnv); hThread->pFile = FF_Open(pEnv->pIoman, Path, FF_GetModeBits("w+"), &Error); if(!hThread->pFile) { free(hThread); printf("Error opening file: %s\n", FF_GetErrMessage(Error)); return 0; } hThread->hThread = CreateThread(0, 0, IOTestThread, hThread, 0, &hThread->dwThreadID); if(hThread->hThread) { if(!hThreadList) { g_ThreadList = hThread; } else { hThread->nThreadNum = 1; while(hThreadList->pNext) { hThreadList = hThreadList->pNext; hThread->nThreadNum += 1; } hThreadList->pNext = hThread; } } else { FF_Close(hThread->pFile); free(hThread); printf("Error creating thread!\n"); } } else { printf("Not enough memory!\n"); } } else { printf("Usage: %s [filename]\n", argv[0]); } return 0; }
int test_7(FF_IOMAN *pIoman, TEST_PARAMS *pParams) { FF_FILE *pFile; FF_ERROR Error; int i; int c; unsigned long size = pIoman->pPartition->SectorsPerCluster * pIoman->pPartition->BlkSize; unsigned long startSize; char test[] = "Another simple sentence."; pFile = FF_Open(pIoman, "\\test.7.dat", FF_GetModeBits("a+"), &Error); if(!pFile) { CHECK_ERR(Error) } startSize = pFile->Filesize; for(i = startSize; i < (size * 3)+startSize; i++) { Error = FF_PutC(pFile, test[i % (sizeof(test)-1)]); } Error = FF_Close(pFile); CHECK_ERR(Error); pFile = FF_Open(pIoman, "\\test.7.dat", FF_GetModeBits("rb"), &Error); if(!pFile) { CHECK_ERR(Error) } i = 0; do { c = FF_GetC(pFile); if(c >= 0) { if(c != test[i++ % (sizeof(test)-1)]) { sprintf(pParams->errBuf, "Char at offset: %d does not match input.\n", i); *pParams->pszpMessage = pParams->errBuf; FF_Close(pFile); DO_FAIL; } } } while(c >= 0); FF_Close(pFile); return PASS; }
void KillAllThreads(void) { while(g_ThreadList) { g_ThreadList->tKill = FF_TRUE; // Signal Thread to Die. while(!g_ThreadList->isDead); // Wait on Thread to Signal its death. FF_Close(g_ThreadList->pFile); // Close the file. CloseHandle(g_ThreadList->hThread); // Close thread handle. RemoveThread(g_ThreadList); // Remove thread from list. } }
/** * @public * @brief MD5 Data Hashing function. * * Generates and displays an MD5 hash of a file. This is really useful when * verify files for their integrity. We used MD5 extensively while stabilising * the read and write functionality of FullFAT. * **/ int md5_cmd(int argc, char **argv, FF_ENVIRONMENT *pEnv) { FF_IOMAN *pIoman = pEnv->pIoman; FF_T_INT8 path[FF_MAX_PATH]; FF_T_UINT8 readBuf[8192]; FF_FILE *fSource; FF_ERROR Error; int len; md5_state_t state; md5_byte_t digest[16]; int di; if(argc == 2) { ProcessPath(path, argv[1], pEnv); fSource = FF_Open(pIoman, path, FF_MODE_READ, &Error); if(fSource) { md5_init(&state); do { len = FF_Read(fSource, 1, 8192, readBuf); md5_append(&state, (const md5_byte_t *)readBuf, len); } while(len); md5_finish(&state, digest); for (di = 0; di < 16; ++di) cons_printf("%02x", digest[di]); cons_printf ("\n"); FF_Close(fSource); } else { cons_printf("Could not open file - %s\n", FF_GetErrMessage(Error)); } } else { cons_printf("Usage: %s [filename]\n", argv[0]); } return 0; }
STATUS SSD_Ddm::Quiesce(Message *p_quiesce_message) // virtual { TRACE_ENTRY(SSD_Ddm::Quiesce); // Save pointer to quiesce message. // When this pointer is non zero, we are processing a quiesce. CT_ASSERT(m_p_quiesce_message == 0, SSD_Ddm::Process_Quiesce); m_p_quiesce_message = p_quiesce_message; Tracef(EOL "Beginning flash file system quiesce."); #ifdef PHS_REPORTER // Start the Status reporter RqDdmReporter *pRqReporter = new RqDdmReporter(PHS_STOP, PHS_SSD_STATUS, MyDid, MyVdn); Send(pRqReporter, (ReplyCallback) &DiscardReply); // Start the Performance reporter RqDdmReporter *pRqReporter = new RqDdmReporter(PHS_STOP, PHS_SSD_PERFORMANCE, MyDid, MyVdn); Send(pRqReporter, (ReplyCallback) &DiscardReply); #endif #if 0 // TEMPORARY always allow quiesce for debugging // Are there any requests outstanding? if (m_num_requests_outstanding) { // If so, Quiesce will be called by Respond_To_BSA_Request // when the number of requests goes to zero. Tracef(EOL "Waiting for %d outstanding requests to quiesce", m_num_requests_outstanding); return OK; } #endif // Set up the callback context to call Process_Quiesce // when the file system has been closed. m_request_context.Set_Callback(&Process_Quiesce); // Start the close operation. FF_Close(m_flash_handle, &m_request_context); return OK; } // SSD_Ddm::Quiesce
static int copy_file(const char *szsrcPath, const char *szdestPath, FF_T_BOOL bVerbose, FF_ENVIRONMENT *pEnv) { FF_FILE *pfSource; FF_FILE *pfDestination = NULL; FILE *pex; FF_ERROR ffError; FF_T_SINT32 slBytesRead, slBytesWritten; unsigned char buffer[CP_BUFFER_SIZE]; if(!strcmp(szsrcPath, szdestPath)) { // Ensure that source and destination are not the same file. printf("cp: Source and Destination files are identical: illegal operation.\n"); return 0; } pfSource = FF_Open(pEnv->pIoman, szsrcPath, FF_MODE_READ, &ffError); // Attempt to open the source. if(!pfSource) { printf("cp: %s: open failed: %s\n", szsrcPath, FF_GetErrMessage(ffError)); // Display a meaningful error message. return 0; } if(!bExternal) { pfDestination = FF_Open(pEnv->pIoman, szdestPath, (FF_MODE_WRITE | FF_MODE_CREATE | FF_MODE_TRUNCATE), &ffError); } else { pex = fopen(szdestPath+1, "w"); } if(!pfDestination && !pex) { printf("cp: %s: open failed: %s\n", szdestPath, FF_GetErrMessage(ffError)); FF_Close(pfSource); // Don't forget to close the Source file. return 0; } // Source and Destination files are open, copy the data from Source to Dest! do { slBytesRead = FF_Read(pfSource, 1, CP_BUFFER_SIZE, buffer); if(!bExternal) { slBytesWritten = FF_Write(pfDestination, 1, slBytesRead, buffer); } else { slBytesWritten = fwrite(buffer, 1, slBytesRead, pex); } if(slBytesWritten != slBytesRead) { printf("cp: write error: %s\n", FF_GetErrMessage(slBytesWritten)); break; } } while(slBytesRead); FF_Close(pfSource); if(!bExternal) { FF_Close(pfDestination); } else { fclose(pex); } if(bVerbose) { printf("'%s' -> '%s'\n", szsrcPath, szdestPath); } return 0; }
FF_ERROR FF_RmFile(FF_IOMAN *pIoman, const FF_T_WCHAR *path) { #else FF_ERROR FF_RmFile(FF_IOMAN *pIoman, const FF_T_INT8 *path) { #endif FF_FILE *pFile; FF_ERROR Error = FF_ERR_NONE; FF_T_UINT8 EntryBuffer[32]; FF_FETCH_CONTEXT FetchContext; pFile = FF_Open(pIoman, path, FF_MODE_READ, &Error); if(!pFile) { return Error; // File in use or File not found! } pFile->FileDeleted = FF_TRUE; if(pFile->ObjectCluster) { // Ensure there is actually a cluster chain to delete! FF_lockFAT(pIoman); // Lock the FAT so its thread-safe. { Error = FF_UnlinkClusterChain(pIoman, pFile->ObjectCluster, 0); // 0 to delete the entire chain! } FF_unlockFAT(pIoman); if(Error) { FF_Close(pFile); return Error; } } // Edit the Directory Entry! (So it appears as deleted); FF_lockDIR(pIoman); { Error = FF_InitEntryFetch(pIoman, pFile->DirCluster, &FetchContext); if(Error) { FF_unlockDIR(pIoman); FF_Close(pFile); return Error; } Error = FF_RmLFNs(pIoman, pFile->DirEntry, &FetchContext); if(Error) { FF_CleanupEntryFetch(pIoman, &FetchContext); FF_unlockDIR(pIoman); FF_Close(pFile); return Error; } Error = FF_FetchEntryWithContext(pIoman, pFile->DirEntry, &FetchContext, EntryBuffer); if(Error) { FF_CleanupEntryFetch(pIoman, &FetchContext); FF_unlockDIR(pIoman); FF_Close(pFile); return Error; } EntryBuffer[0] = 0xE5; Error = FF_PushEntryWithContext(pIoman, pFile->DirEntry, &FetchContext, EntryBuffer); if(Error) { FF_CleanupEntryFetch(pIoman, &FetchContext); FF_unlockDIR(pIoman); FF_Close(pFile); return Error; } FF_CleanupEntryFetch(pIoman, &FetchContext); } FF_unlockDIR(pIoman); Error = FF_FlushCache(pIoman); if(Error) { FF_Close(pFile); return Error; } Error = FF_Close(pFile); // Free the file pointer resources return Error; }
FF_ERROR FF_RmDir(FF_IOMAN *pIoman, const FF_T_INT8 *path) { FF_FILE *pFile; FF_ERROR Error = FF_ERR_NONE; FF_T_UINT8 EntryBuffer[32]; FF_T_SINT8 RetVal = FF_ERR_NONE; #ifdef FF_PATH_CACHE FF_T_UINT32 i; #endif if(!pIoman) { return FF_ERR_NULL_POINTER; } pFile = FF_Open(pIoman, path, FF_MODE_DIR, &Error); if(!pFile) { return Error; // File in use or File not found! } pFile->FileDeleted = FF_TRUE; FF_lockDIR(pIoman); { if(FF_isDirEmpty(pIoman, path)) { FF_lockFAT(pIoman); { FF_UnlinkClusterChain(pIoman, pFile->ObjectCluster, 0); // 0 to delete the entire chain! } FF_unlockFAT(pIoman); // Edit the Directory Entry! (So it appears as deleted); FF_RmLFNs(pIoman, pFile->DirCluster, pFile->DirEntry); FF_FetchEntry(pIoman, pFile->DirCluster, pFile->DirEntry, EntryBuffer); EntryBuffer[0] = 0xE5; FF_PushEntry(pIoman, pFile->DirCluster, pFile->DirEntry, EntryBuffer); #ifdef FF_PATH_CACHE FF_PendSemaphore(pIoman->pSemaphore); // Thread safety on shared object! { for(i = 0; i < FF_PATH_CACHE_DEPTH; i++) { if(FF_strmatch(pIoman->pPartition->PathCache[i].Path, path, (FF_T_UINT16)strlen(path))) { pIoman->pPartition->PathCache[i].Path[0] = '\0'; pIoman->pPartition->PathCache[i].DirCluster = 0; FF_ReleaseSemaphore(pIoman->pSemaphore); } } } FF_ReleaseSemaphore(pIoman->pSemaphore); #endif FF_IncreaseFreeClusters(pIoman, pFile->iChainLength); FF_FlushCache(pIoman); } else { RetVal = FF_ERR_DIR_NOT_EMPTY; } } FF_unlockDIR(pIoman); FF_Close(pFile); // Free the file pointer resources // File is now lost! return RetVal; }
FF_FILE *FF_Open(FF_IOMAN *pIoman, const FF_T_WCHAR *path, FF_T_UINT8 Mode, FF_ERROR *pError) { #else FF_FILE *FF_Open(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT8 Mode, FF_ERROR *pError) { #endif FF_FILE *pFile; FF_FILE *pFileChain; FF_DIRENT Object; FF_T_UINT32 DirCluster, FileCluster; FF_T_UINT32 nBytesPerCluster; #ifdef FF_UNICODE_SUPPORT FF_T_WCHAR filename[FF_MAX_FILENAME]; #else FF_T_INT8 filename[FF_MAX_FILENAME]; #endif FF_ERROR Error; FF_T_UINT16 i; if(pError) { *pError = 0; } if(!pIoman) { if(pError) { *pError = FF_ERR_NULL_POINTER; } return (FF_FILE *)NULL; } pFile = FF_MALLOC(sizeof(FF_FILE)); if(!pFile) { if(pError) { *pError = FF_ERR_NOT_ENOUGH_MEMORY; } return (FF_FILE *)NULL; } // Get the Mode Bits. pFile->Mode = Mode; #ifdef FF_UNICODE_SUPPORT i = (FF_T_UINT16) wcslen(path); #else i = (FF_T_UINT16) strlen(path); #endif while(i != 0) { if(path[i] == '\\' || path[i] == '/') { break; } i--; } #ifdef FF_UNICODE_SUPPORT wcsncpy(filename, (path + i + 1), FF_MAX_FILENAME); #else strncpy(filename, (path + i + 1), FF_MAX_FILENAME); #endif if(i == 0) { i = 1; } DirCluster = FF_FindDir(pIoman, path, i, &Error); if(Error) { if(pError) { *pError = Error; } FF_FREE(pFile); return (FF_FILE *) NULL; } if(DirCluster) { FileCluster = FF_FindEntryInDir(pIoman, DirCluster, filename, 0x00, &Object, &Error); if(Error) { if(pError) { *pError = Error; } FF_FREE(pFile); return (FF_FILE *) NULL; } if(!FileCluster) { // If 0 was returned, it might be because the file has no allocated cluster #ifdef FF_UNICODE_SUPPORT if(wcslen(filename) == wcslen(Object.FileName)) { if(Object.Filesize == 0 && FF_strmatch(filename, Object.FileName, (FF_T_UINT16) wcslen(filename)) == FF_TRUE) { #else if(strlen(filename) == strlen(Object.FileName)) { if(Object.Filesize == 0 && FF_strmatch(filename, Object.FileName, (FF_T_UINT16) strlen(filename)) == FF_TRUE) { #endif // The file really was found! FileCluster = 1; } } } if(!FileCluster) { if((pFile->Mode & FF_MODE_CREATE)) { FileCluster = FF_CreateFile(pIoman, DirCluster, filename, &Object, &Error); if(Error) { if(pError) { *pError = Error; } FF_FREE(pFile); return (FF_FILE *) NULL; } Object.CurrentItem += 1; } } if(FileCluster) { if(Object.Attrib == FF_FAT_ATTR_DIR) { if(!(pFile->Mode & FF_MODE_DIR)) { // Not the object, File Not Found! FF_FREE(pFile); if(pError) { *pError = FF_ERR_FILE_OBJECT_IS_A_DIR; } return (FF_FILE *) NULL; } } //---------- Ensure Read-Only files don't get opened for Writing. if((pFile->Mode & FF_MODE_WRITE) || (pFile->Mode & FF_MODE_APPEND)) { if((Object.Attrib & FF_FAT_ATTR_READONLY)) { FF_FREE(pFile); if(pError) { *pError = FF_ERR_FILE_IS_READ_ONLY; } return (FF_FILE *) NULL; } } pFile->pIoman = pIoman; pFile->FilePointer = 0; pFile->ObjectCluster = Object.ObjectCluster; pFile->Filesize = Object.Filesize; pFile->CurrentCluster = 0; pFile->AddrCurrentCluster = pFile->ObjectCluster; //pFile->Mode = Mode; pFile->Next = NULL; pFile->DirCluster = DirCluster; pFile->DirEntry = Object.CurrentItem - 1; nBytesPerCluster = pFile->pIoman->pPartition->SectorsPerCluster / pIoman->BlkSize; pFile->iChainLength = 0; pFile->iEndOfChain = 0; pFile->FileDeleted = FF_FALSE; // File Permission Processing // Only "w" and "w+" mode strings can erase a file's contents. // Any other combinations will not cause an erase. if((pFile->Mode & FF_MODE_TRUNCATE)) { pFile->Filesize = 0; pFile->FilePointer = 0; } /* Add pFile onto the end of our linked list of FF_FILE objects. */ FF_PendSemaphore(pIoman->pSemaphore); { if(!pIoman->FirstFile) { pIoman->FirstFile = pFile; } else { pFileChain = (FF_FILE *) pIoman->FirstFile; do { if(pFileChain->ObjectCluster == pFile->ObjectCluster) { // File is already open! DON'T ALLOW IT! FF_ReleaseSemaphore(pIoman->pSemaphore); FF_FREE(pFile); if(pError) { *pError = FF_ERR_FILE_ALREADY_OPEN; } return (FF_FILE *) NULL; } if(!pFileChain->Next) { pFileChain->Next = pFile; break; } pFileChain = (FF_FILE *) pFileChain->Next; }while(pFileChain != NULL); } } FF_ReleaseSemaphore(pIoman->pSemaphore); return pFile; }else { FF_FREE(pFile); if(pError) { *pError = FF_ERR_FILE_NOT_FOUND; } return (FF_FILE *) NULL; } } if(pError) { *pError = FF_ERR_FILE_INVALID_PATH; } FF_FREE(pFile); return (FF_FILE *)NULL; } /** * @public * @brief Tests if a Directory contains any other files or folders. * * @param pIoman FF_IOMAN object returned from the FF_CreateIOMAN() function. * **/ #ifdef FF_UNICODE_SUPPORT FF_T_BOOL FF_isDirEmpty(FF_IOMAN *pIoman, const FF_T_WCHAR *Path) { #else FF_T_BOOL FF_isDirEmpty(FF_IOMAN *pIoman, const FF_T_INT8 *Path) { #endif FF_DIRENT MyDir; FF_ERROR RetVal = FF_ERR_NONE; FF_T_UINT8 i = 0; if(!pIoman) { return FF_FALSE; } RetVal = FF_FindFirst(pIoman, &MyDir, Path); while(RetVal == 0) { i++; RetVal = FF_FindNext(pIoman, &MyDir); if(i > 2) { return FF_FALSE; } } return FF_TRUE; } #ifdef FF_UNICODE_SUPPORT FF_ERROR FF_RmDir(FF_IOMAN *pIoman, const FF_T_WCHAR *path) { #else FF_ERROR FF_RmDir(FF_IOMAN *pIoman, const FF_T_INT8 *path) { #endif FF_FILE *pFile; FF_ERROR Error = FF_ERR_NONE; FF_T_UINT8 EntryBuffer[32]; FF_FETCH_CONTEXT FetchContext; FF_T_SINT8 RetVal = FF_ERR_NONE; #ifdef FF_PATH_CACHE FF_T_UINT32 i; #endif if(!pIoman) { return FF_ERR_NULL_POINTER; } pFile = FF_Open(pIoman, path, FF_MODE_DIR, &Error); if(!pFile) { return Error; // File in use or File not found! } pFile->FileDeleted = FF_TRUE; FF_lockDIR(pIoman); { if(FF_isDirEmpty(pIoman, path)) { FF_lockFAT(pIoman); { Error = FF_UnlinkClusterChain(pIoman, pFile->ObjectCluster, 0); // 0 to delete the entire chain! } FF_unlockFAT(pIoman); if(Error) { FF_unlockDIR(pIoman); FF_Close(pFile); return Error; } // Initialise the dirent Fetch Context object for faster removal of dirents. Error = FF_InitEntryFetch(pIoman, pFile->DirCluster, &FetchContext); if(Error) { FF_unlockDIR(pIoman); FF_Close(pFile); return Error; } // Edit the Directory Entry! (So it appears as deleted); Error = FF_RmLFNs(pIoman, pFile->DirEntry, &FetchContext); if(Error) { FF_CleanupEntryFetch(pIoman, &FetchContext); FF_unlockDIR(pIoman); FF_Close(pFile); return Error; } Error = FF_FetchEntryWithContext(pIoman, pFile->DirEntry, &FetchContext, EntryBuffer); if(Error) { FF_CleanupEntryFetch(pIoman, &FetchContext); FF_unlockDIR(pIoman); FF_Close(pFile); return Error; } EntryBuffer[0] = 0xE5; Error = FF_PushEntryWithContext(pIoman, pFile->DirEntry, &FetchContext, EntryBuffer); if(Error) { FF_CleanupEntryFetch(pIoman, &FetchContext); FF_unlockDIR(pIoman); FF_Close(pFile); return Error; } #ifdef FF_PATH_CACHE FF_PendSemaphore(pIoman->pSemaphore); // Thread safety on shared object! { for(i = 0; i < FF_PATH_CACHE_DEPTH; i++) { #ifdef FF_UNICODE_SUPPORT if(FF_strmatch(pIoman->pPartition->PathCache[i].Path, path, (FF_T_UINT16)wcslen(path))) { #else if(FF_strmatch(pIoman->pPartition->PathCache[i].Path, path, (FF_T_UINT16)strlen(path))) { #endif pIoman->pPartition->PathCache[i].Path[0] = '\0'; pIoman->pPartition->PathCache[i].DirCluster = 0; FF_ReleaseSemaphore(pIoman->pSemaphore); } } } FF_ReleaseSemaphore(pIoman->pSemaphore); #endif Error = FF_IncreaseFreeClusters(pIoman, pFile->iChainLength); if(Error) { FF_CleanupEntryFetch(pIoman, &FetchContext); FF_unlockDIR(pIoman); FF_Close(pFile); return Error; } FF_CleanupEntryFetch(pIoman, &FetchContext); Error = FF_FlushCache(pIoman); if(Error) { FF_unlockDIR(pIoman); FF_Close(pFile); return Error; } } else { RetVal = FF_ERR_DIR_NOT_EMPTY; } } FF_unlockDIR(pIoman); Error = FF_Close(pFile); // Free the file pointer resources if(Error) { return Error; } // File is now lost! return RetVal; }
/** * @public * @brief Moves a file or directory from source to destination. * * @param pIoman The FF_IOMAN object pointer. * @param szSourceFile String of the source file to be moved or renamed. * @param szDestinationFile String of the destination file to where the source should be moved or renamed. * * @return FF_ERR_NONE on success. * @return FF_ERR_FILE_DESTINATION_EXISTS if the destination file exists. * @return FF_ERR_FILE_COULD_NOT_CREATE_DIRENT if dirent creation failed (fatal error!). * @return FF_ERR_FILE_DIR_NOT_FOUND if destination directory was not found. * @return FF_ERR_FILE_SOURCE_NOT_FOUND if the source file was not found. * **/ FF_ERROR FF_Move(FF_IOMAN *pIoman, const FF_T_INT8 *szSourceFile, const FF_T_INT8 *szDestinationFile) { FF_ERROR Error; FF_FILE *pSrcFile, *pDestFile; FF_DIRENT MyFile; FF_T_UINT8 EntryBuffer[32]; FF_T_UINT16 i; FF_T_UINT32 DirCluster; if(!pIoman) { return FF_ERR_NULL_POINTER; } // Check destination file doesn't exist! pDestFile = FF_Open(pIoman, szDestinationFile, FF_MODE_READ, &Error); if(pDestFile || (Error == FF_ERR_FILE_OBJECT_IS_A_DIR)) { FF_Close(pDestFile); return FF_ERR_FILE_DESTINATION_EXISTS; // YES -- FAIL } pSrcFile = FF_Open(pIoman, szSourceFile, FF_MODE_READ, &Error); if(Error == FF_ERR_FILE_OBJECT_IS_A_DIR) { // Open a directory for moving! pSrcFile = FF_Open(pIoman, szSourceFile, FF_MODE_DIR, &Error); } if(pSrcFile) { // Create the new dirent. FF_FetchEntry(pIoman, pSrcFile->DirCluster, pSrcFile->DirEntry, EntryBuffer); MyFile.Attrib = FF_getChar(EntryBuffer, (FF_T_UINT16)(FF_FAT_DIRENT_ATTRIB)); MyFile.Filesize = pSrcFile->Filesize; MyFile.ObjectCluster = pSrcFile->ObjectCluster; MyFile.CurrentItem = 0; i = (FF_T_UINT16) strlen(szDestinationFile); while(i != 0) { if(szDestinationFile[i] == '\\' || szDestinationFile[i] == '/') { break; } i--; } strncpy(MyFile.FileName, (szDestinationFile + i + 1), FF_MAX_FILENAME); if(i == 0) { i = 1; } DirCluster = FF_FindDir(pIoman, szDestinationFile, i); if(DirCluster) { // Destination Dir was found, we can now create the new entry. if(FF_CreateDirent(pIoman, DirCluster, &MyFile)) { FF_Close(pSrcFile); return FF_ERR_FILE_COULD_NOT_CREATE_DIRENT; // FAILED } // Edit the Directory Entry! (So it appears as deleted); FF_lockDIR(pIoman); { FF_RmLFNs(pIoman, pSrcFile->DirCluster, pSrcFile->DirEntry); FF_FetchEntry(pIoman, pSrcFile->DirCluster, pSrcFile->DirEntry, EntryBuffer); EntryBuffer[0] = 0xE5; FF_PushEntry(pIoman, pSrcFile->DirCluster, pSrcFile->DirEntry, EntryBuffer); } FF_unlockDIR(pIoman); FF_Close(pSrcFile); FF_FlushCache(pIoman); return FF_ERR_NONE; } return FF_ERR_FILE_DIR_NOT_FOUND; } return FF_ERR_FILE_SOURCE_NOT_FOUND; // Source not found! }
int mkfile_cmd(int xargc, char **xargv, FF_ENVIRONMENT *pEnv) { FF_FILE *f; FF_T_UINT32 Bytes; FF_T_UINT32 BytesWritten = 0; FF_T_UINT32 ElementSize = 0, Elements = 0, Multiplier = 0; FF_T_UINT32 IntBuffer[4096]; // 16Kb of Integers! FF_T_UINT32 i = 0, x; FF_T_INT8 path[FF_MAX_PATH]; FF_ERROR Error; //LARGE_INTEGER ticksPerSecond; //LARGE_INTEGER start_ticks, end_ticks, cputime; float transferRate = 0.0; //cputime.QuadPart = 0; //QueryPerformanceFrequency(&ticksPerSecond); if(xargc == 5) { sscanf(xargv[1], "%d", &ElementSize); //cons_printf("%d ",ElementSize); if(!ElementSize) { cons_printf("Invalid Element Size!\n"); return 0; } sscanf(xargv[2], "%d", &Elements); //cons_printf("%d ",Elements); if(!Elements) { cons_printf("Invalid Number of Elements\n"); return 0; } sscanf(xargv[3], "%d", &Multiplier); //cons_printf("%d \n",Multiplier); if(!Multiplier) { cons_printf("Invalid Multiplier\n"); return 0; } Bytes = ElementSize * Elements * Multiplier; //cons_printf("Creating file of size %lu Bytes (%0.2f MB) (%0.3f GB)\n", Bytes, (float)((float)Bytes / 1048576.0), (float)(((float)Bytes / 1048576.0)/1024.0)); ProcessPath(path, xargv[4], pEnv); f = FF_Open(pEnv->pIoman, path, FF_GetModeBits("wb"), &Error); if(f) { for(x = 0; x < 4096; x++) { IntBuffer[x] = i++; } while(Bytes) { //QueryPerformanceCounter(&start_ticks); if(Bytes >= 4096) { BytesWritten += 4096; Bytes -= FF_Write(f, 1, 4096, (FF_T_UINT8 *) IntBuffer); } else { BytesWritten += Bytes; Bytes -= FF_Write(f, 1, Bytes, (FF_T_UINT8 *) IntBuffer); } //QueryPerformanceCounter(&end_ticks); //cputime.QuadPart += (end_ticks.QuadPart - start_ticks.QuadPart); //time = ((float)cputime.QuadPart/(float)ticksPerSecond.QuadPart); //transferRate = (BytesWritten / time) / 1024; //cons_printf("Written %0.2f MB (%7.2f KB/s)\r", (float) ((float)BytesWritten / 1048576.0), transferRate); } //cons_printf("Written %0.2f MB (%7.2f KB/s)\n", (float) ((float)BytesWritten / 1048576.0), transferRate); FF_Close(f); } else { cons_printf("Error opening file: %s\n", FF_GetErrMessage(Error)); } } else { cons_printf("Generates a File filled with 32-bit integers.\n\n"); cons_printf("Usage: %s [Element Size] [Elements] [Multiplier] [filename]\n\n", xargv[0]); cons_printf("E.g. a 1Mb File, \tFullFAT\\>%s 1024\t 1024\t 1\t 1m.dat\n", xargv[0]); cons_printf("E.g. a 2Mb File, \tFullFAT\\>%s 1024\t 1024\t 2\t 2m.dat\n", xargv[0]); cons_printf("E.g. a 2Mb File, \tFullFAT\\>%s 1024\t 1024\t 10\t 10m.dat\n", xargv[0]); cons_printf("E.g. a 2Mb File, \tFullFAT\\>%s 1024\t 1024\t 100\t 100m.dat\n\n", xargv[0]); } return 0; }