Esempio n. 1
0
void DBKResumeThread(ULONG ThreadID)
{
	KIRQL OldIrql;
	
	struct ThreadData *t_data;


    KeAcquireSpinLock(&ProcesslistSL,&OldIrql); 


	DbgPrint("Going to resume this thread\n");

	//find the thread in the threadlist


	//find the threadid in the processlist
	t_data=GetThreaddata(ThreadID);
	if (t_data)
	{
		if (t_data->suspendcount)
		{
			t_data->suspendcount--;
			if (!t_data->suspendcount) //suspendcount=0 so resume
				KeReleaseSemaphore(&t_data->SuspendSemaphore,0,1,FALSE);
		}
	}
	else
		DbgPrint("Thread not found in the list\n");

	KeReleaseSpinLock(&ProcesslistSL,OldIrql);

}
// =========================================================================
NTSTATUS
QueueIRPToThread(
    IN  PDEVICE_OBJECT DeviceObject,    
    IN  PIRP           Irp
)
{
    PDEVICE_EXTENSION devExt;
    NTSTATUS status;
    PIO_STACK_LOCATION irpSp;

    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("QueueIrpToThread\n"));
    
    devExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    
    status = STATUS_PENDING;                
      
    // Note: IoCsqInsertIrp marks the IRP pending.
    IoCsqInsertIrp(&devExt->CancelSafeQueue, Irp, NULL);

    // A semaphore remains signaled as long as its count is greater than 
    // zero, and non-signaled when the count is zero. Following function 
    // increments the semaphore count by 1.
    KeReleaseSemaphore(
                        &devExt->IRPQueueSemaphore,
                        0,  // No priority boost
                        1,  // Increment semaphore by 1
                        FALSE  // No WaitForXxx after this call
                        );

            
    DEBUGOUTHASHDRV(DEBUGLEV_EXIT, ("QueueIrpToThread\n"));
    
    return status;
}    
void 
PGPdiskSemaphore::Signal(PGPUInt32 count, BOOLEAN wait)
{
	pgpAssertAddrValid(mSemPointer, KSEMAPHORE);

	KeReleaseSemaphore(mSemPointer, 0, count, wait);
}
Esempio n. 4
0
VOID PushEvent(IN PEVENTDATA pEvtData)
/*++

Routine Description:

	“违规事件”压栈


Arguments:

	pEvtData - 指定“违规事件”


Return Value:

	None.

Author:

	Fypher

--*/
{

	PAGED_CODE();

	ExInterlockedInsertTailList(&g_EventDataLinkListHead, &pEvtData->ListEntry, &g_EventDataLock);
	InterlockedIncrement(&g_ulEventDataCount);

	KeReleaseSemaphore(&g_EventDataSemaphore, 0, 1, FALSE);
}
Esempio n. 5
0
VOID __stdcall Filter(ULONG ServiceId, ULONG TableBase, ULONG Argc, ULONG StackAddr) {
	ULONG pid = (ULONG)PsGetCurrentProcessId();
	if (pid == g_nPid) {
		ULONG i;
		PXBoxData pData=(PXBoxData)ExAllocateFromNPagedLookasideList(&g_nPageList);
		if(!pData)
			return;
		
		if (StackAddr < MmUserProbeAddress)
			pData->bFromUser = 1;
		else
			pData->bFromUser = 0;
		
		if (TableBase == (ULONG)KeServiceDescriptorTable.ServiceTableBase)
			pData->bFromSSDT = 1;
		else
			pData->bFromSSDT = 0;

		if (Argc > 16)
			Argc = 16;
		pData->argc = (UCHAR)Argc;
		for (i = 0; i < Argc; ++i)
			pData->args[i] = ((PULONG)StackAddr)[i];

		pData->pid = (ULONG)pid;
		pData->tid = (ULONG)PsGetCurrentThreadId();
		pData->sid = ServiceId;
		KeQuerySystemTime(&pData->time);
		ExInterlockedInsertTailList(&g_linkListHead, &pData->ListEntry, &g_lock);
		KeReleaseSemaphore( &g_keySemaphore, 0, 1, FALSE );
	}
}
Esempio n. 6
0
BOOL 
ShareLockKImp::Unlock() {

	switch(m_LockType) {
	case LockTypeMutex:
		return KeReleaseMutex(&m_LockObject.m_Mutex.m_Mutex,
			FALSE);
		break;
	case LockTypeEvent:
		return KeSetEvent(&m_LockObject.m_Event.m_Event,
			IO_NO_INCREMENT,
			FALSE);
		break;
	case LockTypeSemaphore:
		return KeReleaseSemaphore(&m_LockObject.m_Semaphore.m_Semaphore,
			IO_NO_INCREMENT,
			1,
			FALSE);
		break;
	case LockTypeSpinlock:
		break;
	case LockTypeNamedSpinlock: {
			if (m_LockObject.m_NamedSpinlock.m_lpHeader) {
				InterlockedCompareExchange(&m_LockObject.m_NamedSpinlock.m_lpHeader->m_LockProcId,
					0,
					(LONG)PsGetCurrentProcessId());
				return STATUS_SUCCESS;
			}		
		}
		break;
	default:
		break;
	}
	return FALSE;
}
Esempio n. 7
0
File: unc.c Progetto: GYGit/reactos
/*++
 * @name FsRtlDeregisterUncProvider
 * @implemented
 *
 * FILLME
 *
 * @param Handle
 *        FILLME
 *
 * @return None
 *
 * @remarks None
 *
 *--*/
