Exemplo n.º 1
1
NTSTATUS
NTAPI
PcRegisterSubdevice(
    IN  PDEVICE_OBJECT DeviceObject,
    IN  PWCHAR Name,
    IN  PUNKNOWN Unknown)
{
    PPCLASS_DEVICE_EXTENSION DeviceExt;
    NTSTATUS Status;
    ISubdevice *SubDevice;
    UNICODE_STRING SymbolicLinkName;
    PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
    ULONG Index;
    UNICODE_STRING RefName;
    PSYMBOLICLINK_ENTRY SymEntry;

    DPRINT("PcRegisterSubdevice DeviceObject %p Name %S Unknown %p\n", DeviceObject, Name, Unknown);

    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    // check if all parameters are valid
    if (!DeviceObject || !Name || !Unknown)
    {
        DPRINT("PcRegisterSubdevice invalid parameter\n");
        return STATUS_INVALID_PARAMETER;
    }

    // get device extension
    DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    if (!DeviceExt)
    {
        // should not happen
        DbgBreakPoint();
        return STATUS_UNSUCCESSFUL;
    }

    // look up our undocumented interface
    Status = Unknown->QueryInterface(IID_ISubdevice, (LPVOID*)&SubDevice);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("No ISubdevice interface\n");
        // the provided port driver doesnt support ISubdevice
        return STATUS_INVALID_PARAMETER;
    }

    // get the subdevice descriptor
    Status = SubDevice->GetDescriptor(&SubDeviceDescriptor);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Failed to get subdevice descriptor %x\n", Status);
        SubDevice->Release();
        return STATUS_UNSUCCESSFUL;
    }

    // add an create item to the device header
    Status = KsAddObjectCreateItemToDeviceHeader(DeviceExt->KsDeviceHeader, PcCreateItemDispatch, (PVOID)SubDevice, Name, NULL);
    if (!NT_SUCCESS(Status))
    {
        // failed to attach
        SubDevice->Release();
        DPRINT("KsAddObjectCreateItemToDeviceHeader failed with %x\n", Status);
        return Status;
    }

    // initialize reference string
    RtlInitUnicodeString(&RefName, Name);
    RtlInitUnicodeString(&SubDeviceDescriptor->RefString, Name);

    for(Index = 0; Index < SubDeviceDescriptor->InterfaceCount; Index++)
    {
        // FIXME
        // check if reference string with that name already exists
        
        Status = IoRegisterDeviceInterface(DeviceExt->PhysicalDeviceObject,
                                           &SubDeviceDescriptor->Interfaces[Index],
                                           &RefName,
                                           &SymbolicLinkName);

        if (NT_SUCCESS(Status))
        {
            // activate device interface
            IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
            // allocate symbolic link entry
            SymEntry = (PSYMBOLICLINK_ENTRY)AllocateItem(NonPagedPool, sizeof(SYMBOLICLINK_ENTRY), TAG_PORTCLASS);
            if (SymEntry)
            {
                // initialize symbolic link item
                RtlInitUnicodeString(&SymEntry->SymbolicLink, SymbolicLinkName.Buffer);
                // store item
                InsertTailList(&SubDeviceDescriptor->SymbolicLinkList, &SymEntry->Entry);
            }
            else
            {
                // allocating failed
                RtlFreeUnicodeString(&SymbolicLinkName);
            }
        }
    }

    // release SubDevice reference
    SubDevice->Release();

    return STATUS_SUCCESS;
}
Exemplo n.º 2
0
void add_volume_device(superblock* sb, PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath, UINT64 length, ULONG disk_num, ULONG part_num) {
    NTSTATUS Status;
    LIST_ENTRY* le;
    PDEVICE_OBJECT DeviceObject;
    volume_child* vc;
    PFILE_OBJECT FileObject;
    UNICODE_STRING devpath2;
    BOOL inserted = FALSE, new_pdo = FALSE;
    pdo_device_extension* pdode = NULL;
    PDEVICE_OBJECT pdo = NULL;

    if (devpath->Length == 0)
        return;

    ExAcquireResourceExclusiveLite(&pdo_list_lock, TRUE);

    le = pdo_list.Flink;
    while (le != &pdo_list) {
        pdo_device_extension* pdode2 = CONTAINING_RECORD(le, pdo_device_extension, list_entry);

        if (RtlCompareMemory(&pdode2->uuid, &sb->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
            pdode = pdode2;
            break;
        }

        le = le->Flink;
    }

    Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject);
    if (!NT_SUCCESS(Status)) {
        ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
        ExReleaseResourceLite(&pdo_list_lock);
        return;
    }

    if (!pdode) {
        if (no_pnp) {
            Status = IoReportDetectedDevice(drvobj, InterfaceTypeUndefined, 0xFFFFFFFF, 0xFFFFFFFF, NULL, NULL, 0, &pdo);

            if (!NT_SUCCESS(Status)) {
                ERR("IoReportDetectedDevice returned %08x\n", Status);
                ExReleaseResourceLite(&pdo_list_lock);
                return;
            }

            pdode = ExAllocatePoolWithTag(NonPagedPool, sizeof(pdo_device_extension), ALLOC_TAG);

            if (!pdode) {
                ERR("out of memory\n");
                ExReleaseResourceLite(&pdo_list_lock);
                return;
            }
        } else {
            Status = IoCreateDevice(drvobj, sizeof(pdo_device_extension), NULL, FILE_DEVICE_DISK,
                                    FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &pdo);
            if (!NT_SUCCESS(Status)) {
                ERR("IoCreateDevice returned %08x\n", Status);
                ExReleaseResourceLite(&pdo_list_lock);
                goto fail;
            }

            pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;

            pdode = pdo->DeviceExtension;
        }

        RtlZeroMemory(pdode, sizeof(pdo_device_extension));

        pdode->type = VCB_TYPE_PDO;
        pdode->pdo = pdo;
        pdode->uuid = sb->uuid;

        ExInitializeResourceLite(&pdode->child_lock);
        InitializeListHead(&pdode->children);
        pdode->num_children = sb->num_devices;
        pdode->children_loaded = 0;

        pdo->Flags &= ~DO_DEVICE_INITIALIZING;
        pdo->SectorSize = (USHORT)sb->sector_size;

        ExAcquireResourceExclusiveLite(&pdode->child_lock, TRUE);

        new_pdo = TRUE;
    } else {
        ExAcquireResourceExclusiveLite(&pdode->child_lock, TRUE);
        ExConvertExclusiveToSharedLite(&pdo_list_lock);

        le = pdode->children.Flink;
        while (le != &pdode->children) {
            volume_child* vc2 = CONTAINING_RECORD(le, volume_child, list_entry);

            if (RtlCompareMemory(&vc2->uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
                // duplicate, ignore
                ExReleaseResourceLite(&pdode->child_lock);
                ExReleaseResourceLite(&pdo_list_lock);
                goto fail;
            }

            le = le->Flink;
        }
    }

    vc = ExAllocatePoolWithTag(PagedPool, sizeof(volume_child), ALLOC_TAG);
    if (!vc) {
        ERR("out of memory\n");

        ExReleaseResourceLite(&pdode->child_lock);
        ExReleaseResourceLite(&pdo_list_lock);

        goto fail;
    }

    vc->uuid = sb->dev_item.device_uuid;
    vc->devid = sb->dev_item.dev_id;
    vc->generation = sb->generation;
    vc->notification_entry = NULL;

    Status = IoRegisterPlugPlayNotification(EventCategoryTargetDeviceChange, 0, FileObject,
                                            drvobj, pnp_removal, pdode, &vc->notification_entry);
    if (!NT_SUCCESS(Status))
        WARN("IoRegisterPlugPlayNotification returned %08x\n", Status);

    vc->devobj = DeviceObject;
    vc->fileobj = FileObject;

    devpath2 = *devpath;

    // The PNP path sometimes begins \\?\ and sometimes \??\. We need to remove this prefix
    // so we can compare properly if the device is removed.
    if (devpath->Length > 4 * sizeof(WCHAR) && devpath->Buffer[0] == '\\' && (devpath->Buffer[1] == '\\' || devpath->Buffer[1] == '?') &&
        devpath->Buffer[2] == '?' && devpath->Buffer[3] == '\\') {
        devpath2.Buffer = &devpath2.Buffer[3];
        devpath2.Length -= 3 * sizeof(WCHAR);
        devpath2.MaximumLength -= 3 * sizeof(WCHAR);
    }

    vc->pnp_name.Length = vc->pnp_name.MaximumLength = devpath2.Length;
    vc->pnp_name.Buffer = ExAllocatePoolWithTag(PagedPool, devpath2.Length, ALLOC_TAG);

    if (vc->pnp_name.Buffer)
        RtlCopyMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length);
    else {
        ERR("out of memory\n");
        vc->pnp_name.Length = vc->pnp_name.MaximumLength = 0;
    }

    vc->size = length;
    vc->seeding = sb->flags & BTRFS_SUPERBLOCK_FLAGS_SEEDING ? TRUE : FALSE;
    vc->disk_num = disk_num;
    vc->part_num = part_num;
    vc->had_drive_letter = FALSE;

    le = pdode->children.Flink;
    while (le != &pdode->children) {
        volume_child* vc2 = CONTAINING_RECORD(le, volume_child, list_entry);

        if (vc2->generation < vc->generation) {
            if (le == pdode->children.Flink)
                pdode->num_children = sb->num_devices;

            InsertHeadList(vc2->list_entry.Blink, &vc->list_entry);
            inserted = TRUE;
            break;
        }

        le = le->Flink;
    }

    if (!inserted)
        InsertTailList(&pdode->children, &vc->list_entry);

    pdode->children_loaded++;

    if (pdode->vde && pdode->vde->mounted_device) {
        device_extension* Vcb = pdode->vde->mounted_device->DeviceExtension;

        ExAcquireResourceExclusiveLite(&Vcb->tree_lock, TRUE);

        le = Vcb->devices.Flink;
        while (le != &Vcb->devices) {
            device* dev = CONTAINING_RECORD(le, device, list_entry);

            if (!dev->devobj && RtlCompareMemory(&dev->devitem.device_uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
                dev->devobj = DeviceObject;
                dev->disk_num = disk_num;
                dev->part_num = part_num;
                init_device(Vcb, dev, FALSE);
                break;
            }

            le = le->Flink;
        }

        ExReleaseResourceLite(&Vcb->tree_lock);
    }

    if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
        pdode->removable = TRUE;

        if (pdode->vde && pdode->vde->device)
            pdode->vde->device->Characteristics |= FILE_REMOVABLE_MEDIA;
    }

    if (pdode->num_children == pdode->children_loaded || (pdode->children_loaded == 1 && allow_degraded_mount(&sb->uuid))) {
        if (pdode->num_children == 1) {
            Status = remove_drive_letter(mountmgr, devpath);
            if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND)
                WARN("remove_drive_letter returned %08x\n", Status);

            vc->had_drive_letter = NT_SUCCESS(Status);
        } else {
            le = pdode->children.Flink;

            while (le != &pdode->children) {
                UNICODE_STRING name;

                vc = CONTAINING_RECORD(le, volume_child, list_entry);

                name.Length = name.MaximumLength = vc->pnp_name.Length + (3 * sizeof(WCHAR));
                name.Buffer = ExAllocatePoolWithTag(PagedPool, name.Length, ALLOC_TAG);

                if (!name.Buffer) {
                    ERR("out of memory\n");

                    ExReleaseResourceLite(&pdode->child_lock);
                    ExReleaseResourceLite(&pdo_list_lock);

                    goto fail;
                }

                RtlCopyMemory(name.Buffer, L"\\??", 3 * sizeof(WCHAR));
                RtlCopyMemory(&name.Buffer[3], vc->pnp_name.Buffer, vc->pnp_name.Length);

                Status = remove_drive_letter(mountmgr, &name);

                if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND)
                    WARN("remove_drive_letter returned %08x\n", Status);

                ExFreePool(name.Buffer);

                vc->had_drive_letter = NT_SUCCESS(Status);

                le = le->Flink;
            }
        }

        if ((!new_pdo || !no_pnp) && pdode->vde) {
            Status = IoSetDeviceInterfaceState(&pdode->vde->bus_name, TRUE);
            if (!NT_SUCCESS(Status))
                WARN("IoSetDeviceInterfaceState returned %08x\n", Status);
        }
    }

    ExReleaseResourceLite(&pdode->child_lock);

    if (new_pdo) {
        control_device_extension* cde = master_devobj->DeviceExtension;

        InsertTailList(&pdo_list, &pdode->list_entry);

        if (!no_pnp)
            IoInvalidateDeviceRelations(cde->buspdo, BusRelations);
    }

    ExReleaseResourceLite(&pdo_list_lock);

    if (new_pdo && no_pnp)
        AddDevice(drvobj, pdo);

    return;

