-KsCreateBusEnumObject(
- IN PWCHAR BusIdentifier,
- IN PDEVICE_OBJECT BusDeviceObject,
- IN PDEVICE_OBJECT PhysicalDeviceObject,
- IN PDEVICE_OBJECT PnpDeviceObject OPTIONAL,
- IN REFGUID InterfaceGuid OPTIONAL,
- IN PWCHAR ServiceRelativePath OPTIONAL)
-{
- ULONG Length;
- NTSTATUS Status = STATUS_SUCCESS;
- UNICODE_STRING ServiceKeyPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\");
- PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
- PDEVICE_EXTENSION DeviceExtension;
-
- /* calculate sizeof bus enum device extension */
- Length = wcslen(BusIdentifier) * sizeof(WCHAR);
- Length += sizeof(BUS_ENUM_DEVICE_EXTENSION);
-
- BusDeviceExtension = AllocateItem(NonPagedPool, Length);
- if (!BusDeviceExtension)
- {
- /* not enough memory */
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* zero device extension */
- RtlZeroMemory(BusDeviceExtension, sizeof(BUS_ENUM_DEVICE_EXTENSION));
-
- /* initialize bus device extension */
- wcscpy(BusDeviceExtension->BusIdentifier, BusIdentifier);
-
- /* allocate service path string */
- Length = ServiceKeyPath.MaximumLength;
- Length += BusDeviceObject->DriverObject->DriverExtension->ServiceKeyName.MaximumLength;
-
- if (ServiceRelativePath)
- {
- /* relative path for devices */
- Length += wcslen(ServiceRelativePath) + 2 * sizeof(WCHAR);
- }
-
- BusDeviceExtension->ServicePath.Length = 0;
- BusDeviceExtension->ServicePath.MaximumLength = Length;
- BusDeviceExtension->ServicePath.Buffer = AllocateItem(NonPagedPool, Length);
-
- if (!BusDeviceExtension->ServicePath.Buffer)
- {
- /* not enough memory */
- FreeItem(BusDeviceExtension);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- RtlAppendUnicodeStringToString(&BusDeviceExtension->ServicePath, &ServiceKeyPath);
- RtlAppendUnicodeStringToString(&BusDeviceExtension->ServicePath, &BusDeviceObject->DriverObject->DriverExtension->ServiceKeyName);
-
- if (ServiceRelativePath)
- {
- RtlAppendUnicodeToString(&BusDeviceExtension->ServicePath, L"\\");
- RtlAppendUnicodeToString(&BusDeviceExtension->ServicePath, ServiceRelativePath);
- }
-
- if (InterfaceGuid)
- {
- /* register an device interface */
- Status = IoRegisterDeviceInterface(PhysicalDeviceObject, InterfaceGuid, NULL, &BusDeviceExtension->SymbolicLinkName);
-
- /* check for success */
- if (!NT_SUCCESS(Status))
- {
- FreeItem(BusDeviceExtension->ServicePath.Buffer);
- FreeItem(BusDeviceExtension);
- return Status;
- }
-
- /* now enable device interface */
- Status = IoSetDeviceInterfaceState(&BusDeviceExtension->SymbolicLinkName, TRUE);
-
- if (!NT_SUCCESS(Status))
- {
- FreeItem(BusDeviceExtension->ServicePath.Buffer);
- FreeItem(BusDeviceExtension);
- return Status;
- }
-
- /* set state enabled */
- BusDeviceExtension->Enabled = TRUE;
- }
-
- /* store device objects */
- BusDeviceExtension->BusDeviceObject = BusDeviceObject;
- BusDeviceExtension->PnpDeviceObject = PnpDeviceObject;
- BusDeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
-
- if (!PnpDeviceObject)
- {
- BusDeviceExtension->PnpDeviceObject = IoAttachDeviceToDeviceStack(BusDeviceObject, PhysicalDeviceObject);
-
- if (!BusDeviceExtension->PnpDeviceObject)
- {
- /* failed to attach device */
- if (BusDeviceExtension->Enabled)
- {
- IoSetDeviceInterfaceState(&BusDeviceExtension->SymbolicLinkName, FALSE);
- RtlFreeUnicodeString(&BusDeviceExtension->SymbolicLinkName);
- }
-
- /* free device extension */
- FreeItem(BusDeviceExtension->ServicePath.Buffer);
- FreeItem(BusDeviceExtension);
-
- return STATUS_DEVICE_REMOVED;
- }
- }
-
- /* attach device extension */
- DeviceExtension = (PDEVICE_EXTENSION)BusDeviceObject->DeviceExtension;
- DeviceExtension->DeviceHeader = (PKSIDEVICE_HEADER)BusDeviceExtension;
-
- /* FIXME scan bus and invalidate device relations */
- return Status;
-}
-
- NTSTATUS
-NTAPI