VOID
NTAPI
FsRtlDeregisterUncProvider(IN HANDLE Handle)
{
    PAGED_CODE();

    /* We won't work on invalid input */
    if (Handle == INVALID_HANDLE_VALUE || Handle == 0)
    {
        return;
    }

    KeWaitForSingleObject(&FsRtlpUncSemaphore, Executive, KernelMode, FALSE, NULL);

    /* Sanity check: we need to have providers */
    ASSERT(FsRtlpRedirs > 0);

    /* At that point, we had only one provider at a time */
    if (Handle == (HANDLE)FsRtlpDRD.NullHandle)
    {
        /* Free its name if possible (it might have been overtaken in case of
         * registration of other UNC provider */
        if (FsRtlpDRD.RedirectorDeviceName.Buffer != NULL)
        {
            ExFreePoolWithTag(FsRtlpDRD.RedirectorDeviceName.Buffer, TAG_UNC);
            FsRtlpDRD.RedirectorDeviceName.Buffer = NULL;
        }

        /* Close the handle to MUP */
        if (FsRtlpDRD.MupHandle != INVALID_HANDLE_VALUE)
        {
            ZwClose(FsRtlpDRD.MupHandle);
            FsRtlpDRD.MupHandle = INVALID_HANDLE_VALUE;
        }

        /* Last handle isn't required anymore */
        FsRtlpDRD.NullHandle = INVALID_HANDLE_VALUE;
    }

    /* One less provider */
    --FsRtlpRedirs;

    /* In case we reach no provider anylonger, reset the symbolic link */
    if (FsRtlpRedirs == 0)
    {
        FsRtlpSetSymbolicLink(NULL);
    }

    KeReleaseSemaphore(&FsRtlpUncSemaphore, IO_NO_INCREMENT, 1, FALSE);

    /* Final note:
     * NULL device handle and 'normal' MUP device handle are not closed by
     * FsRtl. It's up to the user to close them afterwards.
     * If the handle is leaked, MUP will never be notified about the
     * unregistration.
     */
}
Esempio n. 8
0
void DBKResumeProcess(ULONG ProcessID)
{
	KIRQL OldIrql;
	
	struct ThreadData *t_data=NULL;
	struct ProcessData *tempProcessData=NULL;


	KeAcquireSpinLock(&ProcesslistSL,&OldIrql);
	

	DbgPrint("Going to suspend this process\n");

	//find the process in the threadlist

	tempProcessData=processlist;
	while (tempProcessData)
	{
		if (tempProcessData->ProcessID==(HANDLE)(UINT_PTR)ProcessID)
		{
			t_data=tempProcessData->Threads;
			break;
		}
		tempProcessData=tempProcessData->next;
	}

	if (!t_data)
	{
		DbgPrint("This process was not found\n");
		KeReleaseSpinLock(&ProcesslistSL,OldIrql);
		return; //no process found
	}


	while (t_data)
	{
		DbgPrint("Resuming thread....\n");		

		if (t_data->suspendcount)
		{
			t_data->suspendcount--;
			if (!t_data->suspendcount) //suspendcount=0 so resume
				KeReleaseSemaphore(&t_data->SuspendSemaphore,0,1,FALSE);
		}


		t_data=t_data->next; //next thread
	}

	KeReleaseSpinLock(&ProcesslistSL,OldIrql);
}
Esempio n. 9
0
//@@@@@@@@@@@@@@@@@@@@@@@@
// IRQL = passive level
//@@@@@@@@@@@@@@@@@@@@@@@@@
VOID Unload( IN PDRIVER_OBJECT pDriverObject)
{
	//Get the pointer to the device extension
	PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pDriverObject->DeviceObject->DeviceExtension; 
	DbgPrint("Driver Unload Called...\n");
	
	//Detach from the device underneath that we're hooked to
	IoDetachDevice(pKeyboardDeviceExtension->pKeyboardDevice);
	DbgPrint("Keyboard hook detached from device...\n");

	///////////////////////////////////////////////////////////////
	//Wait for our tagged IRPs to die before we remove the device
	///////////////////////////////////////////////////////////////
	DbgPrint("There are %d tagged IRPs\n",numPendingIrps);
	DbgPrint("Waiting for tagged IRPs to die...\n");

	//Create a timer
	KTIMER kTimer;
	LARGE_INTEGER  timeout;
	timeout.QuadPart = 1000000; //.1 s
	KeInitializeTimer(&kTimer);
	
	while(numPendingIrps > 0)
	{
		//Set the timer
		KeSetTimer(&kTimer,timeout,NULL);
		KeWaitForSingleObject(&kTimer,Executive,KernelMode,false ,NULL);
	}
	
	//Set our key logger worker thread to terminate
	pKeyboardDeviceExtension ->bThreadTerminate = true;

	//Wake up the thread if its blocked & WaitForXXX after this call
	KeReleaseSemaphore(&pKeyboardDeviceExtension->semQueue,0,1,TRUE);

	//Wait till the worker thread terminates	
	DbgPrint("Waiting for key logger thread to terminate...\n");
	KeWaitForSingleObject(pKeyboardDeviceExtension->pThreadObj,
			Executive,KernelMode,false,NULL);
	DbgPrint("Key logger thread termintated\n");

	//Close the log file
	ZwClose(pKeyboardDeviceExtension->hLogFile);

	//Delete the device
	IoDeleteDevice(pDriverObject->DeviceObject);
	DbgPrint("Tagged IRPs dead...Terminating...\n");

	return;
}
Esempio n. 10
0
/*
 * @implemented
 */