fail:
    ObDereferenceObject(FileObject);
}
Exemplo n.º 3
0
// fdo pnp
NTSTATUS DoFdoPnP(PDEVICE_OBJECT pDevice,PIRP pIrp)
{
	NTSTATUS status = STATUS_SUCCESS;
	PFdoExt pFdoExt = static_cast<PFdoExt>(pDevice->DeviceExtension);

	// nead call next driver
	BOOLEAN bCallNext = TRUE;

	PIO_STACK_LOCATION pIoStack = IoGetCurrentIrpStackLocation(pIrp);

	// inc io count
	IncIoCount(pFdoExt);

	// save minor code
	UCHAR uMinorCode = pIoStack->MinorFunction;

	switch(uMinorCode)
	{
	case IRP_MN_START_DEVICE:
		{
			// send down first
			status = SendIrpToLowerDeviceSyn(pFdoExt->m_pLowerDevice,pIrp);
			if(NT_SUCCESS(status))
			{
				// set device power state
				pFdoExt->m_devPowerState = PowerDeviceD0;
				POWER_STATE state;
				state.DeviceState = PowerDeviceD0;
				PoSetPowerState(pDevice,DevicePowerState,state);

				// set device interface state
				status = IoSetDeviceInterfaceState(&pFdoExt->m_symbolicName,TRUE);

				// set device pnp state
				SetNewPnpState(pFdoExt,IRP_MN_START_DEVICE);
			}

			// complete the irp
			pIrp->IoStatus.Status = status;
			IoCompleteRequest(pIrp,IO_NO_INCREMENT);

			// do not call down the device stack
			bCallNext = FALSE;
		}
		break;

		// set pnp state directly
	case IRP_MN_QUERY_REMOVE_DEVICE:
	case IRP_MN_QUERY_STOP_DEVICE:
		SetNewPnpState(pFdoExt,uMinorCode);
		break;

		// check for current pnp state,and restore it
	case IRP_MN_CANCEL_REMOVE_DEVICE:
		if(pFdoExt->m_ulCurrentPnpState == IRP_MN_QUERY_REMOVE_DEVICE)
			RestorePnpState(pFdoExt);

		break;

		// the same
	case IRP_MN_CANCEL_STOP_DEVICE:
		if(pFdoExt->m_ulCurrentPnpState == IRP_MN_QUERY_STOP_DEVICE)
			RestorePnpState(pFdoExt);

		break;

		// remove
	case IRP_MN_REMOVE_DEVICE:
		{
			// normal remove
			if(pFdoExt->m_ulCurrentPnpState != IRP_MN_SURPRISE_REMOVAL)
			{
				// just stop device interface
				if(pFdoExt->m_symbolicName.Buffer)
				{
					// set device interface false
					IoSetDeviceInterfaceState(&pFdoExt->m_symbolicName,FALSE);

					RtlFreeUnicodeString(&pFdoExt->m_symbolicName);
				}
			}

			// update pnp state
			SetNewPnpState(pFdoExt,IRP_MN_REMOVE_DEVICE);

			// dec outstandingio by 2
			DecIoCount(pFdoExt);

			DecIoCount(pFdoExt);

			// wait other irps finish
			KeWaitForSingleObject(&pFdoExt->m_evRemove,Executive,KernelMode,FALSE,NULL);

			// check pdo
			ExAcquireFastMutex(&pFdoExt->m_mutexEnumPdo);

			// if the pdo is present
			if(pFdoExt->m_pEnumPdo)
			{
				PPdoExt pPdoExt = static_cast<PPdoExt>(pFdoExt->m_pEnumPdo->DeviceExtension);

				// surprise removal.update those field
				if(pPdoExt->m_ulCurrentPnpState == IRP_MN_SURPRISE_REMOVAL)
				{
					pPdoExt->m_pParentFdo = NULL;
					pPdoExt->m_bReportMissing = TRUE;
					pFdoExt->m_pEnumPdo = NULL;
				}

				// delete the pdo device
				IoDeleteDevice(pFdoExt->m_pEnumPdo);
			}

			ExReleaseFastMutex(&pFdoExt->m_mutexEnumPdo);

			pIrp->IoStatus.Status = STATUS_SUCCESS;

			// call next driver,do not need to wait the finish
			IoSkipCurrentIrpStackLocation(pIrp);
			status = IoCallDriver(pFdoExt->m_pLowerDevice,pIrp);

			// first detach it from the device stack
			IoDetachDevice(pFdoExt->m_pLowerDevice);

			// then delete it,note that the device extension will become invalid,so dec need to check the minor code carefully
			IoDeleteDevice(pDevice);

			bCallNext = FALSE;
		}
		break;

		// stop
	case IRP_MN_STOP_DEVICE:
		DecIoCount(pFdoExt);

		KeWaitForSingleObject(&pFdoExt->m_evStop,Executive,KernelMode,FALSE,NULL);

		IncIoCount(pFdoExt);

		SetNewPnpState(pFdoExt,IRP_MN_STOP_DEVICE);
		break;
	
		// query bus relations
	case IRP_MN_QUERY_DEVICE_RELATIONS:
		{
			// only care bus relations
			if (BusRelations != pIoStack->Parameters.QueryDeviceRelations.Type) 
			{
				/*switch(pIoStack->Parameters.QueryDeviceRelations.Type)
				{
				case EjectionRelations:
					devDebugPrint("\tquery EjectionRelations\n");
					break;
				case PowerRelations:
					devDebugPrint("\tquery PowerRelations\n");
					break;
				case RemovalRelations:
					devDebugPrint("\tquery RemovalRelations\n");
					break;
				case TargetDeviceRelation:
					devDebugPrint("\tquery TargetDeviceRelation\n");
					break;
				case SingleBusRelations:
					devDebugPrint("\tquery SingleBusRelations\n");
					break;
				}*/
				
				break;
			}

			// old relations
			PDEVICE_RELATIONS pOldRel = static_cast<PDEVICE_RELATIONS>(ULongToPtr(pIrp->IoStatus.Information));
			ULONG ulNewCount = 0;

			ExAcquireFastMutex(&pFdoExt->m_mutexEnumPdo);

			// no pdo
			if(!pFdoExt->m_pEnumPdo)
			{
				devDebugPrint("\tBusRelations no device plugin \n");
                ExReleaseFastMutex(&pFdoExt->m_mutexEnumPdo);
				break;
			}
			
			PPdoExt pPdoExt = static_cast<PPdoExt>(pFdoExt->m_pEnumPdo->DeviceExtension);
			
			// if the pdo is not present
			if(!pPdoExt->m_bPresent)
			{
				// then we report it as missing
				pPdoExt->m_bReportMissing = TRUE;
			}
			else
			{
				// report the pdo
				ObReferenceObject(pFdoExt->m_pEnumPdo);
				ulNewCount ++;
			}

			// add the old count
			if(pOldRel)
				ulNewCount += pOldRel->Count;

			// allocate paged memory
			ULONG len = sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (ulNewCount - 1);
			PDEVICE_RELATIONS pRel = static_cast<PDEVICE_RELATIONS>(ExAllocatePoolWithTag(PagedPool,len,'suBT'));

			// do not set the status,we should continue with the orignal devices that the upper devices reported
			if(!pRel)
				break;

			// copy old value
			if(pOldRel)
			{
				RtlCopyMemory(pRel,pOldRel,len - sizeof(PDEVICE_OBJECT));
				if(pPdoExt->m_bPresent)
					pRel->Objects[pOldRel->Count] = pFdoExt->m_pEnumPdo;

				// free the previous buffer
				ExFreePool(pOldRel);
			}
			else
			{
				// the device is present
				if(pPdoExt->m_bPresent)
					pRel->Objects[0] = pFdoExt->m_pEnumPdo;
			}

			pRel->Count = ulNewCount;

			pIrp->IoStatus.Information = PtrToUlong(pRel);

			devDebugPrint("\tBusRelations pdo present %d,report %d\n",pPdoExt->m_bPresent,ulNewCount);

			ExReleaseFastMutex(&pFdoExt->m_mutexEnumPdo);
		}
		break;

		// surprise removal
	case IRP_MN_SURPRISE_REMOVAL:
		{
			// set pnp state
			SetNewPnpState(pFdoExt,IRP_MN_SURPRISE_REMOVAL);

			// stop the fdo
			if(pFdoExt->m_symbolicName.Buffer)
			{
				// set device interface
				IoSetDeviceInterfaceState(&pFdoExt->m_symbolicName,FALSE);

				RtlFreeUnicodeString(&pFdoExt->m_symbolicName);
			}

			// update pdo's field
			ExAcquireFastMutex(&pFdoExt->m_mutexEnumPdo);
			PPdoExt pPdoExt = static_cast<PPdoExt>(pFdoExt->m_pEnumPdo->DeviceExtension);
			pPdoExt->m_pParentFdo = NULL;
			pPdoExt->m_bReportMissing = TRUE;
			ExReleaseFastMutex(&pFdoExt->m_mutexEnumPdo);
		}
		break;

	default:
		status = pIrp->IoStatus.Status;
		break;
	}

	// nead call lower device
	if(bCallNext)
	{
		pIrp->IoStatus.Status = status;
		IoSkipCurrentIrpStackLocation(pIrp);
		status = IoCallDriver(pFdoExt->m_pLowerDevice,pIrp);
	}
	
	// specail check for remove irp
	if(uMinorCode != IRP_MN_REMOVE_DEVICE)
		DecIoCount(pFdoExt);

	return status;
}
Exemplo n.º 4
0
Arquivo: pnp.c Projeto: kcrazy/winekit
NTSTATUS
Serenum_FDO_PnP (
    IN PDEVICE_OBJECT       DeviceObject,
    IN PIRP                 Irp,
    IN PIO_STACK_LOCATION   IrpStack,
    IN PFDO_DEVICE_DATA     DeviceData
)
/*++
Routine Description:
    Handle requests from the PlugPlay system for the BUS itself

    NB: the various Minor functions of the PlugPlay system will not be
    overlapped and do not have to be reentrant

--*/
{
    NTSTATUS    status;
    KEVENT      event;
    ULONG       length;
    ULONG       i;
    PDEVICE_RELATIONS   relations;
    PIO_STACK_LOCATION  stack;
    PRTL_QUERY_REGISTRY_TABLE QueryTable = NULL;
    ULONG DebugLevelDefault = SER_DEFAULT_DEBUG_OUTPUT_LEVEL;

    PAGED_CODE();

    status = Serenum_IncIoCount (DeviceData);
    if (!NT_SUCCESS (status)) {
        Irp->IoStatus.Status = status;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        return status;
    }

    stack = IoGetCurrentIrpStackLocation (Irp);

    switch (IrpStack->MinorFunction) {
    case IRP_MN_START_DEVICE:
        //
        // BEFORE you are allowed to ``touch'' the device object to which
        // the FDO is attached (that send an irp from the bus to the Device
        // object to which the bus is attached).   You must first pass down
        // the start IRP.  It might not be powered on, or able to access or
        // something.
        //

        Serenum_KdPrint (DeviceData, SER_DBG_PNP_TRACE, ("Start Device\n"));

        if (DeviceData->Started) {
            Serenum_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
                             ("Device already started\n"));
            status = STATUS_SUCCESS;
            break;
        }

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

        IoSetCompletionRoutine (Irp,
                                SerenumSyncCompletion,
                                &event,
                                TRUE,
                                TRUE,
                                TRUE);

        status = IoCallDriver (DeviceData->TopOfStack, Irp);

        if (STATUS_PENDING == status) {
            // wait for it...

            status = KeWaitForSingleObject (&event,
                                            Executive,
                                            KernelMode,
                                            FALSE, // Not allertable
                                            NULL); // No timeout structure

            ASSERT (STATUS_SUCCESS == status);

            status = Irp->IoStatus.Status;
        }

        if (NT_SUCCESS(status)) {
            //
            // Now we can touch the lower device object as it is now started.
            //



            //
            // Get the debug level from the registry
            //

            if (NULL == (QueryTable = ExAllocatePool(
                                          PagedPool,
                                          sizeof(RTL_QUERY_REGISTRY_TABLE)*2
                                      ))) {
                Serenum_KdPrint (DeviceData, SER_DBG_PNP_ERROR,
                                 ("Failed to allocate memory to query registy\n"));
                DeviceData->DebugLevel = DebugLevelDefault;
            } else {
                RtlZeroMemory(
                    QueryTable,
                    sizeof(RTL_QUERY_REGISTRY_TABLE)*2
                );

                QueryTable[0].QueryRoutine = NULL;
                QueryTable[0].Flags         = RTL_QUERY_REGISTRY_DIRECT;
                QueryTable[0].EntryContext = &DeviceData->DebugLevel;
                QueryTable[0].Name      = L"DebugLevel";
                QueryTable[0].DefaultType   = REG_DWORD;
                QueryTable[0].DefaultData   = &DebugLevelDefault;
                QueryTable[0].DefaultLength= sizeof(ULONG);

                // CIMEXCIMEX: The rest of the table isn't filled in!

                if (!NT_SUCCESS(RtlQueryRegistryValues(
                                    RTL_REGISTRY_SERVICES,
                                    L"Serenum",
                                    QueryTable,
                                    NULL,
                                    NULL))) {
                    Serenum_KdPrint (DeviceData,SER_DBG_PNP_ERROR,
                                     ("Failed to get debug level from registry.  "
                                      "Using default\n"));
                    DeviceData->DebugLevel = DebugLevelDefault;
                }

                ExFreePool( QueryTable );
            }


            Serenum_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
                             ("Start Device: Device started successfully\n"));
            DeviceData->Started = TRUE;
        }

        //
        // We must now complete the IRP, since we stopped it in the
        // completetion routine with MORE_PROCESSING_REQUIRED.
        //
        break;

    case IRP_MN_QUERY_STOP_DEVICE:
        Serenum_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
                         ("Query Stop Device\n"));

        //
        // Test to see if there are any PDO created as children of this FDO
        // If there are then conclude the device is busy and fail the
        // query stop.
        //
        // CIMEXCIMEX
        // We could do better, by seing if the children PDOs are actually
        // currently open.  If they are not then we could stop, get new
        // resouces, fill in the new resouce values, and then when a new client
        // opens the PDO use the new resources.  But this works for now.
        //

        if (DeviceData->AttachedPDO
                || (DeviceData->EnumFlags & SERENUM_ENUMFLAG_PENDING)) {
            status = STATUS_UNSUCCESSFUL;

        } else {
            status = STATUS_SUCCESS;
        }

        Irp->IoStatus.Status = status;

        if (NT_SUCCESS(status)) {
            IoSkipCurrentIrpStackLocation (Irp);
            status = IoCallDriver (DeviceData->TopOfStack, Irp);
        } else {
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
        }

        Serenum_DecIoCount (DeviceData);
        return status;

    case IRP_MN_CANCEL_STOP_DEVICE:
        //
        // We always succeed a cancel stop
        //

        Serenum_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
                         ("Cancel Stop Device\n"));

        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(DeviceData->TopOfStack, Irp);

        Serenum_DecIoCount (DeviceData);
        return status;

    case IRP_MN_STOP_DEVICE:
        Serenum_KdPrint (DeviceData, SER_DBG_PNP_TRACE, ("Stop Device\n"));

        //
        // Wait for the enum thread to complete if it's running
        //

        SerenumWaitForEnumThreadTerminate(DeviceData);

        //
        // After the start IRP has been sent to the lower driver object, the
        // bus may NOT send any more IRPS down ``touch'' until another START
        // has occured.
        // What ever access is required must be done before the Irp is passed
        // on.
        //
        // Stop device means that the resources given durring Start device
        // are no revoked.  So we need to stop using them
        //

        DeviceData->Started = FALSE;

        //
        // We don't need a completion routine so fire and forget.
        //
        // Set the current stack location to the next stack location and
        // call the next device object.
        //
        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoSkipCurrentIrpStackLocation (Irp);
        status = IoCallDriver (DeviceData->TopOfStack, Irp);

        Serenum_DecIoCount (DeviceData);
        return status;

    case IRP_MN_REMOVE_DEVICE:
        Serenum_KdPrint (DeviceData, SER_DBG_PNP_TRACE, ("Remove Device\n"));

        //
        // The PlugPlay system has detected the removal of this device.  We
        // have no choice but to detach and delete the device object.
        // (If we wanted to express and interest in preventing this removal,
        // we should have filtered the query remove and query stop routines.)
        //
        // Note! we might receive a remove WITHOUT first receiving a stop.
        // ASSERT (!DeviceData->Removed);


        //
        // Synchronize with the enum thread if it is running and wait
        // for it to finish
        //


        SerenumWaitForEnumThreadTerminate(DeviceData);

        // We will accept no new requests
        //
        DeviceData->Removed = TRUE;

        //
        // Complete any outstanding IRPs queued by the driver here.
        //

        //
        // Make the DCA go away.  Some drivers may choose to remove the DCA
        // when they receive a stop or even a query stop.  We just don't care.
        //
        (void)IoSetDeviceInterfaceState (&DeviceData->DevClassAssocName, FALSE);

        //
        // Here if we had any outstanding requests in a personal queue we should
        // complete them all now.
        //
        // Note, the device is guarenteed stopped, so we cannot send it any non-
        // PNP IRPS.
        //

        //
        // Fire and forget
        //
        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoSkipCurrentIrpStackLocation (Irp);
        status = IoCallDriver (DeviceData->TopOfStack, Irp);

        //
        // Wait for any outstanding threads to complete
        //

        //
        // Wait for all outstanding requests to complete
        //
        Serenum_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
                         ("Waiting for outstanding requests\n"));
        i = InterlockedDecrement ((volatile LONG*)&DeviceData->OutstandingIO);

        ASSERT (0 < i);

        if (0 != InterlockedDecrement ((volatile LONG*)&DeviceData->OutstandingIO)) {
            Serenum_KdPrint (DeviceData, SER_DBG_PNP_INFO,
                             ("Remove Device waiting for request to complete\n"));

            KeWaitForSingleObject (&DeviceData->RemoveEvent,
                                   Executive,
                                   KernelMode,
                                   FALSE, // Not Alertable
                                   NULL); // No timeout
        }
        //
        // Free the associated resources
        //

        //
        // Detach from the underlying devices.
        //
        Serenum_KdPrint(DeviceData, SER_DBG_PNP_INFO,
                        ("IoDetachDevice: 0x%x\n", DeviceData->TopOfStack));
        IoDetachDevice (DeviceData->TopOfStack);

        //
        // Clean up any resources here
        //


        ExFreePool (DeviceData->DevClassAssocName.Buffer);
        Serenum_KdPrint(DeviceData, SER_DBG_PNP_INFO,
                        ("IoDeleteDevice: 0x%x\n", DeviceObject));

        //
        // Remove any PDO's we ejected
        //

        if (DeviceData->AttachedPDO != NULL) {
            ASSERT(DeviceData->NumPDOs == 1);

            Serenum_PnPRemove(DeviceData->AttachedPDO, DeviceData->PdoData);
            DeviceData->PdoData = NULL;
            DeviceData->AttachedPDO = NULL;
            DeviceData->NumPDOs = 0;
        }

        IoDeleteDevice(DeviceObject);

        return status;

    case IRP_MN_QUERY_DEVICE_RELATIONS:
        if (BusRelations != IrpStack->Parameters.QueryDeviceRelations.Type) {
            //
            // We don't support this
            //
            Serenum_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
                             ("Query Device Relations - Non bus\n"));
            goto SER_FDO_PNP_DEFAULT;
        }

        Serenum_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
                         ("Query Bus Relations\n"));

        status = SerenumCheckEnumerations(DeviceData);


        //
        // Tell the plug and play system about all the PDOs.
        //
        // There might also be device relations below and above this FDO,
        // so, be sure to propagate the relations from the upper drivers.
        //
        // No Completion routine is needed so long as the status is preset
        // to success.  (PDOs complete plug and play irps with the current
        // IoStatus.Status and IoStatus.Information as the default.)
        //

        //KeAcquireSpinLock (&DeviceData->Spin, &oldIrq);

        i = (0 == Irp->IoStatus.Information) ? 0 :
            ((PDEVICE_RELATIONS) Irp->IoStatus.Information)->Count;
        // The current number of PDOs in the device relations structure

        Serenum_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
                         ("#PDOS = %d + %d\n", i, DeviceData->NumPDOs));

        length = sizeof(DEVICE_RELATIONS) +
                 ((DeviceData->NumPDOs + i) * sizeof (PDEVICE_OBJECT));

        relations = (PDEVICE_RELATIONS) ExAllocatePool (NonPagedPool, length);

        if (NULL == relations) {
            Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            Serenum_DecIoCount(DeviceData);
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        //
        // Copy in the device objects so far
        //
        if (i) {
            RtlCopyMemory (
                relations->Objects,
                ((PDEVICE_RELATIONS) Irp->IoStatus.Information)->Objects,
                i * sizeof (PDEVICE_OBJECT));
        }
        relations->Count = DeviceData->NumPDOs + i;

        //
        // For each PDO on this bus add a pointer to the device relations
        // buffer, being sure to take out a reference to that object.
        // The PlugPlay system will dereference the object when it is done with
        // it and free the device relations buffer.
        //

        if (DeviceData->NumPDOs) {
            relations->Objects[relations->Count-1] = DeviceData->AttachedPDO;
            ObReferenceObject (DeviceData->AttachedPDO);
        }

        //
        // Set up and pass the IRP further down the stack
        //
        Irp->IoStatus.Status = STATUS_SUCCESS;

        if (0 != Irp->IoStatus.Information) {
            ExFreePool ((PVOID) Irp->IoStatus.Information);
        }
        Irp->IoStatus.Information = (ULONG_PTR)relations;

        IoSkipCurrentIrpStackLocation (Irp);
        status = IoCallDriver (DeviceData->TopOfStack, Irp);

        Serenum_DecIoCount (DeviceData);

        return status;

    case IRP_MN_QUERY_REMOVE_DEVICE:
        //
        // If we were to fail this call then we would need to complete the
        // IRP here.  Since we are not, set the status to SUCCESS and
        // call the next driver.
        //

        Serenum_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
                         ("Query Remove Device\n"));

        //
        // Wait for the enum thread to complete if it's running
        //
        SerenumWaitForEnumThreadTerminate(DeviceData);


        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoSkipCurrentIrpStackLocation (Irp);
        status = IoCallDriver (DeviceData->TopOfStack, Irp);
        Serenum_DecIoCount (DeviceData);
        return status;


    case IRP_MN_QUERY_CAPABILITIES: {

        PIO_STACK_LOCATION  irpSp;

        //
        // Send this down to the PDO first
        //

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

        IoSetCompletionRoutine (Irp,
                                SerenumSyncCompletion,
                                &event,
                                TRUE,
                                TRUE,
                                TRUE);

        status = IoCallDriver (DeviceData->TopOfStack, Irp);

        if (STATUS_PENDING == status) {
            // wait for it...

            status = KeWaitForSingleObject (&event,
                                            Executive,
                                            KernelMode,
                                            FALSE, // Not allertable
                                            NULL); // No timeout structure

            ASSERT (STATUS_SUCCESS == status);

            status = Irp->IoStatus.Status;
        }

        if (NT_SUCCESS(status)) {

            irpSp = IoGetCurrentIrpStackLocation(Irp);

            DeviceData->SystemWake
                = irpSp->Parameters.DeviceCapabilities.Capabilities->SystemWake;
            DeviceData->DeviceWake
                = irpSp->Parameters.DeviceCapabilities.Capabilities->DeviceWake;
        }

        break;
    }



