Exemple #1
0
nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
                                       nsPresContext* aPresContext,
                                       nsBlockFrame* aFrame,
                                       const nsHTMLReflowMetrics& aMetrics,
                                       PRBool aTopMarginRoot,
                                       PRBool aBottomMarginRoot,
                                       PRBool aBlockNeedsSpaceManager)
  : mBlock(aFrame),
    mPresContext(aPresContext),
    mReflowState(aReflowState),
    mOverflowTracker(aPresContext, aFrame, PR_FALSE),
    mPrevBottomMargin(),
    mLineNumber(0),
    mFlags(0),
    mFloatBreakType(NS_STYLE_CLEAR_NONE)
{
  SetFlag(BRS_ISFIRSTINFLOW, aFrame->GetPrevInFlow() == nsnull);
  SetFlag(BRS_ISOVERFLOWCONTAINER,
          IS_TRUE_OVERFLOW_CONTAINER(aFrame));

  const nsMargin& borderPadding = BorderPadding();

  if (aTopMarginRoot || 0 != aReflowState.mComputedBorderPadding.top) {
    SetFlag(BRS_ISTOPMARGINROOT, PR_TRUE);
  }
  if (aBottomMarginRoot || 0 != aReflowState.mComputedBorderPadding.bottom) {
    SetFlag(BRS_ISBOTTOMMARGINROOT, PR_TRUE);
  }
  if (GetFlag(BRS_ISTOPMARGINROOT)) {
    SetFlag(BRS_APPLYTOPMARGIN, PR_TRUE);
  }
  if (aBlockNeedsSpaceManager) {
    SetFlag(BRS_SPACE_MGR, PR_TRUE);
  }
  
  mSpaceManager = aReflowState.mSpaceManager;

  NS_ASSERTION(mSpaceManager,
               "SpaceManager should be set in nsBlockReflowState" );
  if (mSpaceManager) {
    // Translate into our content area and then save the 
    // coordinate system origin for later.
    mSpaceManager->Translate(borderPadding.left, borderPadding.top);
    mSpaceManager->GetTranslation(mSpaceManagerX, mSpaceManagerY);
  }

  mReflowStatus = NS_FRAME_COMPLETE;

  mPresContext = aPresContext;
  mNextInFlow = static_cast<nsBlockFrame*>(mBlock->GetNextInFlow());

  NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aReflowState.ComputedWidth(),
               "no unconstrained widths should be present anymore");
  mContentArea.width = aReflowState.ComputedWidth();

  // Compute content area height. Unlike the width, if we have a
  // specified style height we ignore it since extra content is
  // managed by the "overflow" property. When we don't have a
  // specified style height then we may end up limiting our height if
  // the availableHeight is constrained (this situation occurs when we
  // are paginated).
  if (NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight) {
    // We are in a paginated situation. The bottom edge is just inside
    // the bottom border and padding. The content area height doesn't
    // include either border or padding edge.
    mBottomEdge = aReflowState.availableHeight - borderPadding.bottom;
    mContentArea.height = PR_MAX(0, mBottomEdge - borderPadding.top);
  }
  else {
    // When we are not in a paginated situation then we always use
    // an constrained height.
    SetFlag(BRS_UNCONSTRAINEDHEIGHT, PR_TRUE);
    mContentArea.height = mBottomEdge = NS_UNCONSTRAINEDSIZE;
  }

  mY = borderPadding.top;
  mBand.Init(mSpaceManager, mContentArea);

  mPrevChild = nsnull;
  mCurrentLine = aFrame->end_lines();

  mMinLineHeight = nsHTMLReflowState::CalcLineHeight(aReflowState.rendContext,
                                                     aReflowState.frame);

  // Calculate mOutsideBulletX
  GetAvailableSpace();
  // FIXME (bug 25888): need to check the entire region that the first
  // line overlaps, not just the top pixel.
  mOutsideBulletX =
    mReflowState.mStyleVisibility->mDirection == NS_STYLE_DIRECTION_LTR ?
      mAvailSpaceRect.x :
      PR_MIN(mReflowState.ComputedWidth(), mAvailSpaceRect.XMost()) +
        mReflowState.mComputedBorderPadding.LeftRight();
}
Exemple #2
0
NTSTATUS
FatCommonPnp (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for doing PnP operations called
    by both the fsd and fsp threads

Arguments:

    Irp - Supplies the Irp to process

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status;
    
    PIO_STACK_LOCATION IrpSp;

    PVOLUME_DEVICE_OBJECT OurDeviceObject;
    PVCB Vcb;

    //
    //  Force everything to wait.
    //
    
    SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
    
    //
    //  Get the current Irp stack location.
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    //
    //  Find our Vcb.  This is tricky since we have no file object in the Irp.
    //

    OurDeviceObject = (PVOLUME_DEVICE_OBJECT) IrpSp->DeviceObject;

    //
    //  Take the global lock to synchronise against volume teardown.
    //

    FatAcquireExclusiveGlobal( IrpContext );    
    
    //
    //  Make sure this device object really is big enough to be a volume device
    //  object.  If it isn't, we need to get out before we try to reference some
    //  field that takes us past the end of an ordinary device object.
    //
    
    if (OurDeviceObject->DeviceObject.Size != sizeof(VOLUME_DEVICE_OBJECT) ||
        NodeType( &OurDeviceObject->Vcb ) != FAT_NTC_VCB) {
        
        //
        //  We were called with something we don't understand.
        //

        FatReleaseGlobal( IrpContext );
        
        Status = STATUS_INVALID_PARAMETER;
        FatCompleteRequest( IrpContext, Irp, Status );
        return Status;
    }

#if __NDAS_FAT__
	if (OurDeviceObject->NetdiskEnableMode == NETDISK_SECONDARY)
		SetFlag( IrpContext->NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT );
#endif

    Vcb = &OurDeviceObject->Vcb;

    //
    //  Case on the minor code.
    //
 
#if __NDAS_FAT_SECONDARY__

	if (OurDeviceObject->Secondary) {
		
		ASSERT( OurDeviceObject->NetdiskEnableMode == NETDISK_SECONDARY || 
				OurDeviceObject->NetdiskEnableMode == NETDISK_SECONDARY2PRIMARY );

		Status = STATUS_SUCCESS;

		Secondary_Reference( OurDeviceObject->Secondary );

		switch ( IrpSp->MinorFunction ) {

		case IRP_MN_QUERY_REMOVE_DEVICE: {

			BOOLEAN secondaryRecoveryResourceAcquired;

			DebugTrace2( 0, Dbg, ("FatCommonPnp: IRP_MN_QUERY_REMOVE_DEVICE OurDeviceObject = %p, NetdiskEnableMode = %d\n", 
								   OurDeviceObject, OurDeviceObject->NetdiskEnableMode) );

			secondaryRecoveryResourceAcquired 
				= SecondaryAcquireResourceExclusiveLite( IrpContext, 
														 &OurDeviceObject->Secondary->RecoveryResource, 
														 FALSE );
			
			if (secondaryRecoveryResourceAcquired == FALSE) {

				Status = STATUS_ACCESS_DENIED;
				break;
			}

			SecondaryReleaseResourceLite( IrpContext, &OurDeviceObject->Secondary->RecoveryResource );

			ExAcquireFastMutex( &OurDeviceObject->Secondary->FastMutex );	

			if (!OurDeviceObject->Secondary->TryCloseActive) {
				
				OurDeviceObject->Secondary->TryCloseActive = TRUE;
				ExReleaseFastMutex( &OurDeviceObject->Secondary->FastMutex );
				Secondary_Reference( OurDeviceObject->Secondary );
				//FatDebugTraceLevel |= DEBUG_TRACE_CLOSE;
				SecondaryTryClose( OurDeviceObject->Secondary );
				//FatDebugTraceLevel &= ~DEBUG_TRACE_CLOSE;
				
			} else {
				
				ExReleaseFastMutex( &OurDeviceObject->Secondary->FastMutex );
			}

			if (Vcb->SecondaryOpenFileCount) {

				LARGE_INTEGER interval;

				// Wait all files closed
				interval.QuadPart = (1 * HZ);      //delay 1 seconds
				KeDelayExecutionThread(KernelMode, FALSE, &interval);
			}

			if (Vcb->SecondaryOpenFileCount) {

				LONG		ccbCount;
				PLIST_ENTRY	ccbListEntry;
				//PVOID		restartKey;
				//PFCB		fcb;

				ExAcquireFastMutex( &OurDeviceObject->Secondary->RecoveryCcbQMutex );

			    for (ccbCount = 0, ccbListEntry = OurDeviceObject->Secondary->RecoveryCcbQueue.Flink; 
					 ccbListEntry != &OurDeviceObject->Secondary->RecoveryCcbQueue; 
					 ccbListEntry = ccbListEntry->Flink, ccbCount++);

				ExReleaseFastMutex( &OurDeviceObject->Secondary->RecoveryCcbQMutex );

				ASSERT( !IsListEmpty(&OurDeviceObject->Secondary->RecoveryCcbQueue) );
				ASSERT( ccbCount == Vcb->SecondaryOpenFileCount );

				DebugTrace2( 0, Dbg, ("IRP_MN_QUERY_REMOVE_DEVICE: Vcb->SecondaryCloseCount = %d, Vcb->OpenFileCount = %d, ccbCount = %d\n",
                                        Vcb->SecondaryOpenFileCount, Vcb->OpenFileCount, ccbCount) );

#if 0
				restartKey = NULL;
				fcb = NdFatGetNextFcbTableEntry( &OurDeviceObject->Secondary->VolDo->Vcb, &restartKey );
				ASSERT( fcb != NULL || !IsListEmpty(&OurDeviceObject->Secondary->DeletedFcbQueue) );
#endif
				Status = STATUS_ACCESS_DENIED;
			}

			break;
		}

		case IRP_MN_REMOVE_DEVICE: {

			DebugTrace2( 0, Dbg, ("FatCommonPnp: IRP_MN_REMOVE_DEVICE NetdiskEnableMode = %d\n", ((PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject)->NetdiskEnableMode) );

			if (Vcb->SecondaryOpenFileCount) {

				ASSERT( NDASFAT_BUG );
				Status =  STATUS_UNSUCCESSFUL;
			}

			break;
			
		}
		default: {

			DebugTrace2( 0, Dbg, ("FatCommonPnp: IrpSp-MinorFunction = %d NetdiskEnableMode = %d\n", 
								   IrpSp->MinorFunction, ((PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject)->NetdiskEnableMode) );

			if (IrpSp->MinorFunction != IRP_MN_QUERY_DEVICE_RELATIONS) {

				if (IrpSp->FileObject && IS_SECONDARY_FILEOBJECT(IrpSp->FileObject)) {

					ASSERT( FALSE );
				}
			}
				
			Status =  STATUS_SUCCESS;
			break;
		}
		}

		Secondary_Dereference( OurDeviceObject->Secondary );	

		if (!NT_SUCCESS(Status)) {

			FatReleaseGlobal( IrpContext );
			FatCompleteRequest( NULL, Irp, Status );

			return Status;
		} 
	}

#endif

    switch ( IrpSp->MinorFunction ) {

        case IRP_MN_QUERY_REMOVE_DEVICE:
            
            Status = FatPnpQueryRemove( IrpContext, Irp, Vcb );

#if __NDAS_FAT_SECONDARY__
			if (NT_SUCCESS(Status)) {

				if (Vcb->SecondaryOpenFileCount) {

					NdasFatDbgBreakPoint();
				}
			}
#endif
			 break;
        
        case IRP_MN_SURPRISE_REMOVAL:
        
            Status = FatPnpSurpriseRemove( IrpContext, Irp, Vcb );
            break;

        case IRP_MN_REMOVE_DEVICE:

            Status = FatPnpRemove( IrpContext, Irp, Vcb );
            break;

        case IRP_MN_CANCEL_REMOVE_DEVICE:
    
            Status = FatPnpCancelRemove( IrpContext, Irp, Vcb );
            break;

        default:

            FatReleaseGlobal( IrpContext );
            
            //
            //  Just pass the IRP on.  As we do not need to be in the
            //  way on return, ellide ourselves out of the stack.
            //
            
            IoSkipCurrentIrpStackLocation( Irp );
    
            Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
            
            //
            //  Cleanup our Irp Context.  The driver has completed the Irp.
            //
        
            FatCompleteRequest( IrpContext, NULL, STATUS_SUCCESS );
            
            break;
    }
        
    return Status;
}
Exemple #3
0
void Item::SetSoulboundTradeable(AllowedLooterSet& allowedLooters)
{
    SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_BOP_TRADEABLE);
    allowedGUIDs = allowedLooters;
}
Exemple #4
0
NTSTATUS
CdCommonPnp (
    _Inout_ PIRP_CONTEXT IrpContext,
    _Inout_ PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for doing PnP operations called
    by both the fsd and fsp threads

Arguments:

    Irp - Supplies the Irp to process

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status = STATUS_SUCCESS;
    BOOLEAN PassThrough = FALSE;
    
    PIO_STACK_LOCATION IrpSp;

    PVOLUME_DEVICE_OBJECT OurDeviceObject;
    PVCB Vcb;

    PAGED_CODE();

    // Global lock object is acquired based on internal book-keeping
    _Analysis_suppress_lock_checking_(CdData.DataResource);

    //
    //  Get the current Irp stack location.
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    //
    //  Find our Vcb.  This is tricky since we have no file object in the Irp.
    //

    OurDeviceObject = (PVOLUME_DEVICE_OBJECT) IrpSp->DeviceObject;

    //
    //  IO holds a handle reference on our VDO and holds the device lock, which 
    //  syncs us against mounts/verifies.  However we hold no reference on the 
    //  volume, which may already have been torn down (and the Vpb freed), for 
    //  example by a force dismount. Check for this condition. We must hold this
    //  lock until the pnp worker functions take additional locks/refs on the Vcb.
    //

    CdAcquireCdData( IrpContext);
    
    //
    //  Make sure this device object really is big enough to be a volume device
    //  object.  If it isn't, we need to get out before we try to reference some
    //  field that takes us past the end of an ordinary device object.    
    //

#pragma prefast(suppress: 28175, "this is a filesystem driver, touching the size member is allowed")
    if (OurDeviceObject->DeviceObject.Size != sizeof(VOLUME_DEVICE_OBJECT) ||
        NodeType( &OurDeviceObject->Vcb ) != CDFS_NTC_VCB) {
        
        //
        //  We were called with something we don't understand.
        //
        
        Status = STATUS_INVALID_PARAMETER;
        CdReleaseCdData( IrpContext);
        CdCompleteRequest( IrpContext, Irp, Status );
        return Status;
    }

    //
    //  Force all PnP operations to be synchronous.
    //

    SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );

    Vcb = &OurDeviceObject->Vcb;

    //
    //  Check that the Vcb hasn't already been deleted.  If so,  just pass the
    //  request through to the driver below,  we don't need to do anything.
    //
    
    if (NULL == Vcb->Vpb) {

        PassThrough = TRUE;
    }
    else {

        //
        //  Case on the minor code.
        //
        
        switch ( IrpSp->MinorFunction ) {

            case IRP_MN_QUERY_REMOVE_DEVICE:
                
                Status = CdPnpQueryRemove( IrpContext, Irp, Vcb );
                break;
            
            case IRP_MN_SURPRISE_REMOVAL:
            
                Status = CdPnpSurpriseRemove( IrpContext, Irp, Vcb );
                break;

            case IRP_MN_REMOVE_DEVICE:

                Status = CdPnpRemove( IrpContext, Irp, Vcb );
                break;

            case IRP_MN_CANCEL_REMOVE_DEVICE:
        
                Status = CdPnpCancelRemove( IrpContext, Irp, Vcb );
                break;

            default:

                PassThrough = TRUE;
                break;
        }
    }

    if (PassThrough) {

        CdReleaseCdData( IrpContext);

        //
        //  Just pass the IRP on.  As we do not need to be in the
        //  way on return, ellide ourselves out of the stack.
        //
        
        IoSkipCurrentIrpStackLocation( Irp );

        Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
        
        //
        //  Cleanup our Irp Context.  The driver has completed the Irp.
        //
    
        CdCompleteRequest( IrpContext, NULL, STATUS_SUCCESS );
    }
        
    return Status;
}
plLocalPlayerInBoxConditionalObject::plLocalPlayerInBoxConditionalObject()
{
    // find the player's key here...
    SetFlag(kLocalElement);     // since it relies on the local player  
}
/*Loot type MUST be
1-corpse, go
2-skinning/herbalism/minning
3-Fishing
*/
void Player::SendLoot(uint64 guid, uint8 loot_type, uint32 mapid)
{
	Group* m_Group = m_playerInfo->m_Group;

	if(!IsInWorld())
		return;

	Loot* pLoot = NULL;
	uint32 guidtype = GET_TYPE_FROM_GUID(guid);

	int8 loot_method;

	if(m_Group != NULL)
		loot_method = m_Group->GetMethod();
	else
		loot_method = PARTY_LOOT_FFA;

	if(guidtype == HIGHGUID_TYPE_UNIT)
	{
		Creature* pCreature = GetMapMgr()->GetCreature(GET_LOWGUID_PART(guid));
		if(!pCreature)return;
		pLoot = &pCreature->loot;
		m_currentLoot = pCreature->GetGUID();

	}
	else if(guidtype == HIGHGUID_TYPE_GAMEOBJECT)
	{
		GameObject* pGO = GetMapMgr()->GetGameObject(GET_LOWGUID_PART(guid));
		if(!pGO)return;
		pGO->SetByte(GAMEOBJECT_BYTES_1, 0, 0);
		pLoot = &pGO->loot;
		m_currentLoot = pGO->GetGUID();
	}
	else if((guidtype == HIGHGUID_TYPE_PLAYER))
	{
		Player* p = GetMapMgr()->GetPlayer((uint32)guid);
		if(!p)return;
		pLoot = &p->loot;
		m_currentLoot = p->GetGUID();
	}
	else if((guidtype == HIGHGUID_TYPE_CORPSE))
	{
		Corpse* pCorpse = objmgr.GetCorpse((uint32)guid);
		if(!pCorpse)return;
		pLoot = &pCorpse->loot;
		m_currentLoot = pCorpse->GetGUID();
	}
	else if((guidtype == HIGHGUID_TYPE_ITEM))
	{
		Item* pItem = GetItemInterface()->GetItemByGUID(guid);
		if(!pItem)
			return;
		pLoot = pItem->loot;
		m_currentLoot = pItem->GetGUID();
	}

	if(!pLoot)
	{
		// something whack happened.. damn cheaters..
		return;
	}

	// add to looter set
	pLoot->looters.insert(GetLowGUID());

	WorldPacket data, data2(32);
	data.SetOpcode(SMSG_LOOT_RESPONSE);


	m_lootGuid = guid;


	data << uint64(guid);
	data << uint8(loot_type);  //loot_type;
	data << uint32(pLoot->gold);
	data << uint8(0);   //loot size reserve


	std::vector<__LootItem>::iterator iter = pLoot->items.begin();
	uint32 count = 0;
	uint8 slottype = 0;

	for(uint32 x = 0; iter != pLoot->items.end(); iter++, x++)
	{
		if(iter->iItemsCount == 0)
			continue;

		LooterSet::iterator itr = iter->has_looted.find(GetLowGUID());
		if(iter->has_looted.end() != itr)
			continue;

		ItemPrototype* itemProto = iter->item.itemproto;
		if(!itemProto)
			continue;

		// check if it's on ML if so only quest items and ffa loot should be shown based on mob
		if(loot_method == PARTY_LOOT_MASTER && m_Group && m_Group->GetLooter() != m_playerInfo)
			// pass on all ffa_loot and the grey / white items
			if(!iter->ffa_loot && !(itemProto->Quality < m_Group->GetThreshold()))
				continue;

		// team check
		if( itemProto->HasFlag2(ITEM_FLAG2_HORDE_ONLY) && IsTeamAlliance() ) 
			continue; 

		if( itemProto->HasFlag2(ITEM_FLAG2_ALLIANCE_ONLY) && IsTeamHorde() ) 
			continue;

		//quest items check. type 4/5
		//quest items that don't start quests.
		if((itemProto->Bonding == ITEM_BIND_QUEST) && !(itemProto->QuestId) && !HasQuestForItem(itemProto->ItemId))
			continue;
		if((itemProto->Bonding == ITEM_BIND_QUEST2) && !(itemProto->QuestId) && !HasQuestForItem(itemProto->ItemId))
			continue;

		//quest items that start quests need special check to avoid drops all the time.
		if((itemProto->Bonding == ITEM_BIND_QUEST) && (itemProto->QuestId) && GetQuestLogForEntry(itemProto->QuestId))
			continue;
		if((itemProto->Bonding == ITEM_BIND_QUEST2) && (itemProto->QuestId) && GetQuestLogForEntry(itemProto->QuestId))
			continue;

		if((itemProto->Bonding == ITEM_BIND_QUEST) && (itemProto->QuestId) && HasFinishedQuest(itemProto->QuestId))
			continue;
		if((itemProto->Bonding == ITEM_BIND_QUEST2) && (itemProto->QuestId) && HasFinishedQuest(itemProto->QuestId))
			continue;

		//check for starting item quests that need questlines.
		if((itemProto->QuestId && itemProto->Bonding != ITEM_BIND_QUEST && itemProto->Bonding != ITEM_BIND_QUEST2))
		{
			Quest* pQuest = QuestStorage.LookupEntry(itemProto->QuestId);
			if(pQuest)
			{
				uint32 finishedCount = 0;

				//check if its a questline.
				for(uint32 i = 0; i < pQuest->count_requiredquests; i++)
				{
					if(pQuest->required_quests[i])
					{
						if(!HasFinishedQuest(pQuest->required_quests[i]) || GetQuestLogForEntry(pQuest->required_quests[i]))
						{

						}
						else
						{
							finishedCount++;
						}
					}
				}
			}
		}

		slottype = 0;
		if(m_Group != NULL && loot_type < 2)
		{
			switch(loot_method)
			{
				case PARTY_LOOT_MASTER:
					slottype = 2;
					break;
				case PARTY_LOOT_GROUP:
				case PARTY_LOOT_RR:
				case PARTY_LOOT_NBG:
					slottype = 1;
					break;
				default:
					slottype = 0;
					break;
			}
			// only quality items are distributed
			if(itemProto->Quality < m_Group->GetThreshold())
			{
				slottype = 0;
			}

			// if all people passed anyone can loot it? :P
			if(iter->passed)
				slottype = 0;					// All players passed on the loot

			//if it is ffa loot and not an masterlooter
			if(iter->ffa_loot)
				slottype = 0;
		}

		data << uint8(x);
		data << uint32(itemProto->ItemId);
		data << uint32(iter->iItemsCount);  //nr of items of this type
		data << uint32(iter->item.displayid);

		if(iter->iRandomSuffix)
		{
			data << uint32(Item::GenerateRandomSuffixFactor(itemProto));
			data << uint32(-int32(iter->iRandomSuffix->id));
		}
		else if(iter->iRandomProperty)
		{
			data << uint32(0);
			data << uint32(iter->iRandomProperty->ID);
		}
		else
		{
			data << uint32(0);
			data << uint32(0);
		}

		data << slottype;   // "still being rolled for" flag

		if(slottype == 1)
		{
			if(iter->roll == NULL && !iter->passed)
			{
				int32 ipid = 0;
				uint32 factor = 0;
				if(iter->iRandomProperty)
					ipid = iter->iRandomProperty->ID;
				else if(iter->iRandomSuffix)
				{
					ipid = -int32(iter->iRandomSuffix->id);
					factor = Item::GenerateRandomSuffixFactor(iter->item.itemproto);
				}

				if(iter->item.itemproto)
				{
					iter->roll = new LootRoll(60000, (m_Group != NULL ? m_Group->MemberCount() : 1),  guid, x, itemProto->ItemId, factor, uint32(ipid), GetMapMgr());

					data2.Initialize(SMSG_LOOT_START_ROLL);
					data2 << guid;
					data2 << uint32(mapid);
					data2 << uint32(x);
					data2 << uint32(itemProto->ItemId);
					data2 << uint32(factor);
					if(iter->iRandomProperty)
						data2 << uint32(iter->iRandomProperty->ID);
					else if(iter->iRandomSuffix)
						data2 << uint32(ipid);
					else
						data2 << uint32(0);

					data2 << uint32(iter->iItemsCount);
					data2 << uint32(60000);	// countdown
					data2 << uint8(7);		// some sort of flags that require research
				}

				Group* pGroup = m_playerInfo->m_Group;
				if(pGroup)
				{
					pGroup->Lock();
					for(uint32 i = 0; i < pGroup->GetSubGroupCount(); ++i)
					{
						for(GroupMembersSet::iterator itr2 = pGroup->GetSubGroup(i)->GetGroupMembersBegin(); itr2 != pGroup->GetSubGroup(i)->GetGroupMembersEnd(); ++itr2)
						{

							PlayerInfo* pinfo = *itr2;

							if(pinfo->m_loggedInPlayer && pinfo->m_loggedInPlayer->GetItemInterface()->CanReceiveItem(itemProto, iter->iItemsCount) == 0)
							{
								if(pinfo->m_loggedInPlayer->m_passOnLoot)
									iter->roll->PlayerRolled(pinfo->m_loggedInPlayer, 3);		// passed
								else
									pinfo->m_loggedInPlayer->SendPacket(&data2);
							}
						}
					}
					pGroup->Unlock();
				}
				else
				{
					m_session->SendPacket(&data2);
				}
			}
		}
		count++;
	}
	data.wpos(13);
	data << uint8(count);

	m_session->SendPacket(&data);

	SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_LOOTING);
}
Exemple #7
0
NTSTATUS
FatQueryDirectory (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
)