VOID
RemoveWorkItem(IN PUNIQUE_ID_WORK_ITEM WorkItem)
{
    PDEVICE_EXTENSION DeviceExtension = WorkItem->DeviceExtension;

    KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);

    /* If even if being worked, it's too late */
    if (WorkItem->Event)
    {
        KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
        KeSetEvent(WorkItem->Event, 0, FALSE);
    }
    else
    {
        /* Otherwise, remove it from the list, and delete it */
        RemoveEntryList(&(WorkItem->UniqueIdWorkerItemListEntry));
        KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
        IoFreeIrp(WorkItem->Irp);
        FreePool(WorkItem->DeviceName.Buffer);
        FreePool(WorkItem->IrpBuffer);
        FreePool(WorkItem);
    }
}
Esempio n. 11
0
BOOL
ShareLockKImp::ReleaseShareSemaphore(LONG lReleaseCount,
	LPLONG lpPreviousCount) {

	switch(m_LockType) {
	case LockTypeSemaphore:
		return KeReleaseSemaphore(&m_LockObject.m_Semaphore.m_Semaphore,
			IO_NO_INCREMENT,
			lReleaseCount,
			FALSE);
		break;
	default:
		break;
	}
	return FALSE;
}
Esempio n. 12
0
VOID 
MPSendPackets(
    IN NDIS_HANDLE MiniportAdapterContext,
    IN PPNDIS_PACKET PacketArray,
    IN UINT NumberOfPackets) {

	PHWT_ADAPTER Adapter;
	KIRQL irql;
	UINT Index;
	Adapter = (PHWT_ADAPTER)MiniportAdapterContext;
	
	KeAcquireSpinLock(&Adapter->UExtKeObj.SendPacketLock,
		&irql);
	if (Adapter->UExtKeObj.SendPacketControl) {
		for(Index=0; Index < NumberOfPackets; Index++) {
			if (get_thread_safe_enlist_count(Adapter->UExtKeObj.SendPacketList) >= MAX_QUEUED_SEND_PACKET) {
				NDIS_SET_PACKET_STATUS(PacketArray[Index], NDIS_STATUS_FAILURE);
				NdisMSendComplete(Adapter->AdapterHandle,
					PacketArray[Index],
					NDIS_STATUS_FAILURE);
				continue;
			}
			insert_thread_safe_enlist_tail(Adapter->UExtKeObj.SendPacketList, 
				PacketArray[Index],
				1); 
			KeReleaseSemaphore(Adapter->UExtKeObj.SendPacketControl,
				IO_NO_INCREMENT,
				1,
				FALSE);
		}
	}
	else {
		for(Index=0; Index < NumberOfPackets; Index++) {
			NDIS_SET_PACKET_STATUS(PacketArray[Index], NDIS_STATUS_FAILURE);
			NdisMSendComplete(Adapter->AdapterHandle,
				PacketArray[Index],
				NDIS_STATUS_FAILURE);
		}
	}
	KeReleaseSpinLock(&Adapter->UExtKeObj.SendPacketLock,
		irql);
    return;
}
void _up_sema(_sema	*sema)
{

#ifdef PLATFORM_LINUX

	//eason 20100210 up(sema);
	cyg_semaphore_post(sema);
#endif	

#ifdef PLATFORM_OS_XP

	KeReleaseSemaphore(sema, IO_NETWORK_INCREMENT, 1,  FALSE );

#endif

#ifdef PLATFORM_OS_CE
	ReleaseSemaphore(*sema,  1,  NULL );
#endif
}
Esempio n. 14
0
void _rtw_up_sema(_sema	*sema)
{

#ifdef PLATFORM_LINUX

	up(sema);

#endif	

#ifdef PLATFORM_OS_XP

	KeReleaseSemaphore(sema, IO_NETWORK_INCREMENT, 1,  FALSE );

#endif

#ifdef PLATFORM_OS_CE
	ReleaseSemaphore(*sema,  1,  NULL );
#endif
}
Esempio n. 15
0
NTSTATUS ultimap_continue(PULTIMAPDATAEVENT data)
/*
Called from usermode to signal that the data has been handled
*/
{
	DbgPrint("ultimap_continue\n");
	MmUnmapLockedPages((PVOID)data->Address, (PMDL)data->Mdl);
	IoFreeMdl((PMDL)data->Mdl);

	ExFreePool((PVOID)data->KernelAddress); //this memory is not needed anymore


	if (DataBlock)
		DataBlock[data->Block].Available=TRUE;


	KeReleaseSemaphore(&DataBlockSemaphore, 1, 1, FALSE); //Let the next block go through
	DbgPrint("Released semaphore\n");
	return STATUS_SUCCESS;	
}
Esempio n. 16
0
static void set_timer(unsigned long delta)
{
	if (delta == LKL_TIMER_INIT)
		return;

	if (delta == LKL_TIMER_SHUTDOWN) {
		/* should not deliver timer shutdown twice */
		if(timer_done) {
			DbgPrint("*** LKL_TIMER_SHUTDOWN called when timer_done ***");
			while(1)
				;
		}

		/* deque the timer so it won't be put in signaled state */
		KeCancelTimer(&timer);
		/* timers run on DPCs. This returns after all active
		 * DPCs have executed, which means the timer is
		 * certainly not running nor being schduled after this
		 * point. */
		KeFlushQueuedDpcs();


		/* signal the timer interrupt we're done */
		timer_done = 1;
		/* the memory barrier is needed because it may be
		 * possible for the compiler/cpu to call
		 * KeReleaseSemaphore before assigning
		 * timer_done. That would make the timer_thread wake
		 * from the wait-for-multiple-objs without noticing
		 * out signalling */
		KeMemoryBarrier();
		KeReleaseSemaphore(&timer_killer_sem, 0, 1, 0);
		return;
	}

	KeSetTimer(&timer, RtlConvertLongToLargeInteger((unsigned long)(-(delta/100))), NULL);
}
Esempio n. 17
0
static void sem_up(void *sem)
{
        KeReleaseSemaphore((KSEMAPHORE*)sem, 0, 1, 0);
}
Esempio n. 18
0
NTSTATUS
NTAPI
USBH_FdoPower(IN PUSBHUB_FDO_EXTENSION HubExtension,
              IN PIRP Irp,
              IN UCHAR Minor)
{
    NTSTATUS Status;
    PIO_STACK_LOCATION IoStack;
    POWER_STATE PowerState;
    POWER_STATE DevicePwrState;
    BOOLEAN IsAllPortsD3;
    PUSBHUB_PORT_DATA PortData;
    PDEVICE_OBJECT PdoDevice;
    PUSBHUB_PORT_PDO_EXTENSION PortExtension;
    ULONG Port;

    DPRINT_PWR("USBH_FdoPower: HubExtension - %p, Irp - %p, Minor - %X\n",
               HubExtension,
               Irp,
               Minor);

    switch (Minor)
    {
        case IRP_MN_WAIT_WAKE:
            DPRINT_PWR("USBH_FdoPower: IRP_MN_WAIT_WAKE\n");

            IoCopyCurrentIrpStackLocationToNext(Irp);

            IoSetCompletionRoutine(Irp,
                                   USBH_FdoWWIrpIoCompletion,
                                   HubExtension,
                                   TRUE,
                                   TRUE,
                                   TRUE);

            PoStartNextPowerIrp(Irp);
            IoMarkIrpPending(Irp);
            PoCallDriver(HubExtension->LowerDevice, Irp);

            return STATUS_PENDING;

        case IRP_MN_POWER_SEQUENCE:
            DPRINT_PWR("USBH_FdoPower: IRP_MN_POWER_SEQUENCE\n");
            break;

        case IRP_MN_SET_POWER:
            DPRINT_PWR("USBH_FdoPower: IRP_MN_SET_POWER\n");

            IoStack = IoGetCurrentIrpStackLocation(Irp);
            DPRINT_PWR("USBH_FdoPower: IRP_MN_SET_POWER/DevicePowerState\n");
            PowerState = IoStack->Parameters.Power.State;

            if (IoStack->Parameters.Power.Type == DevicePowerState)
            {
                DPRINT_PWR("USBH_FdoPower: PowerState - %x\n",
                           PowerState.DeviceState);

                if (HubExtension->CurrentPowerState.DeviceState == PowerState.DeviceState)
                {
                    IoCopyCurrentIrpStackLocationToNext(Irp);

                    PoStartNextPowerIrp(Irp);
                    IoMarkIrpPending(Irp);
                    PoCallDriver(HubExtension->LowerDevice, Irp);

                    return STATUS_PENDING;
                }

                switch (PowerState.DeviceState)
                {
                    case PowerDeviceD0:
                        if (!(HubExtension->HubFlags & USBHUB_FDO_FLAG_SET_D0_STATE))
                        {
                            HubExtension->HubFlags &= ~(USBHUB_FDO_FLAG_NOT_D0_STATE |
                                                        USBHUB_FDO_FLAG_DEVICE_STOPPING);

                            HubExtension->HubFlags |= USBHUB_FDO_FLAG_SET_D0_STATE;

                            IoCopyCurrentIrpStackLocationToNext(Irp);

                            IoSetCompletionRoutine(Irp,
                                                   USBH_PowerIrpCompletion,
                                                   HubExtension,
                                                   TRUE,
                                                   TRUE,
                                                   TRUE);
                        }
                        else
                        {
                            IoCopyCurrentIrpStackLocationToNext(Irp);
                            PoStartNextPowerIrp(Irp);
                        }

                        IoMarkIrpPending(Irp);
                        PoCallDriver(HubExtension->LowerDevice, Irp);
                        return STATUS_PENDING;

                    case PowerDeviceD1:
                    case PowerDeviceD2:
                    case PowerDeviceD3:
                        if (HubExtension->ResetRequestCount)
                        {
                            IoCancelIrp(HubExtension->ResetPortIrp);

                            KeWaitForSingleObject(&HubExtension->ResetEvent,
                                                  Executive,
                                                  KernelMode,
                                                  FALSE,
                                                  NULL);
                        }

                        if (!(HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_STOPPED))
                        {
                            HubExtension->HubFlags |= (USBHUB_FDO_FLAG_NOT_D0_STATE |
                                                       USBHUB_FDO_FLAG_DEVICE_STOPPING);

                            IoCancelIrp(HubExtension->SCEIrp);

                            KeWaitForSingleObject(&HubExtension->StatusChangeEvent,
                                                  Executive,
                                                  KernelMode,
                                                  FALSE,
                                                  NULL);
                        }

                        HubExtension->CurrentPowerState.DeviceState = PowerState.DeviceState;

                        if (HubExtension->HubFlags & USBHUB_FDO_FLAG_DO_SUSPENSE &&
                            USBH_CheckIdleAbort(HubExtension, TRUE, TRUE) == TRUE)
                        {
                            HubExtension->HubFlags &= ~(USBHUB_FDO_FLAG_NOT_D0_STATE |
                                                        USBHUB_FDO_FLAG_DEVICE_STOPPING);

                            HubExtension->CurrentPowerState.DeviceState = PowerDeviceD0;

                            USBH_SubmitStatusChangeTransfer(HubExtension);

                            PoStartNextPowerIrp(Irp);

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

                            HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_DO_SUSPENSE;

                            KeReleaseSemaphore(&HubExtension->IdleSemaphore,
                                               LOW_REALTIME_PRIORITY,
                                               1,
                                               FALSE);

                            return STATUS_UNSUCCESSFUL;
                        }

                        IoCopyCurrentIrpStackLocationToNext(Irp);

                        IoSetCompletionRoutine(Irp,
                                               USBH_PowerIrpCompletion,
                                               HubExtension,
                                               TRUE,
                                               TRUE,
                                               TRUE);

                        PoStartNextPowerIrp(Irp);
                        IoMarkIrpPending(Irp);
                        PoCallDriver(HubExtension->LowerDevice, Irp);

                        if (HubExtension->HubFlags & USBHUB_FDO_FLAG_DO_SUSPENSE)
                        {
                            HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_DO_SUSPENSE;

                            KeReleaseSemaphore(&HubExtension->IdleSemaphore,
                                               LOW_REALTIME_PRIORITY,
                                               1,
                                               FALSE);
                        }

                        return STATUS_PENDING;

                    default:
                        DPRINT1("USBH_FdoPower: Unsupported PowerState.DeviceState\n");
                        DbgBreakPoint();
                        break;
                }
            }
            else
            {
                if (PowerState.SystemState != PowerSystemWorking)
                {
                    USBH_GetRootHubExtension(HubExtension)->SystemPowerState.SystemState =
                                                            PowerState.SystemState;
                }

                if (PowerState.SystemState == PowerSystemHibernate)
                {
                    HubExtension->HubFlags |= USBHUB_FDO_FLAG_HIBERNATE_STATE;
                }

                PortData = HubExtension->PortData;

                IsAllPortsD3 = TRUE;

                if (PortData && HubExtension->HubDescriptor)
                {
                    for (Port = 0;
                         Port < HubExtension->HubDescriptor->bNumberOfPorts;
                         Port++)
                    {
                        PdoDevice = PortData[Port].DeviceObject;

                        if (PdoDevice)
                        {
                            PortExtension = PdoDevice->DeviceExtension;

                            if (PortExtension->CurrentPowerState.DeviceState != PowerDeviceD3)
                            {
                                IsAllPortsD3 = FALSE;
                                break;
                            }
                        }
                    }
                }

                if (PowerState.SystemState == PowerSystemWorking)
                {
                    DevicePwrState.DeviceState = PowerDeviceD0;
                }
                else if (HubExtension->HubFlags & USBHUB_FDO_FLAG_PENDING_WAKE_IRP ||
                         !IsAllPortsD3)
                {
                    DevicePwrState.DeviceState = HubExtension->DeviceState[PowerState.SystemState];

                    if (DevicePwrState.DeviceState == PowerDeviceUnspecified)
                    {
                        goto Exit;
                    }
                }
                else
                {
                    DevicePwrState.DeviceState = PowerDeviceD3;
                }

                if (DevicePwrState.DeviceState != HubExtension->CurrentPowerState.DeviceState &&
                    HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_STARTED)
                {
                    HubExtension->PowerIrp = Irp;

                    IoMarkIrpPending(Irp);

                    if (PoRequestPowerIrp(HubExtension->LowerPDO,
                                          IRP_MN_SET_POWER,
                                          DevicePwrState,
                                          USBH_FdoDeferPoRequestCompletion,
                                          (PVOID)HubExtension,
                                          NULL) == STATUS_PENDING)
                    {
                        return STATUS_PENDING;
                    }

                    IoCopyCurrentIrpStackLocationToNext(Irp);
                    PoStartNextPowerIrp(Irp);
                    PoCallDriver(HubExtension->LowerDevice, Irp);

                    return STATUS_PENDING;
                }

            Exit:

                HubExtension->SystemPowerState.SystemState = PowerState.SystemState;

                if (PowerState.SystemState == PowerSystemWorking)
                {
                    USBH_CheckIdleDeferred(HubExtension);
                }

                IoCopyCurrentIrpStackLocationToNext(Irp);
                PoStartNextPowerIrp(Irp);

                return PoCallDriver(HubExtension->LowerDevice, Irp);
            }

            break;

        case IRP_MN_QUERY_POWER:
            DPRINT_PWR("USBH_FdoPower: IRP_MN_QUERY_POWER\n");
            break;

        default:
            DPRINT1("USBH_FdoPower: unknown IRP_MN_POWER!\n");
            break;
    }

    IoCopyCurrentIrpStackLocationToNext(Irp);
    PoStartNextPowerIrp(Irp);
    Status = PoCallDriver(HubExtension->LowerDevice, Irp);

    return Status;
}
Esempio n. 19
0
NTSTATUS
Serenum_DispatchPassThroughWithoutAcquire(
                           IN PDEVICE_OBJECT DeviceObject,
                           IN PIRP Irp
                           )
