Пример #1
0
NTSTATUS
RfsdAllowExtendedDasdIo(IN PRFSD_IRP_CONTEXT IrpContext)
{
    PIO_STACK_LOCATION IrpSp;
    PRFSD_VCB Vcb;
    PRFSD_CCB Ccb;

    PAGED_CODE();

    IrpSp = IoGetCurrentIrpStackLocation(IrpContext->Irp);

    Vcb = (PRFSD_VCB) IrpSp->FileObject->FsContext;
    Ccb = (PRFSD_CCB) IrpSp->FileObject->FsContext2;

    ASSERT(Vcb != NULL);

    ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
           (Vcb->Identifier.Size == sizeof(RFSD_VCB)));

    ASSERT(IsMounted(Vcb));

    if (Ccb) {
        SetFlag(Ccb->Flags, CCB_ALLOW_EXTENDED_DASD_IO);

        RfsdCompleteIrpContext(IrpContext, STATUS_SUCCESS);

        return STATUS_SUCCESS;
    } else {
        return STATUS_INVALID_PARAMETER;
    }
}
Пример #2
0
void CHeavyMountedWeapon::ProcessEvent(SEntityEvent& event)
{
	if ((event.event == ENTITY_EVENT_XFORM) && IsMounted() && GetOwnerId())
	{
		const float Z_EPSILON = 0.01f;
		const Ang3& worldAngles = GetEntity()->GetWorldAngles();
		float xAngle = worldAngles.x;
		float zAngle = worldAngles.z;
		bool xAnglesAreEquivalent = (fabs(xAngle-m_lastXAngle)<Z_EPSILON);
		bool zAnglesAreEquivalent = (fabs(zAngle-m_lastZAngle)<Z_EPSILON);
		if (!xAnglesAreEquivalent || !zAnglesAreEquivalent)
		{
			if (m_rotatingSoundID==INVALID_SOUNDID)
				m_rotatingSoundID = PlayRotationSound();
			m_RotationSoundTimeOut = 0.15f;
			RequireUpdate( eIUS_General );
			m_lastXAngle = xAngle;
			m_lastZAngle = zAngle;
		}
			
		int flags = (int)event.nParam[0];
		if ((flags & ENTITY_XFORM_FROM_PARENT) && !(flags & ENTITY_XFORM_USER))
		{
			if (CActor* pOwnerActor = GetOwnerActor())
			{
				pOwnerActor->UpdateMountedGunController(true);
			}
		}
	}

	BaseClass::ProcessEvent(event);
}
Пример #3
0
bool MountPoint::Mount() 
{
    debug("MountPoint::Mount() Name=%s\n", Name);
    if (IsMounted())
        return Error("Mountpoint %s is already mounted\n", Name);

    Buf.Init();
    State = MOUNTED;
    return OK;
}
Пример #4
0
void CHeavyMountedWeapon::FadeCrosshair( float to, float time, float delay)
{
	if (IsMounted())
	{
		BaseClass::FadeCrosshair(to, time, delay);
	}
	else
	{
		BaseClass::FadeCrosshair(1.0f, time, delay);
	}
}
Пример #5
0
HRESULT Drive::Mount()
{
	// Get our serial
	LoadSerial();

	// Get our serial as a string
	CHAR serialStr[41]; serialStr[40] = 0; UINT outLen = 0x40;
	GetBytesString(m_Serial, 0x14, serialStr, &outLen);
	m_SerialStr = (string)serialStr;
	if (m_DriveType == DEVICE_USBMEMORY_UNIT0 || 
		m_DriveType == DEVICE_USBMEMORY_UNIT1 ||
		m_DriveType == DEVICE_USBMEMORY_UNIT2 )
		m_SerialStr = m_SerialStr + "_USBMU";
	if (m_DriveType == DEVICE_USBMEMORY_Cache0 ||
		m_DriveType == DEVICE_USBMEMORY_Cache1 ||
		m_DriveType == DEVICE_USBMEMORY_Cache2 )
		m_SerialStr = m_SerialStr + "_USBMUC";

	//DebugMsg("Mounting %s",m_MountPoint.c_str());
	char MountConv[260];
	sprintf_s( MountConv, "\\??\\%s", m_MountPoint.c_str() );
	char SysPath[260];
	sprintf_s( SysPath,"%s", m_SystemPath.c_str() );

	STRING sSysPath = { (USHORT)strlen( SysPath ), (USHORT)strlen( SysPath ) + 1, SysPath };
	STRING sMountConv = { (USHORT)strlen( MountConv ), (USHORT)strlen( MountConv ) + 1, MountConv };
	
	//don't try to mount 'Game:' as it's already there
	if (stricmp(m_MountPoint.c_str(), "Game:") != 0)
	{
		int res = ObCreateSymbolicLink( &sMountConv, &sSysPath );
	
		if (res != 0)
		{
			//DebugMsg("Mount failed : %d",res);
			return res;
		}
	}

	HRESULT ret = IsMounted();
	if(ret == 1)
	{
		GetDiskFreeSpaceEx(getRootPath().c_str(),&m_FreeBytesAvailable,&m_TotalNumberOfBytes,&m_TotalNumberOfFreeBytes);
	}
	else
	{
		m_FreeBytesAvailable.QuadPart = 0;
		m_TotalNumberOfBytes.QuadPart =0;
		m_TotalNumberOfFreeBytes.QuadPart=0;

	}
	return ret;
}
Пример #6
0
/* Opens specified file in FLASH file system when an appropriate call to
   fopen() is made.
   
   pFilename is the name of the file to be opened within the file system.
   Flags specify flags to determine open mode of file.  This file system only
    support O_RDONLY.
   
   Returns NULL if an error was encountered or a pointer to a FileHandle object
    representing the requrested file otherwise.
*/
FileHandle* FlashFileSystem::open(const char* pFilename, int Flags)
{
    const SFileSystemEntry*     pEntry = NULL;
    FlashFileSystemFileHandle*  pFileHandle = NULL;
    SSearchContext              SearchContext;
    
    TRACE("FlashFileSystem: Attempt to open file /FLASH/%s with flags:%x\r\n", pFilename, Flags);
    
    // Can't find the file if file system hasn't been mounted.
    if (!IsMounted())
    {
        return NULL;
    }

    // Can only open files in FLASH for read.
    if (O_RDONLY != Flags)
    {
        TRACE("FlashFileSystem: Can only open files for reading.\r\n");
    }
    
    // Attempt to find the specified file in the file system image.
    SearchContext.pKey = pFilename;
    SearchContext.pFLASHBase = m_pFLASHBase;
    pEntry = (const SFileSystemEntry*) bsearch(&SearchContext,
                                               m_pFileEntries,
                                               m_FileCount, 
                                               sizeof(*m_pFileEntries), 
                                               _CompareKeyToFileEntry);
    if(!pEntry)
    {
        // Create failure response.
        TRACE("FlashFileSystem: Failed to find '%s' in file system image.\n", pFilename);
        return NULL;
    }

    // Attempt to find a free file handle.
    pFileHandle = FindFreeFileHandle();
    if (!pFileHandle)
    {
        TRACE("FlashFileSystem: File handle table is full.\n");
        return NULL;
    }
    
    // Initialize the file handle and return it to caller.
    pFileHandle->SetEntry(m_pFLASHBase + pEntry->FileBinaryOffset,
                          m_pFLASHBase + pEntry->FileBinaryOffset + pEntry->FileBinarySize);
    return pFileHandle;
}
Пример #7
0
// Mount
status_t
ClientVolume::Mount(UserSecurityContext* securityContext, Share* share)
{
	if (!securityContext || !share)
		return B_BAD_VALUE;
	ObjectDeleter<UserSecurityContext> securityContextDeleter(securityContext);
	if (IsMounted())
		return B_BAD_VALUE;
	fSecurityContext = securityContext;
	securityContextDeleter.Detach();

	fShare = share;
	fShare->AcquireReference();
	dev_t volumeID = share->GetVolumeID();
	ino_t nodeID = share->GetNodeID();

	// into root node ref
	fRootNodeRef.device = volumeID;
	fRootNodeRef.node = nodeID;

	// get the share permissions
	fSharePermissions = securityContext->GetNodePermissions(volumeID, nodeID);

	// get the root directory
	VolumeManager* volumeManager = VolumeManager::GetDefault();
	Directory* rootDir;
	status_t error = volumeManager->LoadDirectory(volumeID, nodeID, &rootDir);
	if (error != B_OK)
		return error;

	// register with the volume manager
	error = volumeManager->AddClientVolume(this);
	if (error != B_OK) {
		Unmount();
		return error;
	}
	fMounted = true;

	// notify the statistics manager
	StatisticsManager::GetDefault()->ShareMounted(fShare,
		fSecurityContext->GetUser());

	return B_OK;
}
Пример #8
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int	CAI_FuncTankBehavior::SelectSchedule()
{
	// This shouldn't get called with an m_hFuncTank, see CanSelectSchedule.
	Assert( m_hFuncTank );

	// If we've been told to dismount, or we are out of ammo - dismount.
	if ( HasCondition( COND_FUNCTANK_DISMOUNT ) || m_hFuncTank->GetAmmoCount() == 0 )
	{
		if ( m_bMounted )
		{
			Dismount();
		}

		return BaseClass::SelectSchedule();
	}

	// If we are not mounted to a func_tank look for one.
	if ( !IsMounted() )
	{
		return SCHED_MOVE_TO_FUNCTANK;
	}

	// If we have an enemy, it's in the viewcone & we have LOS to it
	if ( GetEnemy() )
	{
		// Tell the func tank whenever we see the player for the first time since not seeing him for a while
		if ( HasCondition( COND_NEW_ENEMY ) && GetEnemy()->IsPlayer() && !m_bSpottedPlayerOutOfCover )
		{
			m_bSpottedPlayerOutOfCover = true;
			m_hFuncTank->NPC_JustSawPlayer( GetEnemy() );
		}

		// Fire at the enemy.
		return SCHED_FIRE_FUNCTANK;
	}
	else
	{
		// Scan for enemies.
		return SCHED_SCAN_WITH_FUNCTANK;
	}

	return SCHED_IDLE_STAND;
}
Пример #9
0
/////////////////////////////////////////////////
/// Opposition: Unit treats another unit as an enemy it can attack (immediate response)
///
/// @note Relations API Tier 1
///
/// Backported from TBC+ client-side counterpart: <tt>CGUnit_C::CanAttackNow(const CGUnit_C *this, const CGUnit_C *unit)</tt>
/// Intended usage is to verify direct requests to attack something.
/// First appeared in TBC+ clients, backported for API unification between expansions.
/////////////////////////////////////////////////
bool Unit::CanAttackNow(const Unit* unit) const
{
    // Simple sanity check
    if (!unit)
        return false;

    // Original logic

    // We can't initiate attack while dead or ghost
    if (!isAlive())
        return false;

    // We can't initiate attack while mounted
    if (IsMounted())
        return false;

    // We can't initiate attack on dead units
    if (!unit->isAlive())
        return false;

    return CanAttack(unit);
}
Пример #10
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CBaseEntity *CAI_FuncTankBehavior::BestEnemy( void )
{
	// Only use this BestEnemy call when we are on the manned gun.
	if ( !m_hFuncTank ||!IsMounted() )
		return BaseClass::BestEnemy();

	CBaseEntity *pBestEnemy	= NULL;
	int	iBestDistSq	= MAX_COORD_RANGE * MAX_COORD_RANGE;	// so first visible entity will become the closest.
	int	iBestPriority = -1000;
	bool bBestUnreachable = false;							// Forces initial check
	bool bBestSeen = false;
	bool bUnreachable = false;
	int	iDistSq;

	AIEnemiesIter_t iter;

	// Get the current npc for checking from.
	CAI_BaseNPC *pNPC = GetOuter();
	if ( !pNPC )
		return NULL;

	for( AI_EnemyInfo_t *pEMemory = GetEnemies()->GetFirst( &iter ); pEMemory != NULL; pEMemory = GetEnemies()->GetNext( &iter ) )
	{
		CBaseEntity *pEnemy = pEMemory->hEnemy;
		if ( !pEnemy || !pEnemy->IsAlive() )
			continue;
		
		// UNDONE: Move relationship checks into IsValidEnemy?
		if ( ( pEnemy->GetFlags() & FL_NOTARGET ) || 
			 ( pNPC->IRelationType( pEnemy ) != D_HT && pNPC->IRelationType( pEnemy ) != D_FR ) ||
			 !IsValidEnemy( pEnemy ) )
			continue;

		if ( pEMemory->timeLastSeen < pNPC->GetAcceptableTimeSeenEnemy() )
			continue;

		if ( pEMemory->timeValidEnemy > gpGlobals->curtime )
			continue;

		// Skip enemies that have eluded me to prevent infinite loops
		if ( GetEnemies()->HasEludedMe( pEnemy ) )
			continue;

		// Establish the reachability of this enemy
		bUnreachable = pNPC->IsUnreachable( pEnemy );

		// Check view cone of the view tank here.
		bUnreachable = !m_hFuncTank->IsEntityInViewCone( pEnemy );
		if ( !bUnreachable )
		{
			// It's in the viewcone. Now make sure we have LOS to it.
			bUnreachable = !m_hFuncTank->HasLOSTo( pEnemy );
		}

		// If best is reachable and current is unreachable, skip the unreachable enemy regardless of priority
		if ( !bBestUnreachable && bUnreachable )
			continue;

		//  If best is unreachable and current is reachable, always pick the current regardless of priority
		if ( bBestUnreachable && !bUnreachable )
		{
			bBestSeen = ( pNPC->GetSenses()->DidSeeEntity( pEnemy ) || pNPC->FVisible( pEnemy ) ); // @TODO (toml 04-02-03): Need to optimize CanSeeEntity() so multiple calls in frame do not recalculate, rather cache
			iBestPriority = pNPC->IRelationPriority( pEnemy );
			iBestDistSq = static_cast<int>((pEnemy->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr());
			pBestEnemy = pEnemy;
			bBestUnreachable = bUnreachable;
		}
		// If both are unreachable or both are reachable, chose enemy based on priority and distance
		else if ( pNPC->IRelationPriority( pEnemy ) > iBestPriority )
		{
			// this entity is disliked MORE than the entity that we
			// currently think is the best visible enemy. No need to do
			// a distance check, just get mad at this one for now.
			iBestPriority = pNPC->IRelationPriority ( pEnemy );
			iBestDistSq = static_cast<int>(( pEnemy->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr());
			pBestEnemy = pEnemy;
			bBestUnreachable = bUnreachable;
		}
		else if ( pNPC->IRelationPriority( pEnemy ) == iBestPriority )
		{
			// this entity is disliked just as much as the entity that
			// we currently think is the best visible enemy, so we only
			// get mad at it if it is closer.
			iDistSq = static_cast<int>(( pEnemy->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr());

			bool bCloser = ( iDistSq < iBestDistSq ) ;

			if ( bCloser || !bBestSeen )
			{
				// @TODO (toml 04-02-03): Need to optimize FVisible() so multiple calls in frame do not recalculate, rather cache
				bool fSeen = ( pNPC->GetSenses()->DidSeeEntity( pEnemy ) || pNPC->FVisible( pEnemy ) );
				if ( ( bCloser && ( fSeen || !bBestSeen ) ) || ( !bCloser && !bBestSeen && fSeen ) )
				{
					bBestSeen = fSeen;
					iBestDistSq = iDistSq;
					iBestPriority = pNPC->IRelationPriority( pEnemy );
					pBestEnemy = pEnemy;
					bBestUnreachable = bUnreachable;
				}
			}
		}
	}
	return pBestEnemy;
}
Пример #11
0
__drv_mustHoldCriticalRegion
NTSTATUS
RfsdDismountVolume (IN PRFSD_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT  DeviceObject;
    NTSTATUS        Status = STATUS_UNSUCCESSFUL;
    PRFSD_VCB       Vcb = 0;
    BOOLEAN         VcbResourceAcquired = FALSE;

    PAGED_CODE();

    _SEH2_TRY {

        ASSERT(IrpContext != NULL);

        ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
        (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;

        //
        // This request is not allowed on the main device object
        //
        if (DeviceObject == RfsdGlobal->DeviceObject) {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            _SEH2_LEAVE;
        }

        Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;

        ASSERT(Vcb != NULL);

        ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
        (Vcb->Identifier.Size == sizeof(RFSD_VCB)));

        ASSERT(IsMounted(Vcb));

        ExAcquireResourceExclusiveLite(
            &Vcb->MainResource,
            TRUE );

        VcbResourceAcquired = TRUE;

        if ( IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) {
            Status = STATUS_VOLUME_DISMOUNTED;
            _SEH2_LEAVE;
        }

        /*
                if (!FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED)) {
                    RfsdPrint((DBG_ERROR, "RfsdDismount: Volume is not locked.\n"));

                    Status = STATUS_ACCESS_DENIED;

                    _SEH2_LEAVE;
                }
        */
#if DISABLED
        RfsdFlushFiles(Vcb, FALSE);

        RfsdFlushVolume(Vcb, FALSE);

        RfsdPurgeVolume(Vcb, TRUE);
#endif
        ExReleaseResourceForThreadLite(
            &Vcb->MainResource,
            ExGetCurrentResourceThread() );

        VcbResourceAcquired = FALSE;

        RfsdCheckDismount(IrpContext, Vcb, TRUE);

        RfsdPrint((DBG_INFO, "RfsdDismount: Volume dismount pending.\n"));

        Status = STATUS_SUCCESS;

    } _SEH2_FINALLY {

        if (VcbResourceAcquired) {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread()
            );
        }

        if (!IrpContext->ExceptionInProgress) {
            RfsdCompleteIrpContext(IrpContext,  Status);
        }
    } _SEH2_END;

    return Status;
}
Пример #12
0
__drv_mustHoldCriticalRegion
NTSTATUS
RfsdVerifyVolume (IN PRFSD_IRP_CONTEXT IrpContext)
{

    PDEVICE_OBJECT          DeviceObject;
    NTSTATUS                Status = STATUS_UNSUCCESSFUL;
    PRFSD_SUPER_BLOCK       rfsd_sb = NULL;
    PRFSD_VCB               Vcb = 0;
    BOOLEAN                 VcbResourceAcquired = FALSE;
    BOOLEAN                 GlobalResourceAcquired = FALSE;
    PIRP                    Irp;
    PIO_STACK_LOCATION      IoStackLocation;
    ULONG                   ChangeCount;
    ULONG                   dwReturn;

    PAGED_CODE();

    _SEH2_TRY {

        ASSERT(IrpContext != NULL);

        ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
        (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;
        //
        // This request is not allowed on the main device object
        //
        if (DeviceObject == RfsdGlobal->DeviceObject) {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            _SEH2_LEAVE;
        }

        ExAcquireResourceExclusiveLite(
            &RfsdGlobal->Resource,
            TRUE );

        GlobalResourceAcquired = TRUE;

        Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;

        ASSERT(Vcb != NULL);

        ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
        (Vcb->Identifier.Size == sizeof(RFSD_VCB)));

        ExAcquireResourceExclusiveLite(
            &Vcb->MainResource,
            TRUE );

        VcbResourceAcquired = TRUE;

        if (!FlagOn(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME)) {
            Status = STATUS_SUCCESS;
            _SEH2_LEAVE;
        }

        if (!IsMounted(Vcb)) {
            Status = STATUS_WRONG_VOLUME;
            _SEH2_LEAVE;
        }

        dwReturn = sizeof(ULONG);
        Status = RfsdDiskIoControl(
            Vcb->TargetDeviceObject,
            IOCTL_DISK_CHECK_VERIFY,
            NULL,
            0,
            &ChangeCount,
            &dwReturn );

        if (ChangeCount != Vcb->ChangeCount) {
            Status = STATUS_WRONG_VOLUME;
            _SEH2_LEAVE;
        }

        Irp = IrpContext->Irp;

        IoStackLocation = IoGetCurrentIrpStackLocation(Irp);

        rfsd_sb = RfsdLoadSuper(Vcb, TRUE);

        // FUTURE: use the volume name and uuid from the extended superblock to make this happen.
        // NOTE: The magic check will have to use the same thing as mount did!
        if ((rfsd_sb != NULL) /*&& (rfsd_sb->s_magic == RFSD_SUPER_MAGIC) &&
            (memcmp(rfsd_sb->s_uuid, SUPER_BLOCK->s_uuid, 16) == 0) &&
            (memcmp(rfsd_sb->s_volume_name, SUPER_BLOCK->s_volume_name, 16) ==0)*/) {
            ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);

            if (RfsdIsMediaWriteProtected(IrpContext, Vcb->TargetDeviceObject)) {
                SetFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
            } else {
                ClearFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
            }

            RfsdPrint((DBG_INFO, "RfsdVerifyVolume: Volume verify succeeded.\n"));

            Status = STATUS_SUCCESS;
        } else {
            Status = STATUS_WRONG_VOLUME;

            RfsdPurgeVolume(Vcb, FALSE);

            SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);

            ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);

            RfsdPrint((DBG_INFO, "RfsdVerifyVolume: Volume verify failed.\n"));
        }

    } _SEH2_FINALLY {

        if (rfsd_sb)
            ExFreePool(rfsd_sb);

        if (VcbResourceAcquired) {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread()
            );
        }

        if (GlobalResourceAcquired) {
            ExReleaseResourceForThreadLite(
                &RfsdGlobal->Resource,
                ExGetCurrentResourceThread() );
        }

        if (!IrpContext->ExceptionInProgress) {
            RfsdCompleteIrpContext(IrpContext,  Status);
        }
    } _SEH2_END;

    return Status;
}
Пример #13
0
NTSTATUS
Ext2SetVolumeInformation (IN PEXT2_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT          DeviceObject;
    NTSTATUS                Status = STATUS_UNSUCCESSFUL;
    PEXT2_VCB               Vcb;
    PIRP                    Irp;
    PIO_STACK_LOCATION      IoStackLocation;
    FS_INFORMATION_CLASS    FsInformationClass;
    BOOLEAN                 VcbResourceAcquired = FALSE;

    __try {

        ASSERT(IrpContext != NULL);

        ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
               (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;

        //
        // This request is not allowed on the main device object
        //
        if (IsExt2FsDevice(DeviceObject)) {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }

        Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
        ASSERT(Vcb != NULL);
        ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
               (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
        ASSERT(IsMounted(Vcb));

        if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
            Status = STATUS_MEDIA_WRITE_PROTECTED;
            __leave;
        }

        if (!ExAcquireResourceExclusiveLite(
                    &Vcb->MainResource, TRUE)) {
            Status = STATUS_PENDING;
            __leave;
        }
        VcbResourceAcquired = TRUE;

        Ext2VerifyVcb(IrpContext, Vcb);

        Irp = IrpContext->Irp;
        IoStackLocation = IoGetCurrentIrpStackLocation(Irp);

        //Notes: SetVolume is not defined in ntddk.h of win2k ddk,
        //       But it's same to QueryVolume ....
        FsInformationClass =
            IoStackLocation->Parameters./*SetVolume*/QueryVolume.FsInformationClass;

        switch (FsInformationClass) {

        case FileFsLabelInformation:
        {
            PFILE_FS_LABEL_INFORMATION      VolLabelInfo = NULL;
            ULONG                           VolLabelLen;
            UNICODE_STRING                  LabelName  ;

            OEM_STRING                      OemName;

            VolLabelInfo = (PFILE_FS_LABEL_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
            VolLabelLen = VolLabelInfo->VolumeLabelLength;

            if (VolLabelLen > (16 * sizeof(WCHAR))) {
                Status = STATUS_INVALID_VOLUME_LABEL;
                __leave;
            }

            RtlCopyMemory( Vcb->Vpb->VolumeLabel,
                           VolLabelInfo->VolumeLabel,
                           VolLabelLen );

            RtlZeroMemory(Vcb->SuperBlock->s_volume_name, 16);
            LabelName.Buffer = VolLabelInfo->VolumeLabel;
            LabelName.MaximumLength = (USHORT)16 * sizeof(WCHAR);
            LabelName.Length = (USHORT)VolLabelLen;

            OemName.Buffer = SUPER_BLOCK->s_volume_name;
            OemName.Length  = 0;
            OemName.MaximumLength = 16;

            Ext2UnicodeToOEM(Vcb, &OemName, &LabelName);
            Vcb->Vpb->VolumeLabelLength = (USHORT) VolLabelLen;

            if (Ext2SaveSuper(IrpContext, Vcb)) {
                Status = STATUS_SUCCESS;
            }

            Irp->IoStatus.Information = 0;
        }
        break;

        default:
            Status = STATUS_INVALID_INFO_CLASS;
        }

    } __finally {

        if (VcbResourceAcquired) {
            ExReleaseResourceLite(&Vcb->MainResource);
        }

        if (!IrpContext->ExceptionInProgress) {
            if (Status == STATUS_PENDING) {
                Ext2QueueRequest(IrpContext);
            } else {
                Ext2CompleteIrpContext(IrpContext, Status);
            }
        }
    }

    return Status;
}
Пример #14
0
__drv_mustHoldCriticalRegion
NTSTATUS
FFSVerifyVolume(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	PDEVICE_OBJECT          DeviceObject;
	NTSTATUS                Status = STATUS_UNSUCCESSFUL;
	PFFS_SUPER_BLOCK        FFSSb = NULL;
	PFFS_VCB                Vcb = 0;
	BOOLEAN                 VcbResourceAcquired = FALSE;
	BOOLEAN                 GlobalResourceAcquired = FALSE;
	PIRP                    Irp;
	PIO_STACK_LOCATION      IoStackLocation;
	ULONG                   ChangeCount;
	ULONG                   dwReturn;

    PAGED_CODE();

	_SEH2_TRY
	{
		ASSERT(IrpContext != NULL);

		ASSERT((IrpContext->Identifier.Type == FFSICX) &&
				(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

		DeviceObject = IrpContext->DeviceObject;
		//
		// This request is not allowed on the main device object
		//
		if (DeviceObject == FFSGlobal->DeviceObject)
		{
			Status = STATUS_INVALID_DEVICE_REQUEST;
			_SEH2_LEAVE;
		}

		ExAcquireResourceExclusiveLite(
				&FFSGlobal->Resource,
				TRUE);

		GlobalResourceAcquired = TRUE;

		Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;

		ASSERT(Vcb != NULL);

		ASSERT((Vcb->Identifier.Type == FFSVCB) &&
				(Vcb->Identifier.Size == sizeof(FFS_VCB)));

		ExAcquireResourceExclusiveLite(
				&Vcb->MainResource,
				TRUE);

		VcbResourceAcquired = TRUE;

		if (!FlagOn(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME))
		{
			Status = STATUS_SUCCESS;
			_SEH2_LEAVE;
		}

		if (!IsMounted(Vcb))
		{
			Status = STATUS_WRONG_VOLUME;
			_SEH2_LEAVE;
		}

		dwReturn = sizeof(ULONG);
		Status = FFSDiskIoControl(
				Vcb->TargetDeviceObject,
				IOCTL_DISK_CHECK_VERIFY,
				NULL,
				0,
				&ChangeCount,
				&dwReturn);

		if (ChangeCount != Vcb->ChangeCount)
		{
			Status = STATUS_WRONG_VOLUME;
			_SEH2_LEAVE;
		}

		Irp = IrpContext->Irp;

		IoStackLocation = IoGetCurrentIrpStackLocation(Irp);

		if (((((FFSSb = FFSLoadSuper(Vcb, TRUE, SBLOCK_UFS1)) != NULL) && (FFSSb->fs_magic == FS_UFS1_MAGIC)) ||
			 (((FFSSb = FFSLoadSuper(Vcb, TRUE, SBLOCK_UFS2)) != NULL) && (FFSSb->fs_magic == FS_UFS2_MAGIC))) &&
				(memcmp(FFSSb->fs_id, SUPER_BLOCK->fs_id, 8) == 0) &&
				(memcmp(FFSSb->fs_volname, SUPER_BLOCK->fs_volname, 16) == 0))
		{
			ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);

			if (FFSIsMediaWriteProtected(IrpContext, Vcb->TargetDeviceObject))
			{
				SetFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
			}
			else
			{
				ClearFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
			}

			FFSPrint((DBG_INFO, "FFSVerifyVolume: Volume verify succeeded.\n"));

			Status = STATUS_SUCCESS;
		}
		else
		{
			Status = STATUS_WRONG_VOLUME;

			FFSPurgeVolume(Vcb, FALSE);

			SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);

			ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);

			FFSPrint((DBG_INFO, "FFSVerifyVolume: Volume verify failed.\n"));
		}
	}

	_SEH2_FINALLY
	{
		if (FFSSb)
			ExFreePool(FFSSb);

		if (VcbResourceAcquired)
		{
			ExReleaseResourceForThreadLite(
					&Vcb->MainResource,
					ExGetCurrentResourceThread());
		}

		if (GlobalResourceAcquired)
		{
			ExReleaseResourceForThreadLite(
					&FFSGlobal->Resource,
					ExGetCurrentResourceThread());
		}

		if (!IrpContext->ExceptionInProgress)
		{
			FFSCompleteIrpContext(IrpContext,  Status);
		}
	} _SEH2_END;

	return Status;
}
Пример #15
0
NTSTATUS
FFSWrite(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	NTSTATUS            Status;
	PFFS_FCBVCB         FcbOrVcb;
	PDEVICE_OBJECT      DeviceObject;
	PFILE_OBJECT        FileObject;
	PFFS_VCB            Vcb;
	BOOLEAN             bCompleteRequest = TRUE;

	ASSERT(IrpContext);

	ASSERT((IrpContext->Identifier.Type == FFSICX) &&
			(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

	__try
	{
		if (FlagOn(IrpContext->MinorFunction, IRP_MN_COMPLETE))
		{
			Status = FFSWriteComplete(IrpContext);
			bCompleteRequest = FALSE;
		}
		else
		{
			DeviceObject = IrpContext->DeviceObject;

			if (DeviceObject == FFSGlobal->DeviceObject)
			{
				Status = STATUS_INVALID_DEVICE_REQUEST;
				__leave;
			}

			Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;

			if (Vcb->Identifier.Type != FFSVCB ||
					Vcb->Identifier.Size != sizeof(FFS_VCB))
			{
				Status = STATUS_INVALID_PARAMETER;
				__leave;
			}

			ASSERT(IsMounted(Vcb));

			if (IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING))
			{
				Status = STATUS_TOO_LATE;
				__leave;
			}

			if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
			{
				Status = STATUS_MEDIA_WRITE_PROTECTED;
				__leave;
			}

			FileObject = IrpContext->FileObject;

			FcbOrVcb = (PFFS_FCBVCB)FileObject->FsContext;

			if (FcbOrVcb->Identifier.Type == FFSVCB)
			{
				Status = FFSWriteVolume(IrpContext);

				if (!NT_SUCCESS(Status))
				{
					FFSBreakPoint();
				}

				bCompleteRequest = FALSE;
			}
			else if (FcbOrVcb->Identifier.Type == FFSFCB)
			{
				Status = FFSWriteFile(IrpContext);

				if (!NT_SUCCESS(Status))
				{
					FFSBreakPoint();
				}

				bCompleteRequest = FALSE;
			}
			else
			{
				Status = STATUS_INVALID_PARAMETER;
			}
		}
	}

	__finally
	{
		if (bCompleteRequest)
		{
			FFSCompleteIrpContext(IrpContext, Status);
		}
	}

	return Status;
}
Пример #16
0
NTSTATUS
Ext2QueryVolumeInformation (IN PEXT2_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT          DeviceObject;
    NTSTATUS                Status = STATUS_UNSUCCESSFUL;
    PEXT2_VCB               Vcb;
    PIRP                    Irp;
    PIO_STACK_LOCATION      IoStackLocation;
    FS_INFORMATION_CLASS    FsInformationClass;
    ULONG                   Length;
    PVOID                   Buffer;
    BOOLEAN                 VcbResourceAcquired = FALSE;

    __try {

        ASSERT(IrpContext != NULL);
        ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
               (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;

        //
        // This request is not allowed on the main device object
        //
        if (IsExt2FsDevice(DeviceObject)) {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }

        Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
        ASSERT(Vcb != NULL);
        ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
               (Vcb->Identifier.Size == sizeof(EXT2_VCB)));

        if (!IsMounted(Vcb)) {
            Status = STATUS_VOLUME_DISMOUNTED;
            __leave;
        }

        if (!ExAcquireResourceSharedLite(
                    &Vcb->MainResource,
                    IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)
                )) {

            Status = STATUS_PENDING;
            __leave;
        }
        VcbResourceAcquired = TRUE;

        Irp = IrpContext->Irp;
        IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
        FsInformationClass =
            IoStackLocation->Parameters.QueryVolume.FsInformationClass;

        Length = IoStackLocation->Parameters.QueryVolume.Length;
        Buffer = Irp->AssociatedIrp.SystemBuffer;

        RtlZeroMemory(Buffer, Length);

        switch (FsInformationClass) {

        case FileFsVolumeInformation:
        {
            PFILE_FS_VOLUME_INFORMATION FsVolInfo;
            ULONG                       VolumeLabelLength;
            ULONG                       RequiredLength;

            if (Length < sizeof(FILE_FS_VOLUME_INFORMATION)) {
                Status = STATUS_BUFFER_OVERFLOW;
                __leave;
            }

            FsVolInfo = (PFILE_FS_VOLUME_INFORMATION) Buffer;
            FsVolInfo->VolumeCreationTime.QuadPart = 0;
            FsVolInfo->VolumeSerialNumber = Vcb->Vpb->SerialNumber;
            VolumeLabelLength = Vcb->Vpb->VolumeLabelLength;
            FsVolInfo->VolumeLabelLength = VolumeLabelLength;
            /* We don't support ObjectId */
            FsVolInfo->SupportsObjects = FALSE;

            RequiredLength = sizeof(FILE_FS_VOLUME_INFORMATION)
                             + VolumeLabelLength - sizeof(WCHAR);

            if (Length < RequiredLength) {
                Irp->IoStatus.Information =
                    sizeof(FILE_FS_VOLUME_INFORMATION);
                Status = STATUS_BUFFER_OVERFLOW;
                __leave;
            }

            RtlCopyMemory(FsVolInfo->VolumeLabel, Vcb->Vpb->VolumeLabel, Vcb->Vpb->VolumeLabelLength);

            Irp->IoStatus.Information = RequiredLength;
            Status = STATUS_SUCCESS;
        }
        break;

        case FileFsSizeInformation:
        {
            PFILE_FS_SIZE_INFORMATION FsSizeInfo;

            if (Length < sizeof(FILE_FS_SIZE_INFORMATION)) {
                Status = STATUS_BUFFER_OVERFLOW;
                __leave;
            }

            FsSizeInfo = (PFILE_FS_SIZE_INFORMATION) Buffer;
            FsSizeInfo->TotalAllocationUnits.QuadPart =
                ext3_blocks_count(SUPER_BLOCK);
            FsSizeInfo->AvailableAllocationUnits.QuadPart =
                ext3_free_blocks_count(SUPER_BLOCK);
            FsSizeInfo->SectorsPerAllocationUnit =
                Vcb->BlockSize / Vcb->DiskGeometry.BytesPerSector;
            FsSizeInfo->BytesPerSector =
                Vcb->DiskGeometry.BytesPerSector;

            Irp->IoStatus.Information = sizeof(FILE_FS_SIZE_INFORMATION);
            Status = STATUS_SUCCESS;
        }
        break;

        case FileFsDeviceInformation:
        {
            PFILE_FS_DEVICE_INFORMATION FsDevInfo;

            if (Length < sizeof(FILE_FS_DEVICE_INFORMATION)) {
                Status = STATUS_BUFFER_OVERFLOW;
                __leave;
            }

            FsDevInfo = (PFILE_FS_DEVICE_INFORMATION) Buffer;
            FsDevInfo->DeviceType =
                Vcb->TargetDeviceObject->DeviceType;

            if (FsDevInfo->DeviceType != FILE_DEVICE_DISK) {
                DbgBreak();
            }

            FsDevInfo->Characteristics =
                Vcb->TargetDeviceObject->Characteristics;

            if (FlagOn(Vcb->Flags, VCB_READ_ONLY)) {

                SetFlag( FsDevInfo->Characteristics,
                         FILE_READ_ONLY_DEVICE   );
            }

            Irp->IoStatus.Information = sizeof(FILE_FS_DEVICE_INFORMATION);
            Status = STATUS_SUCCESS;
        }
        break;

        case FileFsAttributeInformation:
        {
            PFILE_FS_ATTRIBUTE_INFORMATION  FsAttrInfo;
            ULONG                           RequiredLength;

            if (Length < sizeof(FILE_FS_ATTRIBUTE_INFORMATION)) {
                Status = STATUS_BUFFER_OVERFLOW;
                __leave;
            }

            FsAttrInfo =
                (PFILE_FS_ATTRIBUTE_INFORMATION) Buffer;
            FsAttrInfo->FileSystemAttributes =
                FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
            FsAttrInfo->MaximumComponentNameLength = EXT2_NAME_LEN;
            FsAttrInfo->FileSystemNameLength = 8;

            RequiredLength = sizeof(FILE_FS_ATTRIBUTE_INFORMATION) +
                             8 - sizeof(WCHAR);

            if (Length < RequiredLength) {
                Irp->IoStatus.Information =
                    sizeof(FILE_FS_ATTRIBUTE_INFORMATION);
                Status = STATUS_BUFFER_OVERFLOW;
                __leave;
            }

            if (Vcb->IsExt3fs) {
                RtlCopyMemory(FsAttrInfo->FileSystemName,  L"EXT3\0", 10);
            } else {
                RtlCopyMemory(FsAttrInfo->FileSystemName,  L"EXT2\0", 10);
            }

            Irp->IoStatus.Information = RequiredLength;
            Status = STATUS_SUCCESS;
        }
        break;

#if (_WIN32_WINNT >= 0x0500)

        case FileFsFullSizeInformation:
        {
            PFILE_FS_FULL_SIZE_INFORMATION PFFFSI;

            if (Length < sizeof(FILE_FS_FULL_SIZE_INFORMATION)) {
                Status = STATUS_BUFFER_OVERFLOW;
                __leave;
            }

            PFFFSI = (PFILE_FS_FULL_SIZE_INFORMATION) Buffer;

            /*
                            typedef struct _FILE_FS_FULL_SIZE_INFORMATION {
                                LARGE_INTEGER   TotalAllocationUnits;
                                LARGE_INTEGER   CallerAvailableAllocationUnits;
                                LARGE_INTEGER   ActualAvailableAllocationUnits;
                                ULONG           SectorsPerAllocationUnit;
                                ULONG           BytesPerSector;
                            } FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;
            */

            {
                PFFFSI->TotalAllocationUnits.QuadPart =
                    ext3_blocks_count(SUPER_BLOCK);

                PFFFSI->CallerAvailableAllocationUnits.QuadPart =
                    ext3_free_blocks_count(SUPER_BLOCK);

                /* - Vcb->SuperBlock->s_r_blocks_count; */
                PFFFSI->ActualAvailableAllocationUnits.QuadPart =
                    ext3_free_blocks_count(SUPER_BLOCK);
            }

            PFFFSI->SectorsPerAllocationUnit =
                Vcb->BlockSize / Vcb->DiskGeometry.BytesPerSector;

            PFFFSI->BytesPerSector = Vcb->DiskGeometry.BytesPerSector;

            Irp->IoStatus.Information = sizeof(FILE_FS_FULL_SIZE_INFORMATION);
            Status = STATUS_SUCCESS;
        }
        break;

#endif // (_WIN32_WINNT >= 0x0500)

        default:
            Status = STATUS_INVALID_INFO_CLASS;
            break;
        }

    } __finally {

        if (VcbResourceAcquired) {
            ExReleaseResourceLite(&Vcb->MainResource);
        }

        if (!IrpContext->ExceptionInProgress) {
            if (Status == STATUS_PENDING) {
                Ext2QueueRequest(IrpContext);
            } else {
                Ext2CompleteIrpContext(IrpContext, Status);
            }
        }
    }

    return Status;
}
Пример #17
0
__drv_mustHoldCriticalRegion
NTSTATUS
RfsdSetVolumeInformation (IN PRFSD_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT          DeviceObject;
    NTSTATUS                Status = STATUS_UNSUCCESSFUL;
    PRFSD_VCB               Vcb;
    PIRP                    Irp;
    PIO_STACK_LOCATION      IoStackLocation;
    FS_INFORMATION_CLASS    FsInformationClass;

    PAGED_CODE();

    _SEH2_TRY {

        ASSERT(IrpContext != NULL);
        
        ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
            (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
        
        DeviceObject = IrpContext->DeviceObject;
    
        //
        // This request is not allowed on the main device object
        //
        if (DeviceObject == RfsdGlobal->DeviceObject) {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            _SEH2_LEAVE;
        }
        
        Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
        
        ASSERT(Vcb != NULL);
        
        ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
            (Vcb->Identifier.Size == sizeof(RFSD_VCB)));

        ASSERT(IsMounted(Vcb));

        if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
            Status = STATUS_MEDIA_WRITE_PROTECTED;
            _SEH2_LEAVE;
        }
        
        Irp = IrpContext->Irp;
        
        IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
        
        //Notes: SetVolume is not defined in ntddk.h of win2k ddk,
        //       But it's same to QueryVolume ....
        FsInformationClass =
            IoStackLocation->Parameters./*SetVolume*/QueryVolume.FsInformationClass;
        
        switch (FsInformationClass) {
#if 0
        case FileFsLabelInformation:
            {
                PFILE_FS_LABEL_INFORMATION      VolLabelInfo = NULL;
                ULONG                           VolLabelLen;
                UNICODE_STRING                  LabelName  ;

                OEM_STRING                      OemName;

                VolLabelInfo = (PFILE_FS_LABEL_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
        
                VolLabelLen = VolLabelInfo->VolumeLabelLength;

                if(VolLabelLen > (16 * sizeof(WCHAR))) {
                    Status = STATUS_INVALID_VOLUME_LABEL;
                    _SEH2_LEAVE;
                }
               
                RtlCopyMemory( Vcb->Vpb->VolumeLabel,
                               VolLabelInfo->VolumeLabel,
                               VolLabelLen );

                RtlZeroMemory(Vcb->SuperBlock->s_volume_name, 16);

                LabelName.Buffer = VolLabelInfo->VolumeLabel;
                LabelName.MaximumLength = (USHORT)16 * sizeof(WCHAR);
                LabelName.Length = (USHORT)VolLabelLen;

                OemName.Buffer = SUPER_BLOCK->s_volume_name;
                OemName.Length  = 0;
                OemName.MaximumLength = 16;

                RfsdUnicodeToOEM( &OemName,
                                  &LabelName);

                Vcb->Vpb->VolumeLabelLength = 
                       (USHORT) VolLabelLen;

                if (RfsdSaveSuper(IrpContext, Vcb)) {
                    Status = STATUS_SUCCESS;
                }

                Irp->IoStatus.Information = 0;

            }
            break;
#endif // 0
          default:
            Status = STATUS_INVALID_INFO_CLASS;
        }

    } _SEH2_FINALLY {
       
        if (!IrpContext->ExceptionInProgress) {
            if (Status == STATUS_PENDING) {
                RfsdQueueRequest(IrpContext);
            } else {
                RfsdCompleteIrpContext(IrpContext, Status);
            }
        }
    } _SEH2_END;
    
    return Status;
}
Пример #18
0
__drv_mustHoldCriticalRegion
NTSTATUS
FFSNotifyChangeDirectory(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	PDEVICE_OBJECT      DeviceObject;
	BOOLEAN             CompleteRequest;
	NTSTATUS            Status = STATUS_UNSUCCESSFUL;
	PFFS_VCB            Vcb;
	PFILE_OBJECT        FileObject;
	PFFS_FCB            Fcb = 0;
	PIRP                Irp;
	PIO_STACK_LOCATION  IrpSp;
	ULONG               CompletionFilter;
	BOOLEAN             WatchTree;

	BOOLEAN             bFcbAcquired = FALSE;

	PUNICODE_STRING     FullName;

    PAGED_CODE();

	_SEH2_TRY
	{
		ASSERT(IrpContext);

		ASSERT((IrpContext->Identifier.Type == FFSICX) &&
				(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

		//
		//  Always set the wait flag in the Irp context for the original request.
		//

		SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);

		DeviceObject = IrpContext->DeviceObject;

		if (DeviceObject == FFSGlobal->DeviceObject)
		{
			CompleteRequest = TRUE;
			Status = STATUS_INVALID_DEVICE_REQUEST;
			_SEH2_LEAVE;
		}

		Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;

		ASSERT(Vcb != NULL);

		ASSERT((Vcb->Identifier.Type == FFSVCB) &&
				(Vcb->Identifier.Size == sizeof(FFS_VCB)));

		ASSERT(IsMounted(Vcb));

		FileObject = IrpContext->FileObject;

		Fcb = (PFFS_FCB)FileObject->FsContext;

		ASSERT(Fcb);

		if (Fcb->Identifier.Type == FFSVCB)
		{
			FFSBreakPoint();
			CompleteRequest = TRUE;
			Status = STATUS_INVALID_PARAMETER;
			_SEH2_LEAVE;
		}

		ASSERT((Fcb->Identifier.Type == FFSFCB) &&
				(Fcb->Identifier.Size == sizeof(FFS_FCB)));

		if (!IsDirectory(Fcb))
		{
			FFSBreakPoint();
			CompleteRequest = TRUE;
			Status = STATUS_INVALID_PARAMETER;
			_SEH2_LEAVE;
		}

		if (ExAcquireResourceExclusiveLite(
					&Fcb->MainResource,
					TRUE))
		{
			bFcbAcquired = TRUE;
		}
		else
		{
			Status = STATUS_PENDING;
			_SEH2_LEAVE;
		}

		Irp = IrpContext->Irp;

		IrpSp = IoGetCurrentIrpStackLocation(Irp);

#if !defined(_GNU_NTIFS_) || defined(__REACTOS__)

		CompletionFilter =
			IrpSp->Parameters.NotifyDirectory.CompletionFilter;

#else // _GNU_NTIFS_

		CompletionFilter = ((PEXTENDED_IO_STACK_LOCATION)
				IrpSp)->Parameters.NotifyDirectory.CompletionFilter;

#endif // _GNU_NTIFS_

		WatchTree = IsFlagOn(IrpSp->Flags, SL_WATCH_TREE);

		if (FlagOn(Fcb->Flags, FCB_DELETE_PENDING))
		{
			Status = STATUS_DELETE_PENDING;
			_SEH2_LEAVE;
		}

		FullName = &Fcb->LongName;

		if (FullName->Buffer == NULL)
		{
			if (!FFSGetFullFileName(Fcb->FFSMcb, FullName))
			{
				Status = STATUS_INSUFFICIENT_RESOURCES;
				_SEH2_LEAVE;
			}
		}

		FsRtlNotifyFullChangeDirectory(Vcb->NotifySync,
				&Vcb->NotifyList,
				FileObject->FsContext2,
				(PSTRING)FullName,
				WatchTree,
				FALSE,
				CompletionFilter,
				Irp,
				NULL,
				NULL);

		CompleteRequest = FALSE;

		Status = STATUS_PENDING;

		/*
		   Currently the driver is read-only but here is an example on how to use the
		   FsRtl-functions to report a change:

		   ANSI_STRING TestString;
		   USHORT      FileNamePartLength;

		   RtlInitAnsiString(&TestString, "\\ntifs.h");

		   FileNamePartLength = 7;

		   FsRtlNotifyReportChange(
		   Vcb->NotifySync,            // PNOTIFY_SYNC NotifySync
		   &Vcb->NotifyList,           // PLIST_ENTRY  NotifyList
		   &TestString,                // PSTRING      FullTargetName
		   &FileNamePartLength,        // PUSHORT      FileNamePartLength
		   FILE_NOTIFY_CHANGE_NAME     // ULONG        FilterMatch
		   );

		   or

		   ANSI_STRING TestString;

		   RtlInitAnsiString(&TestString, "\\ntifs.h");

		   FsRtlNotifyFullReportChange(
		   Vcb->NotifySync,            // PNOTIFY_SYNC NotifySync
		   &Vcb->NotifyList,           // PLIST_ENTRY  NotifyList
		   &TestString,                // PSTRING      FullTargetName
		   1,                          // USHORT       TargetNameOffset
		   NULL,                       // PSTRING      StreamName OPTIONAL
		   NULL,                       // PSTRING      NormalizedParentName OPTIONAL
		   FILE_NOTIFY_CHANGE_NAME,    // ULONG        FilterMatch
		   0,                          // ULONG        Action
		   NULL                        // PVOID        TargetContext
		   );
		   */

	}
	_SEH2_FINALLY
	{
		if (bFcbAcquired)
		{
			ExReleaseResourceForThreadLite(
					&Fcb->MainResource,
					ExGetCurrentResourceThread());
		}

		if (!IrpContext->ExceptionInProgress)
		{
			if (!CompleteRequest)
			{
				IrpContext->Irp = NULL;
			}

			FFSCompleteIrpContext(IrpContext, Status);
		}
	} _SEH2_END;

	return Status;
}
Пример #19
0
__drv_mustHoldCriticalRegion
NTSTATUS
FFSQueryDirectory(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	PDEVICE_OBJECT          DeviceObject;
	NTSTATUS                Status = STATUS_UNSUCCESSFUL;
	PFFS_VCB                Vcb = 0;
	PFILE_OBJECT            FileObject;
	PFFS_FCB                Fcb = 0;
	PFFS_CCB                Ccb;
	PIRP                    Irp;
	PIO_STACK_LOCATION      IoStackLocation;
	FILE_INFORMATION_CLASS  FileInformationClass;
	ULONG                   Length;
	PUNICODE_STRING         FileName;
	ULONG                   FileIndex;
	BOOLEAN                 RestartScan;
	BOOLEAN                 ReturnSingleEntry;
	BOOLEAN                 IndexSpecified;
	PUCHAR                  Buffer;
	BOOLEAN                 FirstQuery;
	PFFSv1_INODE            dinode1 = NULL;
	PFFSv2_INODE            dinode2 = NULL;
	BOOLEAN                 FcbResourceAcquired = FALSE;
	ULONG                   UsedLength = 0;
	USHORT                  InodeFileNameLength;
	UNICODE_STRING          InodeFileName;
	PFFS_DIR_ENTRY          pDir = NULL;
	ULONG                   dwBytes;
	ULONG                   dwTemp = 0;
	ULONG                   dwSize = 0;
	ULONG                   dwReturn = 0;
	BOOLEAN                 bRun = TRUE;
	ULONG                   ByteOffset;

    PAGED_CODE();

	InodeFileName.Buffer = NULL;

	_SEH2_TRY
	{
		ASSERT(IrpContext);

		ASSERT((IrpContext->Identifier.Type == FFSICX) &&
				(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

		DeviceObject = IrpContext->DeviceObject;

		//
		// This request is not allowed on the main device object
		//
		if (DeviceObject == FFSGlobal->DeviceObject)
		{
			Status = STATUS_INVALID_DEVICE_REQUEST;
			_SEH2_LEAVE;
		}

		Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;

		ASSERT(Vcb != NULL);

		ASSERT((Vcb->Identifier.Type == FFSVCB) &&
				(Vcb->Identifier.Size == sizeof(FFS_VCB)));

		ASSERT(IsMounted(Vcb));

		FileObject = IrpContext->FileObject;

		Fcb = (PFFS_FCB)FileObject->FsContext;

		ASSERT(Fcb);

		//
		// This request is not allowed on volumes
		//
		if (Fcb->Identifier.Type == FFSVCB)
		{
			Status = STATUS_INVALID_PARAMETER;
			_SEH2_LEAVE;
		}

		ASSERT((Fcb->Identifier.Type == FFSFCB) &&
				(Fcb->Identifier.Size == sizeof(FFS_FCB)));

		if (!IsDirectory(Fcb))
		{
			Status = STATUS_INVALID_PARAMETER;
			_SEH2_LEAVE;
		}

		Ccb = (PFFS_CCB)FileObject->FsContext2;

		ASSERT(Ccb);

		ASSERT((Ccb->Identifier.Type == FFSCCB) &&
				(Ccb->Identifier.Size == sizeof(FFS_CCB)));

		Irp = IrpContext->Irp;

		IoStackLocation = IoGetCurrentIrpStackLocation(Irp);

#if !defined(_GNU_NTIFS_) || defined(__REACTOS__)

		FileInformationClass =
			IoStackLocation->Parameters.QueryDirectory.FileInformationClass;

		Length = IoStackLocation->Parameters.QueryDirectory.Length;

		FileName = IoStackLocation->Parameters.QueryDirectory.FileName;

		FileIndex = IoStackLocation->Parameters.QueryDirectory.FileIndex;

#else // _GNU_NTIFS_

		FileInformationClass = ((PEXTENDED_IO_STACK_LOCATION)
				IoStackLocation)->Parameters.QueryDirectory.FileInformationClass;

		Length = ((PEXTENDED_IO_STACK_LOCATION)
				IoStackLocation)->Parameters.QueryDirectory.Length;

		FileName = ((PEXTENDED_IO_STACK_LOCATION)
				IoStackLocation)->Parameters.QueryDirectory.FileName;

		FileIndex = ((PEXTENDED_IO_STACK_LOCATION)
				IoStackLocation)->Parameters.QueryDirectory.FileIndex;

#endif // _GNU_NTIFS_

		RestartScan = FlagOn(IoStackLocation->Flags, SL_RESTART_SCAN);
		ReturnSingleEntry = FlagOn(IoStackLocation->Flags, SL_RETURN_SINGLE_ENTRY);
		IndexSpecified = FlagOn(IoStackLocation->Flags, SL_INDEX_SPECIFIED);
		/*
		if (!Irp->MdlAddress && Irp->UserBuffer)
		{
			ProbeForWrite(Irp->UserBuffer, Length, 1);
		}
		*/
		Buffer = FFSGetUserBuffer(Irp);

		if (Buffer == NULL)
		{
			FFSBreakPoint();
			Status = STATUS_INVALID_USER_BUFFER;
			_SEH2_LEAVE;
		}

		if (!IrpContext->IsSynchronous)
		{
			Status = STATUS_PENDING;
			_SEH2_LEAVE;
		}

		if (!ExAcquireResourceSharedLite(
					&Fcb->MainResource,
					IrpContext->IsSynchronous))
		{
			Status = STATUS_PENDING;
			_SEH2_LEAVE;
		}

		FcbResourceAcquired = TRUE;

		if (FileName != NULL)
		{
			if (Ccb->DirectorySearchPattern.Buffer != NULL)
			{
				FirstQuery = FALSE;
			}
			else
			{
				FirstQuery = TRUE;

				Ccb->DirectorySearchPattern.Length =
					Ccb->DirectorySearchPattern.MaximumLength =
					FileName->Length;

				Ccb->DirectorySearchPattern.Buffer =
					ExAllocatePoolWithTag(PagedPool, FileName->Length, FFS_POOL_TAG);

				if (Ccb->DirectorySearchPattern.Buffer == NULL)
				{
					Status = STATUS_INSUFFICIENT_RESOURCES;
					_SEH2_LEAVE;
				}

				Status = RtlUpcaseUnicodeString(
						&(Ccb->DirectorySearchPattern),
						FileName,
						FALSE);

				if (!NT_SUCCESS(Status))
					_SEH2_LEAVE;
			}
		}
		else if (Ccb->DirectorySearchPattern.Buffer != NULL)
		{
			FirstQuery = FALSE;
			FileName = &Ccb->DirectorySearchPattern;
		}
		else
		{
			FirstQuery = TRUE;

			Ccb->DirectorySearchPattern.Length =
				Ccb->DirectorySearchPattern.MaximumLength = 2;

			Ccb->DirectorySearchPattern.Buffer =
				ExAllocatePoolWithTag(PagedPool, 2, FFS_POOL_TAG);

			if (Ccb->DirectorySearchPattern.Buffer == NULL)
			{
				Status = STATUS_INSUFFICIENT_RESOURCES;
				_SEH2_LEAVE;
			}

			RtlCopyMemory(
					Ccb->DirectorySearchPattern.Buffer,
					L"*\0", 2);
		}

		if (!IndexSpecified)
		{
			if (RestartScan || FirstQuery)
			{
				FileIndex = Fcb->FFSMcb->DeOffset = 0;
			}
			else
			{
				FileIndex = Ccb->CurrentByteOffset;
			}
		}

		if (FS_VERSION == 1)
		{
			dinode1 = (PFFSv1_INODE)ExAllocatePoolWithTag(
					PagedPool,
					DINODE1_SIZE, FFS_POOL_TAG);

			if (dinode1 == NULL)
			{
				Status = STATUS_INSUFFICIENT_RESOURCES;
				_SEH2_LEAVE;
			}

			RtlZeroMemory(Buffer, Length);

			if (Fcb->dinode1->di_size <= FileIndex)
			{
				Status = STATUS_NO_MORE_FILES;
				_SEH2_LEAVE;
			}
		}
		else
		{
			dinode2 = (PFFSv2_INODE)ExAllocatePoolWithTag(
					PagedPool,
					DINODE2_SIZE, FFS_POOL_TAG);

			if (dinode2 == NULL)
			{
				Status = STATUS_INSUFFICIENT_RESOURCES;
				_SEH2_LEAVE;
			}

			RtlZeroMemory(Buffer, Length);

			if (Fcb->dinode2->di_size <= FileIndex)
			{
				Status = STATUS_NO_MORE_FILES;
				_SEH2_LEAVE;
			}
		}

		pDir = ExAllocatePoolWithTag(PagedPool,
				sizeof(FFS_DIR_ENTRY), FFS_POOL_TAG);
		if (!pDir)
		{
			Status = STATUS_INSUFFICIENT_RESOURCES;
			_SEH2_LEAVE;
		}


		if (FS_VERSION == 1)
		{
			dwBytes = 0;
			dwSize = (ULONG)Fcb->dinode1->di_size - FileIndex -
				(sizeof(FFS_DIR_ENTRY) - FFS_NAME_LEN + 1);

			ByteOffset = FileIndex;

			dwTemp = 0;

			while (bRun && UsedLength < Length  && dwBytes < dwSize)
			{
				OEM_STRING  OemName;

				RtlZeroMemory(pDir, sizeof(FFS_DIR_ENTRY));

				Status = FFSv1ReadInode(
							NULL,
							Vcb,
							Fcb->dinode1,
							ByteOffset,
							(PVOID)pDir,
							sizeof(FFS_DIR_ENTRY),
							&dwReturn);

				if (!NT_SUCCESS(Status))
				{
					_SEH2_LEAVE;
				}

				if (!pDir->d_ino)
				{
					if (pDir->d_reclen == 0)
					{
						FFSBreakPoint();
						_SEH2_LEAVE;
					}

					goto ProcessNextEntryv1;
				}

				OemName.Buffer = pDir->d_name;
				OemName.Length = (pDir->d_namlen & 0xff);
				OemName.MaximumLength = OemName.Length;

#if 0
/*
				//
				// We could not filter the files: "." and ".."
				//

				if ((OemName.Length >) 1 && OemName.Buffer[0] == '.')
				{
					if ( OemName.Length == 2 && OemName.Buffer[1] == '.')
					{
					}
					else
					{
						goto ProcessNextEntry1;
					}
				}
*/
#endif

				InodeFileNameLength = (USHORT)
					RtlOemStringToUnicodeSize(&OemName);

				InodeFileName.Length = 0;
				InodeFileName.MaximumLength = InodeFileNameLength + 2;

				if (InodeFileNameLength <= 0)
				{
					break;
				}

				InodeFileName.Buffer = ExAllocatePoolWithTag(
						PagedPool,
						InodeFileNameLength + 2, FFS_POOL_TAG);

				if (!InodeFileName.Buffer)
				{
					Status = STATUS_INSUFFICIENT_RESOURCES;
					_SEH2_LEAVE;
				}

				RtlZeroMemory(
						InodeFileName.Buffer, 
						InodeFileNameLength + 2);

				Status = FFSOEMToUnicode(&InodeFileName,
						&OemName);

				if (!NT_SUCCESS(Status))
				{
					_SEH2_LEAVE;
				}

				if (FsRtlDoesNameContainWildCards(
							&(Ccb->DirectorySearchPattern)) ?
						FsRtlIsNameInExpression(
							&(Ccb->DirectorySearchPattern),
							&InodeFileName,
							TRUE,
							NULL) :
						!RtlCompareUnicodeString(
							&(Ccb->DirectorySearchPattern),
							&InodeFileName,
							TRUE))
				{
					dwReturn = FFSProcessDirEntry(
							Vcb, FileInformationClass,
							pDir->d_ino,
							Buffer,
							UsedLength, 
							Length - UsedLength,
							(FileIndex + dwBytes),
							&InodeFileName,
							ReturnSingleEntry);

					if (dwReturn <= 0)
					{
						bRun = FALSE;
					}
					else
					{
						dwTemp = UsedLength;
						UsedLength += dwReturn;
					}
				}

				if (InodeFileName.Buffer != NULL)
				{
					ExFreePool(InodeFileName.Buffer);
					InodeFileName.Buffer = NULL;
				}

ProcessNextEntryv1:

				if (bRun)
				{
					dwBytes +=pDir->d_reclen;
					Ccb->CurrentByteOffset = FileIndex + dwBytes;
				}

				if (UsedLength && ReturnSingleEntry)
				{
					Status = STATUS_SUCCESS;
					_SEH2_LEAVE;
				}

				ByteOffset = FileIndex + dwBytes;
			}
		}
		else
		{
			dwBytes = 0;
			dwSize = (ULONG)Fcb->dinode2->di_size - FileIndex -
				(sizeof(FFS_DIR_ENTRY) - FFS_NAME_LEN + 1);

			ByteOffset = FileIndex;

			dwTemp = 0;

			while (bRun && UsedLength < Length  && dwBytes < dwSize)
			{
				OEM_STRING  OemName;

				RtlZeroMemory(pDir, sizeof(FFS_DIR_ENTRY));

				Status = FFSv2ReadInode(
							NULL,
							Vcb,
							Fcb->dinode2,
							ByteOffset,
							(PVOID)pDir,
							sizeof(FFS_DIR_ENTRY),
							&dwReturn);

				if (!NT_SUCCESS(Status))
				{
					_SEH2_LEAVE;
				}

				if (!pDir->d_ino)
				{
					if (pDir->d_reclen == 0)
					{
						FFSBreakPoint();
						_SEH2_LEAVE;
					}

					goto ProcessNextEntryv2;
				}

				OemName.Buffer = pDir->d_name;
				OemName.Length = (pDir->d_namlen & 0xff);
				OemName.MaximumLength = OemName.Length;
#if 0
/*
				//
				// We could not filter the files: "." and ".."
				//

				if ((OemName.Length >) 1 && OemName.Buffer[0] == '.')
				{
					if ( OemName.Length == 2 && OemName.Buffer[1] == '.')
					{
					}
					else
					{
						goto ProcessNextEntry2;
					}
				}
*/
#endif

				InodeFileNameLength = (USHORT)
					RtlOemStringToUnicodeSize(&OemName);

				InodeFileName.Length = 0;
				InodeFileName.MaximumLength = InodeFileNameLength + 2;

				if (InodeFileNameLength <= 0)
				{
					break;
				}

				InodeFileName.Buffer = ExAllocatePoolWithTag(
						PagedPool,
						InodeFileNameLength + 2, FFS_POOL_TAG);

				if (!InodeFileName.Buffer)
				{
					Status = STATUS_INSUFFICIENT_RESOURCES;
					_SEH2_LEAVE;
				}

				RtlZeroMemory(
						InodeFileName.Buffer, 
						InodeFileNameLength + 2);

				Status = FFSOEMToUnicode(&InodeFileName,
						&OemName);

				if (!NT_SUCCESS(Status))
				{
					_SEH2_LEAVE;
				}

				if (FsRtlDoesNameContainWildCards(
							&(Ccb->DirectorySearchPattern)) ?
						FsRtlIsNameInExpression(
							&(Ccb->DirectorySearchPattern),
							&InodeFileName,
							TRUE,
							NULL) :
						!RtlCompareUnicodeString(
							&(Ccb->DirectorySearchPattern),
							&InodeFileName,
							TRUE))
				{
					dwReturn = FFSProcessDirEntry(
							Vcb, FileInformationClass,
							pDir->d_ino,
							Buffer,
							UsedLength, 
							Length - UsedLength,
							(FileIndex + dwBytes),
							&InodeFileName,
							ReturnSingleEntry);

					if (dwReturn <= 0)
					{
						bRun = FALSE;
					}
					else
					{
						dwTemp = UsedLength;
						UsedLength += dwReturn;
					}
				}

				if (InodeFileName.Buffer != NULL)
				{
					ExFreePool(InodeFileName.Buffer);
					InodeFileName.Buffer = NULL;
				}

ProcessNextEntryv2:

				if (bRun)
				{
					dwBytes +=pDir->d_reclen;
					Ccb->CurrentByteOffset = FileIndex + dwBytes;
				}

				if (UsedLength && ReturnSingleEntry)
				{
					Status = STATUS_SUCCESS;
					_SEH2_LEAVE;
				}

				ByteOffset = FileIndex + dwBytes;
			}
		}

		FileIndex += dwBytes;

		((PULONG)((PUCHAR)Buffer + dwTemp)) [0] = 0;

		if (!UsedLength)
		{
			if (FirstQuery)
			{
				Status = STATUS_NO_SUCH_FILE;
			}
			else
			{
				Status = STATUS_NO_MORE_FILES;
			}
		}
		else
		{
			Status = STATUS_SUCCESS;
		}
	}

	_SEH2_FINALLY
	{

		if (FcbResourceAcquired)
		{
			ExReleaseResourceForThreadLite(
					&Fcb->MainResource,
					ExGetCurrentResourceThread());
		}

		if (FS_VERSION == 1)
		{
			if (dinode1 != NULL)
			{
				ExFreePool(dinode1);
			}
		}
		else
		{
			if (dinode2 != NULL)
			{
				ExFreePool(dinode2);
			}
		}

		if (pDir != NULL)
		{
			ExFreePool(pDir);
			pDir = NULL;
		}

		if (InodeFileName.Buffer != NULL)
		{
			ExFreePool(InodeFileName.Buffer);
		}

		if (!IrpContext->ExceptionInProgress)
		{
			if (Status == STATUS_PENDING)
			{
				Status = FFSLockUserBuffer(
						IrpContext->Irp,
						Length,
						IoWriteAccess);

				if (NT_SUCCESS(Status))
				{
					Status = FFSQueueRequest(IrpContext);
				}
				else
				{
					FFSCompleteIrpContext(IrpContext, Status);
				}
			}
			else
			{
				IrpContext->Irp->IoStatus.Information = UsedLength;
				FFSCompleteIrpContext(IrpContext, Status);
			}
		}
	} _SEH2_END;

	return Status;
}
Пример #20
0
NTSTATUS
Ext2Close (IN PEXT2_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT  DeviceObject;
    NTSTATUS        Status = STATUS_SUCCESS;
    PEXT2_VCB       Vcb = NULL;
    PFILE_OBJECT    FileObject;
    PEXT2_FCB       Fcb = NULL;
    PEXT2_CCB       Ccb = NULL;
    BOOLEAN         VcbResourceAcquired = FALSE;
    BOOLEAN         FcbResourceAcquired = FALSE;
    BOOLEAN         bDeleteVcb = FALSE;
    BOOLEAN         bBeingClosed = FALSE;
    BOOLEAN         bSkipLeave = FALSE;

    __try {

        ASSERT(IrpContext != NULL);
        ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
               (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;
        if (IsExt2FsDevice(DeviceObject)) {
            Status = STATUS_SUCCESS;
            Vcb = NULL;
            __leave;
        }

        Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
        ASSERT(Vcb != NULL);
        ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
               (Vcb->Identifier.Size == sizeof(EXT2_VCB)));

        if (!ExAcquireResourceExclusiveLite(
                    &Vcb->MainResource,
                    TRUE )) {
            DEBUG(DL_INF, ("Ext2Close: PENDING ... Vcb: %xh/%xh\n",
                           Vcb->OpenHandleCount, Vcb->ReferenceCount));

            Status = STATUS_PENDING;
            __leave;
        }
        VcbResourceAcquired = TRUE;

        bSkipLeave = TRUE;
        if (IsFlagOn(Vcb->Flags, VCB_BEING_CLOSED)) {
            bBeingClosed = TRUE;
        } else {
            SetLongFlag(Vcb->Flags, VCB_BEING_CLOSED);
            bBeingClosed = FALSE;
        }

        if (IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE)) {

            FileObject = NULL;
            Fcb = IrpContext->Fcb;
            Ccb = IrpContext->Ccb;

        } else {

            FileObject = IrpContext->FileObject;
            Fcb = (PEXT2_FCB) FileObject->FsContext;
            if (!Fcb) {
                Status = STATUS_SUCCESS;
                __leave;
            }
            ASSERT(Fcb != NULL);
            Ccb = (PEXT2_CCB) FileObject->FsContext2;
        }

        DEBUG(DL_INF, ( "Ext2Close: (VCB) bBeingClosed = %d Vcb = %p ReferCount = %d\n",
                        bBeingClosed, Vcb, Vcb->ReferenceCount));

        if (Fcb->Identifier.Type == EXT2VCB) {

            if (Ccb) {

                Ext2DerefXcb(&Vcb->ReferenceCount);
                Ext2FreeCcb(Vcb, Ccb);

                if (FileObject) {
                    FileObject->FsContext2 = Ccb = NULL;
                }
            }

            Status = STATUS_SUCCESS;
            __leave;
        }

        if ( Fcb->Identifier.Type != EXT2FCB ||
                Fcb->Identifier.Size != sizeof(EXT2_FCB)) {
            __leave;
        }

        if (!ExAcquireResourceExclusiveLite(
                    &Fcb->MainResource,
                    TRUE )) {
            Status = STATUS_PENDING;
            __leave;
        }
        FcbResourceAcquired = TRUE;

        Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;

        if (!Ccb) {
            Status = STATUS_SUCCESS;
            __leave;
        }

        ASSERT((Ccb->Identifier.Type == EXT2CCB) &&
               (Ccb->Identifier.Size == sizeof(EXT2_CCB)));

        if (IsFlagOn(Fcb->Flags, FCB_STATE_BUSY)) {
            SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_FILE_BUSY);
            DEBUG(DL_WRN, ( "Ext2Close: busy bit set: %wZ\n", &Fcb->Mcb->FullName ));
            Status = STATUS_PENDING;
            __leave;
        }

        DEBUG(DL_INF, ( "Ext2Close: Fcb = %p OpenHandleCount= %u ReferenceCount=%u NonCachedCount=%u %wZ\n",
                        Fcb, Fcb->OpenHandleCount, Fcb->ReferenceCount, Fcb->NonCachedOpenCount, &Fcb->Mcb->FullName ));

        if (Ccb) {

            Ext2FreeCcb(Vcb, Ccb);

            if (FileObject) {
                FileObject->FsContext2 = Ccb = NULL;
            }
        }

        if (0 == Ext2DerefXcb(&Fcb->ReferenceCount)) {

            //
            // Remove Fcb from Vcb->FcbList ...
            //

            if (FcbResourceAcquired) {
                ExReleaseResourceLite(&Fcb->MainResource);
                FcbResourceAcquired = FALSE;
            }

            Ext2FreeFcb(Fcb);

            if (FileObject) {
                FileObject->FsContext = Fcb = NULL;
            }
        }

        Ext2DerefXcb(&Vcb->ReferenceCount);
        Status = STATUS_SUCCESS;

    } __finally {

        if (NT_SUCCESS(Status) && Vcb != NULL && IsVcbInited(Vcb)) {
            /* for Ext2Fsd driver open/close, Vcb is NULL */
            if ((!bBeingClosed) && (Vcb->ReferenceCount == 0) &&
                (!IsMounted(Vcb) || IsDispending(Vcb))) {
                bDeleteVcb = TRUE;
            }
        }

        if (bSkipLeave && !bBeingClosed) {
            ClearFlag(Vcb->Flags, VCB_BEING_CLOSED);
        }

        if (FcbResourceAcquired) {
            ExReleaseResourceLite(&Fcb->MainResource);
        }

        if (VcbResourceAcquired) {
            ExReleaseResourceLite(&Vcb->MainResource);
        }

        if (!IrpContext->ExceptionInProgress) {

            if (Status == STATUS_PENDING) {

                Ext2QueueCloseRequest(IrpContext);

            } else {

                Ext2CompleteIrpContext(IrpContext, Status);

                if (bDeleteVcb) {

                    PVPB Vpb = Vcb->Vpb;
                    DEBUG(DL_DBG, ( "Ext2Close: Try to free Vcb %p and Vpb %p\n",
                                    Vcb, Vpb));

                    Ext2CheckDismount(IrpContext, Vcb, FALSE);
                }
            }
        }
    }

    return Status;
}
Пример #21
0
__drv_mustHoldCriticalRegion
NTSTATUS
FFSClose(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	PDEVICE_OBJECT  DeviceObject;
	NTSTATUS        Status = STATUS_SUCCESS;
	PFFS_VCB        Vcb = 0;
	BOOLEAN         VcbResourceAcquired = FALSE;
	PFILE_OBJECT    FileObject;
	PFFS_FCB        Fcb = 0;
	BOOLEAN         FcbResourceAcquired = FALSE;
	PFFS_CCB        Ccb;
	BOOLEAN         FreeVcb = FALSE;

    PAGED_CODE();

	_SEH2_TRY
	{
		ASSERT(IrpContext != NULL);

		ASSERT((IrpContext->Identifier.Type == FFSICX) &&
				(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

		DeviceObject = IrpContext->DeviceObject;

		if (DeviceObject == FFSGlobal->DeviceObject)
		{
			Status = STATUS_SUCCESS;
			_SEH2_LEAVE;
		}

		Vcb = (PFFS_VCB) DeviceObject->DeviceExtension;

		ASSERT(Vcb != NULL);

		ASSERT((Vcb->Identifier.Type == FFSVCB) &&
				(Vcb->Identifier.Size == sizeof(FFS_VCB)));

		ASSERT(IsMounted(Vcb));

		if (!ExAcquireResourceExclusiveLite(
					&Vcb->MainResource,
					IrpContext->IsSynchronous))
		{
			FFSPrint((DBG_INFO, "FFSClose: PENDING ... Vcb: %xh/%xh\n",
						Vcb->OpenFileHandleCount, Vcb->ReferenceCount));

			Status = STATUS_PENDING;
			_SEH2_LEAVE;
		}

		VcbResourceAcquired = TRUE;

		FileObject = IrpContext->FileObject;

		if (IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE))
		{
			Fcb = IrpContext->Fcb;
			Ccb = IrpContext->Ccb;
		}
		else
		{
			Fcb = (PFFS_FCB)FileObject->FsContext;

			if (!Fcb)
			{
				Status = STATUS_SUCCESS;
				_SEH2_LEAVE;
			}

			ASSERT(Fcb != NULL);

			Ccb = (PFFS_CCB)FileObject->FsContext2;
		}

		if (Fcb->Identifier.Type == FFSVCB)
		{
			Vcb->ReferenceCount--;

			if (!Vcb->ReferenceCount && FlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING))
			{
				FreeVcb = TRUE;
			}

			if (Ccb)
			{
				FFSFreeCcb(Ccb);
				if (FileObject)
				{
					FileObject->FsContext2 = Ccb = NULL;
				}
			}

			Status = STATUS_SUCCESS;

			_SEH2_LEAVE;
		}

		if (Fcb->Identifier.Type != FFSFCB || Fcb->Identifier.Size != sizeof(FFS_FCB))
		{
#if DBG
			FFSPrint((DBG_ERROR, "FFSClose: Strange IRP_MJ_CLOSE by system!\n"));
			ExAcquireResourceExclusiveLite(
					&FFSGlobal->CountResource,
					TRUE);

			FFSGlobal->IRPCloseCount++;

			ExReleaseResourceForThreadLite(
					&FFSGlobal->CountResource,
					ExGetCurrentResourceThread());
#endif
			_SEH2_LEAVE;
		}

		ASSERT((Fcb->Identifier.Type == FFSFCB) &&
				(Fcb->Identifier.Size == sizeof(FFS_FCB)));

		/*        
			  if ((!IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) && 
			  (!IsFlagOn(Fcb->Flags, FCB_PAGE_FILE)))
			  */
		{
			if (!ExAcquireResourceExclusiveLite(
						&Fcb->MainResource,
						IrpContext->IsSynchronous))
			{
				Status = STATUS_PENDING;
				_SEH2_LEAVE;
			}

			FcbResourceAcquired = TRUE;
		}

		if (!Ccb)
		{
			Status = STATUS_SUCCESS;
			_SEH2_LEAVE;
		}

		ASSERT((Ccb->Identifier.Type == FFSCCB) &&
				(Ccb->Identifier.Size == sizeof(FFS_CCB)));

		Fcb->ReferenceCount--;
		Vcb->ReferenceCount--;

		if (!Vcb->ReferenceCount && IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING))
		{
			FreeVcb = TRUE;
		}

		FFSPrint((DBG_INFO, "FFSClose: OpenHandleCount: %u ReferenceCount: %u %s\n",
					Fcb->OpenHandleCount, Fcb->ReferenceCount, Fcb->AnsiFileName.Buffer));

		if (Ccb)
		{
			FFSFreeCcb(Ccb);

			if (FileObject)
			{
				FileObject->FsContext2 = Ccb = NULL;
			}
		}

		if (!Fcb->ReferenceCount)
		{
			//
			// Remove Fcb from Vcb->FcbList ...
			//

			RemoveEntryList(&Fcb->Next);

			FFSFreeFcb(Fcb);

			FcbResourceAcquired = FALSE;
		}

		Status = STATUS_SUCCESS;
	}

	_SEH2_FINALLY
	{
		if (FcbResourceAcquired)
		{
			ExReleaseResourceForThreadLite(
					&Fcb->MainResource,
					ExGetCurrentResourceThread());
		}

		if (VcbResourceAcquired)
		{
			ExReleaseResourceForThreadLite(
					&Vcb->MainResource,
					ExGetCurrentResourceThread());
		}

		if (!IrpContext->ExceptionInProgress)
		{
			if (Status == STATUS_PENDING)
			{
				FFSQueueCloseRequest(IrpContext);
#if 0
/*
				Status = STATUS_SUCCESS;

				if (IrpContext->Irp != NULL)
				{
					IrpContext->Irp->IoStatus.Status = Status;

					FFSCompleteRequest(
							IrpContext->Irp,
							(BOOLEAN)!IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED),
							(CCHAR)
							(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));

					IrpContext->Irp = NULL;
				}
*/
#endif
			}
			else
			{
				FFSCompleteIrpContext(IrpContext, Status);

				if (FreeVcb)
				{
					ExAcquireResourceExclusiveLite(
							&FFSGlobal->Resource, TRUE);

					FFSClearVpbFlag(Vcb->Vpb, VPB_MOUNTED);

					FFSRemoveVcb(Vcb);

					ExReleaseResourceForThreadLite(
							&FFSGlobal->Resource,
							ExGetCurrentResourceThread());

					FFSFreeVcb(Vcb);
				}
			}
		}
	} _SEH2_END;

	return Status;
}
Пример #22
0
__drv_mustHoldCriticalRegion
NTSTATUS
FFSLockVolume(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	PIO_STACK_LOCATION IrpSp;
	PDEVICE_OBJECT     DeviceObject;
	PFFS_VCB           Vcb = 0;
	NTSTATUS           Status;
	BOOLEAN VcbResourceAcquired = FALSE;

    PAGED_CODE();

	_SEH2_TRY
	{
		ASSERT(IrpContext != NULL);

		ASSERT((IrpContext->Identifier.Type == FFSICX) &&
				(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

		DeviceObject = IrpContext->DeviceObject;

		Status = STATUS_UNSUCCESSFUL;

		//
		// This request is not allowed on the main device object
		//
		if (DeviceObject == FFSGlobal->DeviceObject)
		{
			Status = STATUS_INVALID_PARAMETER;
			_SEH2_LEAVE;
		}

		Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;

		ASSERT(Vcb != NULL);

		ASSERT((Vcb->Identifier.Type == FFSVCB) &&
				(Vcb->Identifier.Size == sizeof(FFS_VCB)));

		ASSERT(IsMounted(Vcb));

		IrpSp = IoGetCurrentIrpStackLocation(IrpContext->Irp);

#if (_WIN32_WINNT >= 0x0500)
		CcWaitForCurrentLazyWriterActivity();
#endif
		ExAcquireResourceExclusiveLite(
				&Vcb->MainResource,
				TRUE);

		VcbResourceAcquired = TRUE;

		Status = FFSLockVcb(Vcb, IrpSp->FileObject);        
	}

	_SEH2_FINALLY
	{
		if (VcbResourceAcquired)
		{
			ExReleaseResourceForThreadLite(
					&Vcb->MainResource,
					ExGetCurrentResourceThread());
		}

		if (!IrpContext->ExceptionInProgress)
		{
			FFSCompleteIrpContext(IrpContext,  Status);
		}
	} _SEH2_END;

	return Status;
}
Пример #23
0
//------------------------------------------------------------------------
void CWeapon::OnShoot(EntityId shooterId, EntityId ammoId, IEntityClass* pAmmoType, const Vec3 &pos, const Vec3 &dir, const Vec3&vel)
{
	BROADCAST_WEAPON_EVENT(OnShoot, (this, shooterId, ammoId, pAmmoType, pos, dir, vel));

	//FIXME:quick temporary solution
	CActor *pActor = static_cast<CActor*> (g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(shooterId));
	if (pActor)
		pActor->HandleEvent(SGameObjectEvent(eCGE_OnShoot,eGOEF_ToExtensions));

	IActor *pClientActor=m_pGameFramework->GetClientActor();

	if (pActor && pActor->GetActorClass() == CPlayer::GetActorClassType() && IsServer())
	{
		if (pActor == pClientActor)
		{
			if (IAIObject *pAIObject=pActor->GetEntity()->GetAI())
				gEnv->pAISystem->SendSignal(SIGNALFILTER_LEADER, 1, "OnEnableFire",	pAIObject, 0);
		}

		CPlayer *pPlayer=static_cast<CPlayer *>(pActor);
		CNanoSuit *pSuit=pPlayer->GetNanoSuit();

		if(m_fm && strcmp(m_fm->GetType(), "Repair"))
		{
			if(pSuit)
			{
				if (pSuit->GetMode() == NANOMODE_STRENGTH && !IsMounted())
					pSuit->SetSuitEnergy(pSuit->GetSuitEnergy()-g_pGameCVars->g_suitRecoilEnergyCost);
				else if(pSuit->GetMode() == NANOMODE_CLOAK)
					pSuit->SetSuitEnergy(0.0f);
			}
		}

		if (gEnv->bServer && pSuit && pSuit->IsInvulnerable())
			pSuit->SetInvulnerability(false);
	}
	
	if (pClientActor && m_fm && strcmp(m_fm->GetType(), "Thrown"))	
	{
		// inform the HUDRadar about the sound event
		Vec3 vPlayerPos=pClientActor->GetEntity()->GetWorldPos();
		float fDist2=(vPlayerPos-pos).len2();
		if (fDist2<250.0f*250.0f)
		{			
			//if (pClientActor->GetEntityId() != shooterId) 
				//	pHUD->ShowSoundOnRadar(pos);
				
			if(gEnv->bMultiplayer)
			{
				CGameRules *pGameRules = g_pGame->GetGameRules();
				if(pGameRules->GetTeamCount() < 2 || (pGameRules->GetTeam(shooterId) != pGameRules->GetTeam(pClientActor->GetEntityId())))
				{
					//Small workaround for patch2...
					IFireMode* pFM = GetFireMode(GetCurrentFireMode());
					bool grenade = pFM?(pFM->GetAmmoType()==CItem::sScarGrenadeClass):false;
					//~...

					if (!IsSilencerAttached() || grenade)
					{
						SAFE_HUD_FUNC(GetRadar()->AddEntityTemporarily(shooterId, 5.0f));
					}
					else if(fDist2<5.0f*5.0f)
					{
						//Silencer attached
						SAFE_HUD_FUNC(GetRadar()->AddEntityTemporarily(shooterId, 5.0f));
					}
				}
			}

			if ((!IsSilencerAttached()) && fDist2<sqr(SAFE_HUD_FUNC_RET(GetBattleRange())))
				SAFE_HUD_FUNC(TickBattleStatus(1.0f));
		}
	}
}
Пример #24
0
NTSTATUS
Ext2ShutDown (IN PEXT2_IRP_CONTEXT IrpContext)
{
    NTSTATUS                Status;

    PIRP                    Irp;
    PIO_STACK_LOCATION      IrpSp;

    PEXT2_VCB               Vcb;
    PLIST_ENTRY             ListEntry;

    BOOLEAN                 GlobalResourceAcquired = FALSE;

    __try {

        Status = STATUS_SUCCESS;

        ASSERT(IrpContext);
        ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
               (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));

        Irp = IrpContext->Irp;
        IrpSp = IoGetCurrentIrpStackLocation(Irp);

        if (!ExAcquireResourceExclusiveLite(
                    &Ext2Global->Resource,
                    IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) {
            Status = STATUS_PENDING;
            __leave;
        }

        GlobalResourceAcquired = TRUE;

        for (ListEntry = Ext2Global->VcbList.Flink;
                ListEntry != &(Ext2Global->VcbList);
                ListEntry = ListEntry->Flink ) {

            Vcb = CONTAINING_RECORD(ListEntry, EXT2_VCB, Next);

            if (ExAcquireResourceExclusiveLite(
                        &Vcb->MainResource,
                        TRUE )) {

                if (IsMounted(Vcb)) {

                    /* update mount count */
                    Vcb->SuperBlock->s_mnt_count++;
                    if (Vcb->SuperBlock->s_mnt_count >
                            Vcb->SuperBlock->s_max_mnt_count ) {
                        Vcb->SuperBlock->s_mnt_count =
                            Vcb->SuperBlock->s_max_mnt_count;
                    }
                    Ext2SaveSuper(IrpContext, Vcb);

                    /* flush dirty cache for all files */
                    Status = Ext2FlushFiles(IrpContext, Vcb, TRUE);
                    if (!NT_SUCCESS(Status)) {
                        DbgBreak();
                    }

                    /* flush volume stream's cache to disk */
                    Status = Ext2FlushVolume(IrpContext, Vcb, TRUE);

                    if (!NT_SUCCESS(Status) && Status != STATUS_MEDIA_WRITE_PROTECTED) {
                        DbgBreak();
                    }

                    /* send shutdown request to underlying disk */
                    Ext2DiskShutDown(Vcb);
                }

                ExReleaseResourceLite(&Vcb->MainResource);
            }
        }

        /*
                IoUnregisterFileSystem(Ext2Global->DiskdevObject);
                IoUnregisterFileSystem(Ext2Global->CdromdevObject);
        */

    } __finally {

        if (GlobalResourceAcquired) {
            ExReleaseResourceLite(&Ext2Global->Resource);
        }

        if (!IrpContext->ExceptionInProgress) {
            if (Status == STATUS_PENDING) {
                Ext2QueueRequest(IrpContext);
            } else {
                Ext2CompleteIrpContext(IrpContext, Status);
            }
        }
    }

    return Status;
}
Пример #25
0
NTSTATUS
Ext2Flush (IN PEXT2_IRP_CONTEXT IrpContext)
{
    NTSTATUS                Status = STATUS_SUCCESS;

    PIRP                    Irp = NULL;
    PIO_STACK_LOCATION      IrpSp = NULL;

    PEXT2_VCB               Vcb = NULL;
    PEXT2_FCB               Fcb = NULL;
    PEXT2_FCBVCB            FcbOrVcb = NULL;
    PEXT2_CCB               Ccb = NULL;
    PFILE_OBJECT            FileObject = NULL;

    PDEVICE_OBJECT          DeviceObject = NULL;

    BOOLEAN                 MainResourceAcquired = FALSE;

    __try {

        ASSERT(IrpContext);

        ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
               (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;

        //
        // This request is not allowed on the main device object
        //
        if (IsExt2FsDevice(DeviceObject)) {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }

        Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
        ASSERT(Vcb != NULL);
        ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
               (Vcb->Identifier.Size == sizeof(EXT2_VCB)));

        ASSERT(IsMounted(Vcb));
        if ( IsFlagOn(Vcb->Flags, VCB_READ_ONLY) ||
                IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) {
            Status =  STATUS_SUCCESS;
            __leave;
        }

        Irp = IrpContext->Irp;
        IrpSp = IoGetCurrentIrpStackLocation(Irp);

        FileObject = IrpContext->FileObject;
        FcbOrVcb = (PEXT2_FCBVCB) FileObject->FsContext;
        ASSERT(FcbOrVcb != NULL);

        Ccb = (PEXT2_CCB) FileObject->FsContext2;
        if (Ccb == NULL) {
            Status =  STATUS_SUCCESS;
            __leave;
        }

        MainResourceAcquired =
            ExAcquireResourceExclusiveLite(&FcbOrVcb->MainResource,
                                           IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT));

        ASSERT(MainResourceAcquired);
        DEBUG(DL_INF, ("Ext2Flush-pre:  total mcb records=%u\n",
                       FsRtlNumberOfRunsInLargeMcb(&Vcb->Extents)));

        if (FcbOrVcb->Identifier.Type == EXT2VCB) {

            Ext2VerifyVcb(IrpContext, Vcb);
            Status = Ext2FlushFiles(IrpContext, (PEXT2_VCB)(FcbOrVcb), FALSE);
            if (NT_SUCCESS(Status)) {
                __leave;
            }

            Status = Ext2FlushVolume(IrpContext, (PEXT2_VCB)(FcbOrVcb), FALSE);

            if (NT_SUCCESS(Status) && IsFlagOn(Vcb->Volume->Flags, FO_FILE_MODIFIED)) {
                ClearFlag(Vcb->Volume->Flags, FO_FILE_MODIFIED);
            }

        } else if (FcbOrVcb->Identifier.Type == EXT2FCB) {

            Fcb = (PEXT2_FCB)(FcbOrVcb);

            Status = Ext2FlushFile(IrpContext, Fcb, Ccb);
            if (NT_SUCCESS(Status)) {
                if (IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED)) {
                    Fcb->Mcb->FileAttr |= FILE_ATTRIBUTE_ARCHIVE;
                    ClearFlag(FileObject->Flags, FO_FILE_MODIFIED);
                }
            }
        }

        DEBUG(DL_INF, ("Ext2Flush-post: total mcb records=%u\n",
                       FsRtlNumberOfRunsInLargeMcb(&Vcb->Extents)));


    } __finally {

        if (MainResourceAcquired) {
            ExReleaseResourceLite(&FcbOrVcb->MainResource);
        }

        if (!IrpContext->ExceptionInProgress) {

            if (Vcb && Irp && IrpSp && (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY))) {

                // Call the disk driver to flush the physial media.
                NTSTATUS DriverStatus;
                PIO_STACK_LOCATION NextIrpSp;

                NextIrpSp = IoGetNextIrpStackLocation(Irp);

                *NextIrpSp = *IrpSp;

                IoSetCompletionRoutine( Irp,
                                        Ext2FlushCompletionRoutine,
                                        NULL,
                                        TRUE,
                                        TRUE,
                                        TRUE );

                DriverStatus = IoCallDriver(Vcb->TargetDeviceObject, Irp);

                Status = (DriverStatus == STATUS_INVALID_DEVICE_REQUEST) ?
                         Status : DriverStatus;

                IrpContext->Irp = Irp = NULL;
            }

            Ext2CompleteIrpContext(IrpContext, Status);
        }
    }

    return Status;
}
Пример #26
0
__drv_mustHoldCriticalRegion
NTSTATUS
RfsdUnlockVolume (
    IN PRFSD_IRP_CONTEXT IrpContext
)
{
    PIO_STACK_LOCATION IrpSp;
    PDEVICE_OBJECT  DeviceObject;
    NTSTATUS        Status;
    PRFSD_VCB       Vcb = 0;
    BOOLEAN         VcbResourceAcquired = FALSE;

    PAGED_CODE();

    _SEH2_TRY {

        ASSERT(IrpContext != NULL);

        ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
        (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;

        //
        // This request is not allowed on the main device object
        //
        if (DeviceObject == RfsdGlobal->DeviceObject) {
            Status = STATUS_INVALID_PARAMETER;
            _SEH2_LEAVE;
        }

        Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;

        ASSERT(Vcb != NULL);

        ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
        (Vcb->Identifier.Size == sizeof(RFSD_VCB)));

        ASSERT(IsMounted(Vcb));

        IrpSp = IoGetCurrentIrpStackLocation(IrpContext->Irp);

        ExAcquireResourceExclusiveLite(
            &Vcb->MainResource,
            TRUE );

        VcbResourceAcquired = TRUE;

        Status = RfsdUnlockVcb(Vcb, IrpSp->FileObject);

    } _SEH2_FINALLY {

        if (VcbResourceAcquired) {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread()
            );
        }

        if (!IrpContext->ExceptionInProgress) {
            RfsdCompleteIrpContext(IrpContext,  Status);
        }
    } _SEH2_END;

    return Status;
}
Пример #27
0
__drv_mustHoldCriticalRegion
NTSTATUS
RfsdQueryVolumeInformation (IN PRFSD_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT          DeviceObject;
    NTSTATUS                Status = STATUS_UNSUCCESSFUL;
    PRFSD_VCB               Vcb = 0;
    PIRP                    Irp;
    PIO_STACK_LOCATION      IoStackLocation;
    FS_INFORMATION_CLASS    FsInformationClass;
    ULONG                   Length;
    PVOID                   Buffer;
    BOOLEAN                 VcbResourceAcquired = FALSE;

    PAGED_CODE();

    _SEH2_TRY {

        ASSERT(IrpContext != NULL);
        
        ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
            (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
        
        DeviceObject = IrpContext->DeviceObject;
    
        //
        // This request is not allowed on the main device object
        //
        if (DeviceObject == RfsdGlobal->DeviceObject) {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            _SEH2_LEAVE;
        }
        
        Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
        
        ASSERT(Vcb != NULL);
        
        ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
            (Vcb->Identifier.Size == sizeof(RFSD_VCB)));

        ASSERT(IsMounted(Vcb));

        if (!ExAcquireResourceSharedLite(
            &Vcb->MainResource,
            IrpContext->IsSynchronous
            )) {

            Status = STATUS_PENDING;
            _SEH2_LEAVE;
        }
        
        VcbResourceAcquired = TRUE;
        
        Irp = IrpContext->Irp;
        
        IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
        
        FsInformationClass =
            IoStackLocation->Parameters.QueryVolume.FsInformationClass;
        
        Length = IoStackLocation->Parameters.QueryVolume.Length;
        
        Buffer = Irp->AssociatedIrp.SystemBuffer;
        
        RtlZeroMemory(Buffer, Length);
        
        switch (FsInformationClass) {

        case FileFsVolumeInformation:
            {
                PFILE_FS_VOLUME_INFORMATION FsVolInfo;
                ULONG                       VolumeLabelLength;
                ULONG                       RequiredLength;
                
                if (Length < sizeof(FILE_FS_VOLUME_INFORMATION)) {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    _SEH2_LEAVE;
                }
                
                FsVolInfo = (PFILE_FS_VOLUME_INFORMATION) Buffer;
                
                FsVolInfo->VolumeCreationTime.QuadPart = 0;
                
                FsVolInfo->VolumeSerialNumber = Vcb->Vpb->SerialNumber;

                VolumeLabelLength = Vcb->Vpb->VolumeLabelLength;
                
                FsVolInfo->VolumeLabelLength = VolumeLabelLength;
                
                // I don't know what this means
                FsVolInfo->SupportsObjects = FALSE;

                RequiredLength = sizeof(FILE_FS_VOLUME_INFORMATION)
                    + VolumeLabelLength - sizeof(WCHAR);
                
                if (Length < RequiredLength) {
                    Irp->IoStatus.Information =
                        sizeof(FILE_FS_VOLUME_INFORMATION);
                    Status = STATUS_BUFFER_OVERFLOW;
                    _SEH2_LEAVE;
                }

                RtlCopyMemory(FsVolInfo->VolumeLabel, Vcb->Vpb->VolumeLabel, Vcb->Vpb->VolumeLabelLength);

                Irp->IoStatus.Information = RequiredLength;
                Status = STATUS_SUCCESS;
                _SEH2_LEAVE;
            }
            
        case FileFsSizeInformation:
            {
                PFILE_FS_SIZE_INFORMATION FsSizeInfo;
                
                if (Length < sizeof(FILE_FS_SIZE_INFORMATION)) {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    _SEH2_LEAVE;
                }
                
                FsSizeInfo = (PFILE_FS_SIZE_INFORMATION) Buffer;
                
                FsSizeInfo->TotalAllocationUnits.QuadPart = 
					Vcb->SuperBlock->s_blocks_count;
                    
                FsSizeInfo->AvailableAllocationUnits.QuadPart =
					Vcb->SuperBlock->s_free_blocks_count;

                FsSizeInfo->SectorsPerAllocationUnit =
                    Vcb->BlockSize / Vcb->DiskGeometry.BytesPerSector;
                
                FsSizeInfo->BytesPerSector =
                    Vcb->DiskGeometry.BytesPerSector;
                
                Irp->IoStatus.Information = sizeof(FILE_FS_SIZE_INFORMATION);
                Status = STATUS_SUCCESS;
                _SEH2_LEAVE;
            }
            
        case FileFsDeviceInformation:
            {
                PFILE_FS_DEVICE_INFORMATION FsDevInfo;
                
                if (Length < sizeof(FILE_FS_DEVICE_INFORMATION)) {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    _SEH2_LEAVE;
                }
                
                FsDevInfo = (PFILE_FS_DEVICE_INFORMATION) Buffer;
                
                FsDevInfo->DeviceType =
                    Vcb->TargetDeviceObject->DeviceType;

                if (FsDevInfo->DeviceType != FILE_DEVICE_DISK) {
                    DbgBreak();
                }

                FsDevInfo->Characteristics =
                    Vcb->TargetDeviceObject->Characteristics;
                
                if (FlagOn(Vcb->Flags, VCB_READ_ONLY)) {

                    SetFlag( FsDevInfo->Characteristics,
                             FILE_READ_ONLY_DEVICE   );
                }
                
                Irp->IoStatus.Information = sizeof(FILE_FS_DEVICE_INFORMATION);
                Status = STATUS_SUCCESS;
                _SEH2_LEAVE;
            }
            
        case FileFsAttributeInformation:
            {
                PFILE_FS_ATTRIBUTE_INFORMATION  FsAttrInfo;
                ULONG                           RequiredLength;
                
                if (Length < sizeof(FILE_FS_ATTRIBUTE_INFORMATION)) {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    _SEH2_LEAVE;
                }
                
                FsAttrInfo =
                    (PFILE_FS_ATTRIBUTE_INFORMATION) Buffer;
                
                FsAttrInfo->FileSystemAttributes =
                    FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
                
                FsAttrInfo->MaximumComponentNameLength = RFSD_NAME_LEN;
                
                FsAttrInfo->FileSystemNameLength = 10;
                
                RequiredLength = sizeof(FILE_FS_ATTRIBUTE_INFORMATION) +
                    10 - sizeof(WCHAR);
                
                if (Length < RequiredLength) {
                    Irp->IoStatus.Information =
                        sizeof(FILE_FS_ATTRIBUTE_INFORMATION);
                    Status = STATUS_BUFFER_OVERFLOW;
                    _SEH2_LEAVE;
                }
                
                RtlCopyMemory(
                    FsAttrInfo->FileSystemName,
                    L"RFSD\0", 10);
                
                Irp->IoStatus.Information = RequiredLength;
                Status = STATUS_SUCCESS;
                _SEH2_LEAVE;
            }

#if (_WIN32_WINNT >= 0x0500)

        case FileFsFullSizeInformation:
            {
                PFILE_FS_FULL_SIZE_INFORMATION PFFFSI;

                if (Length < sizeof(FILE_FS_FULL_SIZE_INFORMATION)) {
                    Status = STATUS_INFO_LENGTH_MISMATCH;
                    _SEH2_LEAVE;
                }

                PFFFSI = (PFILE_FS_FULL_SIZE_INFORMATION) Buffer;

/*
                typedef struct _FILE_FS_FULL_SIZE_INFORMATION {
                    LARGE_INTEGER   TotalAllocationUnits;
                    LARGE_INTEGER   CallerAvailableAllocationUnits;
                    LARGE_INTEGER   ActualAvailableAllocationUnits;
                    ULONG           SectorsPerAllocationUnit;
                    ULONG           BytesPerSector;
                } FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;
*/

                {
                    PFFFSI->TotalAllocationUnits.QuadPart = 
						Vcb->SuperBlock->s_blocks_count;

                    PFFFSI->CallerAvailableAllocationUnits.QuadPart =
						Vcb->SuperBlock->s_free_blocks_count;

                    /* - Vcb->SuperBlock->s_r_blocks_count; */

                    PFFFSI->ActualAvailableAllocationUnits.QuadPart =
						Vcb->SuperBlock->s_free_blocks_count;
                }

                PFFFSI->SectorsPerAllocationUnit =
                    Vcb->BlockSize / Vcb->DiskGeometry.BytesPerSector;

                PFFFSI->BytesPerSector = Vcb->DiskGeometry.BytesPerSector;

                Irp->IoStatus.Information = sizeof(FILE_FS_FULL_SIZE_INFORMATION);
                Status = STATUS_SUCCESS;
                _SEH2_LEAVE;
            }

#endif // (_WIN32_WINNT >= 0x0500)

        default:
            Status = STATUS_INVALID_INFO_CLASS;
        }

    } _SEH2_FINALLY {

        if (VcbResourceAcquired) {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread() );
        }
        
        if (!IrpContext->ExceptionInProgress) {
            if (Status == STATUS_PENDING) {
                RfsdQueueRequest(IrpContext);
            } else {
                RfsdCompleteIrpContext(IrpContext, Status);
            }
        }
    } _SEH2_END;
    
    return Status;
}
Пример #28
0
/*
 * Execute command.
 */
