Beispiel #1
0
NTSTATUS
mvolQueryMountPoint(PVOLUME_EXTENSION pvext)
{
	ULONG mplen = pvext->PhysicalDeviceNameLength + sizeof(MOUNTMGR_MOUNT_POINT);
	ULONG mpslen = 4096 * 2;

	PCHAR inbuf = kmalloc(mplen, 0, '56DW');
	PCHAR otbuf = kmalloc(mpslen, 0, '56DW');
	if (!inbuf || !otbuf) {
		return STATUS_MEMORY_NOT_ALLOCATED;
	}

	PMOUNTMGR_MOUNT_POINT	pmp = (PMOUNTMGR_MOUNT_POINT)inbuf;
	PMOUNTMGR_MOUNT_POINTS	pmps = (PMOUNTMGR_MOUNT_POINTS)otbuf;
	
	pmp->DeviceNameLength = pvext->PhysicalDeviceNameLength;
	pmp->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
	RtlCopyMemory(inbuf + pmp->DeviceNameOffset,
		pvext->PhysicalDeviceName,
		pvext->PhysicalDeviceNameLength);
	
	NTSTATUS status = QueryMountPoint(pmp, mplen, pmps, &mpslen);
	if (!NT_SUCCESS(status)) {
		goto cleanup;
	}

	for (int i = 0; i < pmps->NumberOfMountPoints; i++) {

		PMOUNTMGR_MOUNT_POINT p = pmps->MountPoints + i;
		PUNICODE_STRING link = NULL;
		UNICODE_STRING name = {
			.Length = p->SymbolicLinkNameLength,
			.MaximumLength = p->SymbolicLinkNameLength,
			.Buffer = (PWCH)(otbuf + p->SymbolicLinkNameOffset) };
		
		if (MOUNTMGR_IS_DRIVE_LETTER(&name)) {
			name.Length = strlen(" :") * sizeof(WCHAR);
			name.Buffer += strlen("\\DosDevices\\");
			pvext->VolIndex = name.Buffer[0] - 'C';
			link = &pvext->MountPoint;
			FreeUnicodeString(link);
		}
		else if (MOUNTMGR_IS_VOLUME_NAME(&name)) {
			link = &pvext->VolumeGuid;
		}

		link && ucsdup(link, name.Buffer, name.Length);
	}

cleanup:
	kfree(inbuf);
	kfree(otbuf);
	
	return status;
}

#ifdef _WIN32_GetDiskPerf
NTSTATUS
mvolGetDiskPerf(PDEVICE_OBJECT TargetDeviceObject, PDISK_PERFORMANCE pDiskPerf)
{
	NTSTATUS					status;
	KEVENT						event;
	IO_STATUS_BLOCK				ioStatus;
	PIRP						newIrp;

	KeInitializeEvent(&event, NotificationEvent, FALSE);
	newIrp = IoBuildDeviceIoControlRequest(IOCTL_DISK_PERFORMANCE,
											TargetDeviceObject, NULL, 0,
											pDiskPerf, sizeof(DISK_PERFORMANCE),
											FALSE, &event, &ioStatus);
	if (!newIrp)
	{
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	status = IoCallDriver(TargetDeviceObject, newIrp);
	if (status == STATUS_PENDING)
	{
		KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, (PLARGE_INTEGER) NULL);
		status = ioStatus.Status;
	}
	return status;
}
Beispiel #2
0
/*
 * @implemented
 */