/*++
Routine Description:

    Passes a request on to the lower driver.

--*/
{
    PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
    BOOLEAN waitForEnum = FALSE;
    NTSTATUS rval;
    PFDO_DEVICE_DATA pFdoData;
    BOOLEAN isFdo;
   
    PCOMMON_DEVICE_DATA commonData=(PCOMMON_DEVICE_DATA)DeviceObject->DeviceExtension;
    isFdo = commonData->IsFDO;

    if (isFdo) {
        pFdoData = (PFDO_DEVICE_DATA)DeviceObject->DeviceExtension;

#if DBG
        switch (IrpStack->MajorFunction) {
        case IRP_MJ_READ:
            LOGENTRY(LOG_PASSTHROUGH, 'SFRD', DeviceObject, Irp, 0);
            break;

        case IRP_MJ_WRITE:
            LOGENTRY(LOG_PASSTHROUGH, 'SFWR', DeviceObject, Irp, 0);
            break;

        case IRP_MJ_DEVICE_CONTROL:
            LOGENTRY(LOG_PASSTHROUGH, 'SFDC', DeviceObject, Irp, 0);
            break;

        case IRP_MJ_CREATE:
            LOGENTRY(LOG_PASSTHROUGH, 'SFCR', DeviceObject, Irp, 0);
            break;

        case IRP_MJ_CLOSE:
            LOGENTRY(LOG_PASSTHROUGH, 'SFCL', DeviceObject, Irp, 0);
            break;

        default:
            break;
    }
#endif // DBG

    } else {
        pFdoData = ((PPDO_DEVICE_DATA) DeviceObject->DeviceExtension)->ParentFdo->DeviceExtension;

#if DBG
        switch (IrpStack->MajorFunction) {
            case IRP_MJ_READ:
                LOGENTRY(LOG_PASSTHROUGH, 'SPRD', DeviceObject, Irp, 0);
                break;

            case IRP_MJ_WRITE:
                LOGENTRY(LOG_PASSTHROUGH, 'SPWR', DeviceObject, Irp, 0);
                break;

            case IRP_MJ_DEVICE_CONTROL:
                LOGENTRY(LOG_PASSTHROUGH, 'SPDC', DeviceObject, Irp, 0);
                break;

            case IRP_MJ_CREATE:
                LOGENTRY(LOG_PASSTHROUGH, 'SPCR', DeviceObject, Irp, 0);
                break;

            case IRP_MJ_CLOSE:
                LOGENTRY(LOG_PASSTHROUGH, 'SPCL', DeviceObject, Irp, 0);
                break;

            default:
                break;
        }
#endif // DBG
    }

    if (IrpStack->MajorFunction == IRP_MJ_CREATE) {
        //
        // If we're doing an enumeration, we must wait here
        //

        waitForEnum = TRUE;

        LOGENTRY(LOG_PASSTHROUGH, 'SPCW', DeviceObject, Irp, 0);

        rval = KeWaitForSingleObject(&pFdoData->CreateSemaphore, Executive,
                                   KernelMode, FALSE, NULL);
        if (!NT_SUCCESS(rval)) {
            LOGENTRY(LOG_PASSTHROUGH, 'SPCF', DeviceObject, Irp, rval);
            Irp->IoStatus.Status = rval;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            IoReleaseRemoveLock(&commonData->RemoveLock, Irp);
            return rval;
        }
    }

    //
    // Pass the IRP to the target
    //

   

    if (waitForEnum){
        IoSkipCurrentIrpStackLocation (Irp);
        rval = IoCallDriver(pFdoData->TopOfStack, Irp);
        KeReleaseSemaphore(&pFdoData->CreateSemaphore, IO_NO_INCREMENT, 1, FALSE);
        IoReleaseRemoveLock(&commonData->RemoveLock, Irp);
    }else{
        rval=Serenum_Generic_FireAndRelease_RemoveLock(pFdoData->TopOfStack,Irp);
    }
    return rval;
}
Esempio n. 20
0
File: sema.c Progetto: ditsing/xfsd
int up( struct semaphore *sem)
{
	return KeReleaseSemaphore( ( KSEMAPHORE*)sem->sem, IO_NO_INCREMENT, 1, FALSE);
}
Esempio n. 21
0
VOID
FsRtlDeregisterUncProvider(
    __in HANDLE Handle
    )

/*++

Routine Description:

    This routine deregisters a redir as a UNC provider.

Arguments:

    Handle - A handle to the Multiple UNC router, returned by the
        registration call.

Return Value:

    None.

--*/

{
    NTSTATUS status;

    PAGED_CODE();

    if( Handle == (HANDLE)-1 || Handle == NULL )
        return;

    status = ZwClose( Handle );

    if( !NT_SUCCESS( status ) ) {
        return;
    }

    KeWaitForSingleObject(&FsRtlpUncSemaphore, Executive, KernelMode, FALSE, NULL );

    ASSERT( FsRtlpRedirs > 0 );

    if( Handle == FsRtlpDRD.ReturnedHandle ) {

        //
        // The first redir in the system is closing.  Release the state we saved
        //  for it, and pass the close on to the MUP if necessary
        //

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

        if( FsRtlpDRD.MupHandle != (HANDLE)-1 ) {
            ZwClose( FsRtlpDRD.MupHandle );
            FsRtlpDRD.MupHandle = (HANDLE)-1;
        }

        FsRtlpDRD.ReturnedHandle = (HANDLE)-1;

    }

    if( --FsRtlpRedirs == 0 ) {
        FsRtlpSetSymbolicLink( (PUNICODE_STRING)NULL );
    }

    KeReleaseSemaphore(&FsRtlpUncSemaphore, 0, 1, FALSE );
}
Esempio n. 22
0
NTSTATUS
FsRtlRegisterUncProvider(
    __inout PHANDLE MupHandle,
    __in PUNICODE_STRING RedirDevName,
    __in BOOLEAN MailslotsSupported
    )
