Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
/**
 *	@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!
}
Ejemplo n.º 3
0
VOID
NTAPI
FatSetFcbNames(IN PFAT_IRP_CONTEXT IrpContext,
               IN PFCB Fcb)
{
    FF_DIRENT DirEnt;
    FF_ERROR Err;
    POEM_STRING ShortName;
    CHAR ShortNameRaw[13];
    UCHAR EntryBuffer[32];
    UCHAR NumLFNs;
    PUNICODE_STRING UnicodeName;
    OEM_STRING LongNameOem;
    NTSTATUS Status;

    /* Get the dir entry */
    Err = FF_GetEntry(Fcb->Vcb->Ioman,
                      Fcb->FatHandle->DirEntry,
                      Fcb->FatHandle->DirCluster,
                      &DirEnt);

    if (Err != FF_ERR_NONE)
    {
        DPRINT1("Error %d getting dirent of a file\n", Err);
        return;
    }

    /* Read the dirent to fetch the raw short name */
    FF_FetchEntry(Fcb->Vcb->Ioman,
                  Fcb->FatHandle->DirCluster,
                  Fcb->FatHandle->DirEntry,
                  EntryBuffer);
    NumLFNs = (UCHAR)(EntryBuffer[0] & ~0x40);
    RtlCopyMemory(ShortNameRaw, EntryBuffer, 11);

    /* Initialize short name string */
    ShortName = &Fcb->ShortName.Name.Ansi;
    ShortName->Buffer = Fcb->ShortNameBuffer;
    ShortName->Length = 0;
    ShortName->MaximumLength = sizeof(Fcb->ShortNameBuffer);

    /* Convert raw short name to a proper string */
    Fati8dot3ToString(ShortNameRaw, FALSE, ShortName);

    /* Add the short name link */
    FatInsertName(IrpContext, &Fcb->ParentFcb->Dcb.SplayLinksAnsi, &Fcb->ShortName);
    Fcb->ShortName.Fcb = Fcb;

    /* Get the long file name (if any) */
    if (NumLFNs > 0)
    {
        /* Prepare the oem string */
        LongNameOem.Buffer = DirEnt.FileName;
        LongNameOem.MaximumLength = FF_MAX_FILENAME;
        LongNameOem.Length = strlen(DirEnt.FileName);

        /* Prepare the unicode string */
        UnicodeName = &Fcb->LongName.Name.String;
        UnicodeName->Length = (LongNameOem.Length + 1) * sizeof(WCHAR);
        UnicodeName->MaximumLength = UnicodeName->Length;
        UnicodeName->Buffer = FsRtlAllocatePool(PagedPool, UnicodeName->Length);

        /* Convert it to unicode */
        Status = RtlOemStringToUnicodeString(UnicodeName, &LongNameOem, FALSE);
        if (!NT_SUCCESS(Status))
        {
            ASSERT(FALSE);
        }

        /* Set its length */
        Fcb->FileNameLength = UnicodeName->Length;

        /* Save case-preserved copy */
        Fcb->ExactCaseLongName.Length = UnicodeName->Length;
        Fcb->ExactCaseLongName.MaximumLength = UnicodeName->Length;
        Fcb->ExactCaseLongName.Buffer =
            FsRtlAllocatePoolWithTag(PagedPool, UnicodeName->Length, TAG_FILENAME);

        RtlCopyMemory(Fcb->ExactCaseLongName.Buffer,
                      UnicodeName->Buffer,
                      UnicodeName->Length);

        /* Perform a trick which is done by MS's FASTFAT driver to monocase
           the filename */
        RtlDowncaseUnicodeString(UnicodeName, UnicodeName, FALSE);
        RtlUpcaseUnicodeString(UnicodeName, UnicodeName, FALSE);

        DPRINT("Converted long name: %wZ\n", UnicodeName);

        /* Add the long unicode name link */
        FatInsertName(IrpContext, &Fcb->ParentFcb->Dcb.SplayLinksUnicode, &Fcb->LongName);
        Fcb->LongName.Fcb = Fcb;

        /* Indicate that this FCB has a unicode long name */
        SetFlag(Fcb->State, FCB_STATE_HAS_UNICODE_NAME);
    }
    else
    {
        /* No LFN, set exact case name to 0 length */
        Fcb->ExactCaseLongName.Length = 0;
        Fcb->ExactCaseLongName.MaximumLength = 0;

        /* Set the length based on the short name */
        Fcb->FileNameLength = RtlOemStringToCountedUnicodeSize(ShortName);
    }

    /* Mark the fact that names were added to splay trees*/
    SetFlag(Fcb->State, FCB_STATE_HAS_NAMES);
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
VOID
NTAPI
FatGetFcbUnicodeName(IN PFAT_IRP_CONTEXT IrpContext,
                     IN PFCB Fcb,
                     OUT PUNICODE_STRING LongName)
{
    FF_DIRENT DirEnt;
    FF_ERROR Err;
    OEM_STRING ShortName;
    CHAR ShortNameBuf[13];
    UCHAR EntryBuffer[32];
    UCHAR NumLFNs;
    OEM_STRING LongNameOem;
    NTSTATUS Status;

    /* Make sure this FCB has a FullFAT handle associated with it */
    if (Fcb->FatHandle == NULL &&
        FatNodeType(Fcb) == FAT_NTC_DCB)
    {
        /* Open the dir with FullFAT */
        Fcb->FatHandle = FF_OpenW(Fcb->Vcb->Ioman, &Fcb->FullFileName, FF_MODE_DIR, NULL);
        if (!Fcb->FatHandle)
        {
            ASSERT(FALSE);
        }
    }

    /* Get the dir entry */
    Err = FF_GetEntry(Fcb->Vcb->Ioman,
                      Fcb->FatHandle->DirEntry,
                      Fcb->FatHandle->DirCluster,
                      &DirEnt);

    if (Err != FF_ERR_NONE)
    {
        DPRINT1("Error %d getting dirent of a file\n", Err);
        return;
    }

    /* Read the dirent to fetch the raw short name */
    FF_FetchEntry(Fcb->Vcb->Ioman,
                  Fcb->FatHandle->DirCluster,
                  Fcb->FatHandle->DirEntry,
                  EntryBuffer);
    NumLFNs = (UCHAR)(EntryBuffer[0] & ~0x40);

    /* Check if we only have a short name.
       Convert it to unicode and return if that's the case */
    if (NumLFNs == 0)
    {
        /* Initialize short name string */
        ShortName.Buffer = ShortNameBuf;
        ShortName.Length = 0;
        ShortName.MaximumLength = 12;

        /* Convert raw short name to a proper string */
        Fati8dot3ToString((PCHAR)EntryBuffer, FALSE, &ShortName);

        /* Convert it to unicode */
        Status = RtlOemStringToCountedUnicodeString(LongName,
                                                    &ShortName,
                                                    FALSE);

        /* Ensure conversion was successful */
        ASSERT(Status == STATUS_SUCCESS);

        /* Exit */
        return;
    }

    /* Convert LFN from OEM to unicode and return */
    LongNameOem.Buffer = DirEnt.FileName;
    LongNameOem.MaximumLength = FF_MAX_FILENAME;
    LongNameOem.Length = strlen(DirEnt.FileName);

    /* Convert it to unicode */
    Status = RtlOemStringToUnicodeString(LongName, &LongNameOem, FALSE);

    /* Ensure conversion was successful */
    ASSERT(Status == STATUS_SUCCESS);
}