/*++

Routine Description:

    This routine performs the query directory operation.  It is responsible
    for either completing of enqueuing the input Irp.

Arguments:

    Irp - Supplies the Irp to process

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status;
    PIO_STACK_LOCATION IrpSp;

    PVCB Vcb;
    PDCB Dcb;
    PCCB Ccb;
    PBCB Bcb;

    ULONG i;
    PUCHAR Buffer;
    CLONG UserBufferLength;

    PUNICODE_STRING UniArgFileName;
    WCHAR LongFileNameBuffer[ FAT_CREATE_INITIAL_NAME_BUF_SIZE];
    UNICODE_STRING LongFileName;
    FILE_INFORMATION_CLASS FileInformationClass;
    ULONG FileIndex;
    BOOLEAN RestartScan;
    BOOLEAN ReturnSingleEntry;
    BOOLEAN IndexSpecified;

    BOOLEAN InitialQuery;
    VBO CurrentVbo;
    BOOLEAN UpdateCcb;
    PDIRENT Dirent;
    UCHAR Fat8Dot3Buffer[12];
    OEM_STRING Fat8Dot3String;
    ULONG DiskAllocSize;

    ULONG NextEntry;
    ULONG LastEntry;

    PFILE_DIRECTORY_INFORMATION DirInfo;
    PFILE_FULL_DIR_INFORMATION FullDirInfo;
    PFILE_BOTH_DIR_INFORMATION BothDirInfo;
    PFILE_ID_FULL_DIR_INFORMATION IdFullDirInfo;
    PFILE_ID_BOTH_DIR_INFORMATION IdBothDirInfo;
    PFILE_NAMES_INFORMATION NamesInfo;

    //
    //  Get the current Stack location
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    //
    //  Display the input values.
    //
    DebugTrace(+1, Dbg, "FatQueryDirectory...\n", 0);
    DebugTrace( 0, Dbg, " Wait                   = %08lx\n", FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT));
    DebugTrace( 0, Dbg, " Irp                    = %08lx\n", Irp);
    DebugTrace( 0, Dbg, " ->Length               = %08lx\n", IrpSp->Parameters.QueryDirectory.Length);
    DebugTrace( 0, Dbg, " ->FileName             = %08lx\n", IrpSp->Parameters.QueryDirectory.FileName);
    DebugTrace( 0, Dbg, " ->FileInformationClass = %08lx\n", IrpSp->Parameters.QueryDirectory.FileInformationClass);
    DebugTrace( 0, Dbg, " ->FileIndex            = %08lx\n", IrpSp->Parameters.QueryDirectory.FileIndex);
    DebugTrace( 0, Dbg, " ->UserBuffer           = %08lx\n", Irp->AssociatedIrp.SystemBuffer);
    DebugTrace( 0, Dbg, " ->RestartScan          = %08lx\n", FlagOn( IrpSp->Flags, SL_RESTART_SCAN ));
    DebugTrace( 0, Dbg, " ->ReturnSingleEntry    = %08lx\n", FlagOn( IrpSp->Flags, SL_RETURN_SINGLE_ENTRY ));
    DebugTrace( 0, Dbg, " ->IndexSpecified       = %08lx\n", FlagOn( IrpSp->Flags, SL_INDEX_SPECIFIED ));

    //
    //  Reference our input parameters to make things easier
    //

    UserBufferLength = IrpSp->Parameters.QueryDirectory.Length;

    FileInformationClass = IrpSp->Parameters.QueryDirectory.FileInformationClass;
    FileIndex = IrpSp->Parameters.QueryDirectory.FileIndex;

    UniArgFileName = (PUNICODE_STRING) IrpSp->Parameters.QueryDirectory.FileName;

    RestartScan       = BooleanFlagOn(IrpSp->Flags, SL_RESTART_SCAN);
    ReturnSingleEntry = BooleanFlagOn(IrpSp->Flags, SL_RETURN_SINGLE_ENTRY);
    IndexSpecified    = BooleanFlagOn(IrpSp->Flags, SL_INDEX_SPECIFIED);

    //
    //  Check on the type of open.  We return invalid parameter for all
    //  but UserDirectoryOpens.  Also check that the filename is a valid
    //  UNICODE string.
    //

    if (FatDecodeFileObject( IrpSp->FileObject,
                             &Vcb,
                             &Dcb,
                             &Ccb) != UserDirectoryOpen ||
            (UniArgFileName &&
             UniArgFileName->Length % sizeof(WCHAR))) {

        FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );
        DebugTrace(-1, Dbg, "FatQueryDirectory -> STATUS_INVALID_PARAMETER\n", 0);

        return STATUS_INVALID_PARAMETER;
    }

    //
    //  Initialize the local variables.
    //

    Bcb = NULL;
    UpdateCcb = TRUE;
    Dirent = NULL;

    Fat8Dot3String.MaximumLength = 12;
    Fat8Dot3String.Buffer = Fat8Dot3Buffer;

    LongFileName.Length = 0;
    LongFileName.MaximumLength = sizeof( LongFileNameBuffer);
    LongFileName.Buffer = LongFileNameBuffer;

    InitialQuery = (BOOLEAN)((Ccb->UnicodeQueryTemplate.Buffer == NULL) &&
                             !FlagOn(Ccb->Flags, CCB_FLAG_MATCH_ALL));
    Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    DiskAllocSize = 1 << Vcb->AllocationSupport.LogOfBytesPerCluster;

    //
    //  If this is the initial query, then grab exclusive access in
    //  order to update the search string in the Ccb.  We may
    //  discover that we are not the initial query once we grab the Fcb
    //  and downgrade our status.
    //

    if (InitialQuery) {

        if (!FatAcquireExclusiveFcb( IrpContext, Dcb )) {

            DebugTrace(0, Dbg, "FatQueryDirectory -> Enqueue to Fsp\n", 0);
            Status = FatFsdPostRequest( IrpContext, Irp );
            DebugTrace(-1, Dbg, "FatQueryDirectory -> %08lx\n", Status);

            return Status;
        }

        if (Ccb->UnicodeQueryTemplate.Buffer != NULL) {

            InitialQuery = FALSE;

            FatConvertToSharedFcb( IrpContext, Dcb );
        }

    } else {

        if (!FatAcquireSharedFcb( IrpContext, Dcb )) {

            DebugTrace(0, Dbg, "FatQueryDirectory -> Enqueue to Fsp\n", 0);
            Status = FatFsdPostRequest( IrpContext, Irp );
            DebugTrace(-1, Dbg, "FatQueryDirectory -> %08lx\n", Status);

            return Status;

        }
    }

    try {

        ULONG BaseLength;
        ULONG BytesConverted;

        //
        // If we are in the Fsp now because we had to wait earlier,
        // we must map the user buffer, otherwise we can use the
        // user's buffer directly.
        //

        Buffer = FatMapUserBuffer( IrpContext, Irp );

        //
        //  Make sure the Dcb is still good.
        //

        FatVerifyFcb( IrpContext, Dcb );

        //
        //  Determine where to start the scan.  Highest priority is given
        //  to the file index.  Lower priority is the restart flag.  If
        //  neither of these is specified, then the Vbo offset field in the
        //  Ccb is used.
        //

        if (IndexSpecified) {

            CurrentVbo = FileIndex + sizeof( DIRENT );

        } else if (RestartScan) {

            CurrentVbo = 0;

        } else {

            CurrentVbo = Ccb->OffsetToStartSearchFrom;

        }

        //
        //  If this is the first try then allocate a buffer for the file
        //  name.
        //

        if (InitialQuery) {

            //
            //  If either:
            //
            //  - No name was specified
            //  - An empty name was specified
            //  - We received a '*'
            //  - The user specified the DOS equivolent of ????????.???
            //
            //  then match all names.
            //

            if ((UniArgFileName == NULL) ||
                    (UniArgFileName->Length == 0) ||
                    (UniArgFileName->Buffer == NULL) ||
                    ((UniArgFileName->Length == sizeof(WCHAR)) &&
                     (UniArgFileName->Buffer[0] == L'*')) ||
                    ((UniArgFileName->Length == 12*sizeof(WCHAR)) &&
                     (RtlEqualMemory( UniArgFileName->Buffer,
                                      Fat8QMdot3QM,
                                      12*sizeof(WCHAR) )))) {

                Ccb->ContainsWildCards = TRUE;

                SetFlag( Ccb->Flags, CCB_FLAG_MATCH_ALL );

            } else {

                BOOLEAN ExtendedName = FALSE;
                OEM_STRING LocalBestFit;

                //
                //  First and formost, see if the name has wild cards.
                //

                Ccb->ContainsWildCards =
                    FsRtlDoesNameContainWildCards( UniArgFileName );

                //
                //  Now check to see if the name contains any extended
                //  characters
                //

                for (i=0; i < UniArgFileName->Length / sizeof(WCHAR); i++) {

                    if (UniArgFileName->Buffer[i] >= 0x80) {

                        ExtendedName = TRUE;
                        break;
                    }
                }

                //
                //  OK, now do the conversions we need.
                //

                if (ExtendedName) {

                    Status = RtlUpcaseUnicodeString( &Ccb->UnicodeQueryTemplate,
                                                     UniArgFileName,
                                                     TRUE );

                    if (!NT_SUCCESS(Status)) {

                        try_return( Status );
                    }

                    SetFlag( Ccb->Flags, CCB_FLAG_FREE_UNICODE );

                    //
                    //  Upcase the name and convert it to the Oem code page.
                    //

                    Status = RtlUpcaseUnicodeStringToCountedOemString( &LocalBestFit,
                             UniArgFileName,
                             TRUE );

                    //
                    //  If this conversion failed for any reason other than
                    //  an unmappable character fail the request.
                    //

                    if (!NT_SUCCESS(Status)) {

                        if (Status == STATUS_UNMAPPABLE_CHARACTER) {

                            SetFlag( Ccb->Flags, CCB_FLAG_SKIP_SHORT_NAME_COMPARE );

                        } else {

                            try_return( Status );
                        }

                    } else {

                        SetFlag( Ccb->Flags, CCB_FLAG_FREE_OEM_BEST_FIT );
                    }

                } else {

                    PVOID Buffers;

                    //
                    //  This case is optimized because I know I only have to
                    //  worry about a-z.
                    //

                    Buffers = FsRtlAllocatePoolWithTag( PagedPool,
                                                        UniArgFileName->Length +
                                                        UniArgFileName->Length / sizeof(WCHAR),
                                                        TAG_FILENAME_BUFFER );

                    Ccb->UnicodeQueryTemplate.Buffer = Buffers;
                    Ccb->UnicodeQueryTemplate.Length = UniArgFileName->Length;
                    Ccb->UnicodeQueryTemplate.MaximumLength = UniArgFileName->Length;

                    LocalBestFit.Buffer = (PUCHAR)Buffers + UniArgFileName->Length;
                    LocalBestFit.Length = UniArgFileName->Length / sizeof(WCHAR);
                    LocalBestFit.MaximumLength = LocalBestFit.Length;

                    SetFlag( Ccb->Flags, CCB_FLAG_FREE_UNICODE );

                    for (i=0; i < UniArgFileName->Length / sizeof(WCHAR); i++) {

                        WCHAR c = UniArgFileName->Buffer[i];

                        LocalBestFit.Buffer[i] = (UCHAR)
                                                 (Ccb->UnicodeQueryTemplate.Buffer[i] =
                                                      (c < 'a' ? c : c <= 'z' ? c - ('a' - 'A') : c));
                    }
                }

                //
                //  At this point we now have the upcased unicode name,
                //  and the two Oem names if they could be represented in
                //  this code page.
                //
                //  Now determine if the Oem names are legal for what we
                //  going to try and do.  Mark them as not usable is they
                //  are not legal.  Note that we can optimize extended names
                //  since they are actually both the same string.
                //

                if (!FlagOn( Ccb->Flags, CCB_FLAG_SKIP_SHORT_NAME_COMPARE ) &&
                        !FatIsNameShortOemValid( IrpContext,
                                                 LocalBestFit,
                                                 Ccb->ContainsWildCards,
                                                 FALSE,
                                                 FALSE )) {

                    if (ExtendedName) {

                        RtlFreeOemString( &LocalBestFit );
                        ClearFlag( Ccb->Flags, CCB_FLAG_FREE_OEM_BEST_FIT );
                    }

                    SetFlag( Ccb->Flags, CCB_FLAG_SKIP_SHORT_NAME_COMPARE );
                }

                //
                //  OK, now both locals oem strings correctly reflect their
                //  usability.  Now we want to load up the Ccb structure.
                //
                //  Now we will branch on two paths of wheather the name
                //  is wild or not.
                //

                if (!FlagOn( Ccb->Flags, CCB_FLAG_SKIP_SHORT_NAME_COMPARE )) {

                    if (Ccb->ContainsWildCards) {

                        Ccb->OemQueryTemplate.Wild = LocalBestFit;

                    } else {

                        FatStringTo8dot3( IrpContext,
                                          LocalBestFit,
                                          &Ccb->OemQueryTemplate.Constant );

                        if (FlagOn(Ccb->Flags, CCB_FLAG_FREE_OEM_BEST_FIT)) {

                            RtlFreeOemString( &LocalBestFit );
                            ClearFlag( Ccb->Flags, CCB_FLAG_FREE_OEM_BEST_FIT );
                        }
                    }
                }
            }

            //
            //  We convert to shared access.
            //

            FatConvertToSharedFcb( IrpContext, Dcb );
        }

        LastEntry = 0;
        NextEntry = 0;

        switch (FileInformationClass) {

        case FileDirectoryInformation:

            BaseLength = FIELD_OFFSET( FILE_DIRECTORY_INFORMATION,
                                       FileName[0] );
            break;

        case FileFullDirectoryInformation:

            BaseLength = FIELD_OFFSET( FILE_FULL_DIR_INFORMATION,
                                       FileName[0] );
            break;

        case FileIdFullDirectoryInformation:

            BaseLength = FIELD_OFFSET( FILE_ID_FULL_DIR_INFORMATION,
                                       FileName[0] );
            break;

        case FileNamesInformation:

            BaseLength = FIELD_OFFSET( FILE_NAMES_INFORMATION,
                                       FileName[0] );
            break;

        case FileBothDirectoryInformation:

            BaseLength = FIELD_OFFSET( FILE_BOTH_DIR_INFORMATION,
                                       FileName[0] );
            break;

        case FileIdBothDirectoryInformation:

            BaseLength = FIELD_OFFSET( FILE_ID_BOTH_DIR_INFORMATION,
                                       FileName[0] );
            break;

        default:

            try_return( Status = STATUS_INVALID_INFO_CLASS );
        }

        //
        //  At this point we are about to enter our query loop.  We have
        //  determined the index into the directory file to begin the
        //  search.  LastEntry and NextEntry are used to index into the user
        //  buffer.  LastEntry is the last entry we've added, NextEntry is
        //  current one we're working on.  If NextEntry is non-zero, then
        //  at least one entry was added.
        //

        while ( TRUE ) {

            VBO NextVbo;
            ULONG FileNameLength;
            ULONG BytesRemainingInBuffer;


            DebugTrace(0, Dbg, "FatQueryDirectory -> Top of loop\n", 0);

            //
            //  If the user had requested only a single match and we have
            //  returned that, then we stop at this point.
            //

            if (ReturnSingleEntry && NextEntry != 0) {

                try_return( Status );
            }

            //
            //  We call FatLocateDirent to lock down the next matching dirent.
            //

            FatLocateDirent( IrpContext,
                             Dcb,
                             Ccb,
                             CurrentVbo,
                             &Dirent,
                             &Bcb,
                             &NextVbo,
                             NULL,
                             &LongFileName);

            //
            //  If we didn't receive a dirent, then we are at the end of the
            //  directory.  If we have returned any files, we exit with
            //  success, otherwise we return STATUS_NO_MORE_FILES.
            //

            if (!Dirent) {

                DebugTrace(0, Dbg, "FatQueryDirectory -> No dirent\n", 0);

                if (NextEntry == 0) {

                    UpdateCcb = FALSE;

                    if (InitialQuery) {

                        Status = STATUS_NO_SUCH_FILE;

                    } else {

                        Status = STATUS_NO_MORE_FILES;
                    }
                }

                try_return( Status );
            }

            //
            //  Protect access to the user buffer with an exception handler.
            //  Since (at our request) IO doesn't buffer these requests, we have
            //  to guard against a user messing with the page protection and other
            //  such trickery.
            //

            try {

                if (LongFileName.Length == 0) {

                    //
                    //  Now we have an entry to return to our caller.  We'll convert
                    //  the name from the form in the dirent to a <name>.<ext> form.
                    //  We'll case on the type of information requested and fill up
                    //  the user buffer if everything fits.
                    //

                    Fat8dot3ToString( IrpContext, Dirent, TRUE, &Fat8Dot3String );

                    //
                    //  Determine the UNICODE length of the file name.
                    //

                    FileNameLength = RtlOemStringToCountedUnicodeSize(&Fat8Dot3String);

                    //
                    //  Here are the rules concerning filling up the buffer:
                    //
                    //  1.  The Io system garentees that there will always be
                    //      enough room for at least one base record.
                    //
                    //  2.  If the full first record (including file name) cannot
                    //      fit, as much of the name as possible is copied and
                    //      STATUS_BUFFER_OVERFLOW is returned.
                    //
                    //  3.  If a subsequent record cannot completely fit into the
                    //      buffer, none of it (as in 0 bytes) is copied, and
                    //      STATUS_SUCCESS is returned.  A subsequent query will
                    //      pick up with this record.
                    //

                    BytesRemainingInBuffer = UserBufferLength - NextEntry;

                    if ( (NextEntry != 0) &&
                            ( (BaseLength + FileNameLength > BytesRemainingInBuffer) ||
                              (UserBufferLength < NextEntry) ) ) {

                        DebugTrace(0, Dbg, "Next entry won't fit\n", 0);

                        try_return( Status = STATUS_SUCCESS );
                    }

                    ASSERT( BytesRemainingInBuffer >= BaseLength );

                    //
                    //  Zero the base part of the structure.
                    //

                    RtlZeroMemory( &Buffer[NextEntry], BaseLength );

                    switch ( FileInformationClass ) {

                    //
                    //  Now fill the base parts of the strucure that are applicable.
                    //

                    case FileBothDirectoryInformation:
                    case FileFullDirectoryInformation:
                    case FileIdBothDirectoryInformation:
                    case FileIdFullDirectoryInformation:

                        DebugTrace(0, Dbg, "FatQueryDirectory -> Getting file full directory information\n", 0);

                        //
                        //  Get the Ea file length.
                        //

                        FullDirInfo = (PFILE_FULL_DIR_INFORMATION)&Buffer[NextEntry];

                        //
                        //  If the EAs are corrupt, ignore the error.  We don't want
                        //  to abort the directory query.
                        //

                        try {

                            FatGetEaLength( IrpContext,
                                            Vcb,
                                            Dirent,
                                            &FullDirInfo->EaSize );

                        }
                        except(EXCEPTION_EXECUTE_HANDLER) {

                            FatResetExceptionState( IrpContext );
                            FullDirInfo->EaSize = 0;
                        }

                    case FileDirectoryInformation:

                        DirInfo = (PFILE_DIRECTORY_INFORMATION)&Buffer[NextEntry];

                        FatGetDirTimes( IrpContext, Dirent, DirInfo );

                        DirInfo->EndOfFile.QuadPart = Dirent->FileSize;

                        if (!FlagOn( Dirent->Attributes, FAT_DIRENT_ATTR_DIRECTORY )) {

                            DirInfo->AllocationSize.QuadPart =
                                (((Dirent->FileSize + DiskAllocSize - 1) / DiskAllocSize) *
                                 DiskAllocSize );
                        }

                        DirInfo->FileAttributes = Dirent->Attributes != 0 ?
                                                  Dirent->Attributes :
                                                  FILE_ATTRIBUTE_NORMAL;

                        DirInfo->FileIndex = NextVbo;

                        DirInfo->FileNameLength = FileNameLength;

                        DebugTrace(0, Dbg, "FatQueryDirectory -> Name = \"%Z\"\n", &Fat8Dot3String);

                        break;

                    case FileNamesInformation:

                        DebugTrace(0, Dbg, "FatQueryDirectory -> Getting file names information\n", 0);

                        NamesInfo = (PFILE_NAMES_INFORMATION)&Buffer[NextEntry];

                        NamesInfo->FileIndex = NextVbo;

                        NamesInfo->FileNameLength = FileNameLength;

                        DebugTrace(0, Dbg, "FatQueryDirectory -> Name = \"%Z\"\n", &Fat8Dot3String );

                        break;

                    default:

                        FatBugCheck( FileInformationClass, 0, 0 );
                    }

                    BytesConverted = 0;

                    Status = RtlOemToUnicodeN( (PWCH)&Buffer[NextEntry + BaseLength],
                                               BytesRemainingInBuffer - BaseLength,
                                               &BytesConverted,
                                               Fat8Dot3String.Buffer,
                                               Fat8Dot3String.Length );

                    //
                    //  Check for the case that a single entry doesn't fit.
                    //  This should only get this far on the first entry
                    //

                    if (BytesConverted < FileNameLength) {

                        ASSERT( NextEntry == 0 );
                        Status = STATUS_BUFFER_OVERFLOW;
                    }

                    //
                    //  Set up the previous next entry offset
                    //

                    *((PULONG)(&Buffer[LastEntry])) = NextEntry - LastEntry;

                    //
                    //  And indicate how much of the user buffer we have currently
                    //  used up.  We must compute this value before we long align
                    //  ourselves for the next entry
                    //

                    Irp->IoStatus.Information = QuadAlign( Irp->IoStatus.Information ) +
                                                BaseLength + BytesConverted;

                    //
                    //  If something happened with the conversion, bail here.
                    //

                    if ( !NT_SUCCESS( Status ) ) {

                        try_return( NOTHING );
                    }

                } else {

                    ULONG ShortNameLength;

                    FileNameLength = LongFileName.Length;

                    //
                    //  Here are the rules concerning filling up the buffer:
                    //
                    //  1.  The Io system garentees that there will always be
                    //      enough room for at least one base record.
                    //
                    //  2.  If the full first record (including file name) cannot
                    //      fit, as much of the name as possible is copied and
                    //      STATUS_BUFFER_OVERFLOW is returned.
                    //
                    //  3.  If a subsequent record cannot completely fit into the
                    //      buffer, none of it (as in 0 bytes) is copied, and
                    //      STATUS_SUCCESS is returned.  A subsequent query will
                    //      pick up with this record.
                    //

                    BytesRemainingInBuffer = UserBufferLength - NextEntry;

                    if ( (NextEntry != 0) &&
                            ( (BaseLength + FileNameLength > BytesRemainingInBuffer) ||
                              (UserBufferLength < NextEntry) ) ) {

                        DebugTrace(0, Dbg, "Next entry won't fit\n", 0);

                        try_return( Status = STATUS_SUCCESS );
                    }

                    ASSERT( BytesRemainingInBuffer >= BaseLength );

                    //
                    //  Zero the base part of the structure.
                    //

                    RtlZeroMemory( &Buffer[NextEntry], BaseLength );

                    switch ( FileInformationClass ) {

                    //
                    //  Now fill the base parts of the strucure that are applicable.
                    //

                    case FileBothDirectoryInformation:
                    case FileIdBothDirectoryInformation:

                        BothDirInfo = (PFILE_BOTH_DIR_INFORMATION)&Buffer[NextEntry];

                        //
                        //  Now we have an entry to return to our caller.  We'll convert
                        //  the name from the form in the dirent to a <name>.<ext> form.
                        //  We'll case on the type of information requested and fill up
                        //  the user buffer if everything fits.
                        //

                        Fat8dot3ToString( IrpContext, Dirent, FALSE, &Fat8Dot3String );

                        ASSERT( Fat8Dot3String.Length <= 12 );

                        Status = RtlOemToUnicodeN( &BothDirInfo->ShortName[0],
                                                   12*sizeof(WCHAR),
                                                   &ShortNameLength,
                                                   Fat8Dot3String.Buffer,
                                                   Fat8Dot3String.Length );

                        ASSERT( Status != STATUS_BUFFER_OVERFLOW );
                        ASSERT( BothDirInfo->ShortNameLength <= 12*sizeof(WCHAR) );

                        //
                        //  Copy the length into the dirinfo structure.  Note
                        //  that the LHS below is a USHORT, so it can not
                        //  be specificed as the OUT parameter above.
                        //

                        BothDirInfo->ShortNameLength = (UCHAR)ShortNameLength;

                        //
                        //  If something happened with the conversion, bail here.
                        //

                        if ( !NT_SUCCESS( Status ) ) {

                            try_return( NOTHING );
                        }

                    case FileFullDirectoryInformation:
                    case FileIdFullDirectoryInformation:

                        DebugTrace(0, Dbg, "FatQueryDirectory -> Getting file full directory information\n", 0);

                        //
                        //  Get the Ea file length.
                        //

                        FullDirInfo = (PFILE_FULL_DIR_INFORMATION)&Buffer[NextEntry];

                        //
                        //  If the EAs are corrupt, ignore the error.  We don't want
                        //  to abort the directory query.
                        //

                        try {

                            FatGetEaLength( IrpContext,
                                            Vcb,
                                            Dirent,
                                            &FullDirInfo->EaSize );

                        }
                        except(EXCEPTION_EXECUTE_HANDLER) {

                            FatResetExceptionState( IrpContext );
                            FullDirInfo->EaSize = 0;
                        }

                    case FileDirectoryInformation:

                        DirInfo = (PFILE_DIRECTORY_INFORMATION)&Buffer[NextEntry];

                        FatGetDirTimes( IrpContext, Dirent, DirInfo );

                        DirInfo->EndOfFile.QuadPart = Dirent->FileSize;

                        if (!FlagOn( Dirent->Attributes, FAT_DIRENT_ATTR_DIRECTORY )) {

                            DirInfo->AllocationSize.QuadPart = (
                                                                   (( Dirent->FileSize
                                                                           + DiskAllocSize - 1 )
                                                                    / DiskAllocSize )
                                                                   * DiskAllocSize );
                        }

                        DirInfo->FileAttributes = Dirent->Attributes != 0 ?
                                                  Dirent->Attributes :
                                                  FILE_ATTRIBUTE_NORMAL;

                        DirInfo->FileIndex = NextVbo;

                        DirInfo->FileNameLength = FileNameLength;

                        DebugTrace(0, Dbg, "FatQueryDirectory -> Name = \"%Z\"\n", &Fat8Dot3String);

                        break;

                    case FileNamesInformation:

                        DebugTrace(0, Dbg, "FatQueryDirectory -> Getting file names information\n", 0);

                        NamesInfo = (PFILE_NAMES_INFORMATION)&Buffer[NextEntry];

                        NamesInfo->FileIndex = NextVbo;

                        NamesInfo->FileNameLength = FileNameLength;

                        DebugTrace(0, Dbg, "FatQueryDirectory -> Name = \"%Z\"\n", &Fat8Dot3String );

                        break;

                    default:

                        FatBugCheck( FileInformationClass, 0, 0 );
                    }

                    BytesConverted = BytesRemainingInBuffer - BaseLength >= FileNameLength ?
                                     FileNameLength :
                                     BytesRemainingInBuffer - BaseLength;

                    RtlCopyMemory( &Buffer[NextEntry + BaseLength],
                                   &LongFileName.Buffer[0],
                                   BytesConverted );

                    //
                    //  Set up the previous next entry offset
                    //

                    *((PULONG)(&Buffer[LastEntry])) = NextEntry - LastEntry;

                    //
                    //  And indicate how much of the user buffer we have currently
                    //  used up.  We must compute this value before we long align
                    //  ourselves for the next entry
                    //

                    Irp->IoStatus.Information += BaseLength + BytesConverted;

                    //
                    //  Check for the case that a single entry doesn't fit.
                    //  This should only get this far on the first entry.
                    //

                    if (BytesConverted < FileNameLength) {

                        ASSERT( NextEntry == 0 );

                        try_return( Status = STATUS_BUFFER_OVERFLOW );
                    }
                }

                //
                //  Finish up by filling in the FileId
                //

                switch ( FileInformationClass ) {

                case FileIdBothDirectoryInformation:

                    IdBothDirInfo = (PFILE_ID_BOTH_DIR_INFORMATION)&Buffer[NextEntry];
                    IdBothDirInfo->FileId.QuadPart = FatGenerateFileIdFromDirentAndOffset( Dcb, Dirent, NextVbo );
                    break;

                case FileIdFullDirectoryInformation:

                    IdFullDirInfo = (PFILE_ID_FULL_DIR_INFORMATION)&Buffer[NextEntry];
                    IdFullDirInfo->FileId.QuadPart = FatGenerateFileIdFromDirentAndOffset( Dcb, Dirent, NextVbo );
                    break;

                default:
                    break;
                }

            }
            except (EXCEPTION_EXECUTE_HANDLER) {

                //
                //  We had a problem filling in the user's buffer, so stop and
                //  fail this request.  This is the only reason any exception
                //  would have occured at this level.
                //

                Irp->IoStatus.Information = 0;
                UpdateCcb = FALSE;
                try_return( Status = GetExceptionCode());
            }

            //
            //  Set ourselves up for the next iteration
            //

            LastEntry = NextEntry;
            NextEntry += (ULONG)QuadAlign(BaseLength + BytesConverted);

            CurrentVbo = NextVbo + sizeof( DIRENT );
        }

try_exit:
        NOTHING;
    }
Exemple #8
0
 bool SetIsCheckedAllocLike(bool state) {
     SetFlag(Flag_IsCheckedAllocLike, state);
 }
Exemple #9
0
 bool SetHasSetjmp(bool state) {
     SetFlag(Flag_HasSetjmp, state);
 }
Exemple #10
0
 bool SetHasLongjmp(bool state) {
     SetFlag(Flag_HasLongjmp, state);
 }
Exemple #11
0
 bool SetIsAllocLike(bool state) {
     SetFlag(Flag_IsAllocLike, state);
 }
Exemple #12
0
static void ToggleCheck( Word objID, Int flag )
{
  CtlSetValue( GetObjectPtr( objID ),
	       ! (stor.flags & flag) );
  SetFlag( flag, !(stor.flags & flag) );
}
Exemple #13
0
NTSTATUS
CtxInstanceSetup (
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in FLT_INSTANCE_SETUP_FLAGS Flags,
    __in DEVICE_TYPE VolumeDeviceType,
    __in FLT_FILESYSTEM_TYPE VolumeFilesystemType
    )
/*++

Routine Description:

    This routine is called whenever a new instance is created on a volume. This
    gives us a chance to decide if we need to attach to this volume or not.

Arguments:

    FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
        opaque handles to this filter, instance and its associated volume.

    Flags - Flags describing the reason for this attach request.

Return Value:

    STATUS_SUCCESS - attach
    STATUS_FLT_DO_NOT_ATTACH - do not attach

--*/
{
    PCTX_INSTANCE_CONTEXT instanceContext = NULL;
    NTSTATUS status = STATUS_SUCCESS;
    ULONG volumeNameLength;

#if __NDAS_FS_MINI__

	ULONG					propertyLengthReturned; 

	UNICODE_STRING			ntfs;
	UNICODE_STRING			ndasNtfs;
	UNICODE_STRING			fat;
	UNICODE_STRING			ndasFat;

	PNETDISK_PARTITION		netdiskPartition;
	NETDISK_ENABLE_MODE		netdiskEnableMode;

#endif

#if __LFS__
	ULONG					propertyLengthReturned; 
	BOOLEAN					result;

	UNICODE_STRING			ntfs;
	UNICODE_STRING			ndasNtfs;
	UNICODE_STRING			fat;
	UNICODE_STRING			ndasFat;

	PENABLED_NETDISK		enabledNetdisk;
	NETDISK_ENABLE_MODE		netdiskEnableMode;
#endif

    UNREFERENCED_PARAMETER( Flags );
    UNREFERENCED_PARAMETER( VolumeDeviceType );
    UNREFERENCED_PARAMETER( VolumeFilesystemType );

    PAGED_CODE();

#if __NDAS_FS_MINI__

    DebugTrace( DEBUG_TRACE_INSTANCES,
                ("[Ctx]: Instance setup started FltObjects = %p\n", FltObjects) );

#endif

    DebugTrace( DEBUG_TRACE_INSTANCES,
                ("[Ctx]: Instance setup started (Volume = %p, Instance = %p)\n",
                 FltObjects->Volume,
                 FltObjects->Instance) );

    //
    //  Allocate and initialize the context for this volume
    //


    //
    //  Allocate the instance context
    //

    DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS,
                ("[Ctx]: Allocating instance context (Volume = %p, Instance = %p)\n",
                 FltObjects->Volume,
                 FltObjects->Instance) );

    status = FltAllocateContext( FltObjects->Filter,
                                 FLT_INSTANCE_CONTEXT,
                                 CTX_INSTANCE_CONTEXT_SIZE,
                                 NonPagedPool,
                                 &instanceContext );

    if (!NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
                    ("[Ctx]: Failed to allocate instance context (Volume = %p, Instance = %p, Status = 0x%x)\n",
                     FltObjects->Volume,
                     FltObjects->Instance,
                     status) );

        goto CtxInstanceSetupCleanup;
    }