/*++

Routine Description:

    This routine registers a redir as a UNC provider.

Arguments:

    Handle - Pointer to a handle.  The handle is returned by the routine
        to be used when calling FsRtlDeregisterUncProvider.
        It is valid only if the routines returns STATUS_SUCCESS.

    RedirDevName - The device name of the redir.

    MailslotsSupported - If TRUE, this redir supports mailslots.

Return Value:

    NTSTATUS - The status of the operation.

--*/
{
    NTSTATUS status;
    HANDLE mupHandle = (HANDLE)-1;
    UNICODE_STRING mupDriverName;
    BOOLEAN dfsEnabled;

    PAGED_CODE();

    KeWaitForSingleObject(&FsRtlpUncSemaphore, Executive, KernelMode, FALSE, NULL );

    if (FsRtlpRedirs == 0) {

        dfsEnabled = FsRtlpIsDfsEnabled();

        if (dfsEnabled) {
            FsRtlpRedirs = 1;
            RtlZeroMemory((PVOID) &FsRtlpDRD, sizeof(FsRtlpDRD));
        }

    }

    switch( FsRtlpRedirs ) {
    case 0:
        //
        // Ok, the MUP isn't there and we don't need to use the
        //   MUP for the first redir.
        //
        // We need to return a handle, but we're not really using the MUP yet.
        //   And we may never use it (if there's only 1 redir).  Return
        //   a handle to the NULL device object, since we're committed to returning
        //   a handle to our caller.  Our caller isn't supposed to do anything with
        //   the handle except to call FsRtlDeregisterUncProvider() with it.
        //
        status = FsRtlpOpenDev( &mupHandle, DevNull );

        if( !NT_SUCCESS( status ) )
            break;

        //
        // Save up enough state to allow us to call the MUP later with
        // this registration info if necessary.
        //
        FsRtlpDRD.RedirDevName.Buffer = ExAllocatePoolWithTag( NonPagedPool, 
                                                               RedirDevName->MaximumLength, 
                                                               MODULE_POOL_TAG );

        if( FsRtlpDRD.RedirDevName.Buffer == NULL ) {
            status =  STATUS_INSUFFICIENT_RESOURCES;
            break;
        }

        FsRtlpDRD.RedirDevName.Length = RedirDevName->Length;
        FsRtlpDRD.RedirDevName.MaximumLength = RedirDevName->MaximumLength;

        RtlCopyMemory(
                (PCHAR)FsRtlpDRD.RedirDevName.Buffer,
                RedirDevName->Buffer,
                RedirDevName->MaximumLength
        );

        FsRtlpDRD.MailslotsSupported = MailslotsSupported;
        FsRtlpDRD.ReturnedHandle = mupHandle;
        FsRtlpDRD.MupHandle = (HANDLE)-1;

        //
        // Set the UNC symbolic link to point to the redir we just loaded
        //
        FsRtlpSetSymbolicLink( RedirDevName );

        break;

    default:
        //
        // This is the second or later redir load -- MUST use the MUP
        //
        status = FsRtlpOpenDev( &mupHandle, DevMup );

        if( !NT_SUCCESS( status ) ) {

            RtlInitUnicodeString( &mupDriverName, MupRegKey );

            (VOID)ZwLoadDriver( &mupDriverName );

            status = FsRtlpOpenDev( &mupHandle, DevMup );
            if( !NT_SUCCESS( status ) )
                break;
        }

        //
        // See if we need to tell the MUP about the first redir that registered
        //
        if( FsRtlpDRD.RedirDevName.Buffer ) {

            status = FsRtlpRegisterProviderWithMUP( mupHandle,
                    &FsRtlpDRD.RedirDevName,
                    FsRtlpDRD.MailslotsSupported );

            if( !NT_SUCCESS( status ) )
                break;

            FsRtlpDRD.MupHandle = mupHandle;

            ExFreePool( FsRtlpDRD.RedirDevName.Buffer );
            FsRtlpDRD.RedirDevName.Buffer = NULL;

            //
            // Set the UNC symbolic link to point to the MUP
            //
            RtlInitUnicodeString(  &mupDriverName, DevMup );
            FsRtlpSetSymbolicLink( &mupDriverName );

            status = FsRtlpOpenDev( &mupHandle, DevMup );

            if( !NT_SUCCESS( status ) )
                break;
        }

        //
        //  Pass the request to the MUP for this redir
        //
        status = FsRtlpRegisterProviderWithMUP( mupHandle,
                        RedirDevName,
                        MailslotsSupported );
        break;

    }

    if( NT_SUCCESS( status ) ) {
        FsRtlpRedirs++;
        *MupHandle = mupHandle;

    } else {
        if( mupHandle != (HANDLE)-1 && mupHandle != NULL ) {
            ZwClose( mupHandle );
        }

        *MupHandle = (HANDLE)-1;
    }

    KeReleaseSemaphore(&FsRtlpUncSemaphore, 0, 1, FALSE );
    return status;
}
Esempio n. 23
0
VOID
LspUnload(
    IN PDRIVER_OBJECT DriverObject
    )
