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; }
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); }
// 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; }
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); } }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); } }
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); } }
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); } }
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; }
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
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
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); }
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()
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); } }
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; }