NTSTATUS
MountMgrCreatePointWorker(IN PDEVICE_EXTENSION DeviceExtension,
                          IN PUNICODE_STRING SymbolicLinkName,
                          IN PUNICODE_STRING DeviceName)
{
    NTSTATUS Status;
    PLIST_ENTRY DeviceEntry;
    PMOUNTDEV_UNIQUE_ID UniqueId;
    PSYMLINK_INFORMATION SymlinkInformation;
    UNICODE_STRING SymLink, TargetDeviceName;
    PDEVICE_INFORMATION DeviceInformation = NULL, DeviceInfo;

    /* Get device name */
    Status = QueryDeviceInformation(SymbolicLinkName,
                                    &TargetDeviceName,
                                    NULL, NULL, NULL,
                                    NULL, NULL, NULL);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* First of all, try to find device */
    for (DeviceEntry = DeviceExtension->DeviceListHead.Flink;
         DeviceEntry != &(DeviceExtension->DeviceListHead);
         DeviceEntry = DeviceEntry->Flink)
    {
        DeviceInformation = CONTAINING_RECORD(DeviceEntry, DEVICE_INFORMATION, DeviceListEntry);

        if (RtlCompareUnicodeString(&TargetDeviceName, &(DeviceInformation->DeviceName), TRUE) == 0)
        {
            break;
        }
    }

    /* Copy symbolic link name and null terminate it */
    SymLink.Buffer = AllocatePool(SymbolicLinkName->Length + sizeof(UNICODE_NULL));
    if (!SymLink.Buffer)
    {
        FreePool(TargetDeviceName.Buffer);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlCopyMemory(SymLink.Buffer, SymbolicLinkName->Buffer, SymbolicLinkName->Length);
    SymLink.Buffer[SymbolicLinkName->Length / sizeof(WCHAR)] = UNICODE_NULL;
    SymLink.Length = SymbolicLinkName->Length;
    SymLink.MaximumLength = SymbolicLinkName->Length + sizeof(UNICODE_NULL);

    /* If we didn't find device */
    if (DeviceEntry == &(DeviceExtension->DeviceListHead))
    {
        /* Then, try with unique ID */
        Status = QueryDeviceInformation(SymbolicLinkName,
                                        NULL, &UniqueId,
                                        NULL, NULL, NULL,
                                        NULL, NULL);
        if (!NT_SUCCESS(Status))
        {
            FreePool(TargetDeviceName.Buffer);
            FreePool(SymLink.Buffer);
            return Status;
        }

        /* Create a link to the device */
        Status = GlobalCreateSymbolicLink(&SymLink, &TargetDeviceName);
        if (!NT_SUCCESS(Status))
        {
            FreePool(UniqueId);
            FreePool(TargetDeviceName.Buffer);
            FreePool(SymLink.Buffer);
            return Status;
        }

        /* If caller provided driver letter, delete it */
        if (IsDriveLetter(&SymLink))
        {
            DeleteRegistryDriveLetter(UniqueId);
        }

        /* Device will be identified with its unique ID */
        Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
                                       DatabasePath,
                                       SymLink.Buffer,
                                       REG_BINARY,
                                       UniqueId->UniqueId,
                                       UniqueId->UniqueIdLength);

        FreePool(UniqueId);
        FreePool(TargetDeviceName.Buffer);
        FreePool(SymLink.Buffer);
        return Status;
    }

    /* If call provided a driver letter whereas device already has one
     * fail, this is not doable
     */
    if (IsDriveLetter(&SymLink) && HasDriveLetter(DeviceInformation))
    {
        FreePool(TargetDeviceName.Buffer);
        FreePool(SymLink.Buffer);
        return STATUS_INVALID_PARAMETER;
    }

    /* Now, create a link */
    Status = GlobalCreateSymbolicLink(&SymLink, &TargetDeviceName);
    FreePool(TargetDeviceName.Buffer);
    if (!NT_SUCCESS(Status))
    {
        FreePool(SymLink.Buffer);
        return Status;
    }

    /* Associate Unique ID <-> symbolic name */
    UniqueId = DeviceInformation->UniqueId;
    Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
                                   DatabasePath,
                                   SymLink.Buffer,
                                   REG_BINARY,
                                   UniqueId->UniqueId,
                                   UniqueId->UniqueIdLength);
    if (!NT_SUCCESS(Status))
    {
        GlobalDeleteSymbolicLink(&SymLink);
        FreePool(SymLink.Buffer);
        return Status;
    }

    /* Now, prepare to save the link with the device */
    SymlinkInformation = AllocatePool(sizeof(SYMLINK_INFORMATION));
    if (!SymlinkInformation)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        GlobalDeleteSymbolicLink(&SymLink);
        FreePool(SymLink.Buffer);
        return Status;
    }

    SymlinkInformation->Name.Length = SymLink.Length;
    SymlinkInformation->Name.MaximumLength = SymLink.Length + sizeof(UNICODE_NULL);
    SymlinkInformation->Name.Buffer = AllocatePool(SymlinkInformation->Name.MaximumLength);
    if (!SymlinkInformation->Name.Buffer)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        FreePool(SymlinkInformation);
        GlobalDeleteSymbolicLink(&SymLink);
        FreePool(SymLink.Buffer);
        return Status;
    }

    /* Save the link and mark it online */
    RtlCopyMemory(SymlinkInformation->Name.Buffer, SymLink.Buffer, SymlinkInformation->Name.Length);
    SymlinkInformation->Name.Buffer[SymlinkInformation->Name.Length / sizeof(WCHAR)] = UNICODE_NULL;
    SymlinkInformation->Online = TRUE;
    InsertTailList(&DeviceInformation->SymbolicLinksListHead, &SymlinkInformation->SymbolicLinksListEntry);
    SendLinkCreated(&(SymlinkInformation->Name));

    /* If we have a drive letter */
    if (IsDriveLetter(&SymLink))
    {
        /* Then, delete the no drive letter entry */
        DeleteNoDriveLetterEntry(UniqueId);

        /* And post online notification if asked */
        if (!DeviceInformation->SkipNotifications)
        {
            PostOnlineNotification(DeviceExtension, &DeviceInformation->SymbolicName);
        }
    }

    /* If that's a volume with automatic drive letter, it's now time to resync databases */
    if (MOUNTMGR_IS_VOLUME_NAME(&SymLink) && DeviceExtension->AutomaticDriveLetter)
    {
        for (DeviceEntry = DeviceExtension->DeviceListHead.Flink;
             DeviceEntry != &(DeviceExtension->DeviceListHead);
             DeviceEntry = DeviceEntry->Flink)
        {
            DeviceInfo = CONTAINING_RECORD(DeviceEntry, DEVICE_INFORMATION, DeviceListEntry);

            /* If there's one, ofc! */
            if (!DeviceInfo->NoDatabase)
            {
                ReconcileThisDatabaseWithMaster(DeviceExtension, DeviceInfo);
            }
        }
    }

    /* Notify & quit */
    FreePool(SymLink.Buffer);
    MountMgrNotify(DeviceExtension);

    if (!DeviceInformation->Volume)
    {
        MountMgrNotifyNameChange(DeviceExtension, DeviceName, FALSE);
    }

    return Status;
}