#if __NDAS_FS_MINI__

	RtlZeroMemory( instanceContext, sizeof(CTX_INSTANCE_CONTEXT) );

	status = FltGetVolumeProperties( FltObjects->Volume,
									 NULL,
									 0,
									 &propertyLengthReturned ); 


	DebugTrace( DEBUG_TRACE_INSTANCES,
				("[MiniSpy]: IRP_MJ_VOLUME_MOUNT FltGetVolumeProperties, status = %x, propertyLengthReturned = %d\n",
				 status,
				 propertyLengthReturned) );

	instanceContext->VolumeProperties = ExAllocatePoolWithTag( PagedPool, propertyLengthReturned, CTX_VOLUME_PROPERTY_TAG );

	status = FltGetVolumeProperties( FltObjects->Volume,
									 instanceContext->VolumeProperties,
									 propertyLengthReturned,
									 &propertyLengthReturned ); 

	DebugTrace( DEBUG_TRACE_INSTANCES,
				("[MiniSpy]: FltGetVolumeProperties, status = %x, propertyLengthReturned = %d\n",
				 status,
				 propertyLengthReturned) );

	if( !NT_SUCCESS( status )) {

		status = STATUS_FLT_DO_NOT_ATTACH;
		goto CtxInstanceSetupCleanup;
	}

	DebugTrace( DEBUG_TRACE_INSTANCES,
				("[MiniSpy]: FltGetVolumeProperties, DeviceType = %d "
				 "FileSystemDriverName = %wZ\n"
				 "FileSystemDeviceName = %wZ "
				 "RealDeviceName = %wZ\n",
				 instanceContext->VolumeProperties->DeviceType,
				 &instanceContext->VolumeProperties->FileSystemDriverName,
				 &instanceContext->VolumeProperties->FileSystemDeviceName,
				 &instanceContext->VolumeProperties->RealDeviceName) );

	RtlInitUnicodeString( &ntfs, L"\\Ntfs" );
	RtlInitUnicodeString( &ndasNtfs, NDAS_NTFS_DEVICE_NAME );
	RtlInitUnicodeString( &fat, L"\\Fat" );
	RtlInitUnicodeString( &ndasFat, NDAS_FAT_DEVICE_NAME );

	if (!(RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ntfs, TRUE)		||
		  RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)	||
		  RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &fat, TRUE)		||
		  RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE))) {

		status = STATUS_FLT_DO_NOT_ATTACH;
		goto CtxInstanceSetupCleanup;
	}

	status = FltGetDeviceObject( FltObjects->Volume, &instanceContext->DeviceObject );

	if (!NT_SUCCESS(status)) {

		status = STATUS_FLT_DO_NOT_ATTACH;
		goto CtxInstanceSetupCleanup;
	}
	
	status = FltGetDiskDeviceObject( FltObjects->Volume, &instanceContext->DiskDeviceObject );

	if (!NT_SUCCESS(status)) {

		status = STATUS_FLT_DO_NOT_ATTACH;
		goto CtxInstanceSetupCleanup;
	}

	DebugTrace( DEBUG_TRACE_INSTANCES,
				("DeviceObject = %p, DiskDeviceObject = %p\n", instanceContext->DeviceObject, instanceContext->DiskDeviceObject) );


	if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE) && 
		!GlobalLfs.NdasFatRwSupport && !GlobalLfs.NdasFatRoSupport ||
		RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE) && 
		!GlobalLfs.NdasNtfsRwSupport && !GlobalLfs.NdasNtfsRoSupport) {

		NDASFS_ASSERT( FALSE );
		status = STATUS_FLT_DO_NOT_ATTACH;
		goto CtxInstanceSetupCleanup;
	}

	if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE)) {

		status = NetdiskManager_PreMountVolume( GlobalLfs.NetdiskManager,
												GlobalLfs.NdasFatRwIndirect ? TRUE : FALSE,
												instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.DeviceObject,
												instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.Vpb->RealDevice,
												&netdiskPartition,
												&netdiskEnableMode );
	
	} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) {

		status = NetdiskManager_PreMountVolume( GlobalLfs.NetdiskManager,
												GlobalLfs.NdasNtfsRwIndirect ? TRUE : FALSE,
												instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.DeviceObject,
												instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.Vpb->RealDevice,
												&netdiskPartition,
												&netdiskEnableMode );
	
	} else {

		status = NetdiskManager_PreMountVolume( GlobalLfs.NetdiskManager,
												FALSE,
												instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.DeviceObject,
												instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.Vpb->RealDevice,
												&netdiskPartition,
												&netdiskEnableMode );
	}


	SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("NetdiskManager_IsNetdiskPartition status = %x\n", status) );

	if (!NT_SUCCESS(status)) {

		if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE) ||
			RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) {

			NDASFS_ASSERT( FALSE );
			status = STATUS_FLT_DO_NOT_ATTACH;
			goto CtxInstanceSetupCleanup;
		}

		status = STATUS_FLT_DO_NOT_ATTACH;
		goto CtxInstanceSetupCleanup;
	} 
	
	switch (netdiskEnableMode) {

	case NETDISK_READ_ONLY:

		if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &fat, TRUE)) {

			if (GlobalLfs.NdasFatRoSupport) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );
	
				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}			
			
		} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE)) {

			if (!GlobalLfs.NdasFatRoSupport) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );
	
				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}			

		} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ntfs, TRUE)) {

			if (GlobalLfs.NdasNtfsRoSupport) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );

				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}
			
		} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) {

			if (!GlobalLfs.NdasNtfsRoSupport) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );

				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}
			
		} else {

			NDASFS_ASSERT( FALSE );
		}

		break;

	case NETDISK_SECONDARY:
	case NETDISK_PRIMARY:
	case NETDISK_SECONDARY2PRIMARY:

		if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &fat, TRUE)) {

			if (GlobalLfs.NdasFatRwSupport &&
				FlagOn(netdiskPartition->EnabledNetdisk->NetdiskInformation.EnabledFeatures, NDASFEATURE_SIMULTANEOUS_WRITE)) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );
	
				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}			
			
		} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE)) {

			if (!(GlobalLfs.NdasFatRwSupport &&
				  FlagOn(netdiskPartition->EnabledNetdisk->NetdiskInformation.EnabledFeatures, NDASFEATURE_SIMULTANEOUS_WRITE))) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );
	
				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}			

		} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ntfs, TRUE)) {

			if (GlobalLfs.NdasNtfsRwSupport &&
				FlagOn(netdiskPartition->EnabledNetdisk->NetdiskInformation.EnabledFeatures, NDASFEATURE_SIMULTANEOUS_WRITE)) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );

				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}
			
		} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) {

			if (!(GlobalLfs.NdasNtfsRwSupport &&
				  FlagOn(netdiskPartition->EnabledNetdisk->NetdiskInformation.EnabledFeatures, NDASFEATURE_SIMULTANEOUS_WRITE))) {

				NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
												netdiskPartition,
												netdiskEnableMode,
												FALSE,
												0,
												NULL,
												NULL );

				NDASFS_ASSERT( FALSE );
				status = STATUS_FLT_DO_NOT_ATTACH;
				goto CtxInstanceSetupCleanup;
			}
			
		} else {

			NDASFS_ASSERT( FALSE );
		}
	
		break;

	default:

		NDASFS_ASSERT( FALSE );
		break;
	}

	LfsReference( &GlobalLfs );

    ExInitializeFastMutex( &instanceContext->LfsDeviceExt.FastMutex );
	instanceContext->LfsDeviceExt.ReferenceCount		= 1;

	InitializeListHead( &instanceContext->LfsDeviceExt.LfsQListEntry );

	instanceContext->LfsDeviceExt.Flags = LFS_DEVICE_FLAG_INITIALIZING;

	instanceContext->LfsDeviceExt.FileSpyDeviceObject	= NULL;
	instanceContext->LfsDeviceExt.InstanceContext		= instanceContext;

	FltReferenceContext( instanceContext->LfsDeviceExt.InstanceContext );

	instanceContext->LfsDeviceExt.NetdiskPartition		= netdiskPartition;
	instanceContext->LfsDeviceExt.NetdiskEnabledMode	= netdiskEnableMode;

	instanceContext->LfsDeviceExt.FilteringMode	= LFS_NO_FILTERING;

	instanceContext->LfsDeviceExt.DiskDeviceObject			= instanceContext->DiskDeviceObject;
	instanceContext->LfsDeviceExt.MountVolumeDeviceObject	= instanceContext->DiskDeviceObject;

    SPY_LOG_PRINT( SPYDEBUG_ERROR,
                   ("FileSpy!CtxInstanceSetup: instanceContext->LfsDeviceExt.DiskDeviceObject = %p\n",
					instanceContext->LfsDeviceExt.DiskDeviceObject) );

	ExInterlockedInsertTailList( &GlobalLfs.LfsDeviceExtQueue,
								 &instanceContext->LfsDeviceExt.LfsQListEntry,
								 &GlobalLfs.LfsDeviceExtQSpinLock );


	if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ntfs, TRUE)) {

		instanceContext->LfsDeviceExt.FileSystemType = LFS_FILE_SYSTEM_NTFS;

	} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) {

		instanceContext->LfsDeviceExt.FileSystemType = LFS_FILE_SYSTEM_NDAS_NTFS;
	
	} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &fat, TRUE)) {

		instanceContext->LfsDeviceExt.FileSystemType = LFS_FILE_SYSTEM_FAT;

	} else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE)) {

		instanceContext->LfsDeviceExt.FileSystemType = LFS_FILE_SYSTEM_NDAS_FAT;
	
	} else {

		NDASFS_ASSERT( FALSE ); 
	}

	NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager,
									instanceContext->LfsDeviceExt.NetdiskPartition,
									instanceContext->LfsDeviceExt.NetdiskEnabledMode,
									TRUE,
									instanceContext->LfsDeviceExt.FileSystemType,		
									&instanceContext->LfsDeviceExt,
									&instanceContext->LfsDeviceExt.NetdiskPartitionInformation );

	switch (netdiskEnableMode) {

	case NETDISK_READ_ONLY:

		instanceContext->LfsDeviceExt.FilteringMode = LFS_READONLY;

		break;

	case NETDISK_SECONDARY:

		instanceContext->LfsDeviceExt.FilteringMode = LFS_SECONDARY;

		break;

	case NETDISK_PRIMARY:
	case NETDISK_SECONDARY2PRIMARY:

		instanceContext->LfsDeviceExt.FilteringMode = LFS_PRIMARY;

		break;
	
	default:

		ASSERT( LFS_BUG );

		break;
	}

	SetFlag( instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_MOUNTING );

	ASSERT( instanceContext->DiskDeviceObject->Vpb->DeviceObject );

	instanceContext->LfsDeviceExt.Vpb						= instanceContext->LfsDeviceExt.DiskDeviceObject->Vpb; // Vpb will be changed in IrpSp Why ?
	instanceContext->LfsDeviceExt.BaseVolumeDeviceObject	= instanceContext->LfsDeviceExt.Vpb->DeviceObject;

	switch (instanceContext->LfsDeviceExt.FilteringMode) {

	case LFS_READONLY: {
		
		//
		//	We don't support cache purging yet.
		//

		SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("LfsFsControlMountVolumeComplete: READONLY newDevExt->LfsDeviceExt = %p "
											"newDevExt->LfsDeviceExt.FileSystemType = %d\n",
											 &instanceContext->LfsDeviceExt, instanceContext->LfsDeviceExt.FileSystemType) );
		
		instanceContext->LfsDeviceExt.AttachedToDeviceObject = instanceContext->DeviceObject; //NULL; //instanceContext->NLExtHeader.AttachedToDeviceObject;

		NetdiskManager_MountVolumeComplete( GlobalLfs.NetdiskManager,
											instanceContext->LfsDeviceExt.NetdiskPartition,
											instanceContext->LfsDeviceExt.NetdiskEnabledMode,
											status,
											instanceContext->LfsDeviceExt.AttachedToDeviceObject );

		status = SpyFsControlReadonlyMountVolumeComplete( &instanceContext->LfsDeviceExt );

		break;
	}

	case LFS_PRIMARY: {

		instanceContext->LfsDeviceExt.AttachedToDeviceObject = instanceContext->DeviceObject; //NULL; //instanceContext->NLExtHeader.AttachedToDeviceObject;

		ASSERT( instanceContext->LfsDeviceExt.AttachedToDeviceObject );

		NetdiskManager_MountVolumeComplete( GlobalLfs.NetdiskManager,
											instanceContext->LfsDeviceExt.NetdiskPartition,
											instanceContext->LfsDeviceExt.NetdiskEnabledMode,
											status,
											instanceContext->LfsDeviceExt.AttachedToDeviceObject );

		SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("LfsFsControlMountVolumeComplete: LFS_PRIMARY newDevExt->LfsDeviceExt = %p "
											"newDevExt->LfsDeviceExt.FileSystemType = %d\n",
											 &instanceContext->LfsDeviceExt, instanceContext->LfsDeviceExt.FileSystemType) );

		status = STATUS_SUCCESS;
		break;
	}

	case LFS_SECONDARY: {

		instanceContext->LfsDeviceExt.AttachedToDeviceObject = instanceContext->DeviceObject; //NULL; //instanceContext->NLExtHeader.AttachedToDeviceObject;
					
		NetdiskManager_MountVolumeComplete( GlobalLfs.NetdiskManager,
											instanceContext->LfsDeviceExt.NetdiskPartition,
											instanceContext->LfsDeviceExt.NetdiskEnabledMode,
											status,
											instanceContext->LfsDeviceExt.AttachedToDeviceObject );

		SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("CtxInstanceSetup: LFS_SECONDARY newDevExt->LfsDeviceExt = %p "
											"newDevExt->LfsDeviceExt.FileSystemType = %d\n",
											 &instanceContext->LfsDeviceExt, instanceContext->LfsDeviceExt.FileSystemType) );

		status = SpyFsControlSecondaryMountVolumeComplete( &instanceContext->LfsDeviceExt );

		if (instanceContext->LfsDeviceExt.FilteringMode == LFS_SECONDARY_TO_PRIMARY) {
		
			NetdiskManager_ChangeMode( GlobalLfs.NetdiskManager,
									   instanceContext->LfsDeviceExt.NetdiskPartition,
									   &instanceContext->LfsDeviceExt.NetdiskEnabledMode );
		}

		break;
	}

	default:

		NDASFS_ASSERT( FALSE );

		NetdiskManager_MountVolumeComplete( GlobalLfs.NetdiskManager,
											instanceContext->LfsDeviceExt.NetdiskPartition,
											instanceContext->LfsDeviceExt.NetdiskEnabledMode,
											status,
											NULL );

		status = STATUS_SUCCESS;

		break;
	}

    //
    //  We completed initialization of this device object, so now
    //  clear the initializing flag.
    //

	if (status == STATUS_SUCCESS) {

		ClearFlag( instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_INITIALIZING );
		ClearFlag( instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_MOUNTING );

		SetFlag( instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_MOUNTED );

	} else {

		NTSTATUS status2;


		NDASFS_ASSERT( FALSE );

		//
		//	Queue an event to notify user applications
		//

		XevtQueueVolumeInvalidOrLocked( -1,
										instanceContext->LfsDeviceExt.NetdiskPartitionInformation.NetdiskInformation.SlotNo,
										instanceContext->LfsDeviceExt.NetdiskPartitionInformation.NetdiskInformation.UnitDiskNo );

		//
		//	Try to unplug
		//

		status2 = NetdiskManager_UnplugNetdisk( GlobalLfs.NetdiskManager,
												instanceContext->LfsDeviceExt.NetdiskPartition,
												instanceContext->LfsDeviceExt.NetdiskEnabledMode );

		ASSERT( NT_SUCCESS(status2) );
	}

#endif

    //
    //  Get the NT volume name length
    //

    status = FltGetVolumeName( FltObjects->Volume, NULL, &volumeNameLength );

    if( !NT_SUCCESS( status ) &&
        (status != STATUS_BUFFER_TOO_SMALL) ) {

        DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
                    ("[Ctx]: Unexpected failure in FltGetVolumeName. (Volume = %p, Instance = %p, Status = 0x%x)\n",
                     FltObjects->Volume,
                     FltObjects->Instance,
                     status) );

        goto CtxInstanceSetupCleanup;
    }

    //
    //  Allocate a string big enough to take the volume name
    //

    instanceContext->VolumeName.MaximumLength = (USHORT) volumeNameLength;
    status = CtxAllocateUnicodeString( &instanceContext->VolumeName );

    if( !NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
                    ("[Ctx]: Failed to allocate volume name string. (Volume = %p, Instance = %p, Status = 0x%x)\n",
                     FltObjects->Volume,
                     FltObjects->Instance,
                     status) );

        goto CtxInstanceSetupCleanup;
    }

    //
    //  Get the NT volume name
    //

    status = FltGetVolumeName( FltObjects->Volume, &instanceContext->VolumeName, &volumeNameLength );

    if( !NT_SUCCESS( status ) ) {

        DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR,
                    ("[Ctx]: Unexpected failure in FltGetVolumeName. (Volume = %p, Instance = %p, Status = 0x%x)\n",
                     FltObjects->Volume,
                     FltObjects->Instance,
                     status) );

        goto CtxInstanceSetupCleanup;
    }


    instanceContext->Instance = FltObjects->Instance;
    instanceContext->Volume = FltObjects->Volume;

    //
    //  Set the instance context.
    //

    DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS,
                ("[Ctx]: Setting instance context %p for volume %wZ (Volume = %p, Instance = %p)\n",
                 instanceContext,
                 &instanceContext->VolumeName,
                 FltObjects->Volume,
                 FltObjects->Instance) );

    status = FltSetInstanceContext( FltObjects->Instance,
                                    FLT_SET_CONTEXT_KEEP_IF_EXISTS,
                                    instanceContext,
                                    NULL );

    if( !NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_INSTANCES | DEBUG_TRACE_ERROR,
                    ("[Ctx]: Failed to set instance context for volume %wZ (Volume = %p, Instance = %p, Status = 0x%08X)\n",
                     &instanceContext->VolumeName,
                     FltObjects->Volume,
                     FltObjects->Instance,
                     status) );
        goto CtxInstanceSetupCleanup;
    }

CtxInstanceSetupCleanup:

#if __NDAS_FS_MINI__

	if (status != STATUS_SUCCESS) {

		if (instanceContext->DiskDeviceObject) {

			ObDereferenceObject( instanceContext->DiskDeviceObject );
			instanceContext->DiskDeviceObject = NULL;
		}

		if (instanceContext->DeviceObject) {

			ObDereferenceObject( instanceContext->DeviceObject );
			instanceContext->DeviceObject = NULL;
		}

		if (instanceContext->VolumeProperties) {

			ExFreePoolWithTag( instanceContext->VolumeProperties, CTX_VOLUME_PROPERTY_TAG );
			instanceContext->VolumeProperties = NULL;
		}

		if (FlagOn(instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_INITIALIZING)) {

			LfsDeviceExt_Dereference( &instanceContext->LfsDeviceExt );
		}
	}