SER_FDO_PNP_DEFAULT:
    default:
        //
        // In the default case we merely call the next driver since
        // we don't know what to do.
        //
        Serenum_KdPrint (DeviceData, SER_DBG_PNP_TRACE, ("Default Case\n"));

        //
        // Fire and Forget
        //
        IoSkipCurrentIrpStackLocation (Irp);

        //
        // Done, do NOT complete the IRP, it will be processed by the lower
        // device object, which will complete the IRP
        //

        status = IoCallDriver (DeviceData->TopOfStack, Irp);
        Serenum_DecIoCount (DeviceData);
        return status;
    }

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

    Serenum_DecIoCount (DeviceData);
    return status;
}
int FloppyPnp(int DeviceObject , int Irp ) 
{ int DeviceObject__DeviceExtension = __VERIFIER_nondet_int() ;
  int Irp__Tail__Overlay__CurrentStackLocation = __VERIFIER_nondet_int() ;
  int Irp__IoStatus__Information ;
  int Irp__IoStatus__Status ;
  int Irp__CurrentLocation = __VERIFIER_nondet_int() ;
  int disketteExtension__IsRemoved = __VERIFIER_nondet_int() ;
  int disketteExtension__IsStarted = __VERIFIER_nondet_int() ;
  int disketteExtension__TargetObject = __VERIFIER_nondet_int() ;
  int disketteExtension__HoldNewRequests ;
  int disketteExtension__FloppyThread = __VERIFIER_nondet_int() ;
  int disketteExtension__InterfaceString__Buffer = __VERIFIER_nondet_int() ;
  int disketteExtension__InterfaceString = __VERIFIER_nondet_int() ;
  int disketteExtension__ArcName__Length = __VERIFIER_nondet_int() ;
  int disketteExtension__ArcName = __VERIFIER_nondet_int() ;
  int irpSp__MinorFunction = __VERIFIER_nondet_int() ;
  int IoGetConfigurationInformation__FloppyCount = __VERIFIER_nondet_int() ;
  int irpSp ;
  int disketteExtension ;
  int ntStatus ;
  int doneEvent = __VERIFIER_nondet_int() ;
  int irpSp___0 ;
  int nextIrpSp ;
  int nextIrpSp__Control ;
  int irpSp___1 ;
  int irpSp__Context ;
  int irpSp__Control ;
  long __cil_tmp29 ;
  long __cil_tmp30 ;

  {
  ntStatus = 0;
  PagingReferenceCount ++;
  if (PagingReferenceCount == 1) {

  }
  disketteExtension = DeviceObject__DeviceExtension;
  irpSp = Irp__Tail__Overlay__CurrentStackLocation;
  if (disketteExtension__IsRemoved) {
    {
    Irp__IoStatus__Information = 0;
    Irp__IoStatus__Status = -1073741738;
    myStatus = -1073741738;
    IofCompleteRequest(Irp, 0);
    }
    return (-1073741738);
  }
  if (irpSp__MinorFunction == 0) {
    goto switch_0_0;
  } else {
    if (irpSp__MinorFunction == 5) {
      goto switch_0_5;
    } else {
      if (irpSp__MinorFunction == 1) {
        goto switch_0_5;
      } else {
        if (irpSp__MinorFunction == 6) {
          goto switch_0_6;
        } else {
          if (irpSp__MinorFunction == 3) {
            goto switch_0_6;
          } else {
            if (irpSp__MinorFunction == 4) {
              goto switch_0_4;
            } else {
              if (irpSp__MinorFunction == 2) {
                goto switch_0_2;
              } else {
                goto switch_0_default;
                if (0) {
                  switch_0_0: 
                  {
                  ntStatus = FloppyStartDevice(DeviceObject, Irp);
                  }
                  goto switch_0_break;
                  switch_0_5: 
                  if (irpSp__MinorFunction == 5) {

                  }
                  if (! disketteExtension__IsStarted) {
                    if (s == NP) {
                      s = SKIP1;
                    } else {
                      {
                      errorFn();
                      }
                    }
                    {
                    Irp__CurrentLocation ++;
                    Irp__Tail__Overlay__CurrentStackLocation ++;
                    ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
                    }
                    return (ntStatus);
                  }
                  {
                  disketteExtension__HoldNewRequests = 1;
                  ntStatus = FlQueueIrpToThread(Irp, disketteExtension);
                  }
                  {
                  __cil_tmp29 = (long )ntStatus;
                  if (__cil_tmp29 == 259L) {
                    {
                    KeWaitForSingleObject(disketteExtension__FloppyThread, Executive,
                                          KernelMode, 0, 0);
                    }
                    if (disketteExtension__FloppyThread != 0) {

                    }
                    disketteExtension__FloppyThread = 0;
                    Irp__IoStatus__Status = 0;
                    myStatus = 0;
                    if (s == NP) {
                      s = SKIP1;
                    } else {
                      {
                      errorFn();
                      }
                    }
                    {
                    Irp__CurrentLocation ++;
                    Irp__Tail__Overlay__CurrentStackLocation ++;
                    ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
                    }
                  } else {
                    {
                    ntStatus = -1073741823;
                    Irp__IoStatus__Status = ntStatus;
                    myStatus = ntStatus;
                    Irp__IoStatus__Information = 0;
                    IofCompleteRequest(Irp, 0);
                    }
                  }
                  }
                  goto switch_0_break;
                  switch_0_6: 
                  if (irpSp__MinorFunction == 6) {

                  }
                  if (! disketteExtension__IsStarted) {
                    Irp__IoStatus__Status = 0;
                    myStatus = 0;
                    if (s == NP) {
                      s = SKIP1;
                    } else {
                      {
                      errorFn();
                      }
                    }
                    {
                    Irp__CurrentLocation ++;
                    Irp__Tail__Overlay__CurrentStackLocation ++;
                    ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
                    }
                  } else {
                    Irp__IoStatus__Status = 0;
                    myStatus = 0;
                    irpSp___0 = Irp__Tail__Overlay__CurrentStackLocation;
                    nextIrpSp = Irp__Tail__Overlay__CurrentStackLocation - 1;
                    nextIrpSp__Control = 0;
                    if (s != NP) {
                      {
                      errorFn();
                      }
                    } else {
                      if (compRegistered != 0) {
                        {
                        errorFn();
                        }
                      } else {
                        compRegistered = 1;
                      }
                    }
                    {
                    irpSp___1 = Irp__Tail__Overlay__CurrentStackLocation - 1;
                    irpSp__Context = doneEvent;
                    irpSp__Control = 224;
                    ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
                    }
                    {
                    __cil_tmp30 = (long )ntStatus;
                    if (__cil_tmp30 == 259L) {
                      {
                      KeWaitForSingleObject(doneEvent, Executive, KernelMode, 0, 0);
                      ntStatus = myStatus;
                      }
                    }
                    }
                    {
                    disketteExtension__HoldNewRequests = 0;
                    Irp__IoStatus__Status = ntStatus;
                    myStatus = ntStatus;
                    Irp__IoStatus__Information = 0;
                    IofCompleteRequest(Irp, 0);
                    }
                  }
                  goto switch_0_break;
                  switch_0_4: 
                  disketteExtension__IsStarted = 0;
                  Irp__IoStatus__Status = 0;
                  myStatus = 0;
                  if (s == NP) {
                    s = SKIP1;
                  } else {
                    {
                    errorFn();
                    }
                  }
                  {
                  Irp__CurrentLocation ++;
                  Irp__Tail__Overlay__CurrentStackLocation ++;
                  ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
                  }
                  goto switch_0_break;
                  switch_0_2: 
                  disketteExtension__HoldNewRequests = 0;
                  disketteExtension__IsStarted = 0;
                  disketteExtension__IsRemoved = 1;
                  if (s == NP) {
                    s = SKIP1;
                  } else {
                    {
                    errorFn();
                    }
                  }
                  {
                  Irp__CurrentLocation ++;
                  Irp__Tail__Overlay__CurrentStackLocation ++;
                  Irp__IoStatus__Status = 0;
                  myStatus = 0;
                  ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
                  }
                  if (disketteExtension__InterfaceString__Buffer != 0) {
                    {
                    IoSetDeviceInterfaceState(disketteExtension__InterfaceString,
                                              0);
                    }
                  }
                  if (disketteExtension__ArcName__Length != 0) {
                    {
                    IoDeleteSymbolicLink(disketteExtension__ArcName);
                    }
                  }
                  IoGetConfigurationInformation__FloppyCount --;
                  goto switch_0_break;
                  switch_0_default: ;
                  if (s == NP) {
                    s = SKIP1;
                  } else {
                    {
                    errorFn();
                    }
                  }
                  {
                  Irp__CurrentLocation ++;
                  Irp__Tail__Overlay__CurrentStackLocation ++;
                  ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
                  }
                } else {
                  switch_0_break: ;
                }
              }
            }
          }
        }
      }
    }
  }
  PagingReferenceCount --;
  if (PagingReferenceCount == 0) {

  }
  return (ntStatus);
}
}
Exemplo n.º 6
0
NTSTATUS
NTAPI
DiskRemoveDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR Type
    )

/*++

Routine Description:

    This routine will release any resources the device may have allocated for
    this device object and return.

Arguments:

    DeviceObject - the device object being removed

Return Value:

    status

--*/

{
    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
    PDISK_DATA diskData = commonExtension->DriverData;

    PAGED_CODE();

    //
    // Handle query and cancel
    //

    if((Type == IRP_MN_QUERY_REMOVE_DEVICE) ||
       (Type == IRP_MN_CANCEL_REMOVE_DEVICE))  {
        return STATUS_SUCCESS;
    }

    if(commonExtension->IsFdo) {

        PFUNCTIONAL_DEVICE_EXTENSION fdoExtension =
            DeviceObject->DeviceExtension;

        //
        // Purge the cached partition table (if any).
        //

        DiskAcquirePartitioningLock(fdoExtension);
        DiskInvalidatePartitionTable(fdoExtension, TRUE);
        DiskReleasePartitioningLock(fdoExtension);

        //
        // Delete our object directory.
        //

        if(fdoExtension->AdapterDescriptor) {
            ExFreePool(fdoExtension->AdapterDescriptor);
            fdoExtension->AdapterDescriptor = NULL;
        }

        if(fdoExtension->DeviceDescriptor) {
            ExFreePool(fdoExtension->DeviceDescriptor);
            fdoExtension->DeviceDescriptor = NULL;
        }

        if(fdoExtension->SenseData) {
            ExFreePool(fdoExtension->SenseData);
            fdoExtension->SenseData = NULL;
        }

        if(fdoExtension->DeviceDirectory != NULL) {
            ZwMakeTemporaryObject(fdoExtension->DeviceDirectory);
            ZwClose(fdoExtension->DeviceDirectory);
            fdoExtension->DeviceDirectory = NULL;
        }

        if(Type == IRP_MN_REMOVE_DEVICE) {
            IoGetConfigurationInformation()->DiskCount--;
        }

    } else {

        //PPHYSICAL_DEVICE_EXTENSION pdoExtension = DeviceObject->DeviceExtension;

    }

    DiskDeleteSymbolicLinks(DeviceObject);

    //
    // Release the mounted device interface if we've set it.
    //

    if(diskData->PartitionInterfaceString.Buffer != NULL) {
        IoSetDeviceInterfaceState(&(diskData->PartitionInterfaceString), FALSE);
        RtlFreeUnicodeString(&(diskData->PartitionInterfaceString));
        RtlInitUnicodeString(&(diskData->PartitionInterfaceString), NULL);
    }
    if(diskData->DiskInterfaceString.Buffer != NULL) {
        IoSetDeviceInterfaceState(&(diskData->DiskInterfaceString), FALSE);
        RtlFreeUnicodeString(&(diskData->DiskInterfaceString));
        RtlInitUnicodeString(&(diskData->DiskInterfaceString), NULL);
    }

    ClassDeleteSrbLookasideList(commonExtension);
    return STATUS_SUCCESS;
}
Exemplo n.º 7
0
NTSTATUS
OnPnPRequest(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
    )
/*++

Routine Description:

    This routine is the dispatch routine for plug and play irps 

Arguments:

    DeviceObject - Pointer to the device object.

    Irp - Pointer to the request packet.

Return Value:

    Status is returned.

--*/
{
    PDEVICE_EXTENSION           devExt; 
    PIO_STACK_LOCATION          irpStack;
    NTSTATUS                    status = STATUS_SUCCESS;
    KIRQL                       oldIrql;
    KEVENT                      event;        

    PAGED_CODE();

	DbgPrint("OnPnPRequest: Enter\n");

	devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    switch (irpStack->MinorFunction) {
    case IRP_MN_START_DEVICE: {

        //
        // The device is starting.
        //
        // We cannot touch the device (send it any non pnp irps) until a
        // start device has been passed down to the lower drivers.
        //
        IoCopyCurrentIrpStackLocationToNext(Irp);
        KeInitializeEvent(&event,
                          NotificationEvent,
                          FALSE
                          );

        IoSetCompletionRoutine(Irp,
                               (PIO_COMPLETION_ROUTINE) OnPendingComplete, 
                               &event,
                               TRUE,
                               TRUE,
                               TRUE); // No need for Cancel

  		if(DeviceObject == devExt->HookMouseDeviceObject)
		{
			status = IoCallDriver(devExt->Top_of_Mouse_Stack, Irp);
		} 
		if(DeviceObject == devExt->HookKbrdDeviceObject)
		{
			status = IoCallDriver(devExt->Top_of_KBD_Stack, Irp);
		} 

        if (STATUS_PENDING == status) {
            KeWaitForSingleObject(
               &event,
               Executive, // Waiting for reason of a driver
               KernelMode, // Waiting in kernel mode
               FALSE, // No allert
               NULL); // No timeout

            status = Irp->IoStatus.Status;
        }

        if (NT_SUCCESS(status)) {
            //
            // As we are successfully now back from our start device
            // we can do work.
            //
            devExt->Started = TRUE;
            devExt->Removed = FALSE;
            devExt->SurpriseRemoved = FALSE;
        }

		if (!NT_SUCCESS(IoSetDeviceInterfaceState(&devExt->DeviceLinkName, TRUE))) 
		{
			DbgPrint("OnPnPRequest: failed to Enable Device Interface: \n");
			IoDeleteDevice(devExt->HookMouseDeviceObject);
	    }
		
		//
        // We must now complete the IRP, since we stopped it in the
        // completetion routine with MORE_PROCESSING_REQUIRED.
        //
        Irp->IoStatus.Status = status;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

		break;
    }

    case IRP_MN_SURPRISE_REMOVAL:
        //
        // Same as a remove device, but don't call IoDetach or IoDeleteDevice
        //
        devExt->SurpriseRemoved = TRUE;

        // Remove code here

		if(DeviceObject == devExt->HookMouseDeviceObject || DeviceObject == devExt->HookKbrdDeviceObject)
		{
			status = DispatchPassThrough(DeviceObject, Irp);
	        break;
		} 
        break;

    case IRP_MN_REMOVE_DEVICE:
        
        devExt->Removed = TRUE;

        // remove code here
        Irp->IoStatus.Status = STATUS_SUCCESS;

		status = IoSetDeviceInterfaceState(&devExt->DeviceLinkName, FALSE);
		if (!NT_SUCCESS(status)) 
		{
			DbgPrint("OnPnPRequest: failed to Enable Device Interface: %d\n", status);
	    }
		RtlFreeUnicodeString(&devExt->DeviceLinkName);


		if(DeviceObject == devExt->HookMouseDeviceObject || DeviceObject == devExt->HookKbrdDeviceObject)
		{
			status = DispatchPassThrough(DeviceObject, Irp);
		}

		IoDeleteDevice(DeviceObject);
        break;

    case IRP_MN_QUERY_REMOVE_DEVICE:
    case IRP_MN_QUERY_STOP_DEVICE:
    case IRP_MN_CANCEL_REMOVE_DEVICE:
    case IRP_MN_CANCEL_STOP_DEVICE:
    case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: 
    case IRP_MN_STOP_DEVICE:
    case IRP_MN_QUERY_DEVICE_RELATIONS:
    case IRP_MN_QUERY_INTERFACE:
    case IRP_MN_QUERY_CAPABILITIES:
    case IRP_MN_QUERY_DEVICE_TEXT:
    case IRP_MN_QUERY_RESOURCES:
    case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
    case IRP_MN_READ_CONFIG:
    case IRP_MN_WRITE_CONFIG:
    case IRP_MN_EJECT:
    case IRP_MN_SET_LOCK:
    case IRP_MN_QUERY_ID:
    case IRP_MN_QUERY_PNP_DEVICE_STATE:
    default:
        //
        // Here the filter driver might modify the behavior of these IRPS
        // Please see PlugPlay documentation for use of these IRPs.
        //
        status = DispatchPassThrough( DeviceObject ,Irp);
        break;
    }
	DbgPrint("OnPnPRequest: Leave\n");

    return status;
}
Exemplo n.º 8
0
static VOID NTAPI
i8042PowerWorkItem(
	IN PDEVICE_OBJECT DeviceObject,
	IN PVOID Context)
{
	PI8042_KEYBOARD_EXTENSION DeviceExtension;
	PIRP WaitingIrp;
	NTSTATUS Status;

	DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context;

	UNREFERENCED_PARAMETER(DeviceObject);

	/* See http://blogs.msdn.com/doronh/archive/2006/09/08/746961.aspx */

	/* Register GUID_DEVICE_SYS_BUTTON interface and report capability */
	if (DeviceExtension->NewCaps != DeviceExtension->ReportedCaps)
	{
		WaitingIrp = InterlockedExchangePointer((PVOID)&DeviceExtension->PowerIrp, NULL);
		if (WaitingIrp)
		{
			/* Cancel the current power irp, as capability changed */
			WaitingIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
			WaitingIrp->IoStatus.Information = sizeof(ULONG);
			IoCompleteRequest(WaitingIrp, IO_NO_INCREMENT);
		}

		if (DeviceExtension->PowerInterfaceName.MaximumLength == 0)
		{
			/* We have never registred this interface ; do it */
			Status = IoRegisterDeviceInterface(
				DeviceExtension->Common.Pdo,
				&GUID_DEVICE_SYS_BUTTON,
				NULL,
				&DeviceExtension->PowerInterfaceName);
			if (!NT_SUCCESS(Status))
			{
				/* We can't do more yet, ignore the keypress... */
				WARN_(I8042PRT, "IoRegisterDeviceInterface(GUID_DEVICE_SYS_BUTTON) failed with status 0x%08lx\n",
					Status);
				DeviceExtension->PowerInterfaceName.MaximumLength = 0;
				return;
			}
		}
		else
		{
			/* Disable the interface. Once activated again, capabilities would be asked again */
			Status = IoSetDeviceInterfaceState(
				&DeviceExtension->PowerInterfaceName,
				FALSE);
			if (!NT_SUCCESS(Status))
			{
				/* Ignore the key press... */
				WARN_(I8042PRT, "Disabling interface %wZ failed with status 0x%08lx\n",
					&DeviceExtension->PowerInterfaceName, Status);
				return;
			}
		}
		/* Enable the interface. This leads to receving a IOCTL_GET_SYS_BUTTON_CAPS,
		 * so we can report new capability */
		Status = IoSetDeviceInterfaceState(
				&DeviceExtension->PowerInterfaceName,
				TRUE);
		if (!NT_SUCCESS(Status))
		{
			/* Ignore the key press... */
			WARN_(I8042PRT, "Enabling interface %wZ failed with status 0x%08lx\n",
					&DeviceExtension->PowerInterfaceName, Status);
			return;
		}
	}

	/* Directly complete the IOCTL_GET_SYS_BUTTON_EVENT Irp (if any) */
	WaitingIrp = InterlockedExchangePointer((PVOID)&DeviceExtension->PowerIrp, NULL);
	if (WaitingIrp)
	{
		PULONG pEvent = (PULONG)WaitingIrp->AssociatedIrp.SystemBuffer;

		WaitingIrp->IoStatus.Status = STATUS_SUCCESS;
		WaitingIrp->IoStatus.Information = sizeof(ULONG);
		*pEvent = InterlockedExchange((PLONG)&DeviceExtension->LastPowerKey, 0);
		IoCompleteRequest(WaitingIrp, IO_NO_INCREMENT);
	}
}
NTSTATUS StartDevice( PDEVICE_OBJECT fdo, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated )
{
    USB_CONFIGURATION_DESCRIPTOR  tcd;
    PUSB_CONFIGURATION_DESCRIPTOR pcd;
    PUSB_STRING_DESCRIPTOR        desc;            
    HANDLE                        RecoveryHandle;
    PURB                          selurb;
    URB                           urb;     
    NTSTATUS                      status;

    status = STATUS_SUCCESS; 
    
    PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

    selurb = NULL;
    pcd    = NULL;

    // Read our device descriptor. The only real purpose to this would be to find out how many
    // configurations there are so we can read their descriptors. In this simplest of examples,
    // there's only one configuration.
    
    KdPrint((DRIVERNAME " - Start device\n"));

    UsbBuildGetDescriptorRequest(
                                  &urb, 
                                  sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                  USB_DEVICE_DESCRIPTOR_TYPE,
                                  0, 
                                  LangId, 
                                  &pdx->dd, 
                                  NULL, 
                                  sizeof(pdx->dd), 
                                  NULL
                                );
 
    status = SendAwaitUrb( fdo, &urb );
    
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to retrieve device descriptor\n", status));
        goto cleanup;
    }

    // allocate the buffer for the descriptor; take extra space to null terminate the bString member
    desc = (PUSB_STRING_DESCRIPTOR)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, SPOT_TAG );

    if(!desc)
    {
        KdPrint((DRIVERNAME " - Unable to allocate %X bytes for string descriptor\n", sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }
    
    pdx->devHash = desc;

    UsbBuildGetDescriptorRequest(&urb, 
                                 sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                 USB_STRING_DESCRIPTOR_TYPE,
                                 DeviceId, 
                                 LangId, 
                                 desc, 
                                 NULL, 
                                 sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes,
                                 NULL);
    
    status = SendAwaitUrb(fdo, &urb);
    
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to retrieve string descriptor for DeviceId\n", status));
        goto cleanup;
    }
        
    // null terminate the buffer; we allocated one more wchar_t for the purpose 
    desc->bString[ (desc->bLength / 2) - 1 ] = L'\0';

    UpdateDeviceInformation( fdo );

    // Read the descriptor of the first configuration. This requires two steps. The first step
    // reads the fixed-size configuration descriptor alone. The second step reads the
    // configuration descriptor plus all imbedded interface and endpoint descriptors.

    UsbBuildGetDescriptorRequest(&urb, 
                                 sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                 USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                 0, 
                                 LangId, 
                                 &tcd, 
                                 NULL, 
                                 sizeof(tcd), 
                                 NULL);

    status = SendAwaitUrb(fdo, &urb);
    
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to read configuration descriptor 1\n", status));
        goto cleanup;
    }

    ULONG size = tcd.wTotalLength;
    
    pcd = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePoolWithTag(NonPagedPool, size, SPOT_TAG);
    
    if(!pcd)
    {
        KdPrint((DRIVERNAME " - Unable to allocate %X bytes for configuration descriptor\n", size));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }

    UsbBuildGetDescriptorRequest(&urb, 
                                 sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                 USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                 0, 
                                 LangId, 
                                 pcd, 
                                 NULL, 
                                 size, 
                                 NULL);

    status = SendAwaitUrb(fdo, &urb);
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to read configuration descriptor 1\n", status));
        goto cleanup;
    }
                           
    // Locate the descriptor for the one and only interface we expect to find

    PUSB_INTERFACE_DESCRIPTOR pid = USBD_ParseConfigurationDescriptorEx(pcd, 
                                                                        pcd,
                                                                        -1, 
                                                                        -1, 
                                                                        -1, 
                                                                        -1, 
                                                                        -1);

    ASSERT(pid);
                           
    // Create a URB to use in selecting a configuration.

    USBD_INTERFACE_LIST_ENTRY interfaces[2] = {
        {pid, NULL},
        {NULL, NULL},        // fence to terminate the array
    };

    selurb = USBD_CreateConfigurationRequestEx(pcd, interfaces);
    if(!selurb)
    {
        KdPrint((DRIVERNAME " - Unable to create configuration request\n"));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }

    // Verify that the interface describes exactly the endpoints we expect
    if(pid->bNumEndpoints != 2)
    {
        KdPrint((DRIVERNAME " - %d is the wrong number of endpoints\n", pid->bNumEndpoints));
        status = STATUS_DEVICE_CONFIGURATION_ERROR;
        goto cleanup;
    }

    PUSB_ENDPOINT_DESCRIPTOR ped = (PUSB_ENDPOINT_DESCRIPTOR) pid;
    ped = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(pcd, tcd.wTotalLength, ped, USB_ENDPOINT_DESCRIPTOR_TYPE);
    if(!ped || 0 == (ped->bEndpointAddress & 0x80) || ped->bmAttributes != USB_ENDPOINT_TYPE_BULK || ped->wMaxPacketSize > 64)
    {
        KdPrint((DRIVERNAME " - Endpoint has wrong attributes\n"));
        status = STATUS_DEVICE_CONFIGURATION_ERROR;
        goto cleanup;
    }
    ++ped;
    if(!ped || 0 != (ped->bEndpointAddress & 0x80) || ped->bmAttributes != USB_ENDPOINT_TYPE_BULK || ped->wMaxPacketSize > 64)
    {
        KdPrint((DRIVERNAME " - Endpoint has wrong attributes\n"));
        status = STATUS_DEVICE_CONFIGURATION_ERROR;
        goto cleanup;
    }
    ++ped;

    PUSBD_INTERFACE_INFORMATION pii = interfaces[0].Interface;
    ASSERT(pii->NumberOfPipes == pid->bNumEndpoints);

    // Initialize the maximum transfer size for each of the endpoints. The
    // default would be PAGE_SIZE. The firmware itself only has a 4096-byte
    // ring buffer, though. We need to restrict the test applet to that many
    // bytes. In order to exercise the multi-segment aspect of the transfer code,
    // therefore, reduce the maximum transfer size to 1024 bytes.

    pii->Pipes[0].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
    pii->Pipes[1].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
    pdx->maxtransfer = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;

    // Submit the set-configuration request

    status = SendAwaitUrb(fdo, selurb);
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to select configuration\n", status));
        goto cleanup;
    }

    // Save the configuration and pipe handles
    pdx->hconfig = selurb->UrbSelectConfiguration.ConfigurationHandle;
    pdx->hinpipe = pii->Pipes[0].PipeHandle;
    pdx->houtpipe = pii->Pipes[1].PipeHandle;

    // Transfer ownership of the configuration descriptor to the device extension

    pdx->pcd = pcd;
    pcd = NULL;

    // Enable the interface
    IoSetDeviceInterfaceState(&pdx->operationsInterfaceName, TRUE);        

    // Enable the interface
    IoSetDeviceInterfaceState(&pdx->inquiriesInterfaceName, TRUE);                    

    // create recovery thread                     
    status = PsCreateSystemThread(&RecoveryHandle, 0, NULL, NULL, NULL, RecoveryThread, (PVOID)pdx);

    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - PsCreateSystemThread failed with error %08x\n", status));
        goto cleanup;
    }
    
    status = ObReferenceObjectByHandle( RecoveryHandle,
                                        SYNCHRONIZE,
                                        NULL,
                                        KernelMode,
                                        (PVOID*)&pdx->RecoveryThread,
                                        NULL );

    ASSERT(NT_SUCCESS(status));

    ZwClose(RecoveryHandle);
    
    // Start polling
    status = StartPolling(pdx);
    
    if(!NT_SUCCESS(status))
    {   
        KdPrint((DRIVERNAME " - StartPolling failed 0x%08x\n", status));

        if(pdx->RecoveryThread)
        {
            // shutdown recovery thread
            pdx->RecoveryExit = TRUE; 
            KeSetEvent(&pdx->RecoveryEvent, 0, FALSE);    
            // wait for polling thread to exit 
            KeWaitForSingleObject(pdx->RecoveryThread, Executive, KernelMode, FALSE, NULL);     
            ObDereferenceObject(pdx->RecoveryThread);
            pdx->RecoveryThread = NULL;
        }
        
        goto cleanup;
    }
    
