IOCTL_MOUNTMGR_CREATE_POINT IOCTL (mountmgr.h)
装载管理器客户端可以使用此 IOCTL 请求装载管理器为指示的卷创建永久性符号链接名称。
主要代码
输入缓冲区
装载点管理器将MOUNTMGR_CREATE_POINT_INPUT结构放置在 Irp-AssociatedIrp.SystemBuffer> 的缓冲区的开头。 装载管理器在此结构的 SymbolicLinkNameOffset 成员指向的地址处插入新分配的永久性符号链接名称,并将非永久性设备名称插入到此结构的 DeviceNameOffset 成员指向的地址。
输入缓冲区长度
IRP 的 I/O 堆栈位置中的 Parameters.DeviceIoControl.InputBufferLength 指示输入缓冲区的大小(以字节为单位),该大小必须大于或等于 sizeof(MOUNTMGR_CREATE_POINT_INPUT)
。
输出缓冲区
无。
输出缓冲区长度
无。
输入/输出缓冲区
不可用
输入/输出缓冲区长度
N/A
状态块
如果操作成功,则 “状态” 字段设置为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指定驱动器号,则驱动器号必须为大写。
请注意,客户端可以通过使用 IOCTL_MOUNTMGR_QUERY_POINTS 查询装载管理器来发现装载管理器是否已收到其卷MOUNTDEV_MOUNTED_DEVICE_GUID设备接口通知。
在此伪代码示例中,装载管理器客户端使用 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);
有关详细信息,请参阅 支持存储类驱动程序中的装载管理器请求。
要求
要求 | 值 |
---|---|
Header | mountmgr.h (包括 Mountmgr.h) |