#endif

    //
    //  If FltAllocateContext suceeded then we MUST release the context,
    //  irrespective of whether FltSetInstanceContext suceeded or not.
    //
    //  FltAllocateContext increments the ref count by one.
    //  A successful FltSetInstanceContext increments the ref count by one
    //  and also associates the context with the file system object
    //
    //  FltReleaseContext decrements the ref count by one.
    //
    //  When FltSetInstanceContext succeeds, calling FltReleaseContext will
    //  leave the context with a ref count of 1 corresponding to the internal
    //  reference to the context from the file system structures
    //
    //  When FltSetInstanceContext fails, calling FltReleaseContext will
    //  leave the context with a ref count of 0 which is correct since
    //  there is no reference to the context from the file system structures
    //

    if ( instanceContext != NULL ) {

        DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS,
                    ("[Ctx]: Releasing instance context %p (Volume = %p, Instance = %p)\n",
                     instanceContext,
                     FltObjects->Volume,
                     FltObjects->Instance) );

        FltReleaseContext( instanceContext );
    }


    if (NT_SUCCESS( status )) {

        DebugTrace( DEBUG_TRACE_INSTANCES,
                    ("[Ctx]: Instance setup complete (Volume = %p, Instance = %p). Filter will attach to the volume.\n",
                     FltObjects->Volume,
                     FltObjects->Instance) );
    } else {

        DebugTrace( DEBUG_TRACE_INSTANCES,
                    ("[Ctx]: Instance setup complete (Volume = %p, Instance = %p). Filter will not attach to the volume.\n",
                     FltObjects->Volume,
                     FltObjects->Instance) );
    }

    return status;
}
Exemple #14
0
NTSTATUS
NtfsFsdPnp (
    IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine implements the FSD entry point for plug and play (Pnp).

Arguments:

    VolumeDeviceObject - Supplies the volume device object where the
        file exists

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The FSD status for the IRP

--*/

{
    NTSTATUS Status = STATUS_SUCCESS;

    TOP_LEVEL_CONTEXT TopLevelContext;
    PTOP_LEVEL_CONTEXT ThreadTopLevelContext;

    PIRP_CONTEXT IrpContext = NULL;

#if __NDAS_NTFS__

	if ((PVOID)NdasNtfsControlDeviceObject == VolumeDeviceObject) {

		Status = Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
		Irp->IoStatus.Information = 0;

		IoCompleteRequest( Irp, IO_DISK_INCREMENT );

		return Status;
	}

#endif

    ASSERT_IRP( Irp );

    UNREFERENCED_PARAMETER( VolumeDeviceObject );

#ifdef NTFSPNPDBG
    if (NtfsDebugTraceLevel != 0) SetFlag( NtfsDebugTraceLevel, DEBUG_TRACE_PNP );
#endif

    DebugTrace( +1, Dbg, ("NtfsFsdPnp\n") );

    //
    //  Call the common Pnp routine
    //

    FsRtlEnterFileSystem();

    switch( IoGetCurrentIrpStackLocation( Irp )->MinorFunction ) {

    case IRP_MN_QUERY_REMOVE_DEVICE:
    case IRP_MN_REMOVE_DEVICE:
    case IRP_MN_CANCEL_REMOVE_DEVICE:
    case IRP_MN_SURPRISE_REMOVAL:
    
        ThreadTopLevelContext = NtfsInitializeTopLevelIrp( &TopLevelContext, FALSE, FALSE );
        break;
        
    default:
        
        ThreadTopLevelContext = NtfsInitializeTopLevelIrp( &TopLevelContext, TRUE, TRUE );
        break;
    }
    
    do {

        try {

            //
            //  We are either initiating this request or retrying it.
            //

            if (IrpContext == NULL) {

                //
                //  Allocate and initialize the Irp.
                //

                NtfsInitializeIrpContext( Irp, TRUE, &IrpContext );

                //
                //  Initialize the thread top level structure, if needed.
                //
    
                NtfsUpdateIrpContextWithTopLevel( IrpContext, ThreadTopLevelContext );

            } else if (Status == STATUS_LOG_FILE_FULL) {

                NtfsCheckpointForLogFileFull( IrpContext );
            }

#if __NDAS_NTFS_SECONDARY__

			if (!FlagOn(VolumeDeviceObject->NetdiskPartitionInformation.Flags, NETDISK_PARTITION_INFORMATION_FLAG_INDIRECT) &&
				VolumeDeviceObject->NetdiskEnableMode == NETDISK_SECONDARY) {

				if ((IrpContext->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE	|| 
					 IrpContext->MinorFunction == IRP_MN_SURPRISE_REMOVAL		||
					 IrpContext->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE)) {

					BOOLEAN	secondaryResourceAcquired = FALSE;
					BOOLEAN secondaryRecoveryResourceAcquired = FALSE;

					ASSERT( NtfsIsTopLevelRequest(IrpContext) );

					Status = STATUS_SUCCESS;

					while (TRUE) {
											
						ASSERT( secondaryRecoveryResourceAcquired == FALSE );
						ASSERT( secondaryResourceAcquired == FALSE );

						NDASNTFS_ASSERT( VolumeDeviceObject->Secondary );

						if (FlagOn(VolumeDeviceObject->Secondary->Flags, SECONDARY_FLAG_RECONNECTING)) {
		
							if (!FlagOn(IrpContext->State, IRP_CONTEXT_STATE_WAIT)) {

								Status = NtfsPostRequest( IrpContext, Irp );
								break;
							}
						}
					
						if (FlagOn(VolumeDeviceObject->Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED)) {
						
							if (!FlagOn(IrpContext->State, IRP_CONTEXT_STATE_WAIT)) {

								Status = NtfsPostRequest( IrpContext, Irp );
								break;
							}

							secondaryRecoveryResourceAcquired 
								= SecondaryAcquireResourceExclusiveLite( IrpContext, 
																		 &VolumeDeviceObject->RecoveryResource, 
																		 BooleanFlagOn(IrpContext->State, IRP_CONTEXT_STATE_WAIT) );
								
							if (!FlagOn(VolumeDeviceObject->Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED) ) {
	
								SecondaryReleaseResourceLite( IrpContext, &VolumeDeviceObject->RecoveryResource );
								secondaryRecoveryResourceAcquired = FALSE;
								continue;
							}

							secondaryResourceAcquired 
								= SecondaryAcquireResourceExclusiveLite( IrpContext, 
																		 &VolumeDeviceObject->Resource, 
																		 BooleanFlagOn(IrpContext->State, IRP_CONTEXT_STATE_WAIT) );
							try {
								
								SecondaryRecoverySessionStart( VolumeDeviceObject->Secondary, IrpContext );
									
							} finally {

								SecondaryReleaseResourceLite( IrpContext, &VolumeDeviceObject->Resource );
								secondaryResourceAcquired = FALSE;

								SecondaryReleaseResourceLite( IrpContext, &VolumeDeviceObject->RecoveryResource );
								secondaryRecoveryResourceAcquired = FALSE;
							}

							continue;
						}

						secondaryResourceAcquired 
							= SecondaryAcquireResourceSharedLite( IrpContext, 
																  &VolumeDeviceObject->Resource, 
																  BooleanFlagOn(IrpContext->State, IRP_CONTEXT_STATE_WAIT) );

						if (secondaryResourceAcquired == FALSE) {

							ASSERT( FlagOn(VolumeDeviceObject->Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED) ||
									FlagOn(VolumeDeviceObject->Secondary->Flags, SECONDARY_FLAG_RECONNECTING) );
							continue;
						}

						break;
					}

					if (Status == STATUS_SUCCESS) {
					
						try {

							if (VolumeDeviceObject->NetdiskEnableMode != NETDISK_SECONDARY) {

								NDASNTFS_ASSERT( VolumeDeviceObject->NetdiskEnableMode == NETDISK_SECONDARY2PRIMARY );
								NtfsRaiseStatus( IrpContext, STATUS_CANT_WAIT, NULL, NULL );
							}
							
							SetFlag( IrpContext->NdasNtfsFlags, NDAS_NTFS_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT );

							Status = NtfsCommonPnp( IrpContext, &Irp );
							
						} finally {

							ASSERT( ExIsResourceAcquiredSharedLite(&VolumeDeviceObject->Resource) );
							SecondaryReleaseResourceLite( NULL, &VolumeDeviceObject->Resource );
						}
					}
				
				} else {

					if (VolumeDeviceObject->NetdiskEnableMode != NETDISK_SECONDARY) {

						NDASNTFS_ASSERT( VolumeDeviceObject->NetdiskEnableMode == NETDISK_SECONDARY2PRIMARY );
						NtfsRaiseStatus( IrpContext, STATUS_CANT_WAIT, NULL, NULL );
					}

					SetFlag( IrpContext->NdasNtfsFlags, NDAS_NTFS_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT );

					Status = NtfsCommonPnp( IrpContext, &Irp );
				}

			} else {

				Status = NtfsCommonPnp( IrpContext, &Irp );
			}
#else
            Status = NtfsCommonPnp( IrpContext, &Irp );
#endif
            break;

        } except(NtfsExceptionFilter( IrpContext, GetExceptionInformation() )) {
Exemple #15
0
//
//	Check VMDK sparse disk
//
VDKSTAT VDiskVmdk::Check()
{
	PVOID	cbparams[3];
	CHAR	path[MAX_PATH];
	ULONG	idx;
	VDKSTAT ret;

	FullPath(path);
	cbparams[0] = path;

	//
	//	At least one extent must be present
	//
	if (!m_nExtents) {
		VDiskCallBack(VDISK_CB_EMPTY_IMAGE, cbparams);
		return VDK_DATA;
	}

	//
	//	Sum up extent capacity
	//
	m_nCapacity = 0;

	for (idx = 0; idx < m_nExtents; idx++) {
		if ((ret = m_ppExtents[idx]->Check()) != VDK_OK) {
			return ret;
		}

		if (m_ppExtents[idx]->IsModified()) {
			SetFlag(VDISK_FLAG_DIRTY);
		}

		m_nCapacity += m_ppExtents[idx]->GetCapacity();
	}

	//
	//	Check total capacity
	//
	/*
	if (total_size != m_nCapacity) {

		cbparams[1] = (PVOID)m_nCapacity;
		cbparams[2] = (PVOID)total_size;

		if (!VDiskCallBack(VDISK_CB_EXT_CAPACITY, cbparams)) {
			return VDK_DATA;
		}

		m_nCapacity	= total_size;
		SetGeometry();

		SetFlag(VDISK_FLAG_DIRTY);

		for (idx = 0; idx < m_nExtents; idx++) {
			if (total_size < m_ppExtents[idx]->GetCapacity()) {
				m_ppExtents[idx]->SetCapacity(total_size);
				total_size = 0;
			}
			else {
				total_size -= m_ppExtents[idx]->GetCapacity();
			}
		}
	}
	*/

	//
	//	Any bad parameter?
	//
	if (m_nFlags & VDISK_FLAG_DIRTY) {

		if (VDiskCallBack(VDISK_CB_CONFIRM_FIX, cbparams)) {
			ret = WriteDescriptor(FALSE, FALSE);

			if (ret != VDK_OK) {
				return ret;
			}

			for (idx = 0; idx < m_nExtents; idx++) {
				ret = m_ppExtents[idx]->Update();

				if (ret != VDK_OK) {
					return ret;
				}
			}
		}
		ClrFlag(VDISK_FLAG_DIRTY);
	}

	return VDK_OK;
}
Exemple #16
0
VOID
NtfsFspDispatch (
    IN PVOID Context
    )

/*++

Routine Description:

    This is the main FSP thread routine that is executed to receive
    and dispatch IRP requests.  Each FSP thread begins its execution here.
    There is one thread created at system initialization time and subsequent
    threads created as needed.

Arguments:


    Context - Supplies the thread id.

Return Value:

    None - This routine never exits

--*/

{
    TOP_LEVEL_CONTEXT TopLevelContext;
    PTOP_LEVEL_CONTEXT ThreadTopLevelContext;
    OPLOCK_CLEANUP OplockCleanup; 

    PIRP Irp;
    PIRP_CONTEXT IrpContext;
    PIO_STACK_LOCATION IrpSp;
    ULONG LogFileFullCount = 0;

    PVOLUME_DEVICE_OBJECT VolDo;
    BOOLEAN Retry;
    NTSTATUS Status = STATUS_SUCCESS;
    IrpContext = (PIRP_CONTEXT)Context;

    Irp = IrpContext->OriginatingIrp;

    if (Irp != NULL) {

        IrpSp = IoGetCurrentIrpStackLocation( Irp );
    }

    //
    //  Now because we are the Fsp we will force the IrpContext to
    //  indicate true on Wait.
    //

    SetFlag( IrpContext->State, IRP_CONTEXT_STATE_WAIT );

    //
    //  If this request has an associated volume device object, remember it.
    //

    if ((Irp != NULL) &&
        (IrpSp->FileObject != NULL)) {

        VolDo = CONTAINING_RECORD( IrpSp->DeviceObject,
                                   VOLUME_DEVICE_OBJECT,
                                   DeviceObject );
    } else {

        VolDo = NULL;
    }

    //
    //  Now case on the function code.  For each major function code,
    //  either call the appropriate FSP routine or case on the minor
    //  function and then call the FSP routine.  The FSP routine that
    //  we call is responsible for completing the IRP, and not us.
    //  That way the routine can complete the IRP and then continue
    //  post processing as required.  For example, a read can be
    //  satisfied right away and then read can be done.
    //
    //  We'll do all of the work within an exception handler that
    //  will be invoked if ever some underlying operation gets into
    //  trouble (e.g., if NtfsReadSectorsSync has trouble).
    //

    while (TRUE) {

        FsRtlEnterFileSystem();

        ASSERT( IoGetTopLevelIrp() != (PIRP) &TopLevelContext );

        ThreadTopLevelContext = NtfsInitializeTopLevelIrp( &TopLevelContext, TRUE, TRUE );
        ASSERT( ThreadTopLevelContext == &TopLevelContext );

        NtfsPostRequests += 1;

        do {

            //
            //  If this is the initial try with this Irp Context, update the
            //  top level Irp fields.
            //
    
            NtfsUpdateIrpContextWithTopLevel( IrpContext, ThreadTopLevelContext );
    
            Retry = FALSE;
    
            try {

                //
                //  Always clear the exception code in the IrpContext so we respond
                //  correctly to errors encountered in the Fsp.
                //

                IrpContext->ExceptionStatus = 0;
                SetFlag( IrpContext->State, IRP_CONTEXT_STATE_IN_FSP );

                //
                //  See if we were posted due to a log file full condition, and
                //  if so, then do a clean volume checkpoint if we are the
                //  first ones to get there.  If we see a different Lsn and do
                //  not do the checkpoint, the worst that can happen is that we
                //  will get posted again if the log file is still full.
                //

                if (IrpContext->LastRestartArea.QuadPart != 0) {

                    NtfsCheckpointForLogFileFull( IrpContext );

                    if (++LogFileFullCount >= 2) {

                        SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_EXCESS_LOG_FULL );
                    }
                }

                //
                //  If we have an Irp then proceed with our normal processing.
                //

                if (Irp != NULL) {

                    switch ( IrpContext->MajorFunction ) {

                        //
                        //  For Create Operation,
                        //

                        case IRP_MJ_CREATE:

                            ClearFlag( IrpContext->State, IRP_CONTEXT_STATE_EFS_CREATE );
                            
                            if (FlagOn( IrpContext->State, IRP_CONTEXT_STATE_DASD_OPEN )) {

                                Status = NtfsCommonVolumeOpen( IrpContext, Irp );

                            } else {

                                RtlZeroMemory( &OplockCleanup, sizeof( OplockCleanup ) );
                                Status = NtfsCommonCreate( IrpContext, Irp, &OplockCleanup, NULL );
                            }
                            break;

                        //
                        //  For close operations
                        //

                        case IRP_MJ_CLOSE:

                            //
                            //  We should never post closes to this workqueue.
                            //

                            NtfsBugCheck( 0, 0, 0 );
                            break;

                        //
                        //  For read operations
                        //

                        case IRP_MJ_READ:

                            (VOID) NtfsCommonRead( IrpContext, Irp, TRUE );
                            break;

                        //
                        //  For write operations,
                        //

                        case IRP_MJ_WRITE:

                            (VOID) NtfsCommonWrite( IrpContext, Irp );
                            break;

                        //
                        //  For Query Information operations,
                        //

                        case IRP_MJ_QUERY_INFORMATION:

                            (VOID) NtfsCommonQueryInformation( IrpContext, Irp );
                            break;

                        //
                        //  For Set Information operations,
                        //

                        case IRP_MJ_SET_INFORMATION:

                            (VOID) NtfsCommonSetInformation( IrpContext, Irp );
                            break;

                        //
                        //  For Query EA operations,
                        //

                        case IRP_MJ_QUERY_EA:

                            (VOID) NtfsCommonQueryEa( IrpContext, Irp );
                            break;

                        //
                        //  For Set EA operations,
                        //

                        case IRP_MJ_SET_EA:

                            (VOID) NtfsCommonSetEa( IrpContext, Irp );
                            break;


                        //
                        //  For Flush buffers operations,
                        //

                        case IRP_MJ_FLUSH_BUFFERS:

                            (VOID) NtfsCommonFlushBuffers( IrpContext, Irp );
                            break;

                        //
                        //  For Query Volume Information operations,
                        //

                        case IRP_MJ_QUERY_VOLUME_INFORMATION:

                            (VOID) NtfsCommonQueryVolumeInfo( IrpContext, Irp );
                            break;

                        //
                        //  For Set Volume Information operations,
                        //

                        case IRP_MJ_SET_VOLUME_INFORMATION:

                            (VOID) NtfsCommonSetVolumeInfo( IrpContext, Irp );
                            break;

                        //
                        //  For File Cleanup operations,
                        //

                        case IRP_MJ_CLEANUP:

                            (VOID) NtfsCommonCleanup( IrpContext, Irp );
                            break;

                        //
                        //  For Directory Control operations,
                        //

                        case IRP_MJ_DIRECTORY_CONTROL:

                            (VOID) NtfsCommonDirectoryControl( IrpContext, Irp );
                            break;

                        //
                        //  For File System Control operations,
                        //

                        case IRP_MJ_FILE_SYSTEM_CONTROL:

                            (VOID) NtfsCommonFileSystemControl( IrpContext, Irp );
                            break;

                        //
                        //  For Lock Control operations,
                        //

                        case IRP_MJ_LOCK_CONTROL:

                            (VOID) NtfsCommonLockControl( IrpContext, Irp );
                            break;

                        //
                        //  For Device Control operations,
                        //

                        case IRP_MJ_DEVICE_CONTROL:

                            (VOID) NtfsCommonDeviceControl( IrpContext, Irp );
                            break;

                        //
                        //  For Query Security Information operations,
                        //

                        case IRP_MJ_QUERY_SECURITY:

                            (VOID) NtfsCommonQuerySecurityInfo( IrpContext, Irp );
                            break;

                        //
                        //  For Set Security Information operations,
                        //

                        case IRP_MJ_SET_SECURITY:

                            (VOID) NtfsCommonSetSecurityInfo( IrpContext, Irp );
                            break;

                        //
                        //  For Query Quota operations,
                        //

                        case IRP_MJ_QUERY_QUOTA:

                            (VOID) NtfsCommonQueryQuota( IrpContext, Irp );
                            break;

                        //
                        //  For Set Quota operations,
                        //

                        case IRP_MJ_SET_QUOTA:

                            (VOID) NtfsCommonSetQuota( IrpContext, Irp );
                            break;

                        //
                        //  For any other major operations, return an invalid
                        //  request.
                        //

                        default:

                            NtfsCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST );
                            break;
                    }

                //
                //  Otherwise complete the request to clean up this Irp Context.
                //

                } else {

                    NtfsCompleteRequest( IrpContext, NULL, STATUS_SUCCESS );
                    IrpContext = NULL;
                }

                ASSERT( IoGetTopLevelIrp() != (PIRP) &TopLevelContext );
        
            } except(NtfsExceptionFilter( IrpContext, GetExceptionInformation() )) {

                PIO_STACK_LOCATION IrpSp;

                //
                //  We had some trouble trying to perform the requested
                //  operation, so we'll abort the I/O request with
                //  the error status that we get back from the
                //  execption code
                //

                if (Irp != NULL) {

                    IrpSp = IoGetCurrentIrpStackLocation( Irp );

                    Status = GetExceptionCode();

                    if ((Status == STATUS_FILE_DELETED) && 
                        ((IrpContext->MajorFunction == IRP_MJ_READ) || 
                         (IrpContext->MajorFunction == IRP_MJ_WRITE) || 
                         ((IrpContext->MajorFunction == IRP_MJ_SET_INFORMATION) &&
                          (IrpSp->Parameters.SetFile.FileInformationClass == FileEndOfFileInformation)))) {

                        IrpContext->ExceptionStatus = Status = STATUS_SUCCESS;
                    }
                }
                
                //
                //  If we failed to upgrade the volume's version during mount, we may
                //  not have put the right exception code into the irp context yet.
                //
                
                if ((IrpContext != NULL) &&
                    (FlagOn( IrpContext->State, IRP_CONTEXT_STATE_VOL_UPGR_FAILED )) &&
                    (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
                    (IrpContext->MinorFunction == IRP_MN_MOUNT_VOLUME)) {

                    IrpContext->ExceptionStatus = Status;
                }

                //  
                //  This is the return status code that we want the Irp Completion routine to receive.
                //

                Status = NtfsProcessException( IrpContext, Irp, Status );

                if ((Status == STATUS_CANT_WAIT) || (Status == STATUS_LOG_FILE_FULL)) {

                    Retry = TRUE;
                }
            }

        } while (Retry);

        FsRtlExitFileSystem();

        //
        //  If there are any entries on this volume's overflow queue, service
        //  them.
        //

        if (VolDo != NULL) {

            KIRQL SavedIrql;
            PLIST_ENTRY Entry = NULL;

            //
            //  We have a volume device object so see if there is any work
            //  left to do in its overflow queue.
            //

            KeAcquireSpinLock( &VolDo->OverflowQueueSpinLock, &SavedIrql );

            while (VolDo->OverflowQueueCount > 0) {

                //
                //  There is overflow work to do in this volume so we'll
                //  decrement the Overflow count, dequeue the IRP, and release
                //  the Event
                //

                Entry = VolDo->OverflowQueue.Flink;
                IrpContext = CONTAINING_RECORD( Entry,
                                                IRP_CONTEXT,
                                                WorkQueueItem.List );
                Irp = IrpContext->OriginatingIrp;

                //
                //  If the cancel routine thinks it owns the irp ignore it
                //  

                if (NtfsSetCancelRoutine( Irp, NULL, 0, FALSE )) {
                    
                    VolDo->OverflowQueueCount -= 1;
                    RemoveEntryList( (PLIST_ENTRY)Entry );
                    break;
                
                } else {

                    //
                    //  Release the spinlock to let the cancel routine gain it and finish
                    //  its action
                    //  

                    KeReleaseSpinLock( &VolDo->OverflowQueueSpinLock, SavedIrql );
                    KeAcquireSpinLock( &VolDo->OverflowQueueSpinLock, &SavedIrql );
                    Entry = NULL;
                }
            } //  endwhile

            KeReleaseSpinLock( &VolDo->OverflowQueueSpinLock, SavedIrql );

            //
            //  There wasn't an entry, break out of the loop and return to
            //  the Ex Worker thread.
            //

            if ( Entry == NULL ) {

                break;
            }

            if (VolDo->OverflowQueueCount < OVERFLOW_QUEUE_LIMIT) {
                KeSetEvent( &VolDo->OverflowQueueEvent, IO_NO_INCREMENT, FALSE );
            }

            //
            //  set wait to TRUE, and loop.
            //

            LogFileFullCount = 0;
            SetFlag( IrpContext->State, IRP_CONTEXT_STATE_WAIT );
            continue;

        } else {

            break;
        }
    }

    //
    //  Decrement the PostedRequestCount.
    //

    if (VolDo) {

        ExInterlockedAddUlong( &VolDo->PostedRequestCount,
                               0xffffffff,
                               &VolDo->OverflowQueueSpinLock );
    }

    return;
}
Exemple #17
0
NTSTATUS
FatFsdQueryVolumeInformation (
    IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine implements the Fsd part of the NtQueryVolumeInformation API
    call.

Arguments:

    VolumeDeviceObject - Supplies the volume device object where the file
        being queried exists.

    Irp - Supplies the Irp being processed.

Return Value:

    NTSTATUS - The FSD status for the Irp.

--*/

{
    NTSTATUS Status;
    PIRP_CONTEXT IrpContext = NULL;

    BOOLEAN TopLevel;

    PAGED_CODE();

#if __NDAS_FAT__

	if ((PVOID)FatControlDeviceObject == VolumeDeviceObject) {

		Status = Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
		Irp->IoStatus.Information = 0;

		IoCompleteRequest( Irp, IO_DISK_INCREMENT );

		return Status;
	}

#endif

    DebugTrace(+1, Dbg, "FatFsdQueryVolumeInformation\n", 0);

    //
    //  Call the common query routine, with blocking allowed if synchronous
    //

    FsRtlEnterFileSystem();

    TopLevel = FatIsIrpTopLevel( Irp );

#if (__NDAS_FAT_PRIMARY__ || __NDAS_FAT_SECONDARY__)

	do {
    
		try {

			if (IrpContext == NULL) { 

				IrpContext = FatCreateIrpContext( Irp, CanFsdWait(Irp) );
				IrpContext->TopLevel = TopLevel;
			}

#if __NDAS_FAT_SECONDARY__

			if (IS_SECONDARY_FILEOBJECT(IoGetCurrentIrpStackLocation(Irp)->FileObject)) {

				BOOLEAN	volDoResourceAcquired = FALSE;
				BOOLEAN volDoRecoveryResourceAcquired = FALSE;

				ASSERT( FatIsTopLevelRequest(IrpContext) );

				SetFlag( IrpContext->NdasFatFlags, NDAS_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT );

				Status = STATUS_SUCCESS;

				for (;;) {
			
					NDAS_ASSERT( volDoRecoveryResourceAcquired == FALSE );
					NDAS_ASSERT( volDoResourceAcquired == FALSE );

					if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)) {

						Status = FatFsdPostRequest( IrpContext, Irp );
						break;
					}
									
					if (FlagOn(VolumeDeviceObject->Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED)) {

						volDoRecoveryResourceAcquired 
							= SecondaryAcquireResourceExclusiveLite( IrpContext, 
																	 &VolumeDeviceObject->RecoveryResource, 
																	 BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
								
						if (!FlagOn(VolumeDeviceObject->Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED) ) {

							SecondaryReleaseResourceLite( IrpContext, &VolumeDeviceObject->RecoveryResource );
							volDoRecoveryResourceAcquired = FALSE;
							continue;
						}

						volDoResourceAcquired 
							= SecondaryAcquireResourceExclusiveLite( IrpContext, 
																	 &VolumeDeviceObject->Resource, 
																	 BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
						try {
								
							SecondaryRecoverySessionStart( VolumeDeviceObject->Secondary, IrpContext );
								
						} finally {

							SecondaryReleaseResourceLite( IrpContext, &VolumeDeviceObject->Resource );
							volDoResourceAcquired = FALSE;

							SecondaryReleaseResourceLite( IrpContext, &VolumeDeviceObject->RecoveryResource );
							volDoRecoveryResourceAcquired = FALSE;
						}

						continue;
					}

					volDoResourceAcquired 
						= SecondaryAcquireResourceSharedLite( IrpContext, 
															  &VolumeDeviceObject->Resource, 
															  BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );

					NDAS_ASSERT( volDoResourceAcquired == TRUE );

					break;
				}

				if (Status == STATUS_SUCCESS) {
					
					try {

						Status = FatCommonQueryVolumeInfo( IrpContext, Irp );
							
					} finally {

						ASSERT( ExIsResourceAcquiredSharedLite(&VolumeDeviceObject->Resource) );
						SecondaryReleaseResourceLite( NULL, &VolumeDeviceObject->Resource );
					}
				}

			} else
				Status = FatCommonQueryVolumeInfo( IrpContext, Irp );
#else
	        Status = FatCommonQueryVolumeInfo( IrpContext, Irp );
#endif
            break;

		} except(FatExceptionFilter( IrpContext, GetExceptionInformation() )) {

			//
	        //  We had some trouble trying to perform the requested
		    //  operation, so we'll abort the I/O request with
			//  the error status that we get back from the
	        //  execption code
		    //

			Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
		}
	
	} while (Status == STATUS_CANT_WAIT);
Exemple #18
0
VOID
NtfsSpecialDispatch (
    PVOID Context
    )

/*++

Routine Description:

    This routine is called when a special operation needs to be posted.
    It is called indirectly by NtfsPostSpecial.  It is assumes that the
    Vcb is protected from going away by incrementing the volemue close
    counts for a file.  If this routine fails nothing is done except
    to clean up the Vcb.  This routine also handles issues log file full
    and can't wait.

    The function to be called is stored in the PostSpecialCallout field
    of the Irp Context, and the context is stored int he OriginatingIrp.
    Both fields are zeroed before the the callout function is called.

Arguments:

    Context - Supplies a pointer to an IrpContext.

Return Value:

--*/

{
    PVCB Vcb;
    PIRP_CONTEXT IrpContext = Context;
    TOP_LEVEL_CONTEXT TopLevelContext;
    PTOP_LEVEL_CONTEXT ThreadTopLevelContext;
    POST_SPECIAL_CALLOUT PostSpecialCallout;
    PVOID SpecialContext;
    ULONG LogFileFullCount;
    BOOLEAN Retry;

    PAGED_CODE();

    FsRtlEnterFileSystem();

    do {

        Vcb = IrpContext->Vcb;
        LogFileFullCount = 0;

        //
        //  Capture the funciton pointer and context before using the IrpContext.
        //

        PostSpecialCallout = IrpContext->Union.PostSpecialCallout;
        SpecialContext = IrpContext->OriginatingIrp;
        IrpContext->Union.PostSpecialCallout = NULL;
        IrpContext->OriginatingIrp = NULL;

        ThreadTopLevelContext = NtfsInitializeTopLevelIrp( &TopLevelContext, TRUE, TRUE );
        ASSERT( ThreadTopLevelContext == &TopLevelContext );
        ASSERT( !FlagOn( IrpContext->State, IRP_CONTEXT_STATE_OWNS_TOP_LEVEL ));
        ASSERT( FlagOn( IrpContext->State, IRP_CONTEXT_STATE_ALLOC_FROM_POOL ));

        //
        //  Initialize the thread top level structure, if needed.
        //

        ASSERT( IoGetTopLevelIrp() != (PIRP) &TopLevelContext );
        NtfsUpdateIrpContextWithTopLevel( IrpContext, ThreadTopLevelContext );

        //
        //  Don't let this IrpContext be deleted.
        //

        SetFlag( IrpContext->State, IRP_CONTEXT_STATE_PERSISTENT );

        do {

            Retry = FALSE;

            try {

                //
                //  See if we failed due to a log file full condition, and
                //  if so, then do a clean volume checkpoint if we are the
                //  first ones to get there.  If we see a different Lsn and do
                //  not do the checkpoint, the worst that can happen is that we
                //  will fail again if the log file is still full.
                //

                if (IrpContext->LastRestartArea.QuadPart != 0) {

                    NtfsCheckpointForLogFileFull( IrpContext );

                    if (++LogFileFullCount >= 2) {

                        SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_EXCESS_LOG_FULL );
                    }
                }

                //
                //  Call the requested function.
                //

                ASSERT( FlagOn( IrpContext->TopLevelIrpContext->State, IRP_CONTEXT_STATE_OWNS_TOP_LEVEL ));
                PostSpecialCallout( IrpContext, SpecialContext );

                NtfsCompleteRequest( IrpContext, NULL, STATUS_SUCCESS );

            } except(NtfsExceptionFilter( IrpContext, GetExceptionInformation() )) {

                NTSTATUS ExceptionCode;

                ExceptionCode = GetExceptionCode();
                ExceptionCode = NtfsProcessException( IrpContext, NULL, ExceptionCode );

                if ((ExceptionCode == STATUS_CANT_WAIT) ||
                    (ExceptionCode == STATUS_LOG_FILE_FULL)) {

                    Retry = TRUE;
                }
            }

        } while (Retry);

        //
        //  Ok to let this IrpContext be deleted.
        //

        ClearFlag( IrpContext->State, IRP_CONTEXT_STATE_PERSISTENT );

        //
        //  At this point regardless of the status the volume needs to
        //  be cleaned up and the IrpContext freed.
        //  Dereference the Vcb and check to see if it needs to be deleted.
        //  since this call might raise wrap it with a try/execpt.
        //

        try {

            //
            //  Acquire the volume exclusive so the counts can be
            //  updated.
            //

            ASSERT( FlagOn( IrpContext->State, IRP_CONTEXT_STATE_WAIT ));
            NtfsAcquireExclusiveVcb( IrpContext, Vcb, TRUE );

            InterlockedDecrement( &Vcb->SystemFileCloseCount );
            InterlockedDecrement( &Vcb->CloseCount );

            NtfsReleaseVcb( IrpContext, Vcb );

        } except( EXCEPTION_EXECUTE_HANDLER ) {

            ASSERT( FsRtlIsNtstatusExpected( GetExceptionCode() ) );
        }

        //
        //  Free the irp context.
        //

        NtfsCleanupIrpContext( IrpContext, TRUE );

        //
        //  See if there is more work on the scavenger list.
        //

        ExAcquireFastMutexUnsafe( &NtfsScavengerLock );

        ASSERT( NtfsScavengerRunning );

        IrpContext = NtfsScavengerWorkList;

        if (IrpContext != NULL) {

            //
            //  Remove the entry from the list.
            //

            NtfsScavengerWorkList = (PIRP_CONTEXT) IrpContext->WorkQueueItem.List.Flink;
            IrpContext->WorkQueueItem.List.Flink = NULL;

        } else {

            NtfsScavengerRunning = FALSE;

        }

        ExReleaseFastMutexUnsafe( &NtfsScavengerLock );

    } while ( IrpContext != NULL );

    FsRtlExitFileSystem();
}
Exemple #19
0
void Transport::BuildStartMovePacket(Map const* targetMap)
{
    SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE);
    SetGoState(GO_STATE_ACTIVE);
    UpdateForMap(targetMap);
}
Exemple #20
0
BOOLEAN
ReadonlyPassThrough (
    IN  PDEVICE_OBJECT				DeviceObject,
    IN  PIRP						Irp,
	IN  PFILESPY_DEVICE_EXTENSION	DevExt,
	OUT PNTSTATUS					NtStatus
	)
{
	NTSTATUS			status = STATUS_SUCCESS;
	BOOLEAN				result = FALSE;
    PIO_STACK_LOCATION	irpSp = IoGetCurrentIrpStackLocation( Irp );
	PFILE_OBJECT		fileObject = irpSp->FileObject;
	BOOLEAN				fastMutexAcquired = FALSE;


	UNREFERENCED_PARAMETER( DeviceObject );

	ASSERT( DevExt->LfsDeviceExt.ReferenceCount );
	LfsDeviceExt_Reference( &DevExt->LfsDeviceExt );	

	PrintIrp( LFS_DEBUG_READONLY_NOISE, __FUNCTION__, &DevExt->LfsDeviceExt, Irp );

	ASSERT( KeGetCurrentIrql() <= APC_LEVEL );

	ExAcquireFastMutex( &DevExt->LfsDeviceExt.FastMutex );
	fastMutexAcquired = TRUE;

	try {

		if (!FlagOn(DevExt->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_MOUNTED)) {

			result = FALSE;
			leave;
		}

		ASSERT( DevExt->LfsDeviceExt.AttachedToDeviceObject == DevExt->NLExtHeader.AttachedToDeviceObject );

		if (DevExt->LfsDeviceExt.AttachedToDeviceObject == NULL) {

			NDAS_ASSERT( FALSE );

			result = FALSE;
			leave;
		}

		if (!(FlagOn(DevExt->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_MOUNTED) && !FlagOn(DevExt->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_DISMOUNTED))) {

			ASSERT( DevExt->LfsDeviceExt.Readonly == NULL || ReadonlyLookUpCcb(DevExt->LfsDeviceExt.Readonly, fileObject) == NULL );
			
			result = FALSE;
			leave;
		}

		switch (irpSp->MajorFunction) {

		case IRP_MJ_PNP:

			break;

		default: 

			ExReleaseFastMutex( &DevExt->LfsDeviceExt.FastMutex );
			fastMutexAcquired = FALSE;

			if (DevExt->LfsDeviceExt.Readonly) {

				status = ReadonlyRedirectIrp( DevExt, Irp, &result );
			
			} else {

				result = FALSE;
			}

			leave;
		}

		if (irpSp->MajorFunction == IRP_MJ_PNP) {

			PrintIrp( LFS_DEBUG_READONLY_NOISE, __FUNCTION__, &DevExt->LfsDeviceExt, Irp );

			if (irpSp->MinorFunction == IRP_MN_SURPRISE_REMOVAL) {

				if (DevExt->LfsDeviceExt.NetdiskPartition == NULL) {

					NDAS_ASSERT( FALSE );
				
				} else {

					SetFlag( DevExt->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_SURPRISE_REMOVED );

					ExReleaseFastMutex( &DevExt->LfsDeviceExt.FastMutex );
					fastMutexAcquired = FALSE;

					NetdiskManager_SurpriseRemoval( GlobalLfs.NetdiskManager,
													DevExt->LfsDeviceExt.NetdiskPartition,
													DevExt->LfsDeviceExt.NetdiskEnabledMode );
				}

				DevExt->LfsDeviceExt.NetdiskPartition = NULL;			

				result = FALSE;
				leave;

			}

			// Need to test much whether this is okay..
	
			if (irpSp->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE || irpSp->MinorFunction == IRP_MN_REMOVE_DEVICE) {

				result = FALSE;
				leave;
			
			} else if (irpSp->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE) {

				KEVENT				waitEvent;

				ExReleaseFastMutex( &DevExt->LfsDeviceExt.FastMutex );
				fastMutexAcquired = FALSE;

				if (DevExt->LfsDeviceExt.Readonly) {

					ReadonlyTryCloseCcb( DevExt->LfsDeviceExt.Readonly );

					if (!IsListEmpty(&DevExt->LfsDeviceExt.Readonly->FcbQueue)) {

						LARGE_INTEGER interval;
				
						// Wait all files closed
						interval.QuadPart = (1 * DELAY_ONE_SECOND);      //delay 1 seconds
						KeDelayExecutionThread( KernelMode, FALSE, &interval );
					}
			
					if (!IsListEmpty(&DevExt->LfsDeviceExt.Readonly->FcbQueue)) {

						status = Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
						Irp->IoStatus.Information = 0;
						IoCompleteRequest( Irp, IO_DISK_INCREMENT );
				
						result = TRUE;
						leave;
					} 
				}

				SetFlag( DevExt->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_DISMOUNTING );

				IoCopyCurrentIrpStackLocationToNext( Irp );
				KeInitializeEvent( &waitEvent, NotificationEvent, FALSE );

				IoSetCompletionRoutine( Irp,
										ReadonlyPassThroughCompletion,
										&waitEvent,
										TRUE,
										TRUE,
										TRUE );

				status = IoCallDriver( DevExt->LfsDeviceExt.AttachedToDeviceObject, Irp );

				if (status == STATUS_PENDING) {

					status = KeWaitForSingleObject( &waitEvent, Executive, KernelMode, FALSE, NULL );
					ASSERT( status == STATUS_SUCCESS );
				}

				ASSERT( KeReadStateEvent(&waitEvent) || !NT_SUCCESS(Irp->IoStatus.Status) );
	
				SPY_LOG_PRINT( LFS_DEBUG_READONLY_INFO, 
							   ("%s: lfsDeviceExt = %p, IRP_MN_QUERY_REMOVE_DEVICE Irp->IoStatus.Status = %x\n",
								__FUNCTION__, &DevExt->LfsDeviceExt, Irp->IoStatus.Status) );

				ClearFlag( DevExt->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_DISMOUNTING );

				if (NT_SUCCESS(Irp->IoStatus.Status)) {

					ASSERT( !FlagOn(DevExt->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_DISMOUNTED) );
					LfsDismountVolume( &DevExt->LfsDeviceExt );
				}

				status = Irp->IoStatus.Status;
				IoCompleteRequest( Irp, IO_NO_INCREMENT );

				result = TRUE;
				leave;
			}

			result = FALSE;
			leave;
		}

	} finally {

		if (fastMutexAcquired)
			ExReleaseFastMutex( &DevExt->LfsDeviceExt.FastMutex );

		LfsDeviceExt_Dereference( &DevExt->LfsDeviceExt );
		*NtStatus = status;
	}

	return result;
}
Exemple #21
0
NTSTATUS 
MiniSecondaryNtfsPassThrough (
	IN  PSECONDARY				Secondary,
	IN OUT PFLT_CALLBACK_DATA	Data
	)
{
	NTSTATUS				status = FLT_PREOP_SUCCESS_NO_CALLBACK;
	//PIO_STACK_LOCATION	iopb = IoGetCurrentIrpStackLocation( Irp );
	PFLT_IO_PARAMETER_BLOCK iopb = Data->Iopb;
	PFILE_OBJECT			fileObject = iopb->TargetFileObject;

	BOOLEAN				fastMutexSet = FALSE;
	BOOLEAN				retry = FALSE;


	ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );

	Secondary_Reference( Secondary );
 
	if (fileObject && fileObject->Flags & FO_DIRECT_DEVICE_OPEN) {

		NDASFS_ASSERT( LFS_REQUIRED );
		DbgPrint( "Direct device open\n" );
	}

	if (iopb->MajorFunction == IRP_MJ_CREATE					||	// 0x00
		iopb->MajorFunction == IRP_MJ_CLOSE					||	// 0x01
		iopb->MajorFunction == IRP_MJ_READ						||  // 0x03
		iopb->MajorFunction == IRP_MJ_WRITE					||  // 0x04
		iopb->MajorFunction == IRP_MJ_QUERY_INFORMATION		||  // 0x05
		iopb->MajorFunction == IRP_MJ_SET_INFORMATION			||	// 0x06
		iopb->MajorFunction == IRP_MJ_QUERY_EA					||	// 0x07
		iopb->MajorFunction == IRP_MJ_SET_EA					||	// 0x08
		iopb->MajorFunction == IRP_MJ_FLUSH_BUFFERS			||	// 0x09
		iopb->MajorFunction == IRP_MJ_QUERY_VOLUME_INFORMATION	||	// 0x0a
		iopb->MajorFunction == IRP_MJ_SET_VOLUME_INFORMATION	||	// 0x0b
		iopb->MajorFunction == IRP_MJ_DIRECTORY_CONTROL		||	// 0x0c
		iopb->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL		||	// 0x0c
		iopb->MajorFunction == IRP_MJ_LOCK_CONTROL				||	// 0x11
		iopb->MajorFunction == IRP_MJ_CLEANUP					||	// 0x12
		iopb->MajorFunction == IRP_MJ_QUERY_SECURITY			||	// 0x14
		iopb->MajorFunction == IRP_MJ_SET_SECURITY				||	// 0x15
		iopb->MajorFunction == IRP_MJ_QUERY_QUOTA				||	// 0x19
		iopb->MajorFunction == IRP_MJ_SET_QUOTA) {					// 0x1a
			
	} else if (iopb->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) {

		if (iopb->MinorFunction == IRP_MN_MOUNT_VOLUME		||
			iopb->MinorFunction == IRP_MN_VERIFY_VOLUME	||
			iopb->MinorFunction == IRP_MN_LOAD_FILE_SYSTEM) {
		
			NDASFS_ASSERT( LFS_UNEXPECTED );
			ASSERT( Secondary_LookUpFileExtension(Secondary, fileObject) == NULL );

			PrintData( LFS_DEBUG_SECONDARY_TRACE, "Secondary_PassThrough", Secondary->LfsDeviceExt, Irp );

			Secondary_Dereference( Secondary );
			return FLT_PREOP_SUCCESS_NO_CALLBACK;
		}
	
	} else if (iopb->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL	|| 	// 0x0f
			   iopb->MajorFunction == IRP_MJ_SHUTDOWN					||  // 0x10
			   iopb->MajorFunction == IRP_MJ_CREATE_MAILSLOT			||  // 0x13
			   iopb->MajorFunction == IRP_MJ_POWER						||  // 0x16
			   iopb->MajorFunction == IRP_MJ_SYSTEM_CONTROL			||  // 0x17
			   iopb->MajorFunction == IRP_MJ_DEVICE_CHANGE) {				// 0x18
	
		NDASFS_ASSERT( LFS_REQUIRED );
		PrintData( LFS_DEBUG_SECONDARY_TRACE, "Secondary_PassThrough", Secondary->LfsDeviceExt, Irp );

		Secondary_Dereference( Secondary );

		return FLT_PREOP_SUCCESS_NO_CALLBACK;

	} else if (iopb->MajorFunction == IRP_MJ_DEVICE_CONTROL) {

		PFILE_EXTENTION	fileExt = NULL;

		fileExt = Secondary_LookUpFileExtension(Secondary, fileObject);
		
		if (fileExt == NULL || fileExt->TypeOfOpen != UserVolumeOpen) {

			Secondary_Dereference( Secondary );

			Data->IoStatus.Status = STATUS_INVALID_PARAMETER;
			Data->IoStatus.Information = 0;

			return FLT_PREOP_COMPLETE;
		}

		status = MiniSecondary_Ioctl( Secondary, Data );

		Secondary_Dereference( Secondary );

		return status;	

	} else {

		NDASFS_ASSERT( LFS_UNEXPECTED );

		Secondary_Dereference( Secondary );
		return FLT_PREOP_SUCCESS_NO_CALLBACK;
	}		

	PrintData( LFS_DEBUG_SECONDARY_TRACE, "Secondary_PassThrough", Secondary->LfsDeviceExt, Irp );
	
	if (Secondary->Thread.SessionStatus == STATUS_DISK_CORRUPT_ERROR) {

		NDASFS_ASSERT( Secondary_LookUpFileExtension(Secondary, fileObject) == NULL );

		if (iopb->MajorFunction == IRP_MJ_CLOSE) {

			if (Secondary_LookUpFileExtension(Secondary, fileObject)) {

				SecondaryFileObjectClose( Secondary, fileObject );
			}

			Data->IoStatus.Status = STATUS_SUCCESS;
			Data->IoStatus.Information = 0;

		} else if (iopb->MajorFunction == IRP_MJ_CLEANUP) {

			InterlockedDecrement( &((PLFS_FCB)iopb->TargetFileObject->FsContext)->UncleanCount );
			SetFlag( fileObject->Flags, FO_CLEANUP_COMPLETE );

			Data->IoStatus.Status = STATUS_SUCCESS;
			Data->IoStatus.Information = 0;

		} else {

			Data->IoStatus.Status = STATUS_DISK_CORRUPT_ERROR;
			Data->IoStatus.Information = 0;
		}

		Secondary_Dereference( Secondary );
		
		return FLT_PREOP_COMPLETE;
	} 
	
	if (Secondary->Thread.SessionStatus == STATUS_UNRECOGNIZED_VOLUME) {

		NDASFS_ASSERT( Secondary_LookUpFileExtension(Secondary, fileObject) == NULL );

		if (iopb->MajorFunction == IRP_MJ_CLOSE) {

			if (Secondary_LookUpFileExtension(Secondary, fileObject)) {

				SecondaryFileObjectClose( Secondary, fileObject );
			}

			Data->IoStatus.Status = STATUS_SUCCESS;
			Data->IoStatus.Information = 0;

		} else if (iopb->MajorFunction == IRP_MJ_CLEANUP) {

			InterlockedDecrement( &((PLFS_FCB)iopb->TargetFileObject->FsContext)->UncleanCount );
			SetFlag( fileObject->Flags, FO_CLEANUP_COMPLETE );

			Data->IoStatus.Status = STATUS_SUCCESS;
			Data->IoStatus.Information = 0;

		} else {

			Data->IoStatus.Status = STATUS_DISK_CORRUPT_ERROR;
			Data->IoStatus.Information = 0;
		}

		Secondary_Dereference( Secondary );

		return FLT_PREOP_COMPLETE;
	}

	while (1) {

		NDASFS_ASSERT( fastMutexSet == FALSE );
		NDASFS_ASSERT( retry == FALSE );

		ExAcquireFastMutex( &Secondary->FastMutex );

		if (FlagOn(Secondary->Flags, SECONDARY_FLAG_CLOSED)) {

			SPY_LOG_PRINT( LFS_DEBUG_SECONDARY_ERROR, 
						   ("Secondary is already closed Secondary = %p\n", Secondary) );

			ExReleaseFastMutex( &Secondary->FastMutex );

			NDASFS_ASSERT( iopb->MajorFunction == IRP_MJ_CREATE );

			if (iopb->MajorFunction == IRP_MJ_CLOSE) {

				if (Secondary_LookUpFileExtension(Secondary, fileObject)) {

					SecondaryFileObjectClose( Secondary, fileObject );
				}

				Data->IoStatus.Status = STATUS_SUCCESS;
				Data->IoStatus.Information = 0;

			} else if (iopb->MajorFunction == IRP_MJ_CLEANUP) {

				InterlockedDecrement( &((PLFS_FCB)iopb->TargetFileObject->FsContext)->UncleanCount );
				SetFlag( fileObject->Flags, FO_CLEANUP_COMPLETE );

				Data->IoStatus.Status = STATUS_SUCCESS;
				Data->IoStatus.Information = 0;

			} else {

				Data->IoStatus.Status = STATUS_TOO_LATE;
				Data->IoStatus.Information = 0;
			}

			status = FLT_PREOP_COMPLETE;
			break;
		}

		if (FlagOn(Secondary->Flags, SECONDARY_FLAG_ERROR)) {

			ExReleaseFastMutex( &Secondary->FastMutex );

			if (iopb->MajorFunction == IRP_MJ_CLOSE) {

				if (Secondary_LookUpFileExtension(Secondary, fileObject)) {

					SecondaryFileObjectClose( Secondary, fileObject );
				}

				Data->IoStatus.Status = STATUS_SUCCESS;
				Data->IoStatus.Information = 0;

			} else if (iopb->MajorFunction == IRP_MJ_CREATE) {

				Data->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
				Data->IoStatus.Information = 0;
			
			} else if (iopb->MajorFunction == IRP_MJ_CLEANUP) {

				InterlockedDecrement( &((PLFS_FCB)iopb->TargetFileObject->FsContext)->UncleanCount );
				SetFlag( fileObject->Flags, FO_CLEANUP_COMPLETE );

				Data->IoStatus.Status = STATUS_SUCCESS;
				Data->IoStatus.Information = 0;

			} else {

				Data->IoStatus.Status = STATUS_FILE_CORRUPT_ERROR;
				Data->IoStatus.Information = 0;
			} 

			status = FLT_PREOP_COMPLETE;
			break;
		}
		
		ExReleaseFastMutex( &Secondary->FastMutex );

		if (!FlagOn(Secondary->Flags, SECONDARY_FLAG_RECONNECTING)) {

			NDASFS_ASSERT( Secondary->ThreadObject );
		}

		KeEnterCriticalRegion();
		status = MiniRedirectIrp( Secondary, Data, &fastMutexSet, &retry );
		KeLeaveCriticalRegion();

		if (retry == TRUE) {

			retry = FALSE;
			continue;
		}

		if (status == STATUS_SUCCESS) {

			NDASFS_ASSERT( fastMutexSet == FALSE );

			if (Data->IoStatus.Status == STATUS_PENDING) {

				NDASFS_ASSERT( LFS_BUG );
			}

			status = FLT_PREOP_COMPLETE;
			break;	
		} 
		
		if (status == STATUS_DEVICE_REQUIRES_CLEANING) {

			PrintData( LFS_DEBUG_LFS_INFO, 
					  "STATUS_DEVICE_REQUIRES_CLEANING", 
					  CONTAINING_RECORD(Secondary, LFS_DEVICE_EXTENSION, Secondary), 
					  Irp );

			if (iopb->MajorFunction == IRP_MJ_CLEANUP) {

				InterlockedDecrement( &((PLFS_FCB)iopb->TargetFileObject->FsContext)->UncleanCount );
				SetFlag( fileObject->Flags, FO_CLEANUP_COMPLETE );

				Data->IoStatus.Status = STATUS_SUCCESS;
				Data->IoStatus.Information = 0;

			} else {
			
				Data->IoStatus.Status = STATUS_ACCESS_DENIED;
				Data->IoStatus.Information = 0;
			}

			status = FLT_PREOP_COMPLETE;
			break;
		} 
		
		if (status == STATUS_ALERTED || status == STATUS_USER_APC) {

			NDASFS_ASSERT( fastMutexSet == FALSE );
			continue;		
		} 

		NDASFS_ASSERT( status == STATUS_REMOTE_DISCONNECT || status == STATUS_IO_DEVICE_ERROR );
		NDASFS_ASSERT( fastMutexSet == TRUE );

		ExAcquireFastMutex( &Secondary->FastMutex );

		ASSERT( FlagOn(Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED) );

		if (Secondary->LfsDeviceExt->SecondaryState == CONNECTED_TO_LOCAL_STATE		|| 
			FlagOn(Secondary->LfsDeviceExt->Flags, LFS_DEVICE_FLAG_SURPRISE_REMOVED)		||
			GlobalLfs.ShutdownOccured == TRUE) {

			SetFlag( Secondary->Flags, SECONDARY_FLAG_ERROR );
			ExReleaseFastMutex( &Secondary->FastMutex );

			KeReleaseSemaphore( &Secondary->Semaphore, IO_NO_INCREMENT, 1, FALSE );
			fastMutexSet = FALSE;

			Data->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
			Data->IoStatus.Information = 0;
	
			status = FLT_PREOP_COMPLETE;
			break;
		}

		if (FlagOn(Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED)) {

			//BOOLEAN			recoveryResult;

			ASSERT( !FlagOn(Secondary->Flags, SECONDARY_FLAG_RECONNECTING) );
			SetFlag( Secondary->Flags, SECONDARY_FLAG_RECONNECTING );

			ExReleaseFastMutex( &Secondary->FastMutex );

			if (FlagOn(Secondary->Flags, SECONDARY_FLAG_CLOSED)) {

				ASSERT( iopb->MajorFunction == IRP_MJ_CREATE );
					
				SPY_LOG_PRINT( LFS_DEBUG_SECONDARY_ERROR, 
							   ("Secondary is already closed Secondary = %p\n", Secondary) );

				ClearFlag( Secondary->Flags, SECONDARY_FLAG_RECONNECTING );

				KeReleaseSemaphore( &Secondary->Semaphore, IO_NO_INCREMENT, 1, FALSE );

				continue;
			}

			CallRecoverySessionAsynchronously( Secondary );
			fastMutexSet = FALSE;
				
			continue;
		}

		//
		//	Recovery failed.
		//

		SetFlag( Secondary->Flags, SECONDARY_FLAG_ERROR );
		ExReleaseFastMutex( &Secondary->FastMutex );

		KeReleaseSemaphore( &Secondary->Semaphore, IO_NO_INCREMENT, 1, FALSE );
		fastMutexSet = FALSE;

		NDASFS_ASSERT( IsListEmpty(&Secondary->RequestQueue) );

		continue;
	}

	NDASFS_ASSERT( fastMutexSet == FALSE );

	Secondary_Dereference( Secondary );

	NDASFS_ASSERT( status == FLT_PREOP_COMPLETE );

	return status;
}
Exemple #22
0
VOID
Readonly_Close (
	IN  PREADONLY	Readonly
	)
{
	NTSTATUS		status;
	LARGE_INTEGER	timeOut;

	PLIST_ENTRY			readonlyRequestEntry;
	PREADONLY_REQUEST	readonlyRequest;


	SPY_LOG_PRINT( LFS_DEBUG_READONLY_INFO, ("Readonly close Readonly = %p\n", Readonly) );

	ExAcquireFastMutex( &Readonly->FastMutex );

	ASSERT( !FlagOn(Readonly->Flags, READONLY_FLAG_RECONNECTING) );

	if (FlagOn(Readonly->Flags, READONLY_FLAG_CLOSED)) {

		//ASSERT( FALSE );
		ExReleaseFastMutex( &Readonly->FastMutex );
		return;
	}

	SetFlag( Readonly->Flags, READONLY_FLAG_CLOSED );

	ExReleaseFastMutex( &Readonly->FastMutex );

	FsRtlNotifyUninitializeSync( &Readonly->NotifySync );

	if (Readonly->ThreadHandle == NULL) {

		//ASSERT( FALSE );
		Readonly_Dereference( Readonly );
		return;
	}

	ASSERT( Readonly->ThreadObject != NULL );

	SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE, ("Readonly close READONLY_REQ_DISCONNECT Readonly = %p\n", Readonly) );

	readonlyRequest = AllocReadonlyRequest( Readonly, 0, FALSE );
	readonlyRequest->RequestType = READONLY_REQ_DISCONNECT;

	QueueingReadonlyRequest( Readonly, readonlyRequest );

	readonlyRequest = AllocReadonlyRequest( Readonly, 0, FALSE );
	readonlyRequest->RequestType = READONLY_REQ_DOWN;

	QueueingReadonlyRequest( Readonly, readonlyRequest );

	SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE, ("Readonly close READONLY_REQ_DISCONNECT end Readonly = %p\n", Readonly) );

	timeOut.QuadPart = -LFS_TIME_OUT;

	status = KeWaitForSingleObject( Readonly->ThreadObject,
									Executive,
									KernelMode,
									FALSE,
									&timeOut );

	if (status == STATUS_SUCCESS) {
	   
		SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE, ("Readonly_Close: thread stoped Readonly = %p\n", Readonly) );

		ObDereferenceObject( Readonly->ThreadObject );

		Readonly->ThreadHandle = NULL;
		Readonly->ThreadObject = NULL;
	
	} else {

		ASSERT( LFS_BUG );
		return;
	}

	if (!IsListEmpty(&Readonly->FcbQueue))
		NDAS_ASSERT( FALSE );

	if (!IsListEmpty(&Readonly->CcbQueue))
		NDAS_ASSERT( FALSE );

	if (!IsListEmpty(&Readonly->RequestQueue))
		NDAS_ASSERT( FALSE );

	while (readonlyRequestEntry = ExInterlockedRemoveHeadList(&Readonly->RequestQueue,
															   &Readonly->RequestQSpinLock)) {

		PREADONLY_REQUEST readonlyRequest2;

		InitializeListHead( readonlyRequestEntry );
			
		readonlyRequest2 = CONTAINING_RECORD( readonlyRequestEntry,
											   READONLY_REQUEST,
											   ListEntry );
        
		readonlyRequest2->ExecuteStatus = STATUS_IO_DEVICE_ERROR;
		
		if (readonlyRequest2->Synchronous == TRUE)
			KeSetEvent( &readonlyRequest2->CompleteEvent, IO_DISK_INCREMENT, FALSE );
		else
			DereferenceReadonlyRequest( readonlyRequest2 );
	}
	
	Readonly_Dereference( Readonly );

	return;
}
Exemple #23
0
NTSTATUS
FatFsdCleanup (
    IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine implements the FSD part of closing down a handle to a
    file object.

Arguments:

    VolumeDeviceObject - Supplies the volume device object where the
        file being Cleanup exists

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The FSD status for the IRP

--*/

{
    NTSTATUS Status;
    PIRP_CONTEXT IrpContext = NULL;

    BOOLEAN TopLevel;

    PAGED_CODE();

#if __NDAS_FAT__

	if ((PVOID)FatControlDeviceObject == VolumeDeviceObject) {

		Status = Irp->IoStatus.Status = STATUS_SUCCESS;
		Irp->IoStatus.Information = FILE_OPENED;

		IoCompleteRequest( Irp, IO_DISK_INCREMENT );

		return Status;
	}

#endif

    //
    //  If we were called with our file system device object instead of a
    //  volume device object, just complete this request with STATUS_SUCCESS
    //

    if ( FatDeviceIsFatFsdo( VolumeDeviceObject))  {

        Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information = FILE_OPENED;

        IoCompleteRequest( Irp, IO_DISK_INCREMENT );

        return STATUS_SUCCESS;
    }

    DebugTrace(+1, Dbg, "FatFsdCleanup\n", 0);

    //
    //  Call the common Cleanup routine, with blocking allowed.
    //

    FsRtlEnterFileSystem();

    TopLevel = FatIsIrpTopLevel( Irp );

#if (__NDAS_FAT_PRIMARY__ || __NDAS_FAT_SECONDARY__)

	do {
	
		try {

			if (IrpContext == NULL) { 

				IrpContext = FatCreateIrpContext( Irp, TRUE );
				IrpContext->TopLevel = TopLevel;

#if __NDAS_FAT_PRIMARY__
			{
				ULONG_PTR				stackBottom;
				ULONG_PTR				stackTop;
			    BOOLEAN					validPrimaryRequest = FALSE;
				PPRIMARY_REQUEST_INFO	primaryRequestInfo;
				PIO_STACK_LOCATION		irpSp = IoGetCurrentIrpStackLocation( Irp );
    

				//primaryRequestInfo = (PPRIMARY_REQUEST_INFO)FatGetTopLevelContext()->SavedTopLevelIrp;
				primaryRequestInfo = (PPRIMARY_REQUEST_INFO)IoGetTopLevelIrp();
			    IoGetStackLimits( &stackTop, &stackBottom );

			    if ( (ULONG_PTR)primaryRequestInfo <= stackBottom - sizeof(PRIMARY_REQUEST_INFO)	&&
					 (ULONG_PTR) primaryRequestInfo >= stackTop										&&
					 (!FlagOn( (ULONG_PTR) primaryRequestInfo, 0x3 ))								&&
					 primaryRequestInfo->PrimaryTag == 0xe2027482) {										

					validPrimaryRequest = TRUE;
				}
					
				if (validPrimaryRequest) {
						
					//ASSERT( FatIsTopLevelRequest(IrpContext) );

					IoSetTopLevelIrp( NULL );
					TopLevel = FatIsIrpTopLevel( Irp );
					ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL );

					if (IsListEmpty(&VolumeDeviceObject->PrimarySessionQueue)) {

						NDASFAT_ASSERT( FALSE );
					}

					IrpContext->PrimaryRequestInfo = *primaryRequestInfo;

					DebugTrace2( 0, Dbg, ("primaryRequestInfo = %p\n", primaryRequestInfo) );
				}
			} 
#endif
			}

#if __NDAS_FAT_SECONDARY__

			if (IS_SECONDARY_FILEOBJECT(IoGetCurrentIrpStackLocation(Irp)->FileObject)) {

				BOOLEAN	secondaryResourceAcquired = FALSE;
				BOOLEAN secondaryRecoveryResourceAcquired = FALSE;

				ASSERT( FatIsTopLevelRequest(IrpContext) );

				SetFlag( IrpContext->NdasFatFlags, NDAS_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT );

				Status = STATUS_SUCCESS;

				while (TRUE) {
										
					ASSERT( secondaryRecoveryResourceAcquired == FALSE );
					ASSERT( secondaryResourceAcquired == FALSE );

					if (FlagOn(VolumeDeviceObject->Secondary->Flags, SECONDARY_FLAG_RECONNECTING)) {
		
						if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)) {

							Status = FatFsdPostRequest( IrpContext, Irp );
							break;
						}
					}
					
					if (FlagOn(VolumeDeviceObject->Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED)) {

						if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)) {

							Status = FatFsdPostRequest( IrpContext, Irp );
							break;
						}

						secondaryRecoveryResourceAcquired 
							= SecondaryAcquireResourceExclusiveLite( IrpContext, 
																	 &VolumeDeviceObject->RecoveryResource, 
																	 BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
								
						if (!FlagOn(VolumeDeviceObject->Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED) ) {

							SecondaryReleaseResourceLite( IrpContext, &VolumeDeviceObject->RecoveryResource );
							secondaryRecoveryResourceAcquired = FALSE;
							continue;
						}

						secondaryResourceAcquired 
							= SecondaryAcquireResourceExclusiveLite( IrpContext, 
																	 &VolumeDeviceObject->Resource, 
																	 BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
						try {
								
							SecondaryRecoverySessionStart( VolumeDeviceObject->Secondary, IrpContext );
								
						} finally {

							SecondaryReleaseResourceLite( IrpContext, &VolumeDeviceObject->Resource );
							secondaryResourceAcquired = FALSE;

							SecondaryReleaseResourceLite( IrpContext, &VolumeDeviceObject->RecoveryResource );
							secondaryRecoveryResourceAcquired = FALSE;
						}

						continue;
					}

					secondaryResourceAcquired 
						= SecondaryAcquireResourceSharedLite( IrpContext, 
															  &VolumeDeviceObject->Resource, 
															  BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );

					if (secondaryResourceAcquired == FALSE) {

						ASSERT( FlagOn(VolumeDeviceObject->Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED) ||
								FlagOn(VolumeDeviceObject->Secondary->Flags, SECONDARY_FLAG_RECONNECTING) );
						continue;
					}

					break;
				}

				if (Status == STATUS_SUCCESS) {
					
					try {

						Status = FatCommonCleanup( IrpContext, Irp );
							
					} finally {

						ASSERT( ExIsResourceAcquiredSharedLite(&VolumeDeviceObject->Resource) );
						SecondaryReleaseResourceLite( NULL, &VolumeDeviceObject->Resource );
					}
				}

			} else
				Status = FatCommonCleanup( IrpContext, Irp );
#else
	        Status = FatCommonCleanup( IrpContext, Irp );
#endif

	    } except(FatExceptionFilter( IrpContext, GetExceptionInformation() )) {

		    //
			//  We had some trouble trying to perform the requested
	        //  operation, so we'll abort the I/O request with
		    //  the error status that we get back from the
			//  execption code
			//

	        Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
		}

	} while (Status == STATUS_CANT_WAIT);