/*++

Routine Description:

    Free all the allocated resources, etc.

Arguments:

    DriverObject - pointer to a driver object.

Return Value:

    VOID
--*/
{
	NTSTATUS status;
    PDEVICE_OBJECT       deviceObject = DriverObject->DeviceObject;
    UNICODE_STRING      uniWin32NameString;
    PDEVICE_EXTENSION    deviceExtension = deviceObject->DeviceExtension;

    PAGED_CODE();

    LSP_KDPRINT(("LspUnload Enter\n"));

    //
    // Set the Stop flag
    //
    deviceExtension->ThreadShouldStop = TRUE;

    //
    // Make sure the thread wakes up 
    //
    KeReleaseSemaphore(&deviceExtension->IrpQueueSemaphore,
                        0,  // No priority boost
                        1,  // Increment semaphore by 1
                        TRUE );// WaitForXxx after this call

    //
    // Wait for the thread to terminate
    //
    KeWaitForSingleObject(deviceExtension->ThreadObject,
                        Executive,
                        KernelMode,
                        FALSE,
                        NULL );

    ObDereferenceObject(deviceExtension->ThreadObject);

	IoFreeWorkItem(deviceExtension->CloseWorkItem);

    //
    // Create counted string version of our Win32 device name.
    //

    RtlInitUnicodeString( &uniWin32NameString, LSP_DOS_DEVICE_NAME_U );

    IoDeleteSymbolicLink( &uniWin32NameString );

    ASSERT(!deviceObject->AttachedDevice);
    
    IoDeleteDevice( deviceObject );
 
    LSP_KDPRINT(("LspUnload Exit\n"));
    return;
}
// =========================================================================
// Destroy the specified device object, regardless of it's state
// Note: This can be called to destroy *either* the main device, *or* a
//       disk device
// Returns: The next device object
PDEVICE_OBJECT
DestroyDevice(
    IN PDEVICE_OBJECT devObj    
)
{
    NTSTATUS status;
    PDEVICE_EXTENSION devExt;
    PDEVICE_OBJECT nextDevObj;

    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("DestroyDevice\n"));
        
    nextDevObj = devObj->NextDevice;
    
    devExt = (PDEVICE_EXTENSION)devObj->DeviceExtension;    

    // Signal the device's thread to terminate, and wait until it does.
    devExt->TerminateThread = TRUE;
    CancelAllQueuedIRPs(devObj);
    if (devExt->ThreadObject != NULL) 
        {    
        // Make sure the thread wakes up, so it can see that it should terminate
        KeReleaseSemaphore(&devExt->IRPQueueSemaphore,
                            0,  // No priority boost
                            1,  // Increment semaphore by 1
                            TRUE );// WaitForXxx after this call

        // Wait for the thread to terminate
        KeWaitForSingleObject(devExt->ThreadObject,
                            Executive,
                            KernelMode,
                            FALSE,
                            NULL );

        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Wait completed; thread terminated.\n"));
        
        // Release the thread object ref
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Dereferencing ThreadObject...\n"));
        ObDereferenceObject(devExt->ThreadObject);
        devExt->ThreadObject = NULL;
        }
    

    // Tear down any symbolic device name link
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Tearing down main device specific...\n"));
    if (devExt->zzSymbolicLinkName.Buffer != NULL)
        {
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Tearing down symbolic device link...\n"));
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("About to delete symlink: %ls\n", devExt->zzSymbolicLinkName.Buffer));
        status = IoDeleteSymbolicLink(&devExt->zzSymbolicLinkName);
        if (!NT_SUCCESS(status))
            {
            DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("Status NOT OK\n"));
            }
        
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Freeing off symlink unicode buffer...\n")); 
        SecZeroMemory(
                        devExt->zzSymbolicLinkName.Buffer,
                        devExt->zzSymbolicLinkName.MaximumLength
                        );
        FREEOTFE_FREE(devExt->zzSymbolicLinkName.Buffer);
        devExt->zzSymbolicLinkName.Buffer = NULL;
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("OK.\n"));   
        }
        
    
    // Tear down any device name
    if (devExt->zzDeviceName.Buffer != NULL)
        {
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Freeing off devname unicode buffer...\n"));
        SecZeroMemory(
                      devExt->zzDeviceName.Buffer,
                      devExt->zzDeviceName.MaximumLength
                     );
        FREEOTFE_FREE(devExt->zzDeviceName.Buffer);
        devExt->zzDeviceName.Buffer = NULL;
        }
    

    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("OK.\n"));   
    
    // Cleardown details of hashes supported
    ImpHashDriverExtDetailsCleardown(&(devExt->DriverInfo));

    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("OK.\n"));   

    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Overwriting device extension memory...\n"));   
    SecZeroMemory(devExt, sizeof(DEVICE_EXTENSION));
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("OK.\n"));   

    // Get rid of the device object...
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Deleting device...\n"));   
    IoDeleteDevice(devObj);
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("OK.\n"));   
    

    DEBUGOUTHASHDRV(DEBUGLEV_EXIT, ("DestroyDevice\n"));
    
    return nextDevObj;
}
Esempio n. 25
0
/*
 * @implemented
 */
VOID
IssueUniqueIdChangeNotify(IN PDEVICE_EXTENSION DeviceExtension,
                          IN PUNICODE_STRING DeviceName,
                          IN PMOUNTDEV_UNIQUE_ID UniqueId)
{
    NTSTATUS Status;
    PVOID IrpBuffer = NULL;
    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    PUNIQUE_ID_WORK_ITEM WorkItem = NULL;

    /* Get the associated device object */
    Status = IoGetDeviceObjectPointer(DeviceName,
                                      FILE_READ_ATTRIBUTES,
                                      &FileObject,
                                      &DeviceObject);
    if (!NT_SUCCESS(Status))
    {
        return;
    }

    /* And then, get attached device */
    DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);

    ObDereferenceObject(FileObject);

    /* Allocate a work item */
    WorkItem = AllocatePool(sizeof(UNIQUE_ID_WORK_ITEM));
    if (!WorkItem)
    {
        ObDereferenceObject(DeviceObject);
        return;
    }

    WorkItem->Event = NULL;
    WorkItem->WorkItem = IoAllocateWorkItem(DeviceExtension->DeviceObject);
    if (!WorkItem->WorkItem)
    {
        ObDereferenceObject(DeviceObject);
        goto Cleanup;
    }

    WorkItem->DeviceExtension = DeviceExtension;
    WorkItem->StackSize = DeviceObject->StackSize;
    /* Already provide the IRP */
    WorkItem->Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);

    ObDereferenceObject(DeviceObject);

    if (!WorkItem->Irp)
    {
        goto Cleanup;
    }

    /* Ensure it has enough space */
    IrpBuffer = AllocatePool(sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024);
    if (!IrpBuffer)
    {
        goto Cleanup;
    }

    WorkItem->DeviceName.Length = DeviceName->Length;
    WorkItem->DeviceName.MaximumLength = DeviceName->Length + sizeof(WCHAR);
    WorkItem->DeviceName.Buffer = AllocatePool(WorkItem->DeviceName.MaximumLength);
    if (!WorkItem->DeviceName.Buffer)
    {
        goto Cleanup;
    }

    RtlCopyMemory(WorkItem->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length);
    WorkItem->DeviceName.Buffer[DeviceName->Length / sizeof(WCHAR)] = UNICODE_NULL;

    WorkItem->IrpBuffer = IrpBuffer;
    WorkItem->IrpBufferLength = sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024;

    /* Add the worker in the list */
    KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
    InsertHeadList(&(DeviceExtension->UniqueIdWorkerItemListHead), &(WorkItem->UniqueIdWorkerItemListEntry));
    KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);

    /* And call the worker */
    IssueUniqueIdChangeNotifyWorker(WorkItem, UniqueId);

    return;

Cleanup:
    if (IrpBuffer)
    {
        FreePool(IrpBuffer);
    }

    if (WorkItem->Irp)
    {
        IoFreeIrp(WorkItem->Irp);
    }

    if (WorkItem->WorkItem)
    {
        IoFreeWorkItem(WorkItem->WorkItem);
    }

    if (WorkItem)
    {
        FreePool(WorkItem);
    }
}
Esempio n. 26
0
static int init(void)
{
        KeReleaseSemaphore(&init_sem, 0, 1, 0);
	return 0;
}
Esempio n. 27
0
/*
 * @implemented
 */
