Поделиться через


IOCTL_MOUNTMGR_CREATE_POINT IOCTL (mountmgr.h)

Клиенты диспетчера подключений могут использовать этот IOCTL для запроса диспетчера подключения создать постоянное символьное имя ссылки для указанного тома.

Основной код

IRP_MJ_DEVICE_CONTROL

Входной буфер

Диспетчер точек подключения помещает структуру MOUNTMGR_CREATE_POINT_INPUT в начало буфера в Irp-AssociatedIrp.SystemBuffer>. Диспетчер подключения вставляет только что назначенное имя постоянной символьной ссылки по адресу, указанному членом SymbolicLinkNameOffset этой структуры, и вставляет неперсистентное имя устройства по адресу, указанному элементом DeviceNameOffset этой структуры.

Длина входного буфера

Parameters.DeviceIoControl.InputBufferLength в расположении стека ввода-вывода IRP указывает размер входного буфера в байтах, который должен быть больше или равен sizeof(MOUNTMGR_CREATE_POINT_INPUT).

Выходной буфер

Нет.

Длина выходного буфера

Нет.

Буфер входных и выходных данных

Н/Д

Длина входного/выходного буфера

Н/Д

Блок состояния

Если операция выполнена успешно, в поле Состояние устанавливается значение STATUS_SUCCESS.

Если значение InputBufferLength меньше sizeof(MOUNTMGR_CREATE_POINT_INPUT), для поля Состояние устанавливается значение STATUS_INVALID_PARAMETER.

Комментарии

Входные данные для этого запроса — это имя постоянной символьной ссылки, которое необходимо создать, и имя, которое уже является допустимым для идентификации тома. Имя, заданное для идентификации тома, может иметь любой тип: уникальное имя тома, имя символьной ссылки или имя неперсистентного устройства. Если новое постоянное имя еще не используется, вызов будет выполнен успешно и база данных диспетчера подключений будет изменена, чтобы отразить, что новое постоянное имя принадлежит тому. Если база данных диспетчера подключений уже содержит новое постоянное имя, но том, которому принадлежит это имя, не находится в системе, этот вызов перезапишет владение заданным постоянным именем.

Диспетчер подключения позволяет создать новое имя постоянной символьной ссылки, даже если оно еще не было уведомлено о заданном томе в уведомлении MOUNTDEV_MOUNTED_DEVICE_GUID интерфейсе устройства. В этом случае диспетчер подключения просто создает символьную ссылку и обновляет базу данных диспетчера подключений.

Диспетчер подключения применяет политику не более одной постоянной буквы диска на том. Если запрос IOCTL_MOUNTMGR_CREATE_POINT отправляется с буквой диска, запрос завершится ошибкой, если тому уже назначена буква диска, если диспетчер подключения еще не получил уведомление о томе с помощью уведомления MOUNTDEV_MOUNTED_DEVICE_GUID интерфейса устройства. В последнем случае вызов выполняется успешно, и диспетчер подключения очищает базу данных диспетчера подключений от всех других букв дисков, ранее назначенных тому.

Если IOCTL_MOUNTMGR_CREATE_POINT указывает букву диска, буква диска должна быть прописной.

Обратите внимание, что клиент может определить, получил ли диспетчер подключений уведомление MOUNTDEV_MOUNTED_DEVICE_GUID интерфейса устройства для его тома, запросив диспетчер подключений с IOCTL_MOUNTMGR_QUERY_POINTS.

В этом примере псевдокода клиент диспетчера подключений использует IOCTL_MOUNTMGR_CREATE_POINT для отправки диспетчеру подключения имени объекта устройства и соответствующей символьной ссылки:

    // The persistent symbolic link is a drive letter in
    // this case:
    wsprintf(dosBuffer, L"\\DosDevices\\%C:", DriveLetter);
    RtlInitUnicodeString(&dosName, dosBuffer);
    // The nonpersistent volume (device) object name is
    // formed using the volume number as a suffix
    wsprintf(ntBuffer, L"\\Device\\HarddiskVolume%D", 
                       Extension->VolumeNumber);
    RtlInitUnicodeString(&ntName, ntBuffer);
    createPointSize = sizeof(MOUNTMGR_CREATE_POINT_INPUT) +
                      dosName.Length + ntName.Length;
    // Allocate a header with length and offset information
    createPoint = (PMOUNTMGR_CREATE_POINT_INPUT)
                  ExAllocatePool(PagedPool, 
                  createPointSize);
    createPoint->SymbolicLinkNameOffset = 
                  sizeof(MOUNTMGR_CREATE_POINT_INPUT);
    createPoint->SymbolicLinkNameLength = dosName.Length;
    createPoint->DeviceNameOffset = 
        createPoint -> SymbolicLinkNameOffset +
        createPoint -> SymbolicLinkNameLength;
    createPoint->DeviceNameLength = ntName.Length;
    RtlCopyMemory((PCHAR) createPoint + 
                  createPoint -> SymbolicLinkNameOffset,
                  dosName.Buffer, dosName.Length);
    RtlCopyMemory((PCHAR) createPoint + 
                  createPoint->DeviceNameOffset,
                  ntName.Buffer, ntName.Length);
    // Use the name of the mount manager device object
    // defined in mountmgr.h (MOUNTMGR_DEVICE_NAME) to
    // obtain a pointer to the mount manager.
    RtlInitUnicodeString(&name, MOUNTMGR_DEVICE_NAME);
    status = IoGetDeviceObjectPointer(&name,
                              FILE_READ_ATTRIBUTES, 
                              &fileObject, &deviceObject);
    KeInitializeEvent(&event, NotificationEvent, FALSE);
    irp = IoBuildDeviceIoControlRequest(
            IOCTL_MOUNTMGR_CREATE_POINT,
            deviceObject, createPoint, createPointSize, 
            NULL, 0, FALSE, &event, &ioStatus);
    // Send the irp to the mount manager requesting
    // that a new mount point (persistent symbolic link)
    // be created for the indicated volume.
    status = IoCallDriver(deviceObject, irp);

Дополнительные сведения см. в статье Поддержка запросов диспетчера подключений в драйвере класса хранения.

Требования

Требование Значение
Заголовок mountmgr.h (включая Mountmgr.h)

См. также раздел

MOUNTMGR_CREATE_POINT_INPUT