Exemple #24
0
VOID
ReadonlyThreadProc (
	IN	PREADONLY	Readonly
	)
{
	BOOLEAN		readonlyThreadTerminate = FALSE;
	PLIST_ENTRY	readonlyRequestEntry;

	
	SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE, ("ReadonlyThreadProc: Start Readonly = %p\n", Readonly) );
	
	Readonly_Reference( Readonly );
	
	Readonly->Thread.Flags = READONLY_THREAD_FLAG_INITIALIZING;

	ExAcquireFastMutex( &Readonly->FastMutex );		
	SetFlag( Readonly->Thread.Flags, READONLY_THREAD_FLAG_START );
	ClearFlag( Readonly->Thread.Flags, READONLY_THREAD_FLAG_INITIALIZING );
	ExReleaseFastMutex( &Readonly->FastMutex );
			
	KeSetEvent( &Readonly->ReadyEvent, IO_DISK_INCREMENT, FALSE );

	readonlyThreadTerminate = FALSE;
	
	while (readonlyThreadTerminate == FALSE) {

		PKEVENT			events[2];
		LONG			eventCount;
		NTSTATUS		eventStatus;
		LARGE_INTEGER	timeOut;
		

		ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

		eventCount = 0;
		events[eventCount++] = &Readonly->RequestEvent;

		timeOut.QuadPart = -LFS_READONLY_THREAD_FLAG_TIME_OUT;

		eventStatus = KeWaitForMultipleObjects(	eventCount,
												events,
												WaitAny,
												Executive,
												KernelMode,
												TRUE,
												&timeOut,
												NULL );

		if (eventStatus == STATUS_TIMEOUT) {

			ReadonlyTryCloseCcb( Readonly );
			ReadonlyDismountVolumeStart( Readonly );
			continue;
		}

		ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
		ASSERT( eventCount < THREAD_WAIT_OBJECTS );
		
		if (!NT_SUCCESS( eventStatus ) || eventStatus >= eventCount) {

			ASSERT( LFS_UNEXPECTED );
			SetFlag( Readonly->Thread.Flags, READONLY_THREAD_FLAG_ERROR );
			readonlyThreadTerminate = TRUE;
			continue;
		}
		
		KeClearEvent( events[eventStatus] );

		if (eventStatus == 0) {

			while (!FlagOn(Readonly->Thread.Flags, READONLY_THREAD_FLAG_STOPED) && 
				   (readonlyRequestEntry = ExInterlockedRemoveHeadList(&Readonly->RequestQueue,
																	    &Readonly->RequestQSpinLock))) {

				PREADONLY_REQUEST	readonlyRequest;


				InitializeListHead( readonlyRequestEntry );

				readonlyRequest = CONTAINING_RECORD( readonlyRequestEntry,
													  READONLY_REQUEST,
													  ListEntry );

				if (!(readonlyRequest->RequestType == READONLY_REQ_DISCONNECT ||
					  readonlyRequest->RequestType == READONLY_REQ_DOWN		  ||
					  readonlyRequest->RequestType == READONLY_REQ_SEND_MESSAGE)) {

					ASSERT( FALSE );

					ExAcquireFastMutex( &Readonly->FastMutex );
					SetFlag( Readonly->Thread.Flags, READONLY_THREAD_FLAG_STOPED | READONLY_THREAD_FLAG_ERROR );
					ExReleaseFastMutex( &Readonly->FastMutex );

					ExInterlockedInsertHeadList( &Readonly->RequestQueue,
												 &readonlyRequest->ListEntry,
												 &Readonly->RequestQSpinLock );

					readonlyThreadTerminate = TRUE;
					break;
				}

				if (readonlyRequest->RequestType == READONLY_REQ_DISCONNECT) {
				
					if (readonlyRequest->Synchronous == TRUE)
						KeSetEvent(&readonlyRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE);
					else
						DereferenceReadonlyRequest( readonlyRequest );

					continue;
				}

				if (readonlyRequest->RequestType == READONLY_REQ_DOWN) {

					SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE, ("ReadonlyThread READONLY_REQ_DOWN Readonly = %p\n", Readonly) );

					ExAcquireFastMutex( &Readonly->FastMutex );		
					SetFlag( Readonly->Thread.Flags, READONLY_THREAD_FLAG_STOPED );
					ExReleaseFastMutex( &Readonly->FastMutex );

					ASSERT( IsListEmpty(&Readonly->RequestQueue) );

					if (readonlyRequest->Synchronous == TRUE)
						KeSetEvent( &readonlyRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE );
					else
						DereferenceReadonlyRequest( readonlyRequest );

					readonlyThreadTerminate = TRUE;
					break;
				}

				ASSERT( readonlyRequest->RequestType == READONLY_REQ_SEND_MESSAGE );
				ASSERT( readonlyRequest->Synchronous == TRUE );

			} // while 
		
		} else {

			NDAS_ASSERT( FALSE );
		}
	}

	ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

	ExAcquireFastMutex( &Readonly->FastMutex );

	SetFlag( Readonly->Thread.Flags, READONLY_THREAD_FLAG_STOPED );

	while (readonlyRequestEntry = ExInterlockedRemoveHeadList(&Readonly->RequestQueue,
															   &Readonly->RequestQSpinLock)) {

		PREADONLY_REQUEST readonlyRequest;

		InitializeListHead( readonlyRequestEntry );
			
		readonlyRequest = CONTAINING_RECORD( readonlyRequestEntry,
											  READONLY_REQUEST,
											  ListEntry );
        
		readonlyRequest->ExecuteStatus = STATUS_IO_DEVICE_ERROR;
		
		if (readonlyRequest->Synchronous == TRUE)
			KeSetEvent( &readonlyRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE );
		else
			DereferenceReadonlyRequest( readonlyRequest );
	}

	ExReleaseFastMutex( &Readonly->FastMutex );

	SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE,
				   ("ReadonlyThreadProc: PsTerminateSystemThread Readonly = %p, IsListEmpty(&Readonly->RequestQueue) = %d\n", 
				     Readonly, IsListEmpty(&Readonly->RequestQueue)) );
	
	ExAcquireFastMutex( &Readonly->FastMutex );
	SetFlag( Readonly->Thread.Flags, READONLY_THREAD_FLAG_TERMINATED );
	ExReleaseFastMutex( &Readonly->FastMutex );
	
	Readonly_Dereference( Readonly );

	ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
	
	PsTerminateSystemThread( STATUS_SUCCESS );
}
Exemple #25
0
VOID
VolDoThreadProc (
	IN	PVOLUME_DEVICE_OBJECT	VolDo
	)
{
	BOOLEAN		volDoThreadTerminate = FALSE;


	DebugTrace( 0, Dbg2, ("VolDoThreadProc: Start VolDo = %p\n", VolDo) );
	
	VolDo_Reference( VolDo );
	
	VolDo->Thread.Flags = VOLDO_THREAD_FLAG_INITIALIZING;

	ExAcquireFastMutex( &VolDo->FastMutex );		
	ClearFlag( VolDo->Thread.Flags, VOLDO_THREAD_FLAG_INITIALIZING );
	SetFlag( VolDo->Thread.Flags, VOLDO_THREAD_FLAG_START );
	ExReleaseFastMutex( &VolDo->FastMutex );
			
	KeSetEvent( &VolDo->ReadyEvent, IO_DISK_INCREMENT, FALSE );

	volDoThreadTerminate = FALSE;
	
	while (volDoThreadTerminate == FALSE) {

		PKEVENT			events[2];
		LONG			eventCount;
		NTSTATUS		eventStatus;
		LARGE_INTEGER	timeOut;
		

		ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

		eventCount = 0;
		events[eventCount++] = &VolDo->RequestEvent;

		timeOut.QuadPart = -NDNTFS_VOLDO_THREAD_FLAG_TIME_OUT;

		eventStatus = KeWaitForMultipleObjects(	eventCount,
												events,
												WaitAny,
												Executive,
												KernelMode,
												TRUE,
												&timeOut,
												NULL );


		if (eventStatus == STATUS_TIMEOUT) {

			LARGE_INTEGER	currentTime;

			KeQuerySystemTime( &currentTime );

			if (FlagOn(VolDo->NdasNtfsFlags, NDAS_NTFS_DEVICE_FLAG_SHUTDOWN) || 
				!(FlagOn(VolDo->NdasNtfsFlags, NDAS_NTFS_DEVICE_FLAG_MOUNTED) /*&& !FlagOn(LfsDeviceExt->Flags, LFS_DEVICE_STOP)*/)) {
				
				continue;
			}

			if ((VolDo->NetdiskEnableMode == NETDISK_READ_ONLY && 
				 (VolDo->TryFlushOrPurgeTime.QuadPart > currentTime.QuadPart || 
				 (currentTime.QuadPart - VolDo->TryFlushOrPurgeTime.QuadPart) >= NDNTFS_TRY_PURGE_DURATION)) ||

			    (VolDo->ReceiveWriteCommand == TRUE && 
				 (VolDo->TryFlushOrPurgeTime.QuadPart > currentTime.QuadPart || 
				 (currentTime.QuadPart - VolDo->TryFlushOrPurgeTime.QuadPart) >= NDNTFS_TRY_FLUSH_DURATION))) {

				if (VolDo->NetdiskEnableMode != NETDISK_READ_ONLY && 
					(currentTime.QuadPart - VolDo->CommandReceiveTime.QuadPart) <=  NDNTFS_TRY_FLUSH_DURATION /*&& 
					(currentTime.QuadPart - VolDo->TryFlushOrPurgeTime.QuadPart) <= (100*NDFAT_TRY_FLUSH_OR_PURGE_DURATION)*/) {

					continue;
				}

				do {
				
					HANDLE					eventHandle = NULL;

					HANDLE					fileHandle = NULL;
					ACCESS_MASK				desiredAccess;
					ULONG					attributes;
					OBJECT_ATTRIBUTES		objectAttributes;
					IO_STATUS_BLOCK			ioStatusBlock;
					LARGE_INTEGER			allocationSize;
					ULONG					fileAttributes;
					ULONG					shareAccess;
				    ULONG					createDisposition;
					ULONG					createOptions;
				    PVOID					eaBuffer;
					ULONG					eaLength;

					NTSTATUS				createStatus;
					NTSTATUS				fileSystemControlStatus;

					PIRP					topLevelIrp;
					PRIMARY_REQUEST_INFO	primaryRequestInfo;


					ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

					if (VolDo->NetdiskEnableMode == NETDISK_SECONDARY)
						break;

					DebugTrace( 0, Dbg2, ("VolDoThreadProc: VolDo = %p, VolDo->NetdiskPartitionInformation.VolumeName = %wZ\n", 
											VolDo, &VolDo->NetdiskPartitionInformation.VolumeName) );

					desiredAccess = SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES | FILE_WRITE_EA 
									| FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_READ_EA;

					ASSERT( desiredAccess == 0x0012019F );

					attributes  = OBJ_KERNEL_HANDLE;
					attributes |= OBJ_CASE_INSENSITIVE;

					InitializeObjectAttributes( &objectAttributes,
											    &VolDo->NetdiskPartitionInformation.VolumeName,
												attributes,
												NULL,
												NULL );
		
					allocationSize.LowPart  = 0;
					allocationSize.HighPart = 0;

					fileAttributes	  = 0;		
					shareAccess		  = FILE_SHARE_READ | FILE_SHARE_WRITE;
					createDisposition = FILE_OPEN;
					createOptions     = FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE;
					eaBuffer		  = NULL;
					eaLength		  = 0;

					RtlZeroMemory( &ioStatusBlock, sizeof(ioStatusBlock) );

					createStatus = ZwCreateFile( &fileHandle,
												 desiredAccess,
												 &objectAttributes,
												 &ioStatusBlock,
												 &allocationSize,
												 fileAttributes,
												 shareAccess,
												 createDisposition,
												 createOptions,
												 eaBuffer,
												 eaLength );

					if (createStatus != STATUS_SUCCESS) 
						break;
						
					ASSERT( ioStatusBlock.Information == FILE_OPENED);
	
					createStatus = ZwCreateEvent( &eventHandle,
												  GENERIC_READ,
												  NULL,
												  SynchronizationEvent,
												  FALSE );

					if (createStatus != STATUS_SUCCESS) {

						ASSERT( NDASNTFS_UNEXPECTED );
						ZwClose( fileHandle );
						break;
					}

					primaryRequestInfo.PrimaryTag				= 0xe2027482;
					primaryRequestInfo.PrimarySession			= NULL;
					primaryRequestInfo.NdfsWinxpRequestHeader	= NULL;

					topLevelIrp = IoGetTopLevelIrp();
					ASSERT( topLevelIrp == NULL );
					IoSetTopLevelIrp( (PIRP)&primaryRequestInfo );

					RtlZeroMemory( &ioStatusBlock, sizeof(ioStatusBlock) );

					fileSystemControlStatus = ZwFsControlFile( fileHandle,
															   NULL, //&eventHandle,
															   NULL,
															   NULL,
															   &ioStatusBlock,
															   FSCTL_NDAS_FS_FLUSH_OR_PURGE,
															   NULL,
															   0,
															   NULL,
															   0 );

					DebugTrace( 0, Dbg, ("VolDoThreadProc: VolDo = %p, createStatus = %x, ioStatusBlock = %x\n", 
											VolDo, fileSystemControlStatus, ioStatusBlock.Information) );

					if (fileSystemControlStatus == STATUS_PENDING) {
			
						LARGE_INTEGER			timeOut;
			
						timeOut.QuadPart = -3*NANO100_PER_SEC;

						ASSERT( FALSE );
						//fileSystemControlStatus = ZwWaitForSingleObject( eventHandle, TRUE,NULL /*, &timeOut*/ );
					}

					IoSetTopLevelIrp( topLevelIrp );

					if (fileSystemControlStatus != STATUS_SUCCESS)
						DebugTrace( 0, Dbg2, ("VolDoThreadProc: VolDo = %p, fileSystemControlStatus = %x, ioStatusBlock = %x\n", 
												VolDo, fileSystemControlStatus, ioStatusBlock.Information) );

					ZwClose( eventHandle );
					ZwClose( fileHandle );
					
					break;
				
				} while (0);

				KeQuerySystemTime( &VolDo->TryFlushOrPurgeTime );
				VolDo->ReceiveWriteCommand = FALSE;
			}

			continue;
		}
		
		ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
		ASSERT( eventCount < THREAD_WAIT_OBJECTS );
		
		if (!NT_SUCCESS( eventStatus ) || eventStatus >= eventCount) {

			ASSERT( NDASNTFS_UNEXPECTED );
			SetFlag( VolDo->Thread.Flags, VOLDO_THREAD_FLAG_ERROR );
			volDoThreadTerminate = TRUE;
			continue;
		}
		
		KeClearEvent( events[eventStatus] );

		if (eventStatus == 0) {

			volDoThreadTerminate = TRUE;
			break;
		
		} else {

			NDAS_BUGON( NDASNTFS_BUG );
		}
	}

	ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

	ExAcquireFastMutex( &VolDo->FastMutex );

	SetFlag( VolDo->Thread.Flags, VOLDO_THREAD_FLAG_STOPED );

	ExReleaseFastMutex( &VolDo->FastMutex );

	DebugTrace( 0, Dbg2, ("VolDoThreadProc: PsTerminateSystemThread VolDo = %p\n", VolDo) );
	
	ExAcquireFastMutex( &VolDo->FastMutex );
	SetFlag( VolDo->Thread.Flags, VOLDO_THREAD_FLAG_TERMINATED );
	ExReleaseFastMutex( &VolDo->FastMutex );
	
	VolDo_Dereference( VolDo );

	ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
	
	PsTerminateSystemThread( STATUS_SUCCESS );
}
Exemple #26
0
PREADONLY
Readonly_Create (
	IN	PLFS_DEVICE_EXTENSION	LfsDeviceExt
	)
{
	NTSTATUS				status;
	PREADONLY				readonly;

	OBJECT_ATTRIBUTES		objectAttributes;
	LARGE_INTEGER			timeOut;
	

	readonly = ExAllocatePoolWithTag( NonPagedPool, sizeof(READONLY), LFS_ALLOC_TAG );
	
	if (readonly == NULL) {

		NDAS_ASSERT( NDAS_ASSERT_INSUFFICIENT_RESOURCES );
		return NULL;
	}
	
	RtlZeroMemory( readonly, sizeof(READONLY) );

	readonly->Flags = READONLY_FLAG_INITIALIZING;

#if 0
	ExInitializeResourceLite( &readonly->RecoveryResource );
	ExInitializeResourceLite( &readonly->Resource );
	ExInitializeResourceLite( &readonly->SessionResource );
	ExInitializeResourceLite( &readonly->CreateResource );
#endif

	ExInitializeFastMutex( &readonly->FastMutex );

	readonly->ReferenceCount = 1;

	LfsDeviceExt_Reference( LfsDeviceExt );
	readonly->LfsDeviceExt = LfsDeviceExt;

	readonly->ThreadHandle = NULL;

	InitializeListHead( &readonly->FcbQueue );
	KeInitializeSpinLock( &readonly->FcbQSpinLock );

	InitializeListHead( &readonly->CcbQueue );
    ExInitializeFastMutex( &readonly->CcbQMutex );

#if 0
	InitializeListHead( &readonly->RecoveryCcbQueue );
    ExInitializeFastMutex( &readonly->RecoveryCcbQMutex );

	InitializeListHead( &readonly->DeletedFcbQueue );
#endif

	KeQuerySystemTime( &readonly->TryCloseTime );

#if 0
	readonly->TryCloseWorkItem = IoAllocateWorkItem( (PDEVICE_OBJECT)VolDo );
#endif

	KeInitializeEvent( &readonly->ReadyEvent, NotificationEvent, FALSE );
    
	InitializeListHead( &readonly->RequestQueue );
	KeInitializeSpinLock( &readonly->RequestQSpinLock );
	KeInitializeEvent( &readonly->RequestEvent, NotificationEvent, FALSE );

#if 0
	////////////////////////////////////////
	InitializeListHead( &readonly->FcbQueue );
	ExInitializeFastMutex( &readonly->FcbQMutex );
	/////////////////////////////////////////
#endif

	KeInitializeEvent( &readonly->DiskmountReadyEvent, NotificationEvent, FALSE );

	InitializeListHead( &readonly->DirNotifyList );
	FsRtlNotifyInitializeSync( &readonly->NotifySync );

	InitializeObjectAttributes( &objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL );

	readonly->SessionId = 0;
	
	status = PsCreateSystemThread( &readonly->ThreadHandle,
								   THREAD_ALL_ACCESS,
								   &objectAttributes,
								   NULL,
								   NULL,
								   ReadonlyThreadProc,
								   readonly );

	if (!NT_SUCCESS(status)) {

		ASSERT( LFS_UNEXPECTED );
		Readonly_Close( readonly );
		
		return NULL;
	}

	status = ObReferenceObjectByHandle( readonly->ThreadHandle,
										FILE_READ_DATA,
										NULL,
										KernelMode,
										&readonly->ThreadObject,
										NULL );

	if (!NT_SUCCESS(status)) {

		NDAS_ASSERT( NDAS_ASSERT_INSUFFICIENT_RESOURCES );
		Readonly_Close( readonly );
		
		return NULL;
	}

	readonly->SessionId ++;

	timeOut.QuadPart = -LFS_TIME_OUT;		
	status = KeWaitForSingleObject( &readonly->ReadyEvent,
									Executive,
									KernelMode,
									FALSE,
									&timeOut );

	if (status != STATUS_SUCCESS) {
	
		NDAS_ASSERT( FALSE );
		Readonly_Close( readonly );
		
		return NULL;
	}

	KeClearEvent( &readonly->ReadyEvent );

	ExAcquireFastMutex( &readonly->FastMutex );

	if (!FlagOn(readonly->Thread.Flags, READONLY_THREAD_FLAG_START) ||
		FlagOn(readonly->Thread.Flags, READONLY_THREAD_FLAG_STOPED)) {

		if (readonly->Thread.SessionStatus != STATUS_DISK_CORRUPT_ERROR &&
			readonly->Thread.SessionStatus != STATUS_UNRECOGNIZED_VOLUME) {
	
			ExReleaseFastMutex( &readonly->FastMutex );

			Readonly_Close( readonly );
			return NULL;
		}
	} 

	ExReleaseFastMutex( &readonly->FastMutex );

	ClearFlag( readonly->Flags, READONLY_FLAG_INITIALIZING );
	SetFlag( readonly->Flags, READONLY_FLAG_START );

	SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE,
				("Readonly_Create: The client thread are ready readonly = %p\n", readonly) );

	return readonly;
}
Exemple #27
0
VOID
FatFspDispatch (
    IN PVOID Context
    )

