Esempio n. 1
0
static NTSTATUS
Pkt0DispatchWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    PIO_WORKITEM work_item;
    KIRQL old_irql;
    NTSTATUS status;

    work_item = IoAllocateWorkItem(DeviceObject);
    if (work_item == NULL) {
        return Pkt0CompleteIrp(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
    }

    KeAcquireSpinLock(&Pkt0ContextLock, &old_irql);
    if (Pkt0Context->closing) {
        status = Pkt0CompleteIrp(Irp, STATUS_PIPE_CLOSING, 0);
    } else {
        InsertTailList(&Pkt0Context->irp_write_queue, &Irp->Tail.Overlay.ListEntry);
        IoMarkIrpPending(Irp);
        status = STATUS_PENDING;
    }
    KeReleaseSpinLock(&Pkt0ContextLock, old_irql);

    if (status == STATUS_PENDING) {
        IoQueueWorkItemEx(work_item, Pkt0DeferredWrite, DelayedWorkQueue, NULL);
    } else {
        IoFreeWorkItem(work_item);
    }

    return status;
}
Esempio n. 2
0
NTSTATUS
HidUmdfInternalIoctl(
    _In_ PDEVICE_OBJECT DeviceObject,
    _Inout_ PIRP Irp
    )
{
    PIO_WORKITEM workitem;
    NTSTATUS status;

    //
    // If Irql is not dispatch, handle it in the current thread.
    // otherwise queue a workitem because UMDF cannot handle io request at 
    // dispatch level. HID minidriver receives IOCTLS normally at
    // passive level but it may receive ping pong irp at dispatch level in some
    // error conditions.  
    //
    if (KeGetCurrentIrql() < DISPATCH_LEVEL) {
        return HidUmdfInternalIoctlWorker(DeviceObject, Irp);        
    }

    //
    // allocate and queue workitem
    //
    workitem = IoAllocateWorkItem(DeviceObject);
    if (workitem == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        KdPrint(("HidUmdf: Failed to allocate workitem to process IOCTL "
            "0x%p devobj 0x%p sent at dispatch level. status 0x%x\n", 
            Irp, DeviceObject, status));
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
    }

    //
    // since we are going to return STATUS_PENDING, mark the irp pending.
    //
    IoMarkIrpPending(Irp);

    //
    // Queue the workitem. The workitem will be freed by the worker function.
    //
    IoQueueWorkItemEx(workitem, IoctlWorkItemEx, DelayedWorkQueue, Irp);

    return STATUS_PENDING;
}
Esempio n. 3
0
NTSTATUS Log_Print(LOG_LEVEL Level, LPCSTR pszFormat, ...)
{
	NTSTATUS Status = STATUS_SUCCESS;
	LARGE_INTEGER SystemTime, LocalTime;
	TIME_FIELDS TimeFields;
	PLOG_COUNTED_STRING Line = NULL;
	va_list args;
	KIRQL Irql = KeGetCurrentIrql();
	LPCSTR StrLevel = "       :";

	if (!LogFile)
		return STATUS_INVALID_DEVICE_STATE;

	if (Irql > DISPATCH_LEVEL)
		return STATUS_INVALID_LEVEL;

	KeQuerySystemTime(&SystemTime);
	ExSystemTimeToLocalTime(&SystemTime, &LocalTime);
	RtlTimeToTimeFields(&LocalTime, &TimeFields);

	Line = ExAllocatePoolWithTag(NonPagedPool, MAX_LOG_STRING_SIZE + FIELD_OFFSET(LOG_COUNTED_STRING, Data), LogAllocationTag);
	if (!Line)
		return STATUS_INSUFFICIENT_RESOURCES;

	switch (Level)
	{
	case LL_FATAL:
#if DBG
		DbgBreakPointWithStatus(DBG_STATUS_FATAL);
#endif
		StrLevel = "FATAL  :";
		break;
	case LL_ERROR:
		StrLevel = "ERROR  :";
		break;
	case LL_WARNING:
		StrLevel = "WARNING:";
		break;
	case LL_INFO:
		StrLevel = "INFO   :";
		break;
	case LL_VERBOSE:
		StrLevel = "VERBOSE:";
		break;
	case LL_DEBUG:
		StrLevel = "DEBUG  :";
		break;
	}

	Status = StringCbPrintfA(Line->Data, MAX_LOG_STRING_SIZE, "%04u.%02u.%02u %02u:%02u:%02u.%03u PR:0x%04X TH:0x%04X IL:%d %s ",
		TimeFields.Year,
		TimeFields.Month,
		TimeFields.Day,
		TimeFields.Hour,
		TimeFields.Minute,
		TimeFields.Second,
		TimeFields.Milliseconds,
		(ULONG)PsGetCurrentProcessId() & 0xFFFF,
		(ULONG)PsGetCurrentThreadId() & 0xFFFF,
		(ULONG)Irql,
		StrLevel);

	if (SUCCEEDED(Status))
	{
		va_start(args, pszFormat);
		Line->DataLength = (USHORT)strlen(Line->Data);
		Status = StringCbVPrintfA(Line->Data + Line->DataLength, MAX_LOG_STRING_SIZE - Line->DataLength, pszFormat, args);
		if (SUCCEEDED(Status))
		{
			Line->DataLength = (USHORT)strlen(Line->Data);
			if (Irql != PASSIVE_LEVEL) {
				PIO_WORKITEM pWorkItem = IoAllocateWorkItem(LogDeviceObject);
				InterlockedIncrement(&LogScheduledPrints);
				IoQueueWorkItemEx(pWorkItem, Log_WriteWorker, DelayedWorkQueue, Line);
				Status = STATUS_PENDING;
			}
			else
			{
				Status = Log_WriteLine(Line);
			}
		}

		va_end(args);
	}

	if (Status != STATUS_PENDING)
		ExFreePoolWithTag(Line, LogAllocationTag);

	return Status;
}