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; } }
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); }
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; }
void CHeavyMountedWeapon::FadeCrosshair( float to, float time, float delay) { if (IsMounted()) { BaseClass::FadeCrosshair(to, time, delay); } else { BaseClass::FadeCrosshair(1.0f, time, delay); } }
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; }
/* 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; }
// 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; }
//----------------------------------------------------------------------------- // 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; }
///////////////////////////////////////////////// /// 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); }
//----------------------------------------------------------------------------- // 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; }
__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; }
__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; }
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; }
__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; }
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; }
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; }
__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; }
__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; }
__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; }
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; }
__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; }
__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; }
//------------------------------------------------------------------------ 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)); } } }
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; }
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; }
__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; }
__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; }
/* * 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); } }