/*++

Routine Description:

    This is the main FSP thread routine that is executed to receive
    and dispatch IRP requests.  Each FSP thread begins its execution here.
    There is one thread created at system initialization time and subsequent
    threads created as needed.

Arguments:


    Context - Supplies the thread id.

Return Value:

    None - This routine never exits

--*/

{
    NTSTATUS Status;

    PIRP Irp;
    PIRP_CONTEXT IrpContext;
    PIO_STACK_LOCATION IrpSp;
    BOOLEAN VcbDeleted;

    PVOLUME_DEVICE_OBJECT VolDo;

    PAGED_CODE();

    IrpContext = (PIRP_CONTEXT)Context;

    Irp = IrpContext->OriginatingIrp;

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    //
    //  Now because we are the Fsp we will force the IrpContext to
    //  indicate true on Wait.
    //

    SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT | IRP_CONTEXT_FLAG_IN_FSP);

    //
    //  If this request has an associated volume device object, remember it.
    //

    if ( IrpSp->FileObject != NULL ) {

        VolDo = CONTAINING_RECORD( IrpSp->DeviceObject,
                                   VOLUME_DEVICE_OBJECT,
                                   DeviceObject );
    } else {

        VolDo = NULL;
    }

    //
    //  Now case on the function code.  For each major function code,
    //  either call the appropriate FSP routine or case on the minor
    //  function and then call the FSP routine.  The FSP routine that
    //  we call is responsible for completing the IRP, and not us.
    //  That way the routine can complete the IRP and then continue
    //  post processing as required.  For example, a read can be
    //  satisfied right away and then read can be done.
    //
    //  We'll do all of the work within an exception handler that
    //  will be invoked if ever some underlying operation gets into
    //  trouble (e.g., if FatReadSectorsSync has trouble).
    //

    while ( TRUE ) {

        DebugTrace(0, Dbg, "FatFspDispatch: Irp = 0x%08lx\n", Irp);

        //
        //  If this Irp was top level, note it in our thread local storage.
        //

        FsRtlEnterFileSystem();

        if ( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL) ) {

            IoSetTopLevelIrp( (PIRP)FSRTL_FSP_TOP_LEVEL_IRP );

        } else {

            IoSetTopLevelIrp( Irp );
        }