cleanup:
    if(selurb) ExFreePool(selurb);
    if(pcd   ) ExFreePool(pcd   );

    // get rid of return codes like STATUS_PENDING
    if(NT_SUCCESS(status)) 
    {
        return STATUS_SUCCESS;
    }
    
    return status;
}
Exemplo n.º 10
0
NTSTATUS
IsoUsb_SymbolicLink(
    IN PDEVICE_OBJECT DeviceObject,
    IN OUT PUNICODE_STRING deviceLinkUnicodeString

    )
/*++

Routine Description:

    This routine is called to create and initialize
    a GUID-based symbolic link to our device to be used to open/create
    instances of us from user mode.

    Called from IsoUsb_CreateDeviceObject() to create the link.

Arguments:

    DeviceObject - pointer to our Physical Device Object ( PDO )

    deviceLinkUnicodeString - Points to a unicode string structure allocated by the caller.
	If this routine is successful, it initializes the unicode string and allocates
	the string buffer containing the kernel-mode path to the symbolic link for this
	device interface.


Return Value:

    STATUS_SUCCESS if successful,
    STATUS_UNSUCCESSFUL otherwise

--*/{
    NTSTATUS ntStatus = STATUS_SUCCESS;


    //  Create the symbolic link

    // IoRegisterDeviceInterface registers device functionality (a device interface)
    // that a driver will enable for use by applications or other system components.

    ntStatus = IoRegisterDeviceInterface(
		DeviceObject,
		(LPGUID)&GUID_CLASS_I82930_ISO,
		NULL,
		deviceLinkUnicodeString);

    ISOUSB_KdPrintCond( DBGLVL_MEDIUM, (!(NT_SUCCESS(ntStatus))),
	    ("FAILED to IoRegisterDeviceInterface()\n"));

   if (NT_SUCCESS(ntStatus)) {

       // IoSetDeviceInterfaceState enables or disables a previously
       // registered device interface. Applications and other system components
       // can open only interfaces that are enabled.

	ntStatus = IoSetDeviceInterfaceState(deviceLinkUnicodeString, TRUE);

        ISOUSB_KdPrintCond( DBGLVL_MEDIUM,
		(!(NT_SUCCESS(ntStatus))),
		("FAILED to IoSetDeviceInterfaceState()\n"));

        ISOUSB_KdPrintCond( DBGLVL_MEDIUM,
		((NT_SUCCESS(ntStatus))),
		("SUCCEEDED  IoSetDeviceInterfaceState()\n"));

    }

    return ntStatus;
}
Exemplo n.º 11
0
NTSTATUS NTAPI
PdoDispatchPnp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
{
    ULONG MinorFunction;
    PIO_STACK_LOCATION Stack;
    ULONG_PTR Information = Irp->IoStatus.Information;
    NTSTATUS Status = Irp->IoStatus.Status;
    PDEVICE_CAPABILITIES DeviceCapabilities;
    ULONG i;

    Stack = IoGetCurrentIrpStackLocation(Irp);
    MinorFunction = Stack->MinorFunction;

    switch (MinorFunction)
    {
    case IRP_MN_QUERY_REMOVE_DEVICE:
    case IRP_MN_REMOVE_DEVICE:
    case IRP_MN_CANCEL_REMOVE_DEVICE:
    case IRP_MN_STOP_DEVICE:
    case IRP_MN_QUERY_STOP_DEVICE:
    case IRP_MN_CANCEL_STOP_DEVICE:
    case IRP_MN_QUERY_DEVICE_TEXT:
    case IRP_MN_SURPRISE_REMOVAL:
    case IRP_MN_QUERY_RESOURCES:
    case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
    case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
    {
        Status = STATUS_SUCCESS;
        break;
    }

    case IRP_MN_START_DEVICE:
    {
        PUSB_DEVICE RootHubDevice;
        PPDO_DEVICE_EXTENSION PdoDeviceExtension;
        PFDO_DEVICE_EXTENSION FdoDeviceExtension;
        UNICODE_STRING InterfaceSymLinkName;

        DPRINT1("Ehci: PDO StartDevice\n");
        PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
        FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;

        /* Create the root hub */
        RootHubDevice = InternalCreateUsbDevice(1, 0, NULL, TRUE);

        RtlCopyMemory(&RootHubDevice->DeviceDescriptor,
                      ROOTHUB2_DEVICE_DESCRIPTOR,
                      sizeof(ROOTHUB2_DEVICE_DESCRIPTOR));

        RootHubDevice->DeviceDescriptor.idVendor = FdoDeviceExtension->VendorId;
        RootHubDevice->DeviceDescriptor.idProduct = FdoDeviceExtension->DeviceId;

        /* Here config, interfaces and descriptors are stored. This was duplicated from XEN PV Usb Drivers implementation.
           Not sure that it is really needed as the information can be queueried from the device. */

        RootHubDevice->Configs = ExAllocatePoolWithTag(NonPagedPool,
                                 sizeof(PVOID) * RootHubDevice->DeviceDescriptor.bNumConfigurations,
                                 USB_POOL_TAG);

        RootHubDevice->Configs[0] = ExAllocatePoolWithTag(NonPagedPool,
                                    sizeof(USB_CONFIGURATION) + sizeof(PVOID) * ROOTHUB2_CONFIGURATION_DESCRIPTOR[4],
                                    USB_POOL_TAG);

        RootHubDevice->Configs[0]->Interfaces[0] = ExAllocatePoolWithTag(NonPagedPool,
                sizeof(USB_INTERFACE) + sizeof(PVOID) * ROOTHUB2_INTERFACE_DESCRIPTOR[4],
                USB_POOL_TAG);

        RootHubDevice->Configs[0]->Interfaces[0]->EndPoints[0] = ExAllocatePoolWithTag(NonPagedPool,
                sizeof(USB_ENDPOINT),
                USB_POOL_TAG);

        RootHubDevice->ActiveConfig = RootHubDevice->Configs[0];
        RootHubDevice->ActiveInterface = RootHubDevice->ActiveConfig->Interfaces[0];

        RtlCopyMemory(&RootHubDevice->ActiveConfig->ConfigurationDescriptor,
                      ROOTHUB2_CONFIGURATION_DESCRIPTOR,
                      sizeof(ROOTHUB2_CONFIGURATION_DESCRIPTOR));

        RtlCopyMemory(&RootHubDevice->ActiveConfig->Interfaces[0]->InterfaceDescriptor,
                      ROOTHUB2_INTERFACE_DESCRIPTOR,
                      sizeof(ROOTHUB2_INTERFACE_DESCRIPTOR));

        RtlCopyMemory(&RootHubDevice->ActiveConfig->Interfaces[0]->EndPoints[0]->EndPointDescriptor,
                      ROOTHUB2_ENDPOINT_DESCRIPTOR,
                      sizeof(ROOTHUB2_ENDPOINT_DESCRIPTOR));
        RootHubDevice->DeviceSpeed = UsbHighSpeed;
        RootHubDevice->DeviceType = Usb20Device;

        PdoDeviceExtension->UsbDevices[0] = RootHubDevice;

        Status = IoRegisterDeviceInterface(DeviceObject, &GUID_DEVINTERFACE_USB_HUB, NULL, &InterfaceSymLinkName);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Failed to register interface\n");
            return Status;
        }
        else
        {
            Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE);
            if (!NT_SUCCESS(Status))
                return Status;
        }

        Status = STATUS_SUCCESS;
        break;
    }
    case IRP_MN_QUERY_DEVICE_RELATIONS:
    {
        DPRINT1("Ehci: PDO QueryDeviceRelations\n");
        switch (Stack->Parameters.QueryDeviceRelations.Type)
        {
        case TargetDeviceRelation:
        {
            PDEVICE_RELATIONS DeviceRelations = NULL;
            Status = PdoQueryDeviceRelations(DeviceObject, &DeviceRelations);
            Information = (ULONG_PTR)DeviceRelations;
            break;
        }
        case BusRelations:
        {
            PPDO_DEVICE_EXTENSION PdoDeviceExtension;
            PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

            DPRINT("BusRelations!!!!!\n");

            /* The hub driver has created the new device object and reported to pnp, as a result the pnp manager
               has sent this IRP and type, so leave the next SCE request pending until a new device arrives.
               Is there a better way to do this? */
            ExAcquireFastMutex(&PdoDeviceExtension->ListLock);
            PdoDeviceExtension->HaltQueue = TRUE;
            ExReleaseFastMutex(&PdoDeviceExtension->ListLock);
        }
        case RemovalRelations:
        case EjectionRelations:
        {
            /* Ignore the request */
            Information = Irp->IoStatus.Information;
            Status = Irp->IoStatus.Status;
            break;

        }
        default:
        {
            DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unhandled type 0x%lx\n",
                    Stack->Parameters.QueryDeviceRelations.Type);
            Status = STATUS_NOT_SUPPORTED;
            break;
        }
        }
        break;
    }
    case IRP_MN_QUERY_CAPABILITIES:
    {
        DPRINT("Ehci: PDO Query Capabilities\n");

        DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;

        DeviceCapabilities->LockSupported = FALSE;
        DeviceCapabilities->EjectSupported = FALSE;
        DeviceCapabilities->Removable = FALSE;
        DeviceCapabilities->DockDevice = FALSE;
        DeviceCapabilities->UniqueID = FALSE;
        DeviceCapabilities->SilentInstall = FALSE;
        DeviceCapabilities->RawDeviceOK = FALSE;
        DeviceCapabilities->SurpriseRemovalOK = FALSE;
        DeviceCapabilities->Address = 0;
        DeviceCapabilities->UINumber = 0;
        DeviceCapabilities->DeviceD2 = 1;

        /* FIXME: Verify these settings are correct */
        DeviceCapabilities->HardwareDisabled = FALSE;
        //DeviceCapabilities->NoDisplayInUI = FALSE;
        DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
        for (i = 0; i < PowerSystemMaximum; i++)
            DeviceCapabilities->DeviceState[i] = PowerDeviceD3;
        DeviceCapabilities->DeviceWake = 0;
        DeviceCapabilities->D1Latency = 0;
        DeviceCapabilities->D2Latency = 0;
        DeviceCapabilities->D3Latency = 0;
        Information = 0;
        Status = STATUS_SUCCESS;
        break;
    }
    /*case IRP_MN_QUERY_DEVICE_TEXT:
    {
        Status = STATUS_NOT_SUPPORTED;
        break;
    }*/

    case IRP_MN_QUERY_ID:
    {
        DPRINT("Ehci: PDO Query ID\n");
        Status = PdoQueryId(DeviceObject, Irp, &Information);
        break;
    }
    case IRP_MN_QUERY_INTERFACE:
    {
        UNICODE_STRING GuidString;
        PUSB_BUS_INTERFACE_HUB_V5 InterfaceHub;
        PUSB_BUS_INTERFACE_USBDI_V2 InterfaceDI;
        PPDO_DEVICE_EXTENSION PdoDeviceExtension;
        PFDO_DEVICE_EXTENSION FdoDeviceExtension;

        DPRINT("Ehci: PDO Query Interface\n");

        PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
        FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;

        Status = RtlStringFromGUID(Stack->Parameters.QueryInterface.InterfaceType, &GuidString);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Failed to create string from GUID!\n");
        }

        /* Assume success */
        Status = STATUS_SUCCESS;
        Information = 0;

        if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_GUID))
        {
            InterfaceHub = (PUSB_BUS_INTERFACE_HUB_V5)Stack->Parameters.QueryInterface.Interface;
            InterfaceHub->Version = Stack->Parameters.QueryInterface.Version;
            if (Stack->Parameters.QueryInterface.Version >= 0)
            {
                InterfaceHub->Size = Stack->Parameters.QueryInterface.Size;
                InterfaceHub->BusContext = PdoDeviceExtension->DeviceObject;
                InterfaceHub->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
                InterfaceHub->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
            }
            if (Stack->Parameters.QueryInterface.Version >= 1)
            {
                InterfaceHub->CreateUsbDevice = CreateUsbDevice;
                InterfaceHub->InitializeUsbDevice = InitializeUsbDevice;
                InterfaceHub->GetUsbDescriptors = GetUsbDescriptors;
                InterfaceHub->RemoveUsbDevice = RemoveUsbDevice;
                InterfaceHub->RestoreUsbDevice = RestoreUsbDevice;
                InterfaceHub->GetPortHackFlags = GetPortHackFlags;
                InterfaceHub->QueryDeviceInformation = QueryDeviceInformation;
            }
            if (Stack->Parameters.QueryInterface.Version >= 2)
            {
                InterfaceHub->GetControllerInformation = GetControllerInformation;
                InterfaceHub->ControllerSelectiveSuspend = ControllerSelectiveSuspend;
                InterfaceHub->GetExtendedHubInformation = GetExtendedHubInformation;
                InterfaceHub->GetRootHubSymbolicName = GetRootHubSymbolicName;
                InterfaceHub->GetDeviceBusContext = GetDeviceBusContext;
                InterfaceHub->Initialize20Hub = Initialize20Hub;

            }
            if (Stack->Parameters.QueryInterface.Version >= 3)
            {
                InterfaceHub->RootHubInitNotification = RootHubInitNotification;
            }
            if (Stack->Parameters.QueryInterface.Version >= 4)
            {
                InterfaceHub->FlushTransfers = FlushTransfers;
            }
            if (Stack->Parameters.QueryInterface.Version >= 5)
            {
                InterfaceHub->SetDeviceHandleData = SetDeviceHandleData;
            }
            if (Stack->Parameters.QueryInterface.Version >= 6)
            {
                DPRINT1("USB_BUS_INTERFACE_HUB_GUID version not supported!\n");
            }
            break;
        }

        if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID))
        {
            InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2) Stack->Parameters.QueryInterface.Interface;
            InterfaceDI->Version = Stack->Parameters.QueryInterface.Version;
            if (Stack->Parameters.QueryInterface.Version >= 0)
            {
                //InterfaceDI->Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
                InterfaceDI->Size = Stack->Parameters.QueryInterface.Size;
                InterfaceDI->BusContext = PdoDeviceExtension->DeviceObject;
                InterfaceDI->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
                InterfaceDI->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
                InterfaceDI->GetUSBDIVersion = GetUSBDIVersion;
                InterfaceDI->QueryBusTime = QueryBusTime;
                InterfaceDI->SubmitIsoOutUrb = SubmitIsoOutUrb;
                InterfaceDI->QueryBusInformation = QueryBusInformation;
            }
            if (Stack->Parameters.QueryInterface.Version >= 1)
            {
                InterfaceDI->IsDeviceHighSpeed = IsDeviceHighSpeed;
            }
            if (Stack->Parameters.QueryInterface.Version >= 2)
            {
                InterfaceDI->EnumLogEntry = EnumLogEntry;
            }

            if (Stack->Parameters.QueryInterface.Version >= 3)
            {
                DPRINT1("SB_BUS_INTERFACE_USBDI_GUID version not supported!\n");
            }
            break;
        }

        DPRINT1("GUID Not Supported\n");
        Status = Irp->IoStatus.Status;
        Information = Irp->IoStatus.Information;

        break;
    }
    case IRP_MN_QUERY_BUS_INFORMATION:
    {
        PPNP_BUS_INFORMATION BusInfo;

        BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
        if (!BusInfo)
            Status = STATUS_INSUFFICIENT_RESOURCES;
        else
        {
            /* FIXME */
            /*RtlCopyMemory(
                &BusInfo->BusTypeGuid,
                &GUID_DEVINTERFACE_XXX,
                sizeof(GUID));*/

            BusInfo->LegacyBusType = PNPBus;
            BusInfo->BusNumber = 0;
            Information = (ULONG_PTR)BusInfo;
            Status = STATUS_SUCCESS;
        }
        break;
    }
    default:
    {
        /* We are the PDO. So ignore */
        DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", MinorFunction);
        break;
    }
    }

    Irp->IoStatus.Information = Information;
    Irp->IoStatus.Status = Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return Status;
}
Exemplo n.º 12
0
BOOLEAN HidePort(IN PC0C_FDOPORT_EXTENSION pDevExt)
{
    BOOLEAN res;
    NTSTATUS status;

    if (!pDevExt->shown)
        return TRUE;

    res = TRUE;

    if ((pDevExt->shown & C0C_SHOW_WMIREG) != 0) {
        status = IoWMIRegistrationControl(pDevExt->pDevObj, WMIREG_ACTION_DEREGISTER);
        pDevExt->shown &= ~C0C_SHOW_WMIREG;

        if (NT_SUCCESS(status)) {
            Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"Hidden WMIREG");
        } else {
            res = FALSE;
            Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"HidePort IoWMIRegistrationControl FAIL");
        }
    }

    if (pDevExt->symbolicLinkName.Buffer && (pDevExt->shown & C0C_SHOW_INTERFACE) != 0) {
        status = IoSetDeviceInterfaceState(&pDevExt->symbolicLinkName, FALSE);
        pDevExt->shown &= ~C0C_SHOW_INTERFACE;

        if (NT_SUCCESS(status)) {
            Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"Hidden INTERFACE");
        } else {
            res = FALSE;
            Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"HidePort IoSetDeviceInterfaceState FAIL");
        }
    }

    if (pDevExt->ntDeviceName.Buffer && (pDevExt->shown & C0C_SHOW_DEVICEMAP) != 0) {
        status = RtlDeleteRegistryValue(RTL_REGISTRY_DEVICEMAP, C0C_SERIAL_DEVICEMAP,
                                        pDevExt->ntDeviceName.Buffer);
        pDevExt->shown &= ~C0C_SHOW_DEVICEMAP;

        if (NT_SUCCESS(status)) {
            Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"Hidden DEVICEMAP");
        } else {
            res = FALSE;
            Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"HidePort RtlDeleteRegistryValue " C0C_SERIAL_DEVICEMAP L" FAIL");
        }
    }

    if (pDevExt->win32DeviceName.Buffer && (pDevExt->shown & C0C_SHOW_SYMLINK) != 0) {
        status = IoDeleteSymbolicLink(&pDevExt->win32DeviceName);
        pDevExt->shown &= ~C0C_SHOW_SYMLINK;

        if (NT_SUCCESS(status)) {
            Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"Hidden SYMLINK");
        } else {
            res = FALSE;
            Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"HidePort IoDeleteSymbolicLink FAIL");
        }
    }

    if ((pDevExt->shown & C0C_SHOW_PORTNAME) != 0)
        res = (HidePortName(pDevExt) && res);

    pDevExt->shown &= ~C0C_SHOW_SHOWN;

    Trace00((PC0C_COMMON_EXTENSION)pDevExt, L"HidePort - ", res ? L"OK" : L"FAIL");

    return res;
}
Exemplo n.º 13
0
BOOLEAN ShowPort(IN PC0C_FDOPORT_EXTENSION pDevExt)
{
    BOOLEAN res;
    NTSTATUS status;

    if ((pDevExt->shown & C0C_SHOW_SHOWN) != 0)
        return TRUE;

    res = TRUE;

    if (!pDevExt->pIoPortLocal->isComClass &&
            (pDevExt->shown & C0C_SHOW_PORTNAME) == 0 &&
            (pDevExt->hide & C0C_SHOW_PORTNAME) == 0)
    {
        HANDLE hKey;

        status = IoOpenDeviceRegistryKey(pDevExt->pIoPortLocal->pPhDevObj,
                                         PLUGPLAY_REGKEY_DEVICE,
                                         STANDARD_RIGHTS_WRITE,
                                         &hKey);

        if (NT_SUCCESS(status)) {
            UNICODE_STRING keyName;

            RtlInitUnicodeString(&keyName, L"PortName");

            status = ZwSetValueKey(hKey,
                                   &keyName,
                                   0,
                                   REG_SZ,
                                   pDevExt->portName,
                                   (ULONG)((wcslen(pDevExt->portName) + 1) * sizeof(WCHAR)));

            if (NT_SUCCESS(status)) {
                pDevExt->shown |= C0C_SHOW_PORTNAME;
                Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"Shown PORTNAME");
            } else {
                res = FALSE;
                Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"ShowPort ZwSetValueKey(PortName) FAIL");
            }

            ZwClose(hKey);
        } else {
            res = FALSE;
            Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"ShowPort IoOpenDeviceRegistryKey(PLUGPLAY_REGKEY_DEVICE) FAIL");
        }
    }

    if (pDevExt->ntDeviceName.Buffer) {
        if (pDevExt->win32DeviceName.Buffer &&
                (pDevExt->shown & C0C_SHOW_SYMLINK) == 0 &&
                (pDevExt->hide & C0C_SHOW_SYMLINK) == 0)
        {
            status = IoCreateSymbolicLink(&pDevExt->win32DeviceName, &pDevExt->ntDeviceName);

            if (NT_SUCCESS(status)) {
                pDevExt->shown |= C0C_SHOW_SYMLINK;
                Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"Shown SYMLINK");
            } else {
                res = FALSE;
                Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"ShowPort IoCreateSymbolicLink FAIL");
            }
        }

        if ((pDevExt->shown & C0C_SHOW_SYMLINK) != 0 &&
                (pDevExt->shown & C0C_SHOW_DEVICEMAP) == 0 &&
                (pDevExt->hide & C0C_SHOW_DEVICEMAP) == 0)
        {
            status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP, C0C_SERIAL_DEVICEMAP,
                                           pDevExt->ntDeviceName.Buffer, REG_SZ,
                                           pDevExt->portName,
                                           (ULONG)((wcslen(pDevExt->portName) + 1) * sizeof(WCHAR)));

            if (NT_SUCCESS(status)) {
                pDevExt->shown |= C0C_SHOW_DEVICEMAP;
                Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"Shown DEVICEMAP");
            } else {
                res = FALSE;
                Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"ShowPort RtlWriteRegistryValue " C0C_SERIAL_DEVICEMAP L" FAIL");
            }
        }
    }

    if (pDevExt->symbolicLinkName.Buffer &&
            (pDevExt->shown & C0C_SHOW_INTERFACE) == 0 &&
            (pDevExt->hide & C0C_SHOW_INTERFACE) == 0)
    {
        status = IoSetDeviceInterfaceState(&pDevExt->symbolicLinkName, TRUE);

        if (NT_SUCCESS(status)) {
            pDevExt->shown |= C0C_SHOW_INTERFACE;
            Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"Shown INTERFACE");
        } else {
            res = FALSE;
            Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"ShowPort IoSetDeviceInterfaceState FAIL");
        }
    }

    if ((pDevExt->shown & C0C_SHOW_WMIREG) == 0 && (pDevExt->hide & C0C_SHOW_WMIREG) == 0) {
        status = IoWMIRegistrationControl(pDevExt->pDevObj, WMIREG_ACTION_REGISTER);

        if (NT_SUCCESS(status)) {
            pDevExt->shown |= C0C_SHOW_WMIREG;
            Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"Shown WMIREG");
        } else {
            res = FALSE;
            Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"ShowPort IoWMIRegistrationControl FAIL");
        }
    }

    pDevExt->shown |= C0C_SHOW_SHOWN;

    Trace00((PC0C_COMMON_EXTENSION)pDevExt, L"ShowPort - ", res ? L"OK" : L"FAIL");

    return res;
}
Exemplo n.º 14
0
int FloppyPnp(int DeviceObject , int Irp ) 
{ int DeviceObject__DeviceExtension = __VERIFIER_nondet_int() ;
  int Irp__Tail__Overlay__CurrentStackLocation = __VERIFIER_nondet_int() ;
  int Irp__IoStatus__Information ;
  int Irp__IoStatus__Status ;
  int Irp__CurrentLocation = __VERIFIER_nondet_int() ;
  int disketteExtension__IsRemoved = __VERIFIER_nondet_int() ;
  int disketteExtension__IsStarted = __VERIFIER_nondet_int() ;
  int disketteExtension__TargetObject = __VERIFIER_nondet_int() ;
  int disketteExtension__HoldNewRequests ;
  int disketteExtension__FloppyThread = __VERIFIER_nondet_int() ;
  int disketteExtension__InterfaceString__Buffer = __VERIFIER_nondet_int() ;
  int disketteExtension__InterfaceString = __VERIFIER_nondet_int() ;
  int disketteExtension__ArcName__Length = __VERIFIER_nondet_int() ;
  int disketteExtension__ArcName = __VERIFIER_nondet_int() ;
  int irpSp__MinorFunction = __VERIFIER_nondet_int() ;
  int IoGetConfigurationInformation__FloppyCount = __VERIFIER_nondet_int() ;
  int irpSp ;
  int disketteExtension ;
  int ntStatus ;
  int doneEvent = __VERIFIER_nondet_int() ;
  int irpSp___0 ;
  int nextIrpSp ;
  int nextIrpSp__Control ;
  int irpSp___1 ;
  int irpSp__Context ;
  int irpSp__Control ;
  long __cil_tmp29 ;
  long __cil_tmp30 ;

  {
#line 197
  ntStatus = 0;
#line 198
  PagingReferenceCount ++;
#line 199
  if (PagingReferenceCount == 1) {

  }
#line 204
  disketteExtension = DeviceObject__DeviceExtension;
#line 205
  irpSp = Irp__Tail__Overlay__CurrentStackLocation;
#line 206
  if (disketteExtension__IsRemoved) {
    {
#line 208
    Irp__IoStatus__Information = 0;
#line 209
    Irp__IoStatus__Status = -1073741738;
#line 210
    myStatus = -1073741738;
#line 211
    IofCompleteRequest(Irp, 0);
    }
#line 213
    return (-1073741738);
  }
#line 217
  if (irpSp__MinorFunction == 0) {
    goto switch_0_0;
  } else {
#line 220
    if (irpSp__MinorFunction == 5) {
      goto switch_0_5;
    } else {
#line 223
      if (irpSp__MinorFunction == 1) {
        goto switch_0_5;
      } else {
#line 226
        if (irpSp__MinorFunction == 6) {
          goto switch_0_6;
        } else {
#line 229
          if (irpSp__MinorFunction == 3) {
            goto switch_0_6;
          } else {
#line 232
            if (irpSp__MinorFunction == 4) {
              goto switch_0_4;
            } else {
#line 235
              if (irpSp__MinorFunction == 2) {
                goto switch_0_2;
              } else {
                goto switch_0_default;
#line 240
                if (0) {
                  switch_0_0: 
                  {
#line 243
                  ntStatus = FloppyStartDevice(DeviceObject, Irp);
                  }
                  goto switch_0_break;
                  switch_0_5: 
#line 248
                  if (irpSp__MinorFunction == 5) {

                  }
#line 253
                  if (! disketteExtension__IsStarted) {
#line 254
                    if (s == NP) {
#line 255
                      s = SKIP1;
                    } else {
                      {
#line 258
                      errorFn();
                      }
                    }
                    {
#line 262
                    Irp__CurrentLocation ++;
#line 263
                    Irp__Tail__Overlay__CurrentStackLocation ++;
#line 264
                    ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
                    }
#line 266
                    return (ntStatus);
                  }
                  {
#line 271
                  disketteExtension__HoldNewRequests = 1;
#line 272
                  ntStatus = FlQueueIrpToThread(Irp, disketteExtension);
                  }
                  {
#line 274
                  __cil_tmp29 = (long )ntStatus;
#line 274
                  if (__cil_tmp29 == 259L) {
                    {
#line 276
                    KeWaitForSingleObject(disketteExtension__FloppyThread, Executive,
                                          KernelMode, 0, 0);
                    }
#line 279
                    if (disketteExtension__FloppyThread != 0) {

                    }
#line 284
                    disketteExtension__FloppyThread = 0;
#line 285
                    Irp__IoStatus__Status = 0;
#line 286
                    myStatus = 0;
#line 287
                    if (s == NP) {
#line 288
                      s = SKIP1;
                    } else {
                      {
#line 291
                      errorFn();
                      }
                    }
                    {
#line 295
                    Irp__CurrentLocation ++;
#line 296
                    Irp__Tail__Overlay__CurrentStackLocation ++;
#line 297
                    ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
                    }
                  } else {
                    {
#line 301
                    ntStatus = -1073741823;
#line 302
                    Irp__IoStatus__Status = ntStatus;
#line 303
                    myStatus = ntStatus;
#line 304
                    Irp__IoStatus__Information = 0;
#line 305
                    IofCompleteRequest(Irp, 0);
                    }
                  }
                  }
                  goto switch_0_break;
                  switch_0_6: 
#line 311
                  if (irpSp__MinorFunction == 6) {

                  }
#line 316
                  if (! disketteExtension__IsStarted) {
#line 317
                    Irp__IoStatus__Status = 0;
#line 318
                    myStatus = 0;
#line 319
                    if (s == NP) {
#line 320
                      s = SKIP1;
                    } else {
                      {
#line 323
                      errorFn();
                      }
                    }
                    {
#line 327
                    Irp__CurrentLocation ++;
#line 328
                    Irp__Tail__Overlay__CurrentStackLocation ++;
#line 329
                    ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
                    }
                  } else {
#line 332
                    Irp__IoStatus__Status = 0;
#line 333
                    myStatus = 0;
#line 334
                    irpSp___0 = Irp__Tail__Overlay__CurrentStackLocation;
#line 335
                    nextIrpSp = Irp__Tail__Overlay__CurrentStackLocation - 1;
#line 336
                    nextIrpSp__Control = 0;
#line 337
                    if (s != NP) {
                      {
#line 339
                      errorFn();
                      }
                    } else {
#line 342
                      if (compRegistered != 0) {
                        {
#line 344
                        errorFn();
                        }
                      } else {
#line 347
                        compRegistered = 1;
                      }
                    }
                    {
#line 351
                    irpSp___1 = Irp__Tail__Overlay__CurrentStackLocation - 1;
#line 352
                    irpSp__Context = doneEvent;
#line 353
                    irpSp__Control = 224;
#line 357
                    ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
                    }
                    {
#line 359
                    __cil_tmp30 = (long )ntStatus;
#line 359
                    if (__cil_tmp30 == 259L) {
                      {
#line 361
                      KeWaitForSingleObject(doneEvent, Executive, KernelMode, 0, 0);
#line 362
                      ntStatus = myStatus;
                      }
                    }
                    }
                    {
#line 368
                    disketteExtension__HoldNewRequests = 0;
#line 369
                    Irp__IoStatus__Status = ntStatus;
#line 370
                    myStatus = ntStatus;
#line 371
                    Irp__IoStatus__Information = 0;
#line 372
                    IofCompleteRequest(Irp, 0);
                    }
                  }
                  goto switch_0_break;
                  switch_0_4: 
#line 377
                  disketteExtension__IsStarted = 0;
#line 378
                  Irp__IoStatus__Status = 0;
#line 379
                  myStatus = 0;
#line 380
                  if (s == NP) {
#line 381
                    s = SKIP1;
                  } else {
                    {
#line 384
                    errorFn();
                    }
                  }
                  {
#line 388
                  Irp__CurrentLocation ++;
#line 389
                  Irp__Tail__Overlay__CurrentStackLocation ++;
#line 390
                  ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
                  }
                  goto switch_0_break;
                  switch_0_2: 
#line 394
                  disketteExtension__HoldNewRequests = 0;
#line 395
                  disketteExtension__IsStarted = 0;
#line 396
                  disketteExtension__IsRemoved = 1;
#line 397
                  if (s == NP) {
#line 398
                    s = SKIP1;
                  } else {
                    {
#line 401
                    errorFn();
                    }
                  }
                  {
#line 405
                  Irp__CurrentLocation ++;
#line 406
                  Irp__Tail__Overlay__CurrentStackLocation ++;
#line 407
                  Irp__IoStatus__Status = 0;
#line 408
                  myStatus = 0;
#line 409
                  ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
                  }
#line 411
                  if (disketteExtension__InterfaceString__Buffer != 0) {
                    {
#line 413
                    IoSetDeviceInterfaceState(disketteExtension__InterfaceString,
                                              0);
                    }
                  }
#line 419
                  if (disketteExtension__ArcName__Length != 0) {
                    {
#line 421
                    IoDeleteSymbolicLink(disketteExtension__ArcName);
                    }
                  }
#line 426
                  IoGetConfigurationInformation__FloppyCount --;
                  goto switch_0_break;
                  switch_0_default: ;
#line 429
                  if (s == NP) {
#line 430
                    s = SKIP1;
                  } else {
                    {
#line 433
                    errorFn();
                    }
                  }
                  {
#line 437
                  Irp__CurrentLocation ++;
#line 438
                  Irp__Tail__Overlay__CurrentStackLocation ++;
#line 439
                  ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
                  }
                } else {
                  switch_0_break: ;
                }
              }
            }
          }
        }
      }
    }
  }
#line 452
  PagingReferenceCount --;
#line 453
  if (PagingReferenceCount == 0) {

  }
#line 458
  return (ntStatus);
}
}
Exemplo n.º 15
0
static
VOID
Test_IoSetDeviceInterface(VOID)
{
    NTSTATUS Status;
    UNICODE_STRING SymbolicLinkName;
    PWCHAR Buffer;
    ULONG BufferSize;

    /* Invalid prefix or GUID */
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(NULL, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_INVALID_PARAMETER);

    RtlInitEmptyUnicodeString(&SymbolicLinkName, NULL, 0);
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_INVALID_PARAMETER);

    RtlInitUnicodeString(&SymbolicLinkName, L"\\??");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_INVALID_PARAMETER);

    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_INVALID_PARAMETER);

    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\\\");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_INVALID_PARAMETER);

    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_INVALID_PARAMETER);

    /* Valid prefix & GUID, invalid device node */
    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND);

    RtlInitUnicodeString(&SymbolicLinkName, L"\\\\?\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND);

    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\X{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}\\");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND);

    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
    KmtStartSeh()
        Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
    KmtEndSeh(STATUS_SUCCESS)
    ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND);

    /* Must not read past the buffer */
    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#{aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
    BufferSize = SymbolicLinkName.Length;
    Buffer = KmtAllocateGuarded(BufferSize);
    if (!skip(Buffer != NULL, "Failed to allocate %lu bytes\n", BufferSize))
    {
        RtlCopyMemory(Buffer, SymbolicLinkName.Buffer, BufferSize);
        SymbolicLinkName.Buffer = Buffer;
        SymbolicLinkName.MaximumLength = BufferSize;
        KmtStartSeh()
            Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
        KmtEndSeh(STATUS_SUCCESS)
        ok_eq_hex(Status, STATUS_OBJECT_NAME_NOT_FOUND);
        KmtFreeGuarded(Buffer);
    }

    RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\#aaaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa}");
    BufferSize = SymbolicLinkName.Length;
    Buffer = KmtAllocateGuarded(BufferSize);
    if (!skip(Buffer != NULL, "Failed to allocate %lu bytes\n", BufferSize))
    {
        RtlCopyMemory(Buffer, SymbolicLinkName.Buffer, BufferSize);
        SymbolicLinkName.Buffer = Buffer;
        SymbolicLinkName.MaximumLength = BufferSize;
        KmtStartSeh()
            Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
        KmtEndSeh(STATUS_SUCCESS)
        ok_eq_hex(Status, STATUS_INVALID_PARAMETER);
        KmtFreeGuarded(Buffer);
    }
}
Exemplo n.º 16
0
int FloppyStartDevice(int DeviceObject , int Irp ) 
{ int DeviceObject__DeviceExtension = __VERIFIER_nondet_int() ;
  int Irp__Tail__Overlay__CurrentStackLocation = __VERIFIER_nondet_int() ;
  int Irp__IoStatus__Status ;
  int disketteExtension__TargetObject = __VERIFIER_nondet_int() ;
  int disketteExtension__MaxTransferSize ;
  int disketteExtension__DriveType = __VERIFIER_nondet_int() ;
  int disketteExtension__PerpendicularMode ;
  int disketteExtension__DeviceUnit ;
  int disketteExtension__DriveOnValue ;
  int disketteExtension__UnderlyingPDO = __VERIFIER_nondet_int() ;
  int disketteExtension__InterfaceString = __VERIFIER_nondet_int() ;
  int disketteExtension__IsStarted ;
  int disketteExtension__HoldNewRequests ;
  int ntStatus ;
  int pnpStatus ;
  int doneEvent = __VERIFIER_nondet_int() ;
  int fdcInfo = __VERIFIER_nondet_int() ;
  int fdcInfo__BufferCount ;
  int fdcInfo__BufferSize ;
  int fdcInfo__MaxTransferSize = __VERIFIER_nondet_int() ;
  int fdcInfo__AcpiBios = __VERIFIER_nondet_int() ;
  int fdcInfo__AcpiFdiSupported = __VERIFIER_nondet_int() ;
  int fdcInfo__PeripheralNumber = __VERIFIER_nondet_int() ;
  int fdcInfo__BusType ;
  int fdcInfo__ControllerNumber = __VERIFIER_nondet_int() ;
  int fdcInfo__UnitNumber = __VERIFIER_nondet_int() ;
  int fdcInfo__BusNumber = __VERIFIER_nondet_int() ;
  int Dc ;
  int Fp ;
  int disketteExtension ;
  int irpSp ;
  int irpSp___0 ;
  int nextIrpSp ;
  int nextIrpSp__Control ;
  int irpSp___1 ;
  int irpSp__Control ;
  int irpSp__Context ;
  int InterfaceType ;
  int KUSER_SHARED_DATA__AlternativeArchitecture_NEC98x86 = __VERIFIER_nondet_int() ;
  long __cil_tmp42 ;
  int __cil_tmp43 ;
  int __cil_tmp44 ;
  int __cil_tmp45 ;
  int __cil_tmp46 ;
  int __cil_tmp47 ;
  int __cil_tmp48 ;
  int __cil_tmp49 ;

  {
#line 503
  Dc = DiskController;
#line 504
  Fp = FloppyDiskPeripheral;
#line 505
  disketteExtension = DeviceObject__DeviceExtension;
#line 506
  irpSp = Irp__Tail__Overlay__CurrentStackLocation;
#line 507
  irpSp___0 = Irp__Tail__Overlay__CurrentStackLocation;
#line 508
  nextIrpSp = Irp__Tail__Overlay__CurrentStackLocation - 1;
#line 509
  nextIrpSp__Control = 0;
#line 510
  if (s != NP) {
    {
#line 512
    errorFn();
    }
  } else {
#line 515
    if (compRegistered != 0) {
      {
#line 517
      errorFn();
      }
    } else {
#line 520
      compRegistered = 1;
    }
  }
  {
#line 524
  irpSp___1 = Irp__Tail__Overlay__CurrentStackLocation - 1;
#line 525
  irpSp__Context = doneEvent;
#line 526
  irpSp__Control = 224;
#line 530
  ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
  }
  {
#line 532
  __cil_tmp42 = (long )ntStatus;
#line 532
  if (__cil_tmp42 == 259L) {
    {
#line 534
    ntStatus = KeWaitForSingleObject(doneEvent, Executive, KernelMode, 0, 0);
#line 535
    ntStatus = myStatus;
    }
  }
  }
  {
#line 541
  fdcInfo__BufferCount = 0;
#line 542
  fdcInfo__BufferSize = 0;
#line 543
  __cil_tmp43 = 3080;
#line 543
  __cil_tmp44 = 458752;
#line 543
  __cil_tmp45 = 461832;
#line 543
  __cil_tmp46 = 461835;
#line 543
  ntStatus = FlFdcDeviceIo(disketteExtension__TargetObject, __cil_tmp46, fdcInfo);
  }
#line 546
  if (ntStatus >= 0) {
#line 547
    disketteExtension__MaxTransferSize = fdcInfo__MaxTransferSize;
#line 548
    if (fdcInfo__AcpiBios) {
#line 549
      if (fdcInfo__AcpiFdiSupported) {
        {
#line 551
        ntStatus = FlAcpiConfigureFloppy(disketteExtension, fdcInfo);
        }
#line 553
        if (disketteExtension__DriveType == 4) {
#line 554
          //__cil_tmp47 = uninf1();
#line 554
          //disketteExtension__PerpendicularMode |= __cil_tmp47;
        }
      } else {
        goto _L;
      }
    } else {
      _L: 
#line 563
      if (disketteExtension__DriveType == 4) {
#line 564
        //__cil_tmp48 = uninf1();
#line 564
        //disketteExtension__PerpendicularMode |= __cil_tmp48;
      }
#line 568
      InterfaceType = 0;
      {
#line 570
      while (1) {
        while_0_continue: /* CIL Label */ ;

#line 572
        if (InterfaceType >= MaximumInterfaceType) {
          goto while_1_break;
        }
        {
#line 578
        fdcInfo__BusType = InterfaceType;
#line 579
        ntStatus = IoQueryDeviceDescription(fdcInfo__BusType, fdcInfo__BusNumber,
                                            Dc, fdcInfo__ControllerNumber, Fp, fdcInfo__PeripheralNumber,
                                            FlConfigCallBack, disketteExtension);
        }
#line 583
        if (ntStatus >= 0) {
          goto while_1_break;
        }
#line 588
        InterfaceType ++;
      }
      while_0_break: /* CIL Label */ ;
      }
      while_1_break: ;
    }
#line 593
    if (ntStatus >= 0) {
#line 594
      if (KUSER_SHARED_DATA__AlternativeArchitecture_NEC98x86 != 0) {
#line 595
        disketteExtension__DeviceUnit = fdcInfo__UnitNumber;
#line 596
        //disketteExtension__DriveOnValue = fdcInfo__UnitNumber;
      } else {
#line 598
        disketteExtension__DeviceUnit = fdcInfo__PeripheralNumber;
#line 599
        //__cil_tmp49 = 16 << fdcInfo__PeripheralNumber;
#line 599
        //disketteExtension__DriveOnValue = fdcInfo__PeripheralNumber | __cil_tmp49;
      }
      {
#line 602
      pnpStatus = IoRegisterDeviceInterface(disketteExtension__UnderlyingPDO, MOUNTDEV_MOUNTED_DEVICE_GUID,
                                            0, disketteExtension__InterfaceString);
      }
#line 605
      if (pnpStatus >= 0) {
        {
#line 607
        pnpStatus = IoSetDeviceInterfaceState(disketteExtension__InterfaceString,
                                              1);
        }
      }
#line 613
      disketteExtension__IsStarted = 1;
#line 614
      disketteExtension__HoldNewRequests = 0;
    }
  }
  {
#line 622
  Irp__IoStatus__Status = ntStatus;
#line 623
  myStatus = ntStatus;
#line 624
  IofCompleteRequest(Irp, 0);
  }
#line 626
  return (ntStatus);
}
}
Exemplo n.º 17
0
Arquivo: pdo.c Projeto: RPG-7/reactos
NTSTATUS
HidClassPDO_PnP(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
{
    PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
    PIO_STACK_LOCATION IoStack;
    NTSTATUS Status;
    PPNP_BUS_INFORMATION BusInformation;
    PDEVICE_RELATIONS DeviceRelation;
    ULONG Index, bFound;

    //
    // get device extension
    //
    PDODeviceExtension = DeviceObject->DeviceExtension;
    ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);

    //
    // get current irp stack location
    //
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    //
    // handle request
    //
    switch (IoStack->MinorFunction)
    {
        case IRP_MN_QUERY_ID:
        {
            if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
            {
                //
                // handle query device id
                //
                Status = HidClassPDO_HandleQueryDeviceId(DeviceObject, Irp);
                break;
            }
            else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
            {
                //
                // handle instance id
                //
                Status = HidClassPDO_HandleQueryHardwareId(DeviceObject, Irp);
                break;
            }
            else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
            {
                //
                // handle instance id
                //
                Status = HidClassPDO_HandleQueryInstanceId(DeviceObject, Irp);
                break;
            }
            else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
            {
                //
                // handle instance id
                //
                Status = HidClassPDO_HandleQueryCompatibleId(DeviceObject, Irp);
                break;
            }

            DPRINT1("[HIDCLASS]: IRP_MN_QUERY_ID IdType %x unimplemented\n", IoStack->Parameters.QueryId.IdType);
            Status = STATUS_NOT_SUPPORTED;
            Irp->IoStatus.Information = 0;
            break;
        }
        case IRP_MN_QUERY_CAPABILITIES:
        {
            if (IoStack->Parameters.DeviceCapabilities.Capabilities == NULL)
            {
                //
                // invalid request
                //
                Status = STATUS_DEVICE_CONFIGURATION_ERROR;
                break;
            }

            //
            // copy capabilities
            //
            RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities,
                          &PDODeviceExtension->Capabilities,
                          sizeof(DEVICE_CAPABILITIES));
            Status = STATUS_SUCCESS;
            break;
        }
        case IRP_MN_QUERY_BUS_INFORMATION:
        {
            //
            //
            //
            BusInformation = ExAllocatePoolWithTag(NonPagedPool, sizeof(PNP_BUS_INFORMATION), HIDCLASS_TAG);

            //
            // fill in result
            //
            RtlCopyMemory(&BusInformation->BusTypeGuid, &GUID_BUS_TYPE_HID, sizeof(GUID));
            BusInformation->LegacyBusType = PNPBus;
            BusInformation->BusNumber = 0; //FIXME

            //
            // store result
            //
            Irp->IoStatus.Information = (ULONG_PTR)BusInformation;
            Status = STATUS_SUCCESS;
            break;
        }
        case IRP_MN_QUERY_PNP_DEVICE_STATE:
        {
            //
            // FIXME set flags when driver fails / disabled
            //
            Status = STATUS_SUCCESS;
            break;
        }
        case IRP_MN_QUERY_DEVICE_RELATIONS:
        {
            //
            // only target relations are supported
            //
            if (IoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
            {
                //
                // not supported
                //
                Status = Irp->IoStatus.Status;
                break;
            }

            //
            // allocate device relations
            //
            DeviceRelation = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS), HIDCLASS_TAG);
            if (!DeviceRelation)
            {
                //
                // no memory
                //
                Status = STATUS_INSUFFICIENT_RESOURCES;
                break;
            }

            //
            // init device relation
            //
            DeviceRelation->Count = 1;
            DeviceRelation->Objects[0] = DeviceObject;
            ObReferenceObject(DeviceRelation->Objects[0]);

            //
            // store result
            //
            Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
            Status = STATUS_SUCCESS;
            break;
        }
        case IRP_MN_START_DEVICE:
        {
            //
            // FIXME: support polled devices
            //
            ASSERT(PDODeviceExtension->Common.DriverExtension->DevicesArePolled == FALSE);

            //
            // now register the device interface
            //
            Status = IoRegisterDeviceInterface(PDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject,
                                               &GUID_DEVINTERFACE_HID,
                                               NULL,
                                               &PDODeviceExtension->DeviceInterface);
            DPRINT("[HIDCLASS] IoRegisterDeviceInterfaceState Status %x\n", Status);
            if (NT_SUCCESS(Status))
            {
                //
                // enable device interface
                //
                Status = IoSetDeviceInterfaceState(&PDODeviceExtension->DeviceInterface, TRUE);
                DPRINT("[HIDCLASS] IoSetDeviceInterFaceState %x\n", Status);
            }

            //
            // done
            //
            Status = STATUS_SUCCESS;
            break;
        }
        case IRP_MN_REMOVE_DEVICE:
        {
            /* Disable the device interface */
            if (PDODeviceExtension->DeviceInterface.Length != 0)
                IoSetDeviceInterfaceState(&PDODeviceExtension->DeviceInterface, FALSE);

            //
            // remove us from the fdo's pdo list
            //
            bFound = FALSE;
            for (Index = 0; Index < PDODeviceExtension->FDODeviceExtension->DeviceRelations->Count; Index++)
            {
                if (PDODeviceExtension->FDODeviceExtension->DeviceRelations->Objects[Index] == DeviceObject)
                {
                    //
                    // remove us
                    //
                    bFound = TRUE;
                    PDODeviceExtension->FDODeviceExtension->DeviceRelations->Objects[Index] = NULL;
                    break;
                }
            }

            /* Complete the IRP */
            Irp->IoStatus.Status = STATUS_SUCCESS;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);

            if (bFound)
            {
                /* Delete our device object*/
                IoDeleteDevice(DeviceObject);
            }

            return STATUS_SUCCESS;
        }
        case IRP_MN_QUERY_INTERFACE:
        {
            DPRINT1("[HIDCLASS] PDO IRP_MN_QUERY_INTERFACE not implemented\n");

            //
            // do nothing
            //
            Status = Irp->IoStatus.Status;
            break;
        }
        case IRP_MN_QUERY_REMOVE_DEVICE:
        case IRP_MN_CANCEL_STOP_DEVICE:
        case IRP_MN_QUERY_STOP_DEVICE:
        case IRP_MN_CANCEL_REMOVE_DEVICE:
        {
            //
            // no/op
            //
#if 0
            Status = STATUS_SUCCESS;
#else
            DPRINT1("Denying removal of HID device due to IRP cancellation bugs\n");
            Status = STATUS_UNSUCCESSFUL;
#endif
            break;
        }
        default:
        {
            //
            // do nothing
            //
            Status = Irp->IoStatus.Status;
            break;
        }
    }

    //
    // complete request
    //
    if (Status != STATUS_PENDING)
    {
        //
        // store result
        //
        Irp->IoStatus.Status = Status;

        //
        // complete request
        //
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }

    //
    // done processing
    //
    return Status;
}
Exemplo n.º 18
0
int body() {
   if (nondet()) {

       // haven't stopped yet, lets do so
       ntStatus = t1394Diag_PnpStopDevice(DeviceObject, Irp);
   }

   ntStatus = IoSetDeviceInterfaceState();


   // lets free up any crom data structs we've allocated...
   keA = 1; keA = 0; KeAcquireSpinLock(&lock3, &Irql);

   k1 = nondet();
   while (k1>0) {

       CromData = nondet();

       // get struct off list
       k1--;

       // need to free up everything associated with this allocate...
       if (CromData)
       {
           if (nondet())
               ExFreePool0();

           if (nondet())
               IoFreeMdl();

           // we already checked CromData
           ExFreePool1(CromData);
       }
   }

   keR = 1; keR = 0; KeReleaseSpinLock(&lock3, Irql);

   keA = 1; keA = 0; KeAcquireSpinLock(&lock1, &Irql);

   k2 = nondet();
   while (k2>0) {

     AsyncAddressData = nondet();

       // get struct off list
       AsyncAddressData = nondet();
       k2--;

       // need to free up everything associated with this allocate...
       if (nondet())
           IoFreeMdl();

       if (nondet())
           ExFreePool0();

       if (nondet())
           ExFreePool0();

       if (AsyncAddressData)
           ExFreePool0();
   }

   keR = 1; keR = 0; KeReleaseSpinLock(&lock1, Irql);

   // free up any attached isoch buffers
   while (TRUE) {

       keA = 1; keA = 0; KeAcquireSpinLock(&lock4, &Irql);

       k3 = nondet();
       if (k3>0) {

	 IsochDetachData = nondet();
	 i = nondet();

           IsochDetachData = nondet();
           k3--;


           KeCancelTimer();
           keR = 1; keR = 0; KeReleaseSpinLock(&lock4, Irql);


           t1394_IsochCleanup(IsochDetachData);
       }
       else {

           keR = 1; keR = 0; KeReleaseSpinLock(&lock4, Irql);
           break;
       }
   }

   // remove any isoch resource data

   k4 = nondet();
   while (TRUE) {

       keA = 1; keA = 0; KeAcquireSpinLock(&lock5, &Irql);
       if (k4>0) {

           IsochResourceData = nondet();
           k4--;

           keR = 1; keR = 0; KeReleaseSpinLock(&lock5, Irql);


           if (IsochResourceData) {

	       pIrb = nondet();
               ResourceIrp = nondet();
               StackSize = nondet();
               ResourceIrp = IoAllocateIrp(StackSize, FALSE);

               if (ResourceIrp == NULL) {

               }
               else {

                   pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));

                   if (!pIrb) {

                       IoFreeIrp(ResourceIrp);
                   }
                   else {

                       RtlZeroMemory (pIrb, sizeof (IRB));

                       ntStatus = t1394_SubmitIrpSynch(ResourceIrp, pIrb);


                       ExFreePool1(pIrb);
                       IoFreeIrp(ResourceIrp);
                   }
               }
           }
       }
       else {

           keR = 1; keR = 0; KeReleaseSpinLock(&lock5, Irql);
           break;
       }
   }

   // get rid of any pending bus reset notify requests
   keA = 1; keA = 0; KeAcquireSpinLock(&lock6, &Irql);

   k5 = nondet();
   while (k5>0) {

       prevCancel = NULL;

       // get the irp off of the list
       BusResetIrp = nondet();
       k5--;


       // make this irp non-cancelable...
       prevCancel = IoSetCancelRoutine(NULL);


       // and complete it...
       IoCompleteRequest(IO_NO_INCREMENT);

       ExFreePool1(BusResetIrp);
   }

   keR = 1; keR = 0; KeReleaseSpinLock(&lock6, Irql);

   // free up the symbolic link

   while(1);
} // t1394Diag_PnpRemoveDevice
Exemplo n.º 19
0
NTSTATUS
Bus_StartFdo (
    __in  PFDO_DEVICE_DATA            FdoData,
    __in  PIRP   Irp )