VOID
MountMgrUniqueIdChangeRoutine(IN PDEVICE_EXTENSION DeviceExtension,
                              IN PMOUNTDEV_UNIQUE_ID OldUniqueId,
                              IN PMOUNTDEV_UNIQUE_ID NewUniqueId)
{
    NTSTATUS Status;
    BOOLEAN ResyncNeeded;
    PUNIQUE_ID_REPLICATE DuplicateId;
    PDEVICE_INFORMATION DeviceInformation;
    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
    PMOUNTDEV_UNIQUE_ID UniqueId, NewDuplicateId;
    PLIST_ENTRY ListHead, NextEntry, ReplicatedHead, NextReplicated;

    /* Synchronise with remote databases */
    Status = WaitForRemoteDatabaseSemaphore(DeviceExtension);
    KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);

    RtlZeroMemory(QueryTable, sizeof(QueryTable));
    QueryTable[0].QueryRoutine = ChangeUniqueIdRoutine;
    QueryTable[0].EntryContext = NewUniqueId;

    /* Write new data */
    RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
                           DatabasePath,
                           QueryTable,
                           OldUniqueId,
                           NULL);

    /* Browse all the devices to find the one that
     * owns the old unique ID
     */
    ListHead = &(DeviceExtension->DeviceListHead);
    NextEntry = ListHead->Flink;
    while (ListHead != NextEntry)
    {
        DeviceInformation = CONTAINING_RECORD(NextEntry,
                                              DEVICE_INFORMATION,
                                              DeviceListEntry);

        if (DeviceInformation->UniqueId->UniqueIdLength == OldUniqueId->UniqueIdLength &&
            RtlCompareMemory(OldUniqueId->UniqueId,
                             DeviceInformation->UniqueId->UniqueId,
                             OldUniqueId->UniqueIdLength) == OldUniqueId->UniqueIdLength)
        {
            break;
        }

        NextEntry = NextEntry->Flink;
    }

    /* If we didn't find any release everything and quit */
    if (ListHead == NextEntry)
    {
        KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT,
                           1, FALSE);

        if (NT_SUCCESS(Status))
        {
            ReleaseRemoteDatabaseSemaphore(DeviceExtension);
        }

        return;
    }

    /* If lock failed, then, just update this database */
    if (!NT_SUCCESS(Status))
    {
        ReconcileThisDatabaseWithMaster(DeviceExtension, DeviceInformation);
        KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT,
                           1, FALSE);
        return;
    }

    /* Allocate new unique ID */
    UniqueId = AllocatePool(NewUniqueId->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
    if (!UniqueId)
    {
        KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT,
                           1, FALSE);
        ReleaseRemoteDatabaseSemaphore(DeviceExtension);
        return;
    }

    /* Release old one */
    FreePool(DeviceInformation->UniqueId);
    /* And set new one */
    DeviceInformation->UniqueId = UniqueId;
    UniqueId->UniqueIdLength = NewUniqueId->UniqueIdLength;
    RtlCopyMemory(UniqueId->UniqueId, NewUniqueId->UniqueId, NewUniqueId->UniqueIdLength);

    /* Now, check if it's required to update replicated unique IDs as well */
    ListHead = &(DeviceExtension->DeviceListHead);
    NextEntry = ListHead->Flink;
    while (ListHead != NextEntry)
    {
        DeviceInformation = CONTAINING_RECORD(NextEntry,
                                              DEVICE_INFORMATION,
                                              DeviceListEntry);
        ResyncNeeded = FALSE;

        ReplicatedHead = &(DeviceInformation->ReplicatedUniqueIdsListHead);
        NextReplicated = ReplicatedHead->Flink;
        while (ReplicatedHead != NextReplicated)
        {
            DuplicateId = CONTAINING_RECORD(NextReplicated,
                                            UNIQUE_ID_REPLICATE,
                                            ReplicatedUniqueIdsListEntry);

            if (DuplicateId->UniqueId->UniqueIdLength == OldUniqueId->UniqueIdLength)
            {
                if (RtlCompareMemory(DuplicateId->UniqueId->UniqueId,
                                     OldUniqueId->UniqueId,
                                     OldUniqueId->UniqueIdLength) == OldUniqueId->UniqueIdLength)
                {
                    /* It was our old unique ID */
                    NewDuplicateId = AllocatePool(NewUniqueId->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
                    if (NewDuplicateId)
                    {
                        /* Update it */
                        ResyncNeeded = TRUE;
                        FreePool(DuplicateId->UniqueId);

                        DuplicateId->UniqueId = NewDuplicateId;
                        DuplicateId->UniqueId->UniqueIdLength = NewUniqueId->UniqueIdLength;
                        RtlCopyMemory(NewDuplicateId->UniqueId, NewUniqueId->UniqueId, NewUniqueId->UniqueIdLength);
                    }
                }
            }

            NextReplicated = NextReplicated->Flink;
        }

        /* If resync is required on this device, do it */
        if (ResyncNeeded)
        {
            ChangeRemoteDatabaseUniqueId(DeviceInformation, OldUniqueId, NewUniqueId);
        }

        NextEntry = NextEntry->Flink;
    }

    KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
    ReleaseRemoteDatabaseSemaphore(DeviceExtension);

    return;
}
Esempio n. 28
0
NTSTATUS 
MiniSecondaryPassThrough (
	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;

	PrintData( LFS_DEBUG_SECONDARY_INFO, "MiniSecondaryPassThrough", Secondary->LfsDeviceExt, Data );

	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_LookUpCcb(Secondary, fileObject) == NULL );

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

			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, Data );

		Secondary_Dereference( Secondary );

		return FLT_PREOP_SUCCESS_NO_CALLBACK;

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

		PLFS_CCB	ccb = NULL;

		ccb = Secondary_LookUpCcb(Secondary, fileObject);
		
		if (ccb == NULL || ccb->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, Data );
	
	if (Secondary->Thread.SessionStatus == STATUS_DISK_CORRUPT_ERROR) {

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

		if (iopb->MajorFunction == IRP_MJ_CLOSE) {

			if (Secondary_LookUpCcb(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_LookUpCcb(Secondary, fileObject) == NULL );

		if (iopb->MajorFunction == IRP_MJ_CLOSE) {

			if (Secondary_LookUpCcb(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_LookUpCcb(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_LookUpCcb(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), 
					  Data );

			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;
}
Esempio n. 29
0
NTSTATUS
NtSignalAndWaitForSingleObject(
    IN HANDLE SignalHandle,
    IN HANDLE WaitHandle,
    IN BOOLEAN Alertable,
    IN PLARGE_INTEGER Timeout OPTIONAL
    )

/*++

Routine Description:

    This function atomically signals the specified signal object and then
    waits until the specified wait object attains a state of Signaled. An
    optional timeout can also be specified. If a timeout is not specified,
    then the wait will not be satisfied until the wait object attains a
    state of Signaled. If a timeout is specified, and the wait object has
    not attained a state of Signaled when the timeout expires, then the
    wait is automatically satisfied. If an explicit timeout value of zero
    is specified, then no wait will occur if the wait cannot be satisfied
    immediately. The wait can also be specified as alertable.

Arguments:

    SignalHandle - supplies the handle of the signal object.

    WaitHandle  - Supplies the handle for the wait object.

    Alertable - Supplies a boolean value that specifies whether the wait
        is alertable.

    Timeout - Supplies an pointer to an absolute or relative time over
        which the wait is to occur.

Return Value:

    The wait completion status. A value of STATUS_TIMEOUT is returned if a
    timeout occurred. A value of STATUS_SUCCESS is returned if the specified
    object satisfied the wait. A value of STATUS_ALERTED is returned if the
    wait was aborted to deliver an alert to the current thread. A value of
    STATUS_USER_APC is returned if the wait was aborted to deliver a user
    APC to the current thread.

--*/

{

    OBJECT_HANDLE_INFORMATION HandleInformation;
    KPROCESSOR_MODE PreviousMode;
    PVOID RealObject;
    PVOID SignalObject;
    POBJECT_HEADER SignalObjectHeader;
    NTSTATUS Status;
    LARGE_INTEGER TimeoutValue;
    PVOID WaitObject;
    POBJECT_HEADER WaitObjectHeader;

    //
    // Establish an exception handler and probe the specified timeout value
    // if necessary. If the probe fails, then return the exception code as
    // the service status.
    //

    PreviousMode = KeGetPreviousMode();
    if ((ARGUMENT_PRESENT(Timeout)) && (PreviousMode != KernelMode)) {
        try {
            TimeoutValue = ProbeAndReadLargeInteger(Timeout);
            Timeout = &TimeoutValue;

        } except(EXCEPTION_EXECUTE_HANDLER) {
            return GetExceptionCode();
        }
    }

    //
    // Reference the signal object by handle.
    //

    Status = ObReferenceObjectByHandle(SignalHandle,
                                       0,
                                       NULL,
                                       PreviousMode,
                                       &SignalObject,
                                       &HandleInformation);

    //
    // If the reference was successful, then reference the wait object by
    // handle.
    //

    if (NT_SUCCESS(Status)) {
        Status = ObReferenceObjectByHandle(WaitHandle,
                                           SYNCHRONIZE,
                                           NULL,
                                           PreviousMode,
                                           &WaitObject,
                                           NULL);

        //
        // If the reference was successful, then determine the real wait
        // object, check the signal object access, signal the signal object,
        // and wait for the real wait object.
        //

        if (NT_SUCCESS(Status)) {
            WaitObjectHeader = OBJECT_TO_OBJECT_HEADER(WaitObject);
            RealObject = WaitObjectHeader->Type->DefaultObject;
            if ((LONG)RealObject >= 0) {
                RealObject = (PVOID)((PCHAR)WaitObject + (ULONG)RealObject);
            }

            //
            // If the signal object is an event, then check for modify access
            // and set the event. Otherwise, if the signal object is a mutant,
            // then attempt to release ownership of the mutant. Otherwise, if
            // the object is a semaphore, then check for modify access and
            // release the semaphore. Otherwise, the signal objet is invalid.
            //

            SignalObjectHeader = OBJECT_TO_OBJECT_HEADER(SignalObject);
            Status = STATUS_ACCESS_DENIED;
            if (SignalObjectHeader->Type == ExEventObjectType) {

                //
                // Check for access to the specified event object,
                //

                if ((PreviousMode != KernelMode) &&
                    (SeComputeDeniedAccesses(HandleInformation.GrantedAccess,
                                             EVENT_MODIFY_STATE) != 0)) {
                    goto WaitExit;
                }

                //
                // If the wait object is also an event, the wait is not
                // alertable, and no timeout was specified, then the event
                // pair path can be used. Otherwise, set the event and wait
                // atomically.
                //

                if ((WaitObjectHeader->Type == ExEventObjectType) &&
                    (Alertable == FALSE) &&
                    (Timeout == NULL)) {
                    Status = KiSetServerWaitClientEvent((PKEVENT)SignalObject,
                                                        (PKEVENT)RealObject,
                                                        PreviousMode);

                    goto WaitExit;
                }

                //
                // Set the specified event and wait atomically.
                //

                KeSetEvent((PKEVENT)SignalObject, EVENT_INCREMENT, TRUE);

            } else if (SignalObjectHeader->Type == ExMutantObjectType) {

                //
                // Release the specified mutant and wait atomically.
                //
                // N.B. The release will only be successful if the current
                //      thread is the owner of the mutant.
                //

                try {
                    KeReleaseMutant((PKMUTANT)SignalObject,
                                    MUTANT_INCREMENT,
                                    FALSE,
                                    TRUE);

                } except(EXCEPTION_EXECUTE_HANDLER) {
                    Status = GetExceptionCode();
                    goto WaitExit;
                }

            } else if (SignalObjectHeader->Type == ExSemaphoreObjectType) {

                //
                // Check for access to the specified semaphore object,
                //

                if ((PreviousMode != KernelMode) &&
                    (SeComputeDeniedAccesses(HandleInformation.GrantedAccess,
                                             SEMAPHORE_MODIFY_STATE) != 0)) {
                    goto WaitExit;
                }

                //
                // Release the specified semaphore and wait atomically.
                //

                try {

                    //
                    // If the wait object is also a semaphore, the wait is
                    // not alertable, and no timeout was specified, then
                    // the semaphore path can be used. Otherwise, release
                    // the semaphore and wait atomically.
                    //

                    if ((WaitObjectHeader->Type == ExSemaphoreObjectType) &&
                        (Alertable == FALSE) &&
                        (Timeout == NULL)) {
                        Status = KeReleaseWaitForSemaphore((PKSEMAPHORE)SignalObject,
                                                           (PKSEMAPHORE)RealObject,
                                                           UserRequest,
                                                           PreviousMode);

                        goto WaitExit;
                    }

                    //
                    // Release the specified semaphore and wait atomically.
                    //

                    KeReleaseSemaphore((PKSEMAPHORE)SignalObject,
                                       SEMAPHORE_INCREMENT,
                                       1,
                                       TRUE);

                } except(EXCEPTION_EXECUTE_HANDLER) {
                    Status = GetExceptionCode();
                    goto WaitExit;
                }

            } else {
                Status =
                STATUS_OBJECT_TYPE_MISMATCH;
                goto WaitExit;
            }

            Status = KeWaitForSingleObject(RealObject,
                                           UserRequest,
                                           PreviousMode,
                                           Alertable,
                                           Timeout);

        WaitExit:
            ObDereferenceObject(WaitObject);
        }
Esempio n. 30
0
VOID
NTAPI
LpcpDestroyPortQueue(IN PLPCP_PORT_OBJECT Port,
                     IN BOOLEAN Destroy)
{
    PLIST_ENTRY ListHead, NextEntry;
    PETHREAD Thread;
    PLPCP_MESSAGE Message;
    PLPCP_PORT_OBJECT ConnectionPort = NULL;
    PLPCP_CONNECTION_MESSAGE ConnectMessage;
    PLPCP_NONPAGED_PORT_QUEUE MessageQueue;

    PAGED_CODE();
    LPCTRACE(LPC_CLOSE_DEBUG, "Port: %p. Flags: %lx\n", Port, Port->Flags);

    /* Hold the lock */
    KeAcquireGuardedMutex(&LpcpLock);

    /* Check if we have a connected port */
    if (((Port->Flags & LPCP_PORT_TYPE_MASK) != LPCP_UNCONNECTED_PORT) &&
        (Port->ConnectedPort))
    {
        /* Disconnect it */
        Port->ConnectedPort->ConnectedPort = NULL;
        ConnectionPort = Port->ConnectedPort->ConnectionPort;
        if (ConnectionPort)
        {
            /* Clear connection port */
            Port->ConnectedPort->ConnectionPort = NULL;
        }
    }

    /* Check if this is a connection port */
    if ((Port->Flags & LPCP_PORT_TYPE_MASK) == LPCP_CONNECTION_PORT)
    {
        /* Delete the name */
        Port->Flags |= LPCP_NAME_DELETED;
    }

    /* Walk all the threads waiting and signal them */
    ListHead = &Port->LpcReplyChainHead;
    NextEntry = ListHead->Flink;
    while ((NextEntry) && (NextEntry != ListHead))
    {
        /* Get the Thread */
        Thread = CONTAINING_RECORD(NextEntry, ETHREAD, LpcReplyChain);

        /* Make sure we're not in exit */
        if (Thread->LpcExitThreadCalled) break;

        /* Move to the next entry */
        NextEntry = NextEntry->Flink;

        /* Remove and reinitialize the List */
        RemoveEntryList(&Thread->LpcReplyChain);
        InitializeListHead(&Thread->LpcReplyChain);

        /* Check if someone is waiting */
        if (!KeReadStateSemaphore(&Thread->LpcReplySemaphore))
        {
            /* Get the message */
            Message = LpcpGetMessageFromThread(Thread);
            if (Message)
            {
                /* Check if it's a connection request */
                if (Message->Request.u2.s2.Type == LPC_CONNECTION_REQUEST)
                {
                    /* Get the connection message */
                    ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(Message + 1);

                    /* Check if it had a section */
                    if (ConnectMessage->SectionToMap)
                    {
                        /* Dereference it */
                        ObDereferenceObject(ConnectMessage->SectionToMap);
                    }
                }

                /* Clear the reply message */
                Thread->LpcReplyMessage = NULL;

                /* And remove the message from the port zone */
                LpcpFreeToPortZone(Message, LPCP_LOCK_HELD);
                NextEntry = Port->LpcReplyChainHead.Flink;
            }

            /* Release the semaphore and reset message id count */
            Thread->LpcReplyMessageId = 0;
            KeReleaseSemaphore(&Thread->LpcReplySemaphore, 0, 1, FALSE);
        }
    }

    /* Reinitialize the list head */
    InitializeListHead(&Port->LpcReplyChainHead);

    /* Loop queued messages */
    while ((Port->MsgQueue.ReceiveHead.Flink) &&
           !(IsListEmpty(&Port->MsgQueue.ReceiveHead)))
    {
        /* Get the message */
        Message = CONTAINING_RECORD(Port->MsgQueue.ReceiveHead.Flink,
                                    LPCP_MESSAGE,
                                    Entry);

        /* Free and reinitialize it's list head */
        RemoveEntryList(&Message->Entry);
        InitializeListHead(&Message->Entry);

        /* Remove it from the port zone */
        LpcpFreeToPortZone(Message, LPCP_LOCK_HELD);
    }

    /* Release the lock */
    KeReleaseGuardedMutex(&LpcpLock);

    /* Dereference the connection port */
    if (ConnectionPort) ObDereferenceObject(ConnectionPort);

    /* Check if we have to free the port entirely */
    if (Destroy)
    {
        /* Check if the semaphore exists */
        if (Port->MsgQueue.Semaphore)
        {
            /* Use the semaphore to find the port queue and free it */
            MessageQueue = CONTAINING_RECORD(Port->MsgQueue.Semaphore,
                                             LPCP_NONPAGED_PORT_QUEUE,
                                             Semaphore);
            ExFreePoolWithTag(MessageQueue, 'troP');
        }
    }
}