void
DoCommand(
	Client_t *cli)
{
	int rc;
	char *cmd_name;
	char *lasts;
	char *msg;

	rc = 0;
	SetErrno = 0;

	msg = cli->cmdbuf;
	/*
	 * Extract command name.
	 */
/* LINTED improper pointer/integer combination */
	cmd_name = strtok_r(msg, " ", &lasts);

	if (strcmp(cmd_name, SAMRFT_CMD_CONNECT) == 0) {
		SendReply(cli, "%s %d %d", SAMRFT_CMD_CONNECT, 0, 0);

	} else if (strcmp(cmd_name, SAMRFT_CMD_CONFIG) == 0) {
		char *hostname;
		int blksize;
		int tcpwindowsize;

		hostname = getString(&lasts);
		blksize = GetCfgBlksize();
		tcpwindowsize = GetCfgTcpWindowsize();

		SamStrdup(cli->hostname, hostname);
		rc = CreateCrew(cli, 1, blksize);

		SendReply(cli, "%s %d %d %d %d",
		    SAMRFT_CMD_CONFIG, rc, 1, blksize, tcpwindowsize);

	} else if (strcmp(cmd_name, SAMRFT_CMD_OPEN) == 0) {
		char *filename;
		int oflag;
		SamrftCreateAttr_t creat;

		filename = getString(&lasts);
		oflag = getInteger(&lasts);

		if (getInteger(&lasts)) {
			(void) memset((char *)&creat, 0,
			    sizeof (SamrftCreateAttr_t));
			creat.mode = getInteger(&lasts);
			creat.uid = getInteger(&lasts);
			creat.gid = getInteger(&lasts);
			rc = OpenFile(cli, filename, oflag, &creat);
		} else {
			rc = OpenFile(cli, filename, oflag, NULL);
		}

		SendReply(cli, "%s %d %d", SAMRFT_CMD_OPEN, rc, errno);

	} else if (strcmp(cmd_name, SAMRFT_CMD_DPORT) == 0) {
		struct sockaddr_in data;
		int seqnum;
		char *addr = (char *)&data.sin_addr;
		char *port = (char *)&data.sin_port;

		(void) memset((char *)&data, 0, sizeof (struct sockaddr_in));
		data.sin_family = AF_INET;

		seqnum = getInteger(&lasts);

		/*
		 * Addr.
		 */
		addr[0] = getInteger(&lasts);
		addr[1] = getInteger(&lasts);
		addr[2] = getInteger(&lasts);
		addr[3] = getInteger(&lasts);

		/*
		 * Port.
		 */
		port[0] = getInteger(&lasts);
		port[1] = getInteger(&lasts);

		rc = InitDataConnection(cli, "r", seqnum,
		    data.sin_family, (struct sockaddr *)&data);
		SendReply(cli, "%s %d %d", SAMRFT_CMD_DPORT, rc, errno);

	} else if (strcmp(cmd_name, SAMRFT_CMD_DPORT6) == 0) {
		struct sockaddr_in6 data;
		struct sockaddr_in *data4 = (struct sockaddr_in *)&data;
		int i;
		int seqnum;
		char *addr;
		char *port;

		(void) memset((char *)&data, 0, sizeof (struct sockaddr_in6));

		seqnum = getInteger(&lasts);

		/*
		 * Address family.
		 */
		data.sin6_family = getInteger(&lasts);
		if (data.sin6_family == AF_INET6) {
			addr = (char *)&data.sin6_addr;
			port = (char *)&data.sin6_port;
		} else {
			addr = (char *)&data4->sin_addr;
			port = (char *)&data4->sin_port;
		}

		/*
		 * Addr.
		 */
		for (i = 0; i < 16; i++) {
			addr[i] = getInteger(&lasts);
		}

		/*
		 * Port.
		 */
		port[0] = getInteger(&lasts);
		port[1] = getInteger(&lasts);

		rc = InitDataConnection(cli, "r", seqnum,
		    data.sin6_family, (struct sockaddr *)&data);
		SendReply(cli, "%s %d %d", SAMRFT_CMD_DPORT6, rc, errno);

	} else if (strcmp(cmd_name, SAMRFT_CMD_STOR) == 0) {
		fsize_t nbytes;

		nbytes = getLongLong(&lasts);
		rc = ReceiveData(cli, nbytes);

	} else if (strcmp(cmd_name, SAMRFT_CMD_SEND) == 0) {
		size_t nbytes;

		nbytes = getInteger(&lasts);

		rc = ReceiveData(cli, nbytes);
		SendReply(cli, "%s %d %d", SAMRFT_CMD_SEND, rc, errno);

	} else if (strcmp(cmd_name, SAMRFT_CMD_RECV) == 0) {
		size_t nbytes;

		nbytes = getInteger(&lasts);

		/*
		 * Process receive command from client.  Send data from local
		 * file over data sockets to the client process.
		 */
		rc = SendData(cli, nbytes);
		SendReply(cli, "%s %d %d", SAMRFT_CMD_RECV, rc, errno);

	} else if (strcmp(cmd_name, SAMRFT_CMD_SEEK) == 0) {
		off64_t setpos;
		int whence;
		off64_t offset;

		setpos = getLongLong(&lasts);
		whence = getInteger(&lasts);

		rc = SeekFile(cli, setpos, whence, &offset);
		SendReply(cli, "%s %d %d %lld", SAMRFT_CMD_SEEK,
		    rc, errno, offset);

	} else if (strcmp(cmd_name, SAMRFT_CMD_FLOCK) == 0) {
		int type;

		type = getInteger(&lasts);

		rc = FlockFile(cli, type);
		SendReply(cli, "%s %d %d", SAMRFT_CMD_FLOCK, rc, errno);

	} else if (strcmp(cmd_name, SAMRFT_CMD_ARCHIVEOP) == 0) {
		char *path;
		char *ops;

		path = getString(&lasts);
		ops = getString(&lasts);

		rc = sam_archive(path, ops);
		SendReply(cli, "%s %d %d", SAMRFT_CMD_ARCHIVEOP, rc, errno);

	} else if (strcmp(cmd_name, SAMRFT_CMD_CLOSE) == 0) {

		rc = CloseFile(cli);
		SendReply(cli, "%s %d %d", SAMRFT_CMD_CLOSE, rc, errno);

	} else if (strcmp(cmd_name, SAMRFT_CMD_UNLINK) == 0) {
		char *name;

		name = getString(&lasts);

		rc = UnlinkFile(cli, name);
		SendReply(cli, "%s %d %d", SAMRFT_CMD_UNLINK, rc, errno);

	} else if (strcmp(cmd_name, SAMRFT_CMD_DISCONN) == 0) {

		Trace(TR_DEBUG, "RFT disconnect, no reply: '%s'", cli->cmdbuf);
		CleanupCrew(cli);
		cli->disconnect = 1;

		/*
		 * No reply.
		 */

	} else if (strcmp(cmd_name, SAMRFT_CMD_ISMOUNTED) == 0) {
		int mounted;
		char *mount_point;

		mount_point = getString(&lasts);

		mounted = IsMounted(cli, mount_point);
		SendReply(cli, "%s %d", SAMRFT_CMD_ISMOUNTED, mounted);

	} else if (strcmp(cmd_name, SAMRFT_CMD_STAT) == 0) {
		struct stat64 buf;
		char *filename;

		filename = getString(&lasts);

		(void) memset(&buf, 0, sizeof (buf));
		rc = stat64(filename, &buf);
		SendReply(cli, "%s %d %d %d %d %d %lld",
		    SAMRFT_CMD_STAT, rc, errno,
		    buf.st_mode, buf.st_uid, buf.st_gid, buf.st_size);

	} else if (strcmp(cmd_name, SAMRFT_CMD_STATVFS) == 0) {
		struct statvfs64 buf;
		char *mount_point;
		int offlineFiles;
		fsize_t offlineFileSize;

		mount_point = getString(&lasts);
		offlineFiles = getInteger(&lasts);

		(void) memset(&buf, 0, sizeof (buf));
		rc = statvfs64(mount_point, &buf);

		if (rc == 0 && (strcmp(buf.f_basetype, "samfs") == 0) &&
		    offlineFiles == B_TRUE) {
			offlineFileSize = DiskVolsOfflineFiles(mount_point);
			/*
			 * Adjust capacity to include size of offline files.
			 */
			buf.f_blocks += offlineFileSize / buf.f_frsize;
		}

		SendReply(cli, "%s %d %d %lld %lld %ld %s",
		    SAMRFT_CMD_STATVFS, rc, errno,
		    buf.f_bfree, buf.f_blocks, buf.f_frsize, buf.f_basetype);

	} else if (strcmp(cmd_name, SAMRFT_CMD_SPACEUSED) == 0) {
		char *path;
		fsize_t spaceUsed;

		path = getString(&lasts);

		spaceUsed = DiskVolsAccumSpaceUsed(path);

		SendReply(cli, "%s %d %d %lld",
		    SAMRFT_CMD_SPACEUSED, rc, errno, spaceUsed);

	} else if (strcmp(cmd_name, SAMRFT_CMD_MKDIR) == 0) {
		char *dirname;
		int mode, uid, gid;

		dirname = getString(&lasts);
		mode = getInteger(&lasts);
		uid = getInteger(&lasts);
		gid = getInteger(&lasts);

		rc = MkDir(cli, dirname, mode, uid, gid);
		SendReply(cli, "%s %d %d", SAMRFT_CMD_MKDIR, rc, errno);

	} else if (strcmp(cmd_name, SAMRFT_CMD_OPENDIR) == 0) {
		char *dirname;
		int dirp;

		dirname = getString(&lasts);

		rc = OpenDir(cli, dirname, &dirp);
		SendReply(cli, "%s %d %d %d", SAMRFT_CMD_OPENDIR,
		    rc, errno, dirp);

	} else if (strcmp(cmd_name, SAMRFT_CMD_READDIR) == 0) {
		int dirp;
		SamrftReaddirInfo_t dir_info;

		dirp = getInteger(&lasts);

		rc = ReadDir(cli, dirp, &dir_info);
		if (rc == 0) {
			SendReply(cli, "%s %d %d %s %d", SAMRFT_CMD_READDIR,
			    rc, errno, dir_info.name, dir_info.isdir);
		} else {
			SendReply(cli, "%s %d %d", SAMRFT_CMD_READDIR,
			    rc, errno);
		}

	} else if (strcmp(cmd_name, SAMRFT_CMD_CLOSEDIR) == 0) {
		int dirp;

		dirp = getInteger(&lasts);

		CloseDir(cli, dirp);
		SendReply(cli, "%s %d %d", SAMRFT_CMD_CLOSEDIR, 0, 0);

	} else if (strcmp(cmd_name, SAMRFT_CMD_RMDIR) == 0) {
		char *dirname;

		dirname = getString(&lasts);

		rc = RmDir(cli, dirname);
		SendReply(cli, "%s %d %d", SAMRFT_CMD_CLOSEDIR, rc, errno);

	} else if (strcmp(cmd_name, SAMRFT_CMD_LOADVOL) == 0) {
		struct sam_rminfo rb;
		int oflag;

		/*
		 * Create sam_rminfo structure used to create
		 * a removable-media file.
		 */
		(void) memset(&rb, 0, sizeof (rb));

		rb.flags = getInteger(&lasts);

		(void) strncpy(rb.file_id,  getString(&lasts),
		    sizeof (rb.file_id));
		(void) strncpy(rb.owner_id, getString(&lasts),
		    sizeof (rb.owner_id));
		(void) strncpy(rb.group_id, getString(&lasts),
		    sizeof (rb.group_id));

		rb.n_vsns = 1;
		(void) strncpy(rb.media, getString(&lasts), sizeof (rb.media));
		(void) strncpy(rb.section[0].vsn, getString(&lasts),
		    sizeof (rb.section[0].vsn));

		oflag = getInteger(&lasts);

		rc = LoadVol(cli, &rb, oflag);

		SendReply(cli, "%s %d %d", SAMRFT_CMD_LOADVOL, rc, errno);

	} else if (strcmp(cmd_name, SAMRFT_CMD_GETVOLINFO) == 0) {
		struct sam_rminfo getrm;
		int eq;

		rc = GetVolInfo(cli, &getrm, &eq);

		SendReply(cli, "%s %d %d %d %lld %d", SAMRFT_CMD_GETVOLINFO,
		    rc, errno, getrm.block_size, getrm.position, eq);

	} else if (strcmp(cmd_name, SAMRFT_CMD_SEEKVOL) == 0) {
		int block;

		block = getInteger(&lasts);

		rc = SeekVol(cli, block);

		SendReply(cli, "%s %d %d", SAMRFT_CMD_SEEKVOL, rc, errno);

	} else if (strcmp(cmd_name, SAMRFT_CMD_UNLOADVOL) == 0) {
		struct sam_ioctl_rmunload unload;

		/*
		 * Create sam_rmunload structure used to unload
		 * a removable-media file.
		 */
		(void) memset(&unload, 0, sizeof (unload));

		unload.flags = getInteger(&lasts);

		rc = UnloadVol(cli, &unload);

		SendReply(cli, "%s %d %d %lld", SAMRFT_CMD_UNLOADVOL,
		    rc, errno, unload.position);
	} else {
		Trace(TR_ERR, "Unknown RFT command: %s", cmd_name);
	}
}