/*++

Routine Description:

    Initialize and start the bus controller. Get the resources
    by parsing the list and map them if required.

Arguments:

    DeviceData - Pointer to the FDO's device extension.
    Irp          - Pointer to the irp.

Return Value:

    NT Status is returned.

--*/
{
    NTSTATUS status;
    POWER_STATE powerState;

    PAGED_CODE ();

    //
    // Check the function driver source to learn
    // about parsing resource list.
    //

    //
    // Enable device interface. If the return status is
    // STATUS_OBJECT_NAME_EXISTS means we are enabling the interface
    // that was already enabled, which could happen if the device
    // is stopped and restarted for resource rebalancing.
    //

    status = IoSetDeviceInterfaceState(&FdoData->InterfaceName, TRUE);
    if (!NT_SUCCESS (status)) {
        Bus_KdPrint (FdoData, BUS_DBG_PNP_TRACE,
                ("IoSetDeviceInterfaceState failed: 0x%x\n", status));
        return status;
    }

    //
    // Set the device power state to fully on. Also if this Start
    // is due to resource rebalance, you should restore the device
    // to the state it was before you stopped the device and relinquished
    // resources.
    //

    FdoData->DevicePowerState = PowerDeviceD0;
    powerState.DeviceState = PowerDeviceD0;
    PoSetPowerState ( FdoData->Self, DevicePowerState, powerState );

    SET_NEW_PNP_STATE(FdoData, Started);

    //
    // Register with WMI
    //
    status = Bus_WmiRegistration(FdoData);
    if (!NT_SUCCESS (status)) {
        Bus_KdPrint (FdoData, BUS_DBG_SS_ERROR,
        ("StartFdo: Bus_WmiRegistration failed (%x)\n", status));
    }

    return status;
}
int body() {
  __rho_1_ = nondet();
   if (__rho_1_>0) {

       // haven't stopped yet, lets do so
       ntStatus = t1394Diag_PnpStopDevice(1, Irp);
   }

   ntStatus = IoSetDeviceInterfaceState();


   // lets free up any crom data structs we've allocated...
   KeAcquireSpinLock(1, Irql);

   __rho_5_ = nondet();
   k1 = __rho_5_;
   while (1) {
     if (!(k1>0)) break;

       CromData = nondet();

       // get struct off list
       k1--;

       // need to free up everything associated with this allocate...
       if (CromData>0)
       {
	 __rho_2_ = nondet();
           if (__rho_2_>0)
               ExFreePool0();

	 __rho_3_ = nondet();
           if (__rho_3_>0)
               IoFreeMdl();

           // we already checked CromData
           ExFreePool1(CromData);
       }
   }

   KeReleaseSpinLock(1, Irql);

   KeAcquireSpinLock(1, Irql);

   __rho_4_ = nondet();
   k2 = __rho_4_;
   while (1) {
     if (!(k2>0)) break;

     AsyncAddressData = nondet();

       // get struct off list
       AsyncAddressData = nondet();
       k2--;

       // need to free up everything associated with this allocate...
       __rho_7_ = nondet();
       if (__rho_7_>0)
           IoFreeMdl();

       __rho_8_ = nondet();
       if (__rho_8_>0)
           ExFreePool0();

       __rho_9_ = nondet();
       if (__rho_9_>0)
           ExFreePool0();

       if (AsyncAddressData>0)
           ExFreePool0();
   }

   KeReleaseSpinLock(1, Irql);

   // free up any attached isoch buffers
       __rho_10_ = nondet();
       k3 = __rho_10_;
   while (1>0) {

       KeAcquireSpinLock(1, Irql);

       if (k3>0) {

	 IsochDetachData = nondet();
	 i = nondet();

           IsochDetachData = nondet();
           k3--;


           KeCancelTimer();
           KeReleaseSpinLock(1, Irql);


           t1394_IsochCleanup(IsochDetachData);
       }
       else {

           KeReleaseSpinLock(1, Irql);
           break;
       }
   }

   // remove any isoch resource data
   while (TRUE) {
       KeAcquireSpinLock(1, Irql);
       __rho_11_ = nondet();
       k4 = __rho_11_;
       if (k4>0) {

           IsochResourceData = nondet();
           k4--;

           KeReleaseSpinLock(1, Irql);


           if (IsochResourceData>0) {

	       pIrb = nondet();
               ResourceIrp = nondet();
               //StackSize = nondet();
               ResourceIrp = IoAllocateIrp(1, FALSE);

               if (ResourceIrp == 0) {

               }
               else {

                   pIrb = ExAllocatePool(NonPagedPool, 0);

                   if (pIrb<=0) {

                       IoFreeIrp(ResourceIrp);
                   }
                   else {

                       RtlZeroMemory (pIrb, 0);

                       ntStatus = t1394_SubmitIrpSynch(ResourceIrp, pIrb);


                       ExFreePool1(pIrb);
                       IoFreeIrp(ResourceIrp);
                   }
               }
           }
       }
       else {

           KeReleaseSpinLock(1, Irql);
           break;
       }
   }

   // get rid of any pending bus reset notify requests
   KeAcquireSpinLock(1, Irql);



   __rho_12_ = nondet();
   k5 = __rho_12_;
   //if(__rho_666_>0) { assume(k5 > 0);} 
   while (1) {
     if (!(k5>0)) break;

     //prevCancel = NULL;

       // get the irp off of the list
       //BusResetIrp = nondet();
       k5--;


       // make this irp non-cancelable...
       //prevCancel = IoSetCancelRoutine(NULL);


       // and complete it...
       IoCompleteRequest(IO_NO_INCREMENT);

       ExFreePool1(1);
   }

   KeReleaseSpinLock(1, Irql);

   //if(__rho_666_<=0) { assume(ntStatus != STATUS_SUCCESS); }
   // free up the symbolic link
   if(ntStatus != STATUS_SUCCESS) { 
     phi_nSUC_ret = 1;
   }
  while(1) { dummy=dummy; } L_return: return 0;
} // t1394Diag_PnpRemoveDevice
Exemplo n.º 21
0
VOID DokanDeleteDeviceObject(__in PDokanDCB Dcb) {
  PDokanVCB vcb;
  DOKAN_CONTROL dokanControl;
  PMOUNT_ENTRY mountEntry = NULL;

  ASSERT(GetIdentifierType(Dcb) == DCB);
  vcb = Dcb->Vcb;

  if (Dcb->SymbolicLinkName == NULL) {
    DDbgPrint("  Symbolic Name already deleted, so go out here\n");
    return;
  }

  RtlZeroMemory(&dokanControl, sizeof(dokanControl));
  RtlCopyMemory(dokanControl.DeviceName, Dcb->DiskDeviceName->Buffer,
                Dcb->DiskDeviceName->Length);
  mountEntry = FindMountEntry(Dcb->Global, &dokanControl);
  if (mountEntry != NULL) {
    if (mountEntry->MountControl.Type == FILE_DEVICE_NETWORK_FILE_SYSTEM) {
      // Run FsRtlDeregisterUncProvider in System thread.
      HANDLE handle;
      PKTHREAD thread;
      OBJECT_ATTRIBUTES objectAttribs;
      NTSTATUS status;

      InitializeObjectAttributes(&objectAttribs, NULL, OBJ_KERNEL_HANDLE, NULL,
                                 NULL);
      status = PsCreateSystemThread(
          &handle, THREAD_ALL_ACCESS, &objectAttribs, NULL, NULL,
          (PKSTART_ROUTINE)DokanDeregisterUncProvider, Dcb);
      if (!NT_SUCCESS(status)) {
        DDbgPrint("PsCreateSystemThread failed: 0x%X\n", status);
      } else {
        ObReferenceObjectByHandle(handle, THREAD_ALL_ACCESS, NULL, KernelMode,
                                  &thread, NULL);
        ZwClose(handle);
        KeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL);
        ObDereferenceObject(thread);
      }
    }
    RemoveMountEntry(Dcb->Global, mountEntry);
  } else {
    DDbgPrint("  Cannot found associated mount entry.\n");
  }

  DDbgPrint("  Delete Symbolic Name: %wZ\n", Dcb->SymbolicLinkName);
  IoDeleteSymbolicLink(Dcb->SymbolicLinkName);

  if (Dcb->MountedDeviceInterfaceName.Buffer != NULL) {
    IoSetDeviceInterfaceState(&Dcb->MountedDeviceInterfaceName, FALSE);

    RtlFreeUnicodeString(&Dcb->MountedDeviceInterfaceName);
    RtlInitUnicodeString(&Dcb->MountedDeviceInterfaceName, NULL);
  }
  if (Dcb->DiskDeviceInterfaceName.Buffer != NULL) {
    IoSetDeviceInterfaceState(&Dcb->DiskDeviceInterfaceName, FALSE);

    RtlFreeUnicodeString(&Dcb->DiskDeviceInterfaceName);
    RtlInitUnicodeString(&Dcb->DiskDeviceInterfaceName, NULL);
  }

  FreeDcbNames(Dcb);

  if (Dcb->DeviceObject->Vpb) {
    Dcb->DeviceObject->Vpb->DeviceObject = NULL;
    Dcb->DeviceObject->Vpb->RealDevice = NULL;
    Dcb->DeviceObject->Vpb->Flags = 0;
  }

  if (vcb != NULL) {
    DDbgPrint("  FCB allocated: %d\n", vcb->FcbAllocated);
    DDbgPrint("  FCB     freed: %d\n", vcb->FcbFreed);
    DDbgPrint("  CCB allocated: %d\n", vcb->CcbAllocated);
    DDbgPrint("  CCB     freed: %d\n", vcb->CcbFreed);

    // delete volDeviceObject
    DDbgPrint("  Delete Volume DeviceObject\n");
    IoDeleteDevice(vcb->DeviceObject);
  }

  // delete diskDeviceObject
  DDbgPrint("  Delete Disk DeviceObject\n");
  IoDeleteDevice(Dcb->DeviceObject);
}
Exemplo n.º 22
0
NTSTATUS
NTAPI
DiskInitFdo(
    IN PDEVICE_OBJECT Fdo
    )