#if __NDAS_FAT__

		do {

#if __NDAS_FAT_SECONDARY__

			BOOLEAN	volDoResourceAcquired = FALSE;

#endif

			try {

#if __NDAS_FAT_SECONDARY__

				Status = STATUS_SUCCESS;

				if (Irp && IS_SECONDARY_FILEOBJECT(IoGetCurrentIrpStackLocation(Irp)->FileObject)) {

					BOOLEAN volDoRecoveryResourceAcquired = FALSE;

					ASSERT( FatIsTopLevelRequest(IrpContext) );

					ASSERT( FlagOn(IrpContext->NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT) );

					while (TRUE) {
			
						ASSERT( volDoRecoveryResourceAcquired == FALSE );
						ASSERT( volDoResourceAcquired == FALSE );

						if (FlagOn(VolDo->Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED)) {
		
							volDoRecoveryResourceAcquired 
								= SecondaryAcquireResourceExclusiveLite( IrpContext, 
																		 &VolDo->Secondary->RecoveryResource, 
																		 BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
								
							if (!FlagOn(VolDo->Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_REMOTE_DISCONNECTED) ) {

								SecondaryReleaseResourceLite( IrpContext, &VolDo->Secondary->RecoveryResource );
								volDoRecoveryResourceAcquired = FALSE;
								continue;
							}

							volDoResourceAcquired 
								= SecondaryAcquireResourceExclusiveLite( IrpContext, 
																		 &VolDo->Secondary->Resource, 
																		 BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
							try {
								
								SecondaryRecoverySessionStart( VolDo->Secondary, IrpContext );
								
							} finally {

								SecondaryReleaseResourceLite( IrpContext, &VolDo->Secondary->Resource );
								volDoResourceAcquired = FALSE;

								SecondaryReleaseResourceLite( IrpContext, &VolDo->Secondary->RecoveryResource );
								volDoRecoveryResourceAcquired = FALSE;
							}

							continue;
						}

						volDoResourceAcquired 
							= SecondaryAcquireResourceSharedLite( IrpContext, 
																  &VolDo->Secondary->Resource, 
																  BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );

						ASSERT( volDoResourceAcquired == TRUE );

						break;
					}
				}
#endif

	            switch ( IrpContext->MajorFunction ) {

		            //
			        //  For Create Operation,
				    //

					case IRP_MJ_CREATE:

						(VOID) FatCommonCreate( IrpContext, Irp );
	                    break;

		            //
			        //  For close operations.  We do a little kludge here in case
				    //  this close causes a volume to go away.  It will NULL the
					//  VolDo local variable so that we will not try to look at
	                //  the overflow queue.
		            //

	                case IRP_MJ_CLOSE:

		            {
			            PVCB Vcb;
				        PFCB Fcb;
					    PCCB Ccb;
						TYPE_OF_OPEN TypeOfOpen;

	                    //
		                //  Extract and decode the file object
			            //

				        TypeOfOpen = FatDecodeFileObject( IrpSp->FileObject, &Vcb, &Fcb, &Ccb );

					    //
						//  Do the close.  We have a slightly different format
	                    //  for this call because of the async closes.
		                //

			            Status = FatCommonClose( Vcb,
				                                 Fcb,
					                             Ccb,
						                         TypeOfOpen,
							                     TRUE,
								                 &VcbDeleted );

	                    //
		                //  If the VCB was deleted, do not try to access it later.
			            //

				        if (VcbDeleted) {

					        VolDo = NULL;
						}

	                    ASSERT(Status == STATUS_SUCCESS);

		                FatCompleteRequest( IrpContext, Irp, Status );

			            break;
				    }

	                //
		            //  For read operations
			        //

				    case IRP_MJ_READ:

					    (VOID) FatCommonRead( IrpContext, Irp );
						break;

	                //
		            //  For write operations,
			        //

				    case IRP_MJ_WRITE:

					    (VOID) FatCommonWrite( IrpContext, Irp );
						break;

	                //
		            //  For Query Information operations,
			        //

				    case IRP_MJ_QUERY_INFORMATION:

					    (VOID) FatCommonQueryInformation( IrpContext, Irp );
						break;

	                //
		            //  For Set Information operations,
			        //

				    case IRP_MJ_SET_INFORMATION:

					    (VOID) FatCommonSetInformation( IrpContext, Irp );
						break;

	                //
		            //  For Query EA operations,
			        //

				    case IRP_MJ_QUERY_EA:

					    (VOID) FatCommonQueryEa( IrpContext, Irp );
						break;

	                //
		            //  For Set EA operations,
			        //

				    case IRP_MJ_SET_EA:

					    (VOID) FatCommonSetEa( IrpContext, Irp );
						break;

	                //
		            //  For Flush buffers operations,
			        //

				    case IRP_MJ_FLUSH_BUFFERS:

					    (VOID) FatCommonFlushBuffers( IrpContext, Irp );
						break;

	                //
		            //  For Query Volume Information operations,
			        //

				    case IRP_MJ_QUERY_VOLUME_INFORMATION:

					    (VOID) FatCommonQueryVolumeInfo( IrpContext, Irp );
						break;

	                //
		            //  For Set Volume Information operations,
			        //

				    case IRP_MJ_SET_VOLUME_INFORMATION:

					    (VOID) FatCommonSetVolumeInfo( IrpContext, Irp );
						break;

	                //
		            //  For File Cleanup operations,
			        //

				    case IRP_MJ_CLEANUP:

					    (VOID) FatCommonCleanup( IrpContext, Irp );
						break;

	                //
		            //  For Directory Control operations,
			        //

				    case IRP_MJ_DIRECTORY_CONTROL:

					    (VOID) FatCommonDirectoryControl( IrpContext, Irp );
						break;

	                //
		            //  For File System Control operations,
			        //

				    case IRP_MJ_FILE_SYSTEM_CONTROL:

					    (VOID) FatCommonFileSystemControl( IrpContext, Irp );
						break;

	                //
		            //  For Lock Control operations,
			        //

				    case IRP_MJ_LOCK_CONTROL:

					    (VOID) FatCommonLockControl( IrpContext, Irp );
						break;

	                //
		            //  For Device Control operations,
			        //

				    case IRP_MJ_DEVICE_CONTROL:

					    (VOID) FatCommonDeviceControl( IrpContext, Irp );
						break;

	                //
		            //  For the Shutdown operation,
			        //

				    case IRP_MJ_SHUTDOWN:

					    (VOID) FatCommonShutdown( IrpContext, Irp );
						break;

	                //
		            //  For plug and play operations.
			        //

				    case IRP_MJ_PNP:

					    //
						//  I don't believe this should ever occur, but allow for the unexpected.
	                    //

		                (VOID) FatCommonPnp( IrpContext, Irp );
			            break;

				    //
					//  For any other major operations, return an invalid
	                //  request.
		            //

			        default:

				        FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST );
					    break;

				}

#if __NDAS_FAT_SECONDARY__

				if (volDoResourceAcquired) {

					SecondaryReleaseResourceLite( NULL, &VolDo->Secondary->Resource );
					volDoResourceAcquired = FALSE;
				}
#endif


	        } except(FatExceptionFilter( IrpContext, GetExceptionInformation() )) {

#if __NDAS_FAT_SECONDARY__

				if (volDoResourceAcquired) {

					SecondaryReleaseResourceLite( NULL, &VolDo->Secondary->Resource );
					volDoResourceAcquired = FALSE;
				}
#endif
				
				//
			    //  We had some trouble trying to perform the requested
				//  operation, so we'll abort the I/O request with
	            //  the error status that we get back from the
		        //  execption code.
			    //

				Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
			}
		
		} while (Status == STATUS_CANT_WAIT);
Exemple #28
0
//
//	Initialize instance from a VMware 4.x descriptor file
//
VDKSTAT VDiskVmdk::Initialize(PCHAR pPath)
{
	VDiskFile file;
	CHAR	buf[MAX_PATH + 40];
	CHAR	path[MAX_PATH];
	PVOID	cbparams[2];
	PCHAR	current;
	ULONG	signature;
	ULONG_PTR len;
	VDKSTAT	ret;

	//
	//	parameter check
	//
	if (!pPath || !*pPath) {
		return VDK_PARAM;
	}

	//
	//	store path
	//
	if ((ret = StorePath(pPath)) != VDK_OK) {
		return ret;
	}

	//
	//	open file
	//
	if ((ret = file.Open(pPath)) != VDK_OK) {
		return ret;
	}

	//
	//	initialize members
	//
	cbparams[0] = pPath;

	//
	//	read first 4 bytes
	//
	signature = 0;

	ret = file.ReadByte((PUCHAR)&signature, sizeof(signature), &len);

	if (ret != VDK_OK) {
		return ret;
	}

	if (len != sizeof(signature)) {
		return VDK_EOF;
	}

	if (signature == VMDK_SIGNATURE) {
		//
		//	it's a monolithic sparse file
		//	-- descriptor offset is stored in header
		//
		VMDK_HEADER vmdk;

		ret = file.ReadByte((PUCHAR)&vmdk + sizeof(signature), 
			sizeof(vmdk) - sizeof(signature), &len);

		if (ret != VDK_OK) {
			return ret;
		}

		if (len != sizeof(vmdk) - sizeof(signature)) {
			return VDK_DATA;
		}

		if (vmdk.DescOffsetLow == 0		||
			vmdk.DescOffsetHigh != 0	||
			vmdk.DescSizeLow == 0		||
			vmdk.DescSizeHigh != 0) {

			VDiskCallBack(VDISK_CB_VMDK_NODESC, cbparams);

			return VDK_DATA;
		}

		ret = VdkSeekFile(file.Handle(),
			vmdk.DescOffsetLow << VDK_BYTE_SHIFT_TO_SECTOR);

		if (ret != VDK_OK) {
			return ret;
		}
	}
	else {
		ret = VdkSeekFile(file.Handle(), 0);

		if (ret != VDK_OK) {
			return ret;
		}
	}

	while ((ret = file.ReadText(buf, sizeof(buf), NULL)) == VDK_OK) {

		//
		//	replace tabs with blanks
		//
		current = buf;

		while (*current) {
			if (*current == '\t' || *current == '\n') {
				*current = ' ';
			}
			current++;
		}

		//
		//	remove trailing blanks
		//
		while (current > buf && *(--current) == ' ') {
			*current = '\0';
		}

		//
		//	skip leading blanks
		//
		current = buf;

		while (*current == ' ') {
			current++;
		}

		//
		//	blank line?
		//
		if (!*current) {
			continue;
		}

		cbparams[1] = current;

		//
		//	parse current line
		//
		if (!VdkCmpNoCaseN(current, "RW ", 3) ||
			!VdkCmpNoCaseN(current, "RDONLY", 6)) {
			VDiskExt	*ext;
			PCHAR		top, tail, p;
			ULONG		capacity;
			CHAR		delim;
			BOOL		sparse;
			ULONG		offset;
			HANDLE		hFile;

			//
			//	search capacity field
			//
			p = current + 3;

			while (*p == ' ') {
				p++;
			}

			capacity = atol(p);

			if (!capacity) {

				capacity = VDiskCallBack(
					VDISK_CB_DESC_CAPACITY, cbparams);

				if (!capacity) {
					return VDK_DATA;
				}

				SetFlag(VDISK_FLAG_DIRTY);
			}

			//
			//	search extent type field
			//
			while (isdigit(*p)) {
				p++;
			}

			while (*p == ' ') {
				p++;
			}

			if (!VdkCmpNoCaseN(p, "flat ", 5)) {
				sparse = FALSE;
			}
			else if (!VdkCmpNoCaseN(p, "sparse ", 7)) {
				sparse = TRUE;
			}
			else {

				ULONG type = VDiskCallBack(
					VDISK_CB_DESC_FILETYPE, cbparams);

				if (type == VDK_FILETYPE_FLAT) {
					sparse = FALSE;
				}
				else if (type == VDK_FILETYPE_VMDK) {
					sparse = TRUE;
				}
				else {
					return VDK_DATA;
				}

				SetFlag(VDISK_FLAG_DIRTY);
			}

			//
			//	search extent path field
			//
			top = p;

			while (*top && *top != ' ') {
				top++;
			}

			while (*top == ' ') {
				top++;
			}

			if (*top == '\"') {
				delim = '\"';
				top++;
			}
			else {
				delim = ' ';
			}

			tail = top;

			while (*tail && *tail != delim) {
				tail++;
			}

			if (!*tail || tail - top >= MAX_PATH) {

				if (!VDiskCallBack(VDISK_CB_DESC_BADENTRY, cbparams)) {
					return VDK_CANCEL;
				}

				SetFlag(VDISK_FLAG_DIRTY);
				continue;
			}

			if ((isalpha(*top) && *(top + 1) == ':') ||
				*top == PATH_SEPARATOR_CHAR ||
				*top == ALT_SEPARATOR_CHAR) {

				SetFlag(VDISK_FLAG_ABSPATH);
			}
			else {
				ClrFlag(VDISK_FLAG_ABSPATH);
			}

			VdkCopyMem(path, top, tail - top);
			path[tail - top] = '\0';

			if (sparse) {
				offset = 0;
			}
			else {
				//
				//	search "backing offset" field
				//
				p = tail + 1;

				while (*p == ' ') {
					p++;
				}

				if (isdigit(*p)) {
					offset = atol(p);
				}
				else {
					offset = 0;
				}
			}

			//	open the extent file
			*tail = '\0';

			ret = VDiskSearchFile(&hFile, path, m_pPath);

			if (ret != VDK_OK) {
				return ret;
			}

			//
			//	create an extent object
			//
			if (sparse) {
				ext = new VDiskExtVmdk;
			}
			else {
				ext = new VDiskExtRaw;
			}

			if (ext == NULL) {
				ret = VdkLastError();
				VdkCloseFile(hFile);
				return ret;
			}

			ret = AddExtent(ext);

			if (ret != VDK_OK) {
				VdkCloseFile(hFile);
				delete ext;
				return ret;
			}

			ret = ext->SetPath(path);

			if (ret != VDK_OK) {
				VdkCloseFile(hFile);
				return ret;
			}

			ret = ext->Load(hFile);

			VdkCloseFile(hFile);

			if (ret != VDK_OK) {
				return ret;
			}

			ext->SetCapacity(capacity);

			if (!sparse) {
				((VDiskExtRaw *)ext)->SetBackOffset(offset);
			}
		}
		else if (!VdkCmpNoCaseN(current, "ddb.geometry.sectors", 20)) {
			PCHAR p = current + 20;

			while (*p == ' ' || *p == '=' || *p == '\"') {
				p++;
			}

			m_nSectors = atol(p);

			if (!m_nSectors) {

				m_nSectors = VDiskCallBack(
					VDISK_CB_DESC_GEOMETRY, cbparams);

				if (!m_nSectors) {
					return VDK_DATA;
				}

				SetFlag(VDISK_FLAG_DIRTY);
			}
		}
		else if (!VdkCmpNoCaseN(current, "ddb.geometry.heads", 18)) {
			PCHAR p = current + 18;

			while (*p == ' ' || *p == '=' || *p == '\"') {
				p++;
			}

			m_nTracks = atol(p);

			if (!m_nTracks) {

				m_nTracks = VDiskCallBack(
					VDISK_CB_DESC_GEOMETRY, cbparams);

				if (!m_nTracks) {
					return VDK_DATA;
				}

				SetFlag(VDISK_FLAG_DIRTY);
			}
		}
		else if (!VdkCmpNoCaseN(current, "ddb.geometry.cylinders", 22)) {
			PCHAR p = current + 22;

			while (*p == ' ' || *p == '=' || *p == '\"') {
				p++;
			}

			m_nCylinders = atol(p);

			if (!m_nCylinders) {

				m_nCylinders = VDiskCallBack(
					VDISK_CB_DESC_GEOMETRY, cbparams);

				if (!m_nCylinders) {
					return VDK_DATA;
				}

				SetFlag(VDISK_FLAG_DIRTY);
			}
		}
		else if (!VdkCmpNoCaseN(current, "CID", 3)) {
			PCHAR p = current + 3;

			while (*p == ' ' || *p == '=' || *p == '\"') {
				p++;
			}

			if (!sscanf(p, "%lx", &m_nTimeStamp)) {

				if (!VDiskCallBack(VDISK_CB_DESC_TIMESTAMP, cbparams)) {
					return VDK_CANCEL;
				}

				m_nTimeStamp = (ULONG)-1;
				SetFlag(VDISK_FLAG_DIRTY);
			}
		}
		else if (!VdkCmpNoCaseN(current, "parentCID", 9)) {
			PCHAR p = current + 9;

			while (*p == ' ' || *p == '=' || *p == '\"') {
				p++;

			}

			if (!sscanf(p, "%lx", &m_nParentTS)) {

				if (!VDiskCallBack(VDISK_CB_DESC_TIMESTAMP, cbparams)) {
					return VDK_CANCEL;
				}

				m_nParentTS = (ULONG)-1;
				SetFlag(VDISK_FLAG_DIRTY);
			}

			if (m_nParentTS != (ULONG)-1) {
				SetFlag(VDISK_FLAG_CHILD);
			}
		}
		else if (!VdkCmpNoCaseN(current, "ddb.virtualHWVersion", 20)) {
			PCHAR p = current + 20;

			while (*p == ' ' || *p == '=' || *p == '\"') {
				p++;
			}

			m_nHardwareVer = atol(p);
		}
		else if (!VdkCmpNoCaseN(current, "ddb.adapterType", 15)) {
			PCHAR p = current + 15;

			while (*p == ' ' || *p == '=' || *p == '\"') {
				p++;
			}

			if (!VdkCmpNoCaseN(p, "ide", 3)) {
				m_nController = VDISK_CONTROLLER_IDE;
			}
			else if (!VdkCmpNoCaseN(p, "buslogic", 8) ||
				!VdkCmpNoCaseN(p, "lsilogic", 8)) {
				m_nController = VDISK_CONTROLLER_SCSI;
			}
			else {

				m_nController = VDiskCallBack(
					VDISK_CB_CONTROLLER, cbparams);

				if (m_nController != VDISK_CONTROLLER_SCSI &&
					m_nController != VDISK_CONTROLLER_IDE) {
					return VDK_CANCEL;
				}

				SetFlag(VDISK_FLAG_DIRTY);
			}
		}
		else if (!VdkCmpNoCaseN(current, "createType", 10)) {
			PCHAR p = current + 10;
			ULONG type;

			while (*p == ' ' || *p == '=' || *p == '\"') {
				p++;
			}

			if (!VdkCmpNoCaseN(p, "twoGbMaxExtentSparse", 20)) {
				type = VDISK_VMDK_SPLIT_SPARSE;
			}
			else if (!VdkCmpNoCaseN(p, "monolithicSparse", 16)) {
				type = VDISK_VMDK_MONO_SPARSE;
			}
			else if (!VdkCmpNoCaseN(p, "twoGbMaxExtentFlat", 18)) {
				type = VDISK_VMDK_SPLIT_FLAT;
			}
			else if (!VdkCmpNoCaseN(p, "monolithicFlat", 14)) {
				type = VDISK_VMDK_MONO_FLAT;
			}
			else {

				type = VDiskCallBack(
					VDISK_CB_DESC_DISKTYPE, cbparams);

				SetFlag(VDISK_FLAG_DIRTY);
			}

			switch (type) {
			case VDISK_VMDK_SPLIT_FLAT:
				ClrFlag(VDISK_FLAG_SINGLE);
				ClrFlag(VDISK_FLAG_CHILD);
				ClrFlag(VDISK_FLAG_SPARSE);
				break;

			case VDISK_VMDK_MONO_FLAT:
				SetFlag(VDISK_FLAG_SINGLE);
				ClrFlag(VDISK_FLAG_CHILD);
				ClrFlag(VDISK_FLAG_SPARSE);
				break;

			case VDISK_VMDK_SPLIT_SPARSE:
				ClrFlag(VDISK_FLAG_SINGLE);
				SetFlag(VDISK_FLAG_SPARSE);
				break;

			case VDISK_VMDK_MONO_SPARSE:
				SetFlag(VDISK_FLAG_SINGLE);
				SetFlag(VDISK_FLAG_SPARSE);
				break;

			default:
				return VDK_DATA;
			}
		}
		else if (!VdkCmpNoCaseN(current, "version", 7)) {
/*
			PCHAR p = current + 7;

			while (*p == ' ' || *p == '=' || *p == '\"') {
				p++;
			}

			m_nVmdkVersion = atol(p);
*/
		}
		else if (!VdkCmpNoCaseN(current, "parentFileNameHint", 18)) {
			PCHAR top = current + 18;
			PCHAR tail;

			while (*top == ' ' || *top == '=' || *top == '\"') {
				top++;
			}

			tail = top;

			while (*tail && *tail != '\"') {
				tail++;
			}

			*tail = '\0';

			ret = StoreParentPath(top);

			if (ret != VDK_OK) {
				return ret;
			}

			SetFlag(VDISK_FLAG_CHILD);
		}
		else if (!VdkCmpNoCaseN(current, "ddb.toolsVersion", 16)) {
			PCHAR p = current + 16;

			while (*p == ' ' || *p == '=' || *p == '\"') {
				p++;
			}

			m_nToolsFlag = atol(p);
		}
		else if (*current && *current != '#') {

			if (!VDiskCallBack(VDISK_CB_DESC_BADENTRY, cbparams)) {
				return VDK_CANCEL;
			}

			SetFlag(VDISK_FLAG_DIRTY);
		}
	}

	if (ret == VDK_EOF) {
		return Check();
	}
	else {
		return ret;
	}
}
Exemple #29
0
int	CGameConfigFlag::LoadFlagFile()
{
	FILE *fp;
	int size;
	byte *buffer;
	char *token;
	
	char filename[128];

	sprintf( filename, "flag%s.cfg", g_lTableToken[g_config.languageType] );
	fp = fopen(filename, "rb" );

	if( !fp )   
	{
		MessageBox(NULL, "does not exist 'flag.cfg' file", "Error", MB_ICONHAND|MB_OK);
		return false;
	}

	fseek(fp,0,SEEK_END);

	size = ftell(fp);

	buffer = new byte[size+1];

	fseek(fp,0,SEEK_SET);
	fread(buffer,size,1,fp);
	fclose(fp);

	curpos = (char *)buffer;
	endpos = curpos + size;
	
	while ((token = NextToken()) != NULL)
    {
		if( !stricmp( token, "CHARACTER_STORAGE" ) )
		{
			token = NextArg();
			if(!stricmp( token, "TRUE" ))			gGameConfigFlag.m_bCharacter_Storage = TRUE;
			else if (!stricmp( token, "FALSE" ))	gGameConfigFlag.m_bCharacter_Storage = FALSE;
		}
		else if( !stricmp( token, "PRECOCITY_TIME" ) )
		{
			token = NextArg();
			if(!stricmp( token, "TRUE" ))			gGameConfigFlag.m_bPrecocity_Time = TRUE;
			else if (!stricmp( token, "FALSE" ))	gGameConfigFlag.m_bPrecocity_Time = FALSE;
		}

		else if( !stricmp( token, "DIE_REDUCE_PANALTY" ) )
		{
			token = NextArg();
			if(!stricmp( token, "TRUE" ))			gGameConfigFlag.m_bDie_Reduce_panality = TRUE;
			else if (!stricmp( token, "FALSE" ))	gGameConfigFlag.m_bDie_Reduce_panality = FALSE;
		}

		else if( !stricmp( token, "MAP_ATTR_RATIO" ) )
		{
			token = NextArg();
			if(!stricmp( token, "TRUE" ))			gGameConfigFlag.m_bMap_Attr_Ratio = TRUE;
			else if (!stricmp( token, "FALSE" ))	gGameConfigFlag.m_bMap_Attr_Ratio = FALSE;
		}


		else if( !stricmp( token, "ITEM_UPGRADE_LIMIT" ) )
		{
			token = NextArg();
			if(!stricmp( token, "TRUE" ))			gGameConfigFlag.m_bItem_Upgrade_Limit = TRUE;
			else if (!stricmp( token, "FALSE" ))	gGameConfigFlag.m_bItem_Upgrade_Limit = FALSE;
		}

		else if( !stricmp( token, "ITEM_CRAFT_LIMIT" ) )
		{
			token = NextArg();
			if(!stricmp( token, "TRUE" ))			gGameConfigFlag.m_bItem_Craft_Limit = TRUE;
			else if (!stricmp( token, "FALSE" ))	gGameConfigFlag.m_bItem_Craft_Limit = FALSE;
		}


		else if( !stricmp( token, "WORLD_CHAT_LIMIT" ) )
		{
			token = NextArg();
			if(!stricmp( token, "TRUE" ))			gGameConfigFlag.m_bWorld_Chat_Limit = TRUE;
			else if (!stricmp( token, "FALSE" ))	gGameConfigFlag.m_bWorld_Chat_Limit = FALSE;
		}
	}

	fclose(fp);

	SetFlag();

	
	if(NULL  != buffer){ 
		delete []buffer;
		buffer=NULL; 
	}
	return true;
}
Exemple #30
0
//-----------------------------------------------------------------------------
void Unit::ApplyModifier(const Modifier *mod, bool apply, Affect* parent)
{
	//Player * player;
	Creature * creature;
	Unit * unit;
	WorldPacket data;

	Unit * caster = WorldGetUnit (parent->GetCasterGUID());
	if (caster != NULL && Call_Aura_ApplyModifier (mod->GetType(), caster, this, 
		apply, mod->GetAmount(), mod->GetMiscValue(), mod->GetMiscValue2()))
	{
		sLog.outDebug ("ApplyModifier->SCRIPT: Type=%d Amount=%d V1=%d V2=%d",
			mod->GetType(), mod->GetAmount(), mod->GetMiscValue(), mod->GetMiscValue2());
		return;
	}

	sLog.outDebug ("ApplyModifier: Type=%d Amount=%d V1=%d V2=%d",
		mod->GetType(), mod->GetAmount(), mod->GetMiscValue(), mod->GetMiscValue2());

	switch(mod->GetType())
	{
	case SPELL_AURA_NONE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_NONE");
		break; }

	case SPELL_AURA_BIND_SIGHT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_BIND_SIGHT");
		break; }

	case SPELL_AURA_MOD_THREAT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_THREAT");
		break; }

	case SPELL_AURA_AURAS_VISIBLE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_AURAS_VISIBLE");
		break; }

	case SPELL_AURA_MOD_RESISTANCE_PCT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RESISTANCE_PCT");
		break; }

	case SPELL_AURA_MOD_CREATURE_ATTACK_POWER: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_CREATURE_ATTACK_POWER");
		break; }

	case SPELL_AURA_MOD_TOTAL_THREAT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_TOTAL_THREAT");
		break; }

	case SPELL_AURA_WATER_WALK: {
		apply ?
			data.Initialize(SMSG_MOVE_WATER_WALK)
			: data.Initialize(SMSG_MOVE_LAND_WALK);
		data << GetGUID();
		SendMessageToSet(&data,true);
		break; }

	case SPELL_AURA_FEATHER_FALL: {
		apply ?
			data.Initialize(SMSG_MOVE_FEATHER_FALL)
			: data.Initialize(SMSG_MOVE_NORMAL_FALL);
		data << GetGUID();
		SendMessageToSet(&data,true);
		break; }

	case SPELL_AURA_HOVER: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_HOVER");
		break; }

	case SPELL_AURA_ADD_FLAT_MODIFIER: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_ADD_FLAT_MODIFIER");
		break; }

	case SPELL_AURA_ADD_PCT_MODIFIER: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_ADD_PCT_MODIFIER");
		break; }

	case SPELL_AURA_ADD_TARGET_TRIGGER: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_ADD_TARGET_TRIGGER");
		break; }

	case SPELL_AURA_MOD_TAUNT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_TAUNT");
		break; }

	case SPELL_AURA_MOD_POWER_REGEN_PERCENT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_POWER_REGEN_PERCENT");
		break; }

	case SPELL_AURA_ADD_CASTER_HIT_TRIGGER: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_ADD_CASTER_HIT_TRIGGER");
		break; }

	case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_OVERRIDE_CLASS_SCRIPTS");
		break; }

	case SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN");
		break; }

	case SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT");
		break; }

	case SPELL_AURA_MOD_HEALING: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_HEALING");
		break; }

	case SPELL_AURA_IGNORE_REGEN_INTERRUPT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_IGNORE_REGEN_INTERRUPT");
		break; }

	case SPELL_AURA_MOD_MECHANIC_RESISTANCE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_MECHANIC_RESISTANCE");
		break; }

	case SPELL_AURA_MOD_HEALING_PCT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_HEALING_PCT");
		break; }

	case SPELL_AURA_SHARE_PET_TRACKING: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_SHARE_PET_TRACKING");
		break; }

	case SPELL_AURA_MOD_CONFUSE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_CONFUSE");
		break; }

	case SPELL_AURA_MOD_STUN: {
		//sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_STUN");
		if (apply)
			SetTarget (0);
		break; } 

	case SPELL_AURA_UNTRACKABLE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_UNTRACKABLE");
		break; }

	case SPELL_AURA_EMPATHY: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_EMPATHY");
		break; }

	case SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT");
		break; }

	case SPELL_AURA_MOD_POWER_COST_PCT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_POWER_COST_PCT");
		break; }

	case SPELL_AURA_MOD_RANGED_ATTACK_POWER: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RANGED_ATTACK_POWER");
		break; }

	case SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN");
		break; }

	case SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT");
		break; }

	case SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS");
		break; }

	case SPELL_AURA_MOD_POSSESS_PET: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_POSSESS_PET");
		break; }

	case SPELL_AURA_MOD_INCREASE_SPEED_ALWAYS: {
		unit = WorldGetUnit (GetGUID());
		if (unit != NULL) {
			if (apply)	unit->ModifySpeedMod (mod->GetAmount() / 100.0f);
			else {
				if (mod->GetAmount() != 0)
					unit->ModifySpeedMod (100.0f / mod->GetAmount());
				else
					unit->SetSpeedMod (1.0f);
			}
		} else {
			sLog.outDebug ("ApplyModifier SPELL_AURA_MOD_INCREASE_SPEED_ALWAYS: Unit %X not found", GetGUIDLow());
		}
		break; }

	case SPELL_AURA_MOD_DAMAGE_DONE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DAMAGE_DONE");
		break; }

	case SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS");
		break; }

	case SPELL_AURA_MOD_CREATURE_RANGED_ATTACK_POWER: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_CREATURE_RANGED_ATTACK_POWER");
		break; }

	case SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT: {
		uint32 percent = mod->GetAmount();
		uint32 current = GetUInt32Value(UNIT_FIELD_POWER4);
		apply ?
			SetUInt32Value(UNIT_FIELD_POWER4,current+current/100*percent)
		:	SetUInt32Value(UNIT_FIELD_POWER4,current-current/(100+percent)*100);
		break; }

	case SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT: {
		uint32 percent = mod->GetAmount();
		uint32 current = GetUInt32Value(UNIT_FIELD_MAXHEALTH);
		apply ?
			SetUInt32Value(UNIT_FIELD_MAXHEALTH,current+current/100*percent)
		:	SetUInt32Value(UNIT_FIELD_MAXHEALTH,current-current/(100+percent)*100);
		break; }

	case SPELL_AURA_MOD_MANA_REGEN_INTERRUPT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_MANA_REGEN_INTERRUPT");
		break; }

	case SPELL_AURA_MOD_HEALING_DONE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_HEALING_DONE");
		break; }

	case SPELL_AURA_MOD_HEALING_DONE_PERCENT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_HEALING_DONE_PERCENT");
		break; }

	case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE");
		break; }

	case SPELL_AURA_MOD_HASTE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_HASTE");
		break; }

	case SPELL_AURA_FORCE_REACTION: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_FORCE_REACTION");
		break; }

	case SPELL_AURA_MOD_DAMAGE_TAKEN: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DAMAGE_TAKEN");
		break; }

	case SPELL_AURA_MOD_RANGED_HASTE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RANGED_HASTE");
		break; }

	case SPELL_AURA_MOD_RANGED_AMMO_HASTE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RANGED_AMMO_HASTE");
		break; }

	case SPELL_AURA_MOD_BASE_RESISTANCE_PCT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_BASE_RESISTANCE_PCT");
		break; }

	case SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE");
		break; }

	case SPELL_AURA_SAFE_FALL: {
		apply ? data.Initialize(SMSG_MOVE_FEATHER_FALL) : data.Initialize(SMSG_MOVE_NORMAL_FALL);
		data << GetGUID();
		SendMessageToSet(&data,true);
		break; }

	case SPELL_AURA_CHARISMA: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_CHARISMA");
		break; }

	case SPELL_AURA_PERSUADED: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERSUADED");
		break; }

	case SPELL_AURA_ADD_CREATURE_IMMUNITY: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_ADD_CREATURE_IMMUNITY");
		break; }

	case SPELL_AURA_RETAIN_COMBO_POINTS: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_RETAIN_COMBO_POINTS");
		break; }

	case SPELL_AURA_DAMAGE_SHIELD: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_DAMAGE_SHIELD");
		break; }

	case SPELL_AURA_MOD_STEALTH: {
		//sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_STEALTH");
		
		// Convert float stored into integer field to normal view
		float amountf;
		*((int *)&amountf) = mod->GetAmount();

		// Clip effective stealth level by spell level
		int amount = min (GetLevel() * 5, (int)amountf + 95);

		if (apply)	m_stealthLevel += amount;
		else		m_stealthLevel -= amount;
		
		sLog.outDebug ("ApplyModifier: STEALTH value set to %d", m_stealthLevel);
		break; }

	case SPELL_AURA_MOD_DETECT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DETECT");
		break; }

	case SPELL_AURA_MOD_INVISIBILITY: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_INVISIBILITY");
		break; }

	case SPELL_AURA_MOD_INVISIBILITY_DETECTION: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_INVISIBILITY_DETECTION");
		break; }

	case SPELL_AURA_MOD_POSSESS: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_POSSESS");
		break; }

	case SPELL_AURA_MOD_RESISTANCE: {
		uint16 index = 0;
		uint16 index2 = 0;
		switch(mod->GetMiscValue())
		{
		case DMG_PHYSICAL: {
			index = UNIT_FIELD_RESISTANCES;
			mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE : index2 = PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE;
			break; }
		case DMG_HOLY: {
			index = UNIT_FIELD_RESISTANCES + DMG_HOLY;
			mod->GetMiscValue2() == 0 ?
				index2 = PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE + DMG_HOLY :
				index2 = PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + DMG_HOLY;
			break; }
		case DMG_FIRE: {
			index = UNIT_FIELD_RESISTANCES + DMG_FIRE;
			mod->GetMiscValue2() == 0 ?
				index2 = PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE + DMG_FIRE :
				index2 = PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + DMG_FIRE;
			break; }
		case DMG_NATURE: {
			index = UNIT_FIELD_RESISTANCES + DMG_NATURE;
			mod->GetMiscValue2() == 0 ?
				index2 = PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE + DMG_NATURE :
				index2 = PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + DMG_NATURE;
			break; }
		case DMG_FROST: {
			index = UNIT_FIELD_RESISTANCES + DMG_FROST;
			mod->GetMiscValue2() == 0 ?
				index2 = PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE + DMG_FROST :
				index2 = PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + DMG_FROST;
			break; }
		case DMG_SHADOW:{
			index = UNIT_FIELD_RESISTANCES + DMG_SHADOW;
			mod->GetMiscValue2() == 0 ?
				index2 = PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE + DMG_SHADOW :
			index2 = PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + DMG_SHADOW;
			break; }
		case DMG_ARCANE:{
			index = UNIT_FIELD_RESISTANCES + DMG_ARCANE;
			mod->GetMiscValue2() == 0 ?
				index2 = PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE + DMG_ARCANE :
				index2 = PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + DMG_ARCANE;
			break; }
		default:{
			sLog.outDetail ("WARNING: Misc Value for SPELL_AURA_MOD_STAT not valid\n");
			return;
			break; }
		}

		if(apply){
			SetUInt32Value(index,GetUInt32Value(index)+mod->GetAmount());
			if (isPlayer())
				SetUInt32Value(index2,GetUInt32Value(index2)+mod->GetAmount());
		}else{
			SetUInt32Value(index,GetUInt32Value(index)-mod->GetAmount());
			if (isPlayer())
				SetUInt32Value(index2,GetUInt32Value(index2)-mod->GetAmount());
		}
		break; }

	case SPELL_AURA_PERIODIC_TRIGGER_SPELL: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_TRIGGER_SPELL");
		break; }

	case SPELL_AURA_PERIODIC_ENERGIZE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_ENERGIZE");
		break; }

	case SPELL_AURA_MOD_PACIFY: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_PACIFY");
		break; }

	case SPELL_AURA_MOD_ROOT: {
		apply ? data.Initialize(MSG_MOVE_ROOT) 
			: data.Initialize(MSG_MOVE_UNROOT);
		data << GetGUID();
		SendMessageToSet(&data,true);
		break; }

	case SPELL_AURA_MOD_SILENCE: {
		apply ? m_silenced = true 
			: m_silenced = false;
		break; }

	case SPELL_AURA_REFLECT_SPELLS: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_REFLECT_SPELLS");
		break; }

	case SPELL_AURA_MOD_STAT: {
		uint16 index = 0;
		uint16 index2 = 0;
		int32 v = mod->GetAmount();

		switch(mod->GetMiscValue())
		{
		case 0:{
			//index = UNIT_FIELD_STAT0;
			ModifyStrength (apply ? v : -v);
			mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_POSSTAT0 : index2 = PLAYER_FIELD_NEGSTAT0;
			break; }
		case 1:{
			//index = UNIT_FIELD_STAT1;
			ModifyAgility (apply ? v : -v);
			mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_POSSTAT1 : index2 = PLAYER_FIELD_NEGSTAT1;
			break; }
		case 2:{
			//index = UNIT_FIELD_STAT2;
			ModifyStamina (apply ? v : -v);
			mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_POSSTAT2 : index2 = PLAYER_FIELD_NEGSTAT2;
			break; }
		case 3:{
			//index = UNIT_FIELD_STAT3;
			ModifyIntellect (apply ? v : -v);
			mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_POSSTAT3 : index2 = PLAYER_FIELD_NEGSTAT3;
			break; }
		case 4:{
			//index = UNIT_FIELD_STAT4;
			ModifySpirit (apply ? v : -v);
			mod->GetMiscValue2() == 0 ? index2 = PLAYER_FIELD_POSSTAT4 : index2 = PLAYER_FIELD_NEGSTAT4;
			break; }
		default:{
			printf("WARNING: Misc Value for SPELL_AURA_MOD_STAT not valid\n");
			return;
			break; }
		}
		if(apply){
			if (isPlayer())
				SetUInt32Value(index2,GetUInt32Value(index2) + v);
		}else{
			if (isPlayer())
				SetUInt32Value(index2,GetUInt32Value(index2) - v);
		}
		break; }

	case SPELL_AURA_PERIODIC_DAMAGE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_DAMAGE");
		break; }

	case SPELL_AURA_MOD_SKILL: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_SKILL");
		break; }

	case SPELL_AURA_MOD_INCREASE_SPEED: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_INCREASE_SPEED");
		break; }

	case SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED: {
		if (GetUInt32Value(UNIT_FIELD_FLAGS) & UNIT_FLAG_MOUNTED ) {
			float newspeed = (float)mod->GetAmount() / 100.0f;
			newspeed = newspeed + 1.0f;
			sLog.outDebug("New Speed (With mount): %.1f", newspeed);
			unit = WorldGetUnit (GetGUID());
			if (unit != NULL)
				unit->SetSpeedMod(newspeed);
		} else {
			unit = WorldGetUnit (GetGUID());
			if (unit != NULL)
				unit->SetSpeedMod(1.0f);
		}
		sLog.outDebug ("ApplyModifier: SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED");
		break; }

	case SPELL_AURA_MOD_DECREASE_SPEED: {
		unit = WorldGetUnit (GetGUID());
		if (unit != NULL) {
			if (apply)	unit->ModifySpeedMod (mod->GetAmount() / 100.0f);
			else {
				if (mod->GetAmount() != 0)
					unit->ModifySpeedMod (100.0f / mod->GetAmount());
				else
					unit->SetSpeedMod (1.0f);
			}
		}
		break; }

	case SPELL_AURA_MOD_INCREASE_HEALTH: {
		uint32 newValue;
		newValue = GetUInt32Value(UNIT_FIELD_MAXHEALTH);
		apply ? newValue += mod->GetAmount() : newValue -= mod->GetAmount();
		SetUInt32Value(UNIT_FIELD_MAXHEALTH,newValue);
		break; }

	case SPELL_AURA_MOD_INCREASE_ENERGY: {
		uint32 powerField = 23;
		uint8 powerType = (uint8)(GetUInt32Value(UNIT_FIELD_BYTES_0) >> 24);
		if(powerType == 0) // Mana
			powerField = UNIT_FIELD_POWER1;
		else if(powerType == 1) // Rage
			powerField = UNIT_FIELD_POWER2;
		else if(powerType == 3) // Energy
			powerField = UNIT_FIELD_POWER4;

		uint32 newValue = GetUInt32Value(powerType);
		apply ? newValue += mod->GetAmount() : newValue -= mod->GetAmount();
		SetUInt32Value(powerType,newValue);
		break; }

	case SPELL_AURA_MOD_SHAPESHIFT: {
		Affect* tmpAff;
		uint32 spellId;
		switch(mod->GetMiscValue())
		{
		case FORM_CAT: {
			spellId = 3025;
			break; }
		case FORM_TREE:{
			spellId = 3122;
			break; }
		case FORM_TRAVEL:{
			spellId = 5419;
			break; }
		case FORM_AQUA:{
			spellId = 5421;
			break; }
		case FORM_BEAR:{
			spellId = 1178;
			break; }
		case FORM_AMBIENT:{
			spellId = 0;
			break; }
		case FORM_GHOUL:{
			spellId = 0;
			break; }
		case FORM_DIREBEAR:{
			spellId = 9635;
			break; }
		case FORM_CREATUREBEAR:{
			spellId = 2882;
			break; }
		case FORM_GHOSTWOLF:{
			spellId = 0;
			break; }
		case FORM_BATTLESTANCE:{
			spellId = 2457;
			break; }
		case FORM_DEFENSIVESTANCE:{
			spellId = 7376;
			break; }
		case FORM_BERSERKERSTANCE:{
			spellId = 7381;
			break; }
		case FORM_SHADOW:{
			spellId = 0;
			break; }
		case FORM_STEALTH:{
			//spellId = 0;
			// Turn on Sneaky Stance, Switch stealth button to unstealth and switch spellbar
			SetUInt32Value (UNIT_FIELD_BYTES_1, apply? 0x021E0000: 0);
			if (apply == false && isPlayer())
			{
				data.Initialize (SMSG_COOLDOWN_EVENT);
				data << (uint32)1784 << GetGUID();
				((Player*)this)->GetSession()->SendPacket (&data);
			}
			return; }

		default:{
			printf("Unknown Shapeshift Type\n");
			break; }
		}
		// check for spell id
		SpellEntry *spellInfo = sSpellStore.LookupEntry( spellId );

		if(!spellInfo)
		{
			sLog.outError("WORLD: unknown spell id %i\n", spellId);
			break;
		}
		tmpAff = new Affect(spellInfo,parent->GetDuration(),parent->GetCasterGUID());
		for(uint8 i=0; i<3; ++i){
			if(spellInfo->Effect[i] == 6){
				uint32 value = 0;
				uint32 type = 0;
				uint32 damage = 0;
				
				if(spellInfo->EffectBasePoints[i] < 0){
					tmpAff->SetNegative();
					type = 1;
				}

				uint32 sBasePoints = (uint32)sqrt((float)(spellInfo->EffectBasePoints[i]*spellInfo->EffectBasePoints[i]));
				if(spellInfo->EffectApplyAuraName[i] == 3){       // Periodic Trigger Damage
					damage = spellInfo->EffectBasePoints[i]+rand()%spellInfo->EffectDieSides[i]+1;
					//TODO: why the hell it takes uint16?
					tmpAff->SetDamagePerTick((uint16)damage, spellInfo->EffectAmplitude[i]);
					tmpAff->SetNegative();
				}else if(spellInfo->EffectApplyAuraName[i] == 23)// Periodic Trigger Spell
					tmpAff->SetPeriodicTriggerSpell(spellInfo->EffectTriggerSpell[i],spellInfo->EffectAmplitude[i]);
				else{
					if(spellInfo->EffectDieSides[i] != 0)
						value = sBasePoints+rand()%spellInfo->EffectDieSides[i];
					else
						value = sBasePoints;
					if(spellInfo->EffectDieSides[i] <= 1)
						value += 1;
					//TODO: why the hell it takes uint8? 
					tmpAff->AddMod((uint8)spellInfo->EffectApplyAuraName[i],value,spellInfo->EffectMiscValue[i],type);
				}
			}
		}
		if(tmpAff){
			parent->SetCoAffect(tmpAff);
			AddAffect(tmpAff);
		}

		break; }

	case SPELL_AURA_EFFECT_IMMUNITY: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_EFFECT_IMMUNITY");
		break; }

	case SPELL_AURA_STATE_IMMUNITY: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_STATE_IMMUNITY");
		break; }

	case SPELL_AURA_SCHOOL_IMMUNITY: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_SCHOOL_IMMUNITY");
		break; }

	case SPELL_AURA_DAMAGE_IMMUNITY: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_DAMAGE_IMMUNITY");
		break; }

	case SPELL_AURA_DISPEL_IMMUNITY: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_DISPEL_IMMUNITY");
		break; }

	case SPELL_AURA_PROC_TRIGGER_SPELL: {
		apply ? m_triggerSpell = mod->GetAmount() : m_triggerSpell = 0;
		break; }

	case SPELL_AURA_PROC_TRIGGER_DAMAGE: {
		apply ? m_triggerDamage = mod->GetAmount() : m_triggerDamage = 0;
		break; }

	case SPELL_AURA_TRACK_CREATURES: {
		apply ? SetUInt32Value(PLAYER_TRACK_CREATURES,mod->GetMiscValue()) : SetUInt32Value(PLAYER_TRACK_CREATURES,0);
		break; }

	case SPELL_AURA_TRACK_RESOURCES: {
		apply ? SetUInt32Value(PLAYER_TRACK_RESOURCES,mod->GetMiscValue()) : SetUInt32Value(PLAYER_TRACK_RESOURCES,0);
		break; }

	case SPELL_AURA_MOD_PARRY_SKILL: {
		break; }

	case SPELL_AURA_MOD_PARRY_PERCENT: {
		//uint32 current = GetUInt32Value(PLAYER_PARRY_PERCENTAGE);
		//apply ? SetUInt32Value(PLAYER_PARRY_PERCENTAGE,current+mod->GetAmount()) : SetUInt32Value(PLAYER_PARRY_PERCENTAGE,current-mod->GetAmount());
		ModifyParryChance (apply ? mod->GetAmount() : -mod->GetAmount());
		break; }

	case SPELL_AURA_MOD_DODGE_SKILL: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DODGE_SKILL");
		break; }

	case SPELL_AURA_MOD_DODGE_PERCENT: {
		//uint32 current = GetUInt32Value(PLAYER_DODGE_PERCENTAGE);
		//apply ? SetUInt32Value(PLAYER_DODGE_PERCENTAGE,current+mod->GetAmount()) : SetUInt32Value(PLAYER_DODGE_PERCENTAGE,current-mod->GetAmount());
		ModifyDodgeChance (apply ? mod->GetAmount() : -mod->GetAmount());
		break; }

	case SPELL_AURA_MOD_BLOCK_SKILL: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_BLOCK_SKILL");
		break; }

	case SPELL_AURA_MOD_BLOCK_PERCENT: {
		//uint32 current = GetUInt32Value(PLAYER_BLOCK_PERCENTAGE);
		//apply ? SetUInt32Value(PLAYER_BLOCK_PERCENTAGE,current+mod->GetAmount()) : SetUInt32Value(PLAYER_BLOCK_PERCENTAGE,current-mod->GetAmount());
		ModifyBlockChance (apply ? mod->GetAmount() : -mod->GetAmount());
		break; }

	case SPELL_AURA_MOD_CRIT_PERCENT: {
		//uint32 current = GetUInt32Value(PLAYER_CRIT_PERCENTAGE);
		//apply ? SetUInt32Value(PLAYER_CRIT_PERCENTAGE,current+mod->GetAmount()) : SetUInt32Value(PLAYER_CRIT_PERCENTAGE,current-mod->GetAmount());
		ModifyCritChance (apply ? mod->GetAmount() : -mod->GetAmount());
		break; }

	case SPELL_AURA_PERIODIC_LEECH: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_LEECH");
		break; }

	case SPELL_AURA_MOD_HIT_CHANCE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_HIT_CHANCE");
		break; }

	case SPELL_AURA_MOD_SPELL_HIT_CHANCE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_SPELL_HIT_CHANCE");
		break; }

	case SPELL_AURA_TRANSFORM: {
		if (parent->GetId() == 118) {
			if (apply) {
				//((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID));
				SetUInt32Value (UNIT_FIELD_DISPLAYID, 856);
			} else {
				SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
				if (caster != NULL)
					AddHate (caster, 1.0f);
			}
		}
		if (parent->GetId() == 228) {
			if (apply) {
				//((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID));
				SetUInt32Value (UNIT_FIELD_DISPLAYID, 304);
			} else {
				SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
				if (caster != NULL)
					AddHate (caster, 1.0f);
			}
		}
		if (parent->GetId() == 851) {
			if (apply) {
				//((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID));
				SetUInt32Value (UNIT_FIELD_DISPLAYID, 856);
			} else {
				SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
				if (caster != NULL)
					AddHate (caster, 1.0f);
			}
		}
		if (parent->GetId() == 4060) {
			if (apply) {
				//((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID));
				SetUInt32Value (UNIT_FIELD_DISPLAYID, 131);
			} else {
				SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
				if (caster != NULL)
					AddHate (caster, 1.0f);
			}
		}
		if (parent->GetId() == 5254) {
			if (apply) {
				//((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID));
				SetUInt32Value (UNIT_FIELD_DISPLAYID, 856);
			} else {
				SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
				if (caster != NULL)
					AddHate (caster, 1.0f);
			}
		}
		if (parent->GetId() == 12824) {
			if (apply) {
				//((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID));
				SetUInt32Value (UNIT_FIELD_DISPLAYID, 856);
			} else {
				SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
				if (caster != NULL)
					AddHate (caster, 1.0f);
			}
		}
		if (parent->GetId() == 12825) {
			if (apply) {
				//((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID));
				SetUInt32Value (UNIT_FIELD_DISPLAYID, 856);
			} else {
				SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
				if (caster != NULL)
					AddHate (caster, 1.0f);
			}
		}
		if (parent->GetId() == 12826) {
			if (apply) {
				//((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID));
				SetUInt32Value (UNIT_FIELD_DISPLAYID, 856);
			} else {
				SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
				if (caster != NULL)
					AddHate (caster, 1.0f);
			}
		}
		if (parent->GetId() == 13323) {
			if (apply) {
				//((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID));
				SetUInt32Value (UNIT_FIELD_DISPLAYID, 856);
			} else {
				SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
				if (caster != NULL)
					AddHate (caster, 1.0f);
			}
		}
		if (parent->GetId() == 15534) {
			if (apply) {
				//((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID));
				SetUInt32Value (UNIT_FIELD_DISPLAYID, 856);
			} else {
				SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
				if (caster != NULL)
					AddHate (caster, 1.0f);
			}
		}
		if (parent->GetId() == 17738) {
			if (apply) {
				//((Modifier *)mod)->SetValue1 (GetUInt32Value (UNIT_FIELD_DISPLAYID));
				SetUInt32Value (UNIT_FIELD_DISPLAYID, 1141);
			} else {
				SetUInt32Value (UNIT_FIELD_DISPLAYID, GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
				if (caster != NULL)
					AddHate (caster, 1.0f);
			}
		}
		break; }

	case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_SPELL_CRIT_CHANCE");
		break; }

	case SPELL_AURA_MOD_INCREASE_SWIM_SPEED: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_INCREASE_SWIM_SPEED");
		break; }

	case SPELL_AURA_MOD_DAMAGE_DONE_CREATURE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DAMAGE_DONE_CREATURE");
		break; }

	case SPELL_AURA_MOD_CHARM: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_CHARM");
		break; }

	case SPELL_AURA_MOD_PACIFY_SILENCE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_PACIFY_SILENCE");
		break; }

	case SPELL_AURA_MOD_SCALE: {
			float current = GetFloatValue(OBJECT_FIELD_SCALE_X);
			apply ? SetFloatValue(OBJECT_FIELD_SCALE_X,current+current/100*10) : SetFloatValue(OBJECT_FIELD_SCALE_X,current-current/110*100);
			break; }

	case SPELL_AURA_PERIODIC_HEALTH_FUNNEL: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_HEALTH_FUNNEL");
		break; }

	case SPELL_AURA_PERIODIC_MANA_FUNNEL: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_MANA_FUNNEL");
		break; }

	case SPELL_AURA_PERIODIC_MANA_LEECH: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_MANA_LEECH");
		break; }

	case SPELL_AURA_MOD_CASTING_SPEED: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_CASTING_SPEED");
		break; }

	case SPELL_AURA_FEIGN_DEATH: {
			sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_FEIGN_DEATH");
			break; }

	case SPELL_AURA_MOD_DISARM: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DISARM");
		break; }

	case SPELL_AURA_MOD_STALKED: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_STALKED");
		break; }

	case SPELL_AURA_SCHOOL_ABSORB: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_SCHOOL_ABSORB");
		break; }

	case SPELL_AURA_MOD_FEAR: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_FEAR");
		break; }

	case SPELL_AURA_EXTRA_ATTACKS: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_EXTRA_ATTACKS");
		break; }

	case SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL");
		break; }

	case SPELL_AURA_MOD_POWER_COST: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_POWER_COST");
		break; }

	case SPELL_AURA_MOD_POWER_COST_SCHOOL: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_POWER_COST_SCHOOL");
		break; }

	case SPELL_AURA_REFLECT_SPELLS_SCHOOL: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_REFLECT_SPELLS_SCHOOL");
		break; }

	case SPELL_AURA_MOD_LANGUAGE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_LANGUAGE");
		break; }

	case SPELL_AURA_FAR_SIGHT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_FAR_SIGHT");
		break; }

	case SPELL_AURA_MECHANIC_IMMUNITY: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MECHANIC_IMMUNITY");
		break; }

	case SPELL_AURA_MOUNTED: {
		sLog.outDebug ("ApplyModifier: SPELL_AURA_MOUNTED");
		if (GetUInt32Value(UNIT_FIELD_FLAGS) & UNIT_FLAG_MOUNTED )
		{
			SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID , 0);
			RemoveFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNTED );
			// Remove the "player locked" flag, to allow movement
			if (GetUInt32Value(UNIT_FIELD_FLAGS) & UNIT_FLAG_LOCKED )
				RemoveFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_LOCKED );
			// Make sure we're standing ;)
			SetUInt32Value(UNIT_FIELD_BYTES_1, STANDSTATE_STAND);
		} else {
			// Set mount ID from creatures_templ
			CreatureTemplate *ptempl = objmgr.GetCreatureTemplate(mod->GetMiscValue(), true);
			SetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID , ptempl->Model);
			//SetUInt32Value( UNIT_FIELD_FLAGS , UNIT_FLAG_MOUNTED );
			SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNTED );
		}
		break; }

	case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DAMAGE_PERCENT_DONE");
		break; }

	case SPELL_AURA_PERIODIC_HEAL: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_HEAL");
		break; }

	case SPELL_AURA_MOD_PERCENT_STAT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_PERCENT_STAT");
		break; }

	case SPELL_AURA_SPLIT_DAMAGE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_SPLIT_DAMAGE");
		break; }

	case SPELL_AURA_WATER_BREATHING: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_WATER_BREATHING");
		break; }

	case SPELL_AURA_MOD_BASE_RESISTANCE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_BASE_RESISTANCE");
		break; }

	case SPELL_AURA_MOD_REGEN: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_REGEN");
		break; }

	case SPELL_AURA_MOD_POWER_REGEN: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_POWER_REGEN");
		break; }

	case SPELL_AURA_CHANNEL_DEATH_ITEM: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_CHANNEL_DEATH_ITEM");
		break; }

	case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN");
		break; }

	case SPELL_AURA_MOD_PERCENT_REGEN: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_PERCENT_REGEN");
		break; }

	case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PERIODIC_DAMAGE_PERCENT");
		break; }

	case SPELL_AURA_MOD_ATTACKSPEED: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_ATTACKSPEED");
		break; }

	case SPELL_AURA_MOD_RESIST_CHANCE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_RESIST_CHANCE");
		break; }

	case SPELL_AURA_MOD_DETECT_RANGE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_DETECT_RANGE");
		break; }

	case SPELL_AURA_PREVENTS_FLEEING: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_PREVENTS_FLEEING");
		break; }

	case SPELL_AURA_MOD_UNATTACKABLE: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_UNATTACKABLE");
		break; }

	case SPELL_AURA_INTERRUPT_REGEN: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_INTERRUPT_REGEN");
		break; }

	case SPELL_AURA_GHOST: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_GHOST");
		break; }

	case SPELL_AURA_SPELL_MAGNET: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_SPELL_MAGNET");
		break; }

	case SPELL_AURA_MANA_SHIELD: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MANA_SHIELD");
		break; }

	case SPELL_AURA_MOD_SKILL_TALENT: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_SKILL_TALENT");
		break; }

	case SPELL_AURA_MOD_ATTACK_POWER: {
		sLog.outDebug ("ApplyModifier: Unsupported SPELL_AURA_MOD_ATTACK_POWER");
		break; }

	default: {
		sLog.outError("Unknown affect id %u", (uint32)mod->GetType());
			 }
	}
}