Esempio n. 1
0
VOID
Secondary_ChangeFcbFileName(
	IN PIRP_CONTEXT		IrpContext,
	IN PFCB				Fcb,
	IN PUNICODE_STRING	FullFileName
	)
{
    RtlInitEmptyUnicodeString( &Fcb->FullFileName,
							   Fcb->FullFileNameBuffer,
							   sizeof(Fcb->FullFileNameBuffer) );

	RtlCopyUnicodeString( &Fcb->FullFileName, FullFileName );

    RtlInitEmptyUnicodeString( &Fcb->CaseInSensitiveFullFileName,
							   Fcb->CaseInSensitiveFullFileNameBuffer,
							   sizeof(Fcb->CaseInSensitiveFullFileNameBuffer) );

	RtlDowncaseUnicodeString( &Fcb->CaseInSensitiveFullFileName,
							  &Fcb->FullFileName,
							  FALSE );

	if (FullFileName->Length && FullFileName->Buffer[0] != L'\\')
		ASSERT( NDFAT_BUG );

	return;
}
PXIXFS_LCB
xixfs_FCBTLBInsertPrefix (
	IN PXIXFS_IRPCONTEXT IrpContext,
	IN PXIXFS_FCB Fcb,
	IN PUNICODE_STRING Name,
	IN PXIXFS_FCB ParentFcb
)
{
	PXIXFS_LCB Lcb;
	PRTL_SPLAY_LINKS *TreeRoot;
	PLIST_ENTRY ListLinks;

	PWCHAR NameBuffer;

	PAGED_CODE();
	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CREATE|DEBUG_TARGET_CLOSE| DEBUG_TARGET_FCB),
		("Enter xixfs_FCBTLBInsertPrefix \n" ));
	//
	//  Check inputs.
	//

	ASSERT_IRPCONTEXT( IrpContext );
	ASSERT_FCB( Fcb );

	ASSERT_EXCLUSIVE_FCB( Fcb );
	ASSERT_EXCLUSIVE_FCB( ParentFcb );
	ASSERT( ParentFcb->XixcoreFcb.FCBType == FCB_TYPE_DIR);

	//
	//  It must be the case that an index Fcb is only referenced by a single index.  Now
	//  we walk the child's Lcb queue to insure that if any prefixes have already been
	//  inserted, they all refer to the index Fcb we are linking to.  This is the only way
	//  we can detect directory cross-linkage.
	//

	if (Fcb->XixcoreFcb.FCBType == FCB_TYPE_DIR) {

		for (ListLinks = Fcb->ParentLcbQueue.Flink;
			 ListLinks != &Fcb->ParentLcbQueue;
			 ListLinks = ListLinks->Flink) {

			Lcb = CONTAINING_RECORD( ListLinks, XIXFS_LCB, ChildFcbLinks );

			if (Lcb->ParentFcb != ParentFcb) {

				XifsdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR );
			}
		}
	}


    //
    //  Allocate space for the Lcb.
    //

	Lcb = xixfs_AllocateLCB(Name->Length);
 
    //
    //  Initialize the name-based file attributes.
    //
    
    Lcb->FileAttributes = 0;
    
    //
    //  Set up the filename in the Lcb.
    //

 
    RtlCopyMemory( Lcb->FileName.Buffer,
                   Name->Buffer,
                   Name->Length );
    
		


	//
	//  Capture the separate cases.
	//

	TreeRoot = &ParentFcb->Root;


    //
    //  Insert the Lcb into the prefix tree.
    //
    
    if (!xixfs_NLInsertNameLink( IrpContext,
                            TreeRoot,
                            Lcb )) {

        //
        //  This will very rarely occur.
        //

        xixfs_FreeLCB( Lcb );

        Lcb = xixfs_NLFindNameLink( IrpContext,
                               TreeRoot,
                               Name );

        if (Lcb == NULL) {

            //
            //  Even worse.
            //

            XifsdRaiseStatus( IrpContext, STATUS_DRIVER_INTERNAL_ERROR );
        }


		if(!XIXCORE_TEST_FLAGS(Lcb->LCBFlags, XIFSD_LCB_STATE_IGNORE_CASE_SET)){
			XifsdRaiseStatus( IrpContext, STATUS_DRIVER_INTERNAL_ERROR );
		}

        return Lcb;
    }

	//
	//  Capture the separate cases.
	//

	TreeRoot = &ParentFcb->IgnoreCaseRoot;
 

    //
    //  Set up the filename in the Lcb.
    //

 	RtlDowncaseUnicodeString(&(Lcb->IgnoreCaseFileName),
						Name,
						FALSE);


	if(!xixfs_NLInsertNameLinkIgnoreCase( IrpContext,
									TreeRoot,
									Lcb )){
		XifsdRaiseStatus( IrpContext, STATUS_DRIVER_INTERNAL_ERROR );
	}


	XIXCORE_SET_FLAGS(Lcb->LCBFlags, XIFSD_LCB_STATE_IGNORE_CASE_SET);

    //
    //  Link the Fcbs together through the Lcb.
    //

    Lcb->ParentFcb = ParentFcb;
    Lcb->ChildFcb = Fcb;

    InsertHeadList( &ParentFcb->ChildLcbQueue, &Lcb->ParentFcbLinks );
    InsertHeadList( &Fcb->ParentLcbQueue, &Lcb->ChildFcbLinks );

    //
    //  Initialize the reference count.
    //

    Lcb->Reference = 0;
    

	//DbgPrint(" !!!Insert LCB FileName(%wZ) IgnoreFileName(%wZ)  .\n", &Lcb->FileName, &Lcb->IgnoreCaseFileName);

	DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CREATE|DEBUG_TARGET_CLOSE| DEBUG_TARGET_FCB),
		("Exit xixfs_FCBTLBInsertPrefix \n" ));
    return Lcb;
}
Esempio n. 3
0
PNDAS_FCB
ReadonlyAllocateFcb (
	IN PFILESPY_DEVICE_EXTENSION	DevExt,
	IN PUNICODE_STRING				FullFileName,
	IN BOOLEAN						IsPagingFile
    )
{
    PNDAS_FCB fcb;

	
    fcb = FsRtlAllocatePoolWithTag( NonPagedPool,
									sizeof(NDAS_FCB),
									LFS_FCB_TAG );
	
	if (fcb == NULL) {
	
		SPY_LOG_PRINT( LFS_DEBUG_READONLY_ERROR, ("ReadonlyAllocateFcb: failed to allocate fcb\n") );
		return NULL;
	}
	
	RtlZeroMemory( fcb, sizeof(NDAS_FCB) );

    fcb->NonPaged = LfsAllocateNonPagedFcb();
	
	if (fcb->NonPaged == NULL) {
	
		SPY_LOG_PRINT( LFS_DEBUG_READONLY_ERROR, ("ReadonlyAllocateFcb: failed to allocate fcb->NonPaged\n") );
		ExFreePool( fcb );
		
		return NULL;
	}

    RtlZeroMemory( fcb->NonPaged, sizeof(NON_PAGED_FCB) );

#define FAT_NTC_FCB                      (0x0502)
	
	fcb->Header.NodeTypeCode = FAT_NTC_FCB;
	fcb->Header.IsFastIoPossible = FastIoIsPossible;
    fcb->Header.Resource = LfsAllocateResource();
	fcb->Header.PagingIoResource = NULL; //fcb->Header.Resource;
	
	if (fcb->Header.Resource == NULL) {
	
		SPY_LOG_PRINT( LFS_DEBUG_READONLY_ERROR, ("ReadonlyAllocateFcb: failed to allocate fcb->Header.Resource\n") );
		ExFreePool( fcb->NonPaged );
		ExFreePool( fcb );
		return NULL;
	}

	if (LfsFsRtlTeardownPerStreamContexts) {

		ExInitializeFastMutex( &fcb->NonPaged->AdvancedFcbHeaderMutex );
		FsRtlSetupAdvancedHeader( &fcb->Header, &fcb->NonPaged->AdvancedFcbHeaderMutex );

		if (IsPagingFile) {

			ClearFlag( fcb->Header.Flags2, FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS );
		}
	}

	FsRtlInitializeFileLock( &fcb->FileLock, NULL, NULL );

	fcb->ReferenceCount = 1;
	InitializeListHead( &fcb->ListEntry );

	fcb->Readonly = DevExt->LfsDeviceExt.Readonly;

    RtlInitEmptyUnicodeString( &fcb->FullFileName,
							   fcb->FullFileNameBuffer,
							   sizeof(fcb->FullFileNameBuffer) );

	RtlCopyUnicodeString( &fcb->FullFileName, FullFileName );

    RtlInitEmptyUnicodeString( &fcb->CaseInSensitiveFullFileName,
							   fcb->CaseInSensitiveFullFileNameBuffer,
							   sizeof(fcb->CaseInSensitiveFullFileNameBuffer) );

	RtlDowncaseUnicodeString( &fcb->CaseInSensitiveFullFileName,
							  &fcb->FullFileName,
							  FALSE );

	if(FullFileName->Length)
		if(FullFileName->Buffer[0] != L'\\')
			ASSERT( LFS_BUG );
	
	return fcb;
}
Esempio n. 4
0
PNDAS_FCB
ReadonlyLookUpFcb (
	IN PFILESPY_DEVICE_EXTENSION	DevExt,
	IN PUNICODE_STRING				FullFileName,
    IN BOOLEAN						CaseInSensitive
	)
{
	PNDAS_FCB		fcb = NULL;
    PLIST_ENTRY		listEntry;
	KIRQL			oldIrql;
	UNICODE_STRING	caseInSensitiveFullFileName;
	PWCHAR			caseInSensitiveFullFileNameBuffer;
	NTSTATUS		downcaseStatus;

	//
	//	Allocate a name buffer
	//

	caseInSensitiveFullFileNameBuffer = ExAllocatePoolWithTag(NonPagedPool, NDFS_MAX_PATH, LFS_ALLOC_TAG);
	
	if (caseInSensitiveFullFileNameBuffer == NULL) {
	
		ASSERT( LFS_REQUIRED );
		return NULL;
	}

	ASSERT( FullFileName->Length <= NDFS_MAX_PATH*sizeof(WCHAR) );

	if (CaseInSensitive == TRUE) {

		RtlInitEmptyUnicodeString( &caseInSensitiveFullFileName,
								   caseInSensitiveFullFileNameBuffer,
								   NDFS_MAX_PATH );

		downcaseStatus = RtlDowncaseUnicodeString( &caseInSensitiveFullFileName,
												   FullFileName,
												   FALSE );
	
		if (downcaseStatus != STATUS_SUCCESS) {

			ExFreePool( caseInSensitiveFullFileNameBuffer );
			ASSERT( LFS_UNEXPECTED );
			return NULL;
		}
	}

	KeAcquireSpinLock( &DevExt->LfsDeviceExt.Readonly->FcbQSpinLock, &oldIrql );

    for (listEntry = DevExt->LfsDeviceExt.Readonly->FcbQueue.Flink;
         listEntry != &DevExt->LfsDeviceExt.Readonly->FcbQueue;
         listEntry = listEntry->Flink) {

		fcb = CONTAINING_RECORD( listEntry, NDAS_FCB, ListEntry );
		
		if (fcb->FullFileName.Length != FullFileName->Length) {

			fcb = NULL;
			continue;
		}

		if (CaseInSensitive == TRUE) {

			if (RtlEqualMemory(fcb->CaseInSensitiveFullFileName.Buffer, 
							   caseInSensitiveFullFileName.Buffer, 
							   fcb->CaseInSensitiveFullFileName.Length)) {

				InterlockedIncrement( &fcb->ReferenceCount );
				break;
			}
		
		} else {

			if (RtlEqualMemory(fcb->FullFileName.Buffer,
							   FullFileName->Buffer,
							   fcb->FullFileName.Length)) {

				InterlockedIncrement( &fcb->ReferenceCount );
				break;
			}
		}

		fcb = NULL;
	}

	KeReleaseSpinLock( &DevExt->LfsDeviceExt.Readonly->FcbQSpinLock, oldIrql );

	ExFreePool( caseInSensitiveFullFileNameBuffer );

	return fcb;
}
Esempio n. 5
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);
}