/*++

Routine Description:

    This routine is called to do one-time initialization of new device objects


Arguments:

    Fdo - a pointer to the functional device object for this device

Return Value:

    status

--*/

{
    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;

    PDISK_DATA diskData = (PDISK_DATA) fdoExtension->CommonExtension.DriverData;

    //ULONG srbFlags = 0;

    ULONG timeOut = 0;

    ULONG bytesPerSector;
    //UCHAR sectorShift;

    //BOOLEAN dmActive = FALSE;
    PULONG dmSkew;
    //ULONG dmByteSkew;

    NTSTATUS status;

    PAGED_CODE();

    //
    // Build the lookaside list for srb's for the physical disk. Should only
    // need a couple.  If this fails then we don't have an emergency SRB so
    // fail the call to initialize.
    //

    ClassInitializeSrbLookasideList((PCOMMON_DEVICE_EXTENSION) fdoExtension,
                                    PARTITION0_LIST_SIZE);

    //
    // Because all requests share a common sense buffer, it is possible
    // for the buffer to be overwritten if the port driver completes
    // multiple failed requests that require a request sense before the
    // class driver's completion routine can consume the data in the buffer.
    // To prevent this, we allow the port driver to allocate a unique sense
    // buffer each time it needs one.  We are responsible for freeing this
    // buffer.  This also allows the adapter to be configured to support
    // additional sense data beyond the minimum 18 bytes.
    //

    fdoExtension->SrbFlags = SRB_FLAGS_PORT_DRIVER_ALLOCSENSE;

    //
    // Initialize the srb flags.
    //

    if (fdoExtension->DeviceDescriptor->CommandQueueing &&
        fdoExtension->AdapterDescriptor->CommandQueueing) {

        fdoExtension->SrbFlags = SRB_FLAGS_QUEUE_ACTION_ENABLE;

    }

    if (!TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
        SET_FLAG(fdoExtension->DeviceFlags, DEV_SAFE_START_UNIT);
    }

    //
    // Look for controllers that require special flags.
    //

    ClassScanForSpecial(fdoExtension, DiskBadControllers, DiskSetSpecialHacks);

    //
    // Look into the registry to see if this device
    // requires special attention - [ like a hack ]
    //

    DiskScanRegistryForSpecial(fdoExtension);

    //srbFlags = fdoExtension->SrbFlags;

    //
    // Clear buffer for drive geometry.
    //

    RtlZeroMemory(&(fdoExtension->DiskGeometry),
                  sizeof(DISK_GEOMETRY));

    //
    // Allocate request sense buffer.
    //

    fdoExtension->SenseData = ExAllocatePoolWithTag(NonPagedPoolCacheAligned,
                                                    SENSE_BUFFER_SIZE,
                                                    DISK_TAG_START);

    if (fdoExtension->SenseData == NULL) {

        //
        // The buffer can not be allocated.
        //

        DebugPrint((1, "DiskInitFdo: Can not allocate request sense buffer\n"));

        status = STATUS_INSUFFICIENT_RESOURCES;
        return status;
    }

    //
    // Physical device object will describe the entire
    // device, starting at byte offset 0.
    //

    fdoExtension->CommonExtension.StartingOffset.QuadPart = (LONGLONG)(0);

    //
    // Set timeout value in seconds.
    //

    timeOut = ClassQueryTimeOutRegistryValue(Fdo);
    if (timeOut) {
        fdoExtension->TimeOutValue = timeOut;
    } else {
        fdoExtension->TimeOutValue = SCSI_DISK_TIMEOUT;
    }

    //
    // If this is a removable drive, build an entry in devicemap\scsi
    // indicating it's physicaldriveN name, set up the appropriate
    // update partitions routine and set the flags correctly.
    // note: only do this after the timeout value is set, above.
    //

    if (fdoExtension->DeviceDescriptor->RemovableMedia) {
        ClassUpdateInformationInRegistry( Fdo,
                                          "PhysicalDrive",
                                          fdoExtension->DeviceNumber,
                                          NULL,
                                          0);
        //
        // Enable media change notification for removable disks
        //
        ClassInitializeMediaChangeDetection(fdoExtension,
                                            "Disk");

        SET_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA);
        diskData->UpdatePartitionRoutine = DiskUpdateRemovablePartitions;

    } else {

        SET_FLAG(fdoExtension->SrbFlags, SRB_FLAGS_NO_QUEUE_FREEZE);
        diskData->UpdatePartitionRoutine = DiskUpdatePartitions;

    }

    //
    // Read the drive capacity.  Don't use the disk version of the routine here
    // since we don't know the disk signature yet - the disk version will
    // attempt to determine the BIOS reported geometry.
    //

    status = ClassReadDriveCapacity(Fdo);

    //
    // If the read capcity failed then just return, unless this is a
    // removable disk where a device object partition needs to be created.
    //

    if (!NT_SUCCESS(status) &&
        !(Fdo->Characteristics & FILE_REMOVABLE_MEDIA)) {

        DebugPrint((1,
            "DiskInitFdo: Can't read capacity for device %p\n",
            Fdo));

        if (fdoExtension->DeviceDescriptor->RemovableMedia) {
            fdoExtension->DiskGeometry.MediaType = RemovableMedia;
            Fdo->Flags &= ~DO_VERIFY_VOLUME;
        } else {
            fdoExtension->DiskGeometry.MediaType = FixedMedia;
        }

        status = STATUS_SUCCESS;
    }

    //
    // Set up sector size fields.
    //
    // Stack variables will be used to update
    // the partition device extensions.
    //
    // The device extension field SectorShift is
    // used to calculate sectors in I/O transfers.
    //
    // The DiskGeometry structure is used to service
    // IOCTls used by the format utility.
    //

    bytesPerSector = fdoExtension->DiskGeometry.BytesPerSector;

    //
    // Make sure sector size is not zero.
    //

    if (bytesPerSector == 0) {

        //
        // Default sector size for disk is 512.
        //

        bytesPerSector = fdoExtension->DiskGeometry.BytesPerSector = 512;
    }

    //sectorShift = fdoExtension->SectorShift;

    //
    // Determine is DM Driver is loaded on an IDE drive that is
    // under control of Atapi - this could be either a crashdump or
    // an Atapi device is sharing the controller with an IDE disk.
    //

    HalExamineMBR(fdoExtension->CommonExtension.DeviceObject,
                  fdoExtension->DiskGeometry.BytesPerSector,
                  (ULONG)0x54,
                  (PVOID*)&dmSkew);

    if (dmSkew) {

        //
        // Update the device extension, so that the call to IoReadPartitionTable
        // will get the correct information. Any I/O to this disk will have
        // to be skewed by *dmSkew sectors aka DMByteSkew.
        //

        fdoExtension->DMSkew = *dmSkew;
        fdoExtension->DMActive = TRUE;
        fdoExtension->DMByteSkew = fdoExtension->DMSkew * bytesPerSector;

        //
        // Save away the infomation that we need, since this deviceExtension will soon be
        // blown away.
        //

        //dmActive = TRUE;
        //dmByteSkew = fdoExtension->DMByteSkew;

    }

#if defined(_X86_)
    //
    // Try to read the signature off the disk and determine the correct drive
    // geometry based on that.  This requires rereading the disk size to get
    // the cylinder count updated correctly.
    //

    if(fdoExtension->DeviceDescriptor->RemovableMedia == FALSE) {
        DiskReadSignature(Fdo);
        DiskReadDriveCapacity(Fdo);
    }
#endif

    //
    // Register interfaces for this device
    //
    {
        UNICODE_STRING interfaceName;

        RtlInitUnicodeString(&interfaceName, NULL);

        status = IoRegisterDeviceInterface(fdoExtension->LowerPdo,
                                           (LPGUID) &DiskClassGuid,
                                           NULL,
                                           &interfaceName);

        if(NT_SUCCESS(status)) {

            diskData->DiskInterfaceString = interfaceName;
            status = IoSetDeviceInterfaceState(&interfaceName, TRUE);

        } else {
            interfaceName.Buffer = NULL;
        }

        if(!NT_SUCCESS(status)) {

            DebugPrint((1, "DiskInitFdo: Unable to register or set disk DCA "
                           "for fdo %p [%lx]\n", Fdo, status));

            RtlFreeUnicodeString(&interfaceName);
            RtlInitUnicodeString(&(diskData->DiskInterfaceString), NULL);
        }
    }

    DiskCreateSymbolicLinks(Fdo);

    //
    // Determine the type of disk and enable failure preiction in the hardware
    // and enable failure prediction polling.
    //

    if (InitSafeBootMode == 0)
    {
        DiskDetectFailurePrediction(fdoExtension,
                                  &diskData->FailurePredictionCapability);

        if (diskData->FailurePredictionCapability != FailurePredictionNone)
        {
            //
            // Cool, we've got some sort of failure prediction, enable it
            // at the hardware and then enable polling for it
            //

            //
            // By default we allow performance to be degradeded if failure
            // prediction is enabled.
            //
            // TODO: Make a registry entry ?
            //

            diskData->AllowFPPerfHit = TRUE;

            //
            // Enable polling only after Atapi and SBP2 add support for the new
            // SRB flag that indicates that the request should not reset the
            // drive spin down idle timer.
            //

            status = DiskEnableDisableFailurePredictPolling(fdoExtension,
                                          TRUE,
                                          DISK_DEFAULT_FAILURE_POLLING_PERIOD);

            DebugPrint((3, "DiskInitFdo: Failure Prediction Poll enabled as "
                           "%d for device %p\n",
                     diskData->FailurePredictionCapability,
                     Fdo));
        }
    } else {

        //
        // In safe boot mode we do not enable failure prediction, as perhaps
        // it is the reason why normal boot does not work
        //

        diskData->FailurePredictionCapability = FailurePredictionNone;

    }

    //
    // Initialize the verify mutex
    //

    KeInitializeMutex(&diskData->VerifyMutex, MAX_SECTORS_PER_VERIFY);

    return(STATUS_SUCCESS);

} // end DiskInitFdo()
Exemplo n.º 23
0
NTSTATUS
DokanRegisterDeviceInterface(__in PDRIVER_OBJECT DriverObject,
                             __in PDEVICE_OBJECT DeviceObject,
                             __in PDokanDCB Dcb) {
  PDEVICE_OBJECT pnpDeviceObject = NULL;
  NTSTATUS status;

  status = IoReportDetectedDevice(DriverObject, InterfaceTypeUndefined, 0, 0,
                                  NULL, NULL, FALSE, &pnpDeviceObject);

  if (NT_SUCCESS(status)) {
    DDbgPrint("  IoReportDetectedDevice success\n");
  } else {
    DDbgPrint("  IoReportDetectedDevice failed: 0x%x\n", status);
    return status;
  }

  if (IoAttachDeviceToDeviceStack(pnpDeviceObject, DeviceObject) != NULL) {
    DDbgPrint("  IoAttachDeviceToDeviceStack success\n");
  } else {
    DDbgPrint("  IoAttachDeviceToDeviceStack failed\n");
  }

  status = IoRegisterDeviceInterface(pnpDeviceObject, &GUID_DEVINTERFACE_DISK,
                                     NULL, &Dcb->DiskDeviceInterfaceName);

  if (NT_SUCCESS(status)) {
    DDbgPrint("  IoRegisterDeviceInterface success: %wZ\n",
              &Dcb->DiskDeviceInterfaceName);
  } else {
    RtlInitUnicodeString(&Dcb->DiskDeviceInterfaceName, NULL);
    DDbgPrint("  IoRegisterDeviceInterface failed: 0x%x\n", status);
    return status;
  }

  status = IoSetDeviceInterfaceState(&Dcb->DiskDeviceInterfaceName, TRUE);

  if (NT_SUCCESS(status)) {
    DDbgPrint("  IoSetDeviceInterfaceState success\n");
  } else {
    DDbgPrint("  IoSetDeviceInterfaceState failed: 0x%x\n", status);
    return status;
  }

  status =
      IoRegisterDeviceInterface(pnpDeviceObject, &MOUNTDEV_MOUNTED_DEVICE_GUID,
                                NULL, &Dcb->MountedDeviceInterfaceName);

  if (NT_SUCCESS(status)) {
    DDbgPrint("  IoRegisterDeviceInterface success: %wZ\n",
              &Dcb->MountedDeviceInterfaceName);
  } else {
    DDbgPrint("  IoRegisterDeviceInterface failed: 0x%x\n", status);
    return status;
  }

  status = IoSetDeviceInterfaceState(&Dcb->MountedDeviceInterfaceName, TRUE);

  if (NT_SUCCESS(status)) {
    DDbgPrint("  IoSetDeviceInterfaceState success\n");
  } else {
    RtlInitUnicodeString(&Dcb->MountedDeviceInterfaceName, NULL);
    DDbgPrint("  IoSetDeviceInterfaceState failed: 0x%x\n", status);
    return status;
  }

  return status;
}
int FloppyStartDevice(int DeviceObject , int Irp ) 
{ int DeviceObject__DeviceExtension = __VERIFIER_nondet_int() ;
  int Irp__Tail__Overlay__CurrentStackLocation = __VERIFIER_nondet_int() ;
  int Irp__IoStatus__Status ;
  int disketteExtension__TargetObject = __VERIFIER_nondet_int() ;
  int disketteExtension__MaxTransferSize ;
  int disketteExtension__DriveType = __VERIFIER_nondet_int() ;
  int disketteExtension__PerpendicularMode ;
  int disketteExtension__DeviceUnit ;
  int disketteExtension__DriveOnValue ;
  int disketteExtension__UnderlyingPDO = __VERIFIER_nondet_int() ;
  int disketteExtension__InterfaceString = __VERIFIER_nondet_int() ;
  int disketteExtension__IsStarted ;
  int disketteExtension__HoldNewRequests ;
  int ntStatus ;
  int pnpStatus ;
  int doneEvent = __VERIFIER_nondet_int() ;
  int fdcInfo = __VERIFIER_nondet_int() ;
  int fdcInfo__BufferCount ;
  int fdcInfo__BufferSize ;
  int fdcInfo__MaxTransferSize = __VERIFIER_nondet_int() ;
  int fdcInfo__AcpiBios = __VERIFIER_nondet_int() ;
  int fdcInfo__AcpiFdiSupported = __VERIFIER_nondet_int() ;
  int fdcInfo__PeripheralNumber = __VERIFIER_nondet_int() ;
  int fdcInfo__BusType ;
  int fdcInfo__ControllerNumber = __VERIFIER_nondet_int() ;
  int fdcInfo__UnitNumber = __VERIFIER_nondet_int() ;
  int fdcInfo__BusNumber = __VERIFIER_nondet_int() ;
  int Dc ;
  int Fp ;
  int disketteExtension ;
  int irpSp ;
  int irpSp___0 ;
  int nextIrpSp ;
  int nextIrpSp__Control ;
  int irpSp___1 ;
  int irpSp__Control ;
  int irpSp__Context ;
  int InterfaceType ;
  int KUSER_SHARED_DATA__AlternativeArchitecture_NEC98x86 = __VERIFIER_nondet_int() ;
  long __cil_tmp42 ;
  int __cil_tmp43 ;
  int __cil_tmp44 ;
  int __cil_tmp45 ;
  int __cil_tmp46 ;
  int __cil_tmp47 ;
  int __cil_tmp48 ;
  int __cil_tmp49 ;

  {
  Dc = DiskController;
  Fp = FloppyDiskPeripheral;
  disketteExtension = DeviceObject__DeviceExtension;
  irpSp = Irp__Tail__Overlay__CurrentStackLocation;
  irpSp___0 = Irp__Tail__Overlay__CurrentStackLocation;
  nextIrpSp = Irp__Tail__Overlay__CurrentStackLocation - 1;
  nextIrpSp__Control = 0;
  if (s != NP) {
    {
    errorFn();
    }
  } else {
    if (compRegistered != 0) {
      {
      errorFn();
      }
    } else {
      compRegistered = 1;
    }
  }
  {
  irpSp___1 = Irp__Tail__Overlay__CurrentStackLocation - 1;
  irpSp__Context = doneEvent;
  irpSp__Control = 224;
  ntStatus = IofCallDriver(disketteExtension__TargetObject, Irp);
  }
  {
  __cil_tmp42 = (long )ntStatus;
  if (__cil_tmp42 == 259L) {
    {
    ntStatus = KeWaitForSingleObject(doneEvent, Executive, KernelMode, 0, 0);
    ntStatus = myStatus;
    }
  }
  }
  {
  fdcInfo__BufferCount = 0;
  fdcInfo__BufferSize = 0;
  __cil_tmp43 = 3080;
  __cil_tmp44 = 458752;
  __cil_tmp45 = 461832;
  __cil_tmp46 = 461835;
  ntStatus = FlFdcDeviceIo(disketteExtension__TargetObject, __cil_tmp46, fdcInfo);
  }
  if (ntStatus >= 0) {
    disketteExtension__MaxTransferSize = fdcInfo__MaxTransferSize;
    if (fdcInfo__AcpiBios) {
      if (fdcInfo__AcpiFdiSupported) {
        {
        ntStatus = FlAcpiConfigureFloppy(disketteExtension, fdcInfo);
        }
        if (disketteExtension__DriveType == 4) {
          //__cil_tmp47 = uninf1();
          //disketteExtension__PerpendicularMode |= __cil_tmp47;
        }
      } else {
        goto _L;
      }
    } else {
      _L: 
      if (disketteExtension__DriveType == 4) {
        //__cil_tmp48 = uninf1();
        //disketteExtension__PerpendicularMode |= __cil_tmp48;
      }
      InterfaceType = 0;
      {
      while (1) {
        while_0_continue: /* CIL Label */ ;

        if (InterfaceType >= MaximumInterfaceType) {
          goto while_1_break;
        }
        {
        fdcInfo__BusType = InterfaceType;
        ntStatus = IoQueryDeviceDescription(fdcInfo__BusType, fdcInfo__BusNumber,
                                            Dc, fdcInfo__ControllerNumber, Fp, fdcInfo__PeripheralNumber,
                                            FlConfigCallBack, disketteExtension);
        }
        if (ntStatus >= 0) {
          goto while_1_break;
        }
        InterfaceType ++;
      }
      while_0_break: /* CIL Label */ ;
      }
      while_1_break: ;
    }
    if (ntStatus >= 0) {
      if (KUSER_SHARED_DATA__AlternativeArchitecture_NEC98x86 != 0) {
        disketteExtension__DeviceUnit = fdcInfo__UnitNumber;
        //disketteExtension__DriveOnValue = fdcInfo__UnitNumber;
      } else {
        disketteExtension__DeviceUnit = fdcInfo__PeripheralNumber;
        //__cil_tmp49 = 16 << fdcInfo__PeripheralNumber;
        //disketteExtension__DriveOnValue = fdcInfo__PeripheralNumber | __cil_tmp49;
      }
      {
      pnpStatus = IoRegisterDeviceInterface(disketteExtension__UnderlyingPDO, MOUNTDEV_MOUNTED_DEVICE_GUID,
                                            0, disketteExtension__InterfaceString);
      }
      if (pnpStatus >= 0) {
        {
        pnpStatus = IoSetDeviceInterfaceState(disketteExtension__InterfaceString,
                                              1);
        }
      }
      disketteExtension__IsStarted = 1;
      disketteExtension__HoldNewRequests = 0;
    }
  }
  {
  Irp__IoStatus__Status = ntStatus;
  myStatus = ntStatus;
  IofCompleteRequest(Irp, 0);
  }
  return (ntStatus);
}
}
Exemplo n.º 25
0
Arquivo: pnp.c Projeto: kcrazy/winekit
NTSTATUS
Serenum_AddDevice(IN PDRIVER_OBJECT DriverObject,
                  IN PDEVICE_OBJECT BusPhysicalDeviceObject)
/*++
Routine Description.
    A bus has been found.  Attach our FDO to it.
    Allocate any required resources.  Set things up.  And be prepared for the
    first ``start device.''

Arguments:
    BusPhysicalDeviceObject - Device object representing the bus.  That to which
        we attach a new FDO.

    DriverObject - This very self referenced driver.

--*/
{
    NTSTATUS status;
    PDEVICE_OBJECT deviceObject;
    PFDO_DEVICE_DATA pDeviceData;
    HANDLE keyHandle;
    ULONG actualLength;

    PAGED_CODE();

    Serenum_KdPrint_Def(SER_DBG_PNP_TRACE, ("Add Device: 0x%x\n",
                                            BusPhysicalDeviceObject));
    //
    // Create our FDO
    //

    status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_DATA), NULL,
                            FILE_DEVICE_BUS_EXTENDER, 0, TRUE, &deviceObject);

    if (NT_SUCCESS(status)) {
        pDeviceData = (PFDO_DEVICE_DATA)deviceObject->DeviceExtension;
        RtlFillMemory (pDeviceData, sizeof (FDO_DEVICE_DATA), 0);

        pDeviceData->IsFDO = TRUE;
        pDeviceData->DebugLevel = SER_DEFAULT_DEBUG_OUTPUT_LEVEL;
        pDeviceData->Self = deviceObject;
        pDeviceData->AttachedPDO = NULL;
        pDeviceData->NumPDOs = 0;
        pDeviceData->DeviceState = PowerDeviceD0;
        pDeviceData->SystemState = PowerSystemWorking;
        pDeviceData->PDOForcedRemove = FALSE;

        pDeviceData->SystemWake=PowerSystemUnspecified;
        pDeviceData->DeviceWake=PowerDeviceUnspecified;

        pDeviceData->Removed = FALSE;

        //
        // Set the PDO for use with PlugPlay functions
        //

        pDeviceData->UnderlyingPDO = BusPhysicalDeviceObject;


        //
        // Attach our filter driver to the device stack.
        // the return value of IoAttachDeviceToDeviceStack is the top of the
        // attachment chain.  This is where all the IRPs should be routed.
        //
        // Our filter will send IRPs to the top of the stack and use the PDO
        // for all PlugPlay functions.
        //

        pDeviceData->TopOfStack
            = IoAttachDeviceToDeviceStack(deviceObject, BusPhysicalDeviceObject);

        if (!pDeviceData->TopOfStack) {
            Serenum_KdPrint(pDeviceData, SER_DBG_PNP_ERROR,
                            ("AddDevice: IoAttach failed (%x)", status));
            IoDeleteDevice(deviceObject);
            return STATUS_UNSUCCESSFUL;
        }

        //
        // Set the type of IO we do
        //

        if (pDeviceData->TopOfStack->Flags & DO_BUFFERED_IO) {
            deviceObject->Flags |= DO_BUFFERED_IO;
        } else if (pDeviceData->TopOfStack->Flags & DO_DIRECT_IO) {
            deviceObject->Flags |= DO_DIRECT_IO;
        }

        //
        // Bias outstanding request to 1 so that we can look for a
        // transition to zero when processing the remove device PlugPlay IRP.
        //

        pDeviceData->OutstandingIO = 1;

        KeInitializeEvent(&pDeviceData->RemoveEvent, SynchronizationEvent,
                          FALSE);
        KeInitializeSemaphore(&pDeviceData->CreateSemaphore, 1, 1);
        KeInitializeSpinLock(&pDeviceData->EnumerationLock);



        //
        // Tell the PlugPlay system that this device will need an interface
        // device class shingle.
        //
        // It may be that the driver cannot hang the shingle until it starts
        // the device itself, so that it can query some of its properties.
        // (Aka the shingles guid (or ref string) is based on the properties
        // of the device.)
        //

        status = IoRegisterDeviceInterface(BusPhysicalDeviceObject,
                                           (LPGUID)&GUID_SERENUM_BUS_ENUMERATOR,
                                           NULL,
                                           &pDeviceData->DevClassAssocName);

        if (!NT_SUCCESS(status)) {
            Serenum_KdPrint(pDeviceData, SER_DBG_PNP_ERROR,
                            ("AddDevice: IoRegisterDCA failed (%x)", status));
            IoDetachDevice(pDeviceData->TopOfStack);
            IoDeleteDevice(deviceObject);
            return status;
        }

        //
        // If for any reason you need to save values in a safe location that
        // clients of this DeviceClassAssociate might be interested in reading
        // here is the time to do so, with the function
        // IoOpenDeviceClassRegistryKey
        // the symbolic link name used is was returned in
        // pDeviceData->DevClassAssocName (the same name which is returned by
        // IoGetDeviceClassAssociations and the SetupAPI equivs.
        //

#if DBG
        {
            PWCHAR deviceName = NULL;
            ULONG nameLength = 0;

            status = IoGetDeviceProperty(BusPhysicalDeviceObject,
                                         DevicePropertyPhysicalDeviceObjectName, 0,
                                         NULL, &nameLength);

            if ((nameLength != 0) && (status == STATUS_BUFFER_TOO_SMALL)) {
                deviceName = ExAllocatePool(NonPagedPool, nameLength);

                if (NULL == deviceName) {
                    goto someDebugStuffExit;
                }

                IoGetDeviceProperty(BusPhysicalDeviceObject,
                                    DevicePropertyPhysicalDeviceObjectName,
                                    nameLength, deviceName, &nameLength);

                Serenum_KdPrint(pDeviceData, SER_DBG_PNP_TRACE,
                                ("AddDevice: %x to %x->%x (%ws) \n", deviceObject,
                                 pDeviceData->TopOfStack, BusPhysicalDeviceObject,
                                 deviceName));
            }

someDebugStuffExit:
            ;
            if (deviceName != NULL) {
                ExFreePool(deviceName);
            }
        }
#endif // DBG

        //
        // Turn on the shingle and point it to the given device object.
        //
        status = IoSetDeviceInterfaceState(&pDeviceData->DevClassAssocName,
                                           TRUE);

        if (!NT_SUCCESS(status)) {
            Serenum_KdPrint(pDeviceData, SER_DBG_PNP_ERROR,
                            ("AddDevice: IoSetDeviceClass failed (%x)", status));
            return status;
        }

        //
        // Open the registry and read in our settings
        //

        status = IoOpenDeviceRegistryKey(pDeviceData->UnderlyingPDO,
                                         PLUGPLAY_REGKEY_DEVICE,
                                         STANDARD_RIGHTS_READ, &keyHandle);

        if (status == STATUS_SUCCESS) {
            status
                = Serenum_GetRegistryKeyValue(keyHandle, L"SkipEnumerations",
                                              sizeof(L"SkipEnumerations"),
                                              &pDeviceData->SkipEnumerations,
                                              sizeof(pDeviceData->SkipEnumerations),
                                              &actualLength);

            if ((status != STATUS_SUCCESS)
                    || (actualLength != sizeof(pDeviceData->SkipEnumerations))) {
                pDeviceData->SkipEnumerations = 0;
                status = STATUS_SUCCESS;

            }

            ZwClose(keyHandle);
        }
    }

    if (NT_SUCCESS(status)) {
        deviceObject->Flags |= DO_POWER_PAGABLE;
        deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    }

    return status;
}