需要在非管理员用户下实现虚拟磁盘 但是DefineDosDevice非管理员下似乎无法使用
打算使用驱动实现给虚拟盘加载盘符
参考了TRUECRYPT
驱动下给MOUNTMGR发送
IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION
IOCTL_MOUNTMGR_CREATE_POINT
卷中也相应实现了
IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
然后返回用户层广播设备信息
结果是
注册表已经显示诸如 \DosDevices\G: \??\MyVolume0等
但是始终无法显示盘符
请问哪里忽略了
或者麻烦指点下 如何跟踪DefineDosDevice的调用过程
谢谢
-----------------------------
这点小问题还煎熬啊,系统实现见nt4源码Srvinit.c (nt4\\private\\csr\\server) BaseSrvDefineDosDevice函数
ULONG
BaseSrvDefineDosDevice(
IN OUT PCSR_API_MSG m,
IN OUT PCSR_REPLY_STATUS ReplyStatus
)
{
NTSTATUS Status;
PBASE_DEFINEDOSDEVICE_MSG a = (PBASE_DEFINEDOSDEVICE_MSG)&m->u.ApiMessageData;
UNICODE_STRING LinkName;
UNICODE_STRING LinkValue;
HANDLE LinkHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
PWSTR Buffer, s, Src, Dst, pchValue;
ULONG cchBuffer, cch;
ULONG cchName, cchValue, cchSrc, cchSrcStr, cchDst;
BOOLEAN QueryNeeded, MatchFound, RevertToSelfNeeded, DeleteRequest;
ULONG ReturnedLength;
SID_IDENTIFIER_AUTHORITY WorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
SECURITY_DESCRIPTOR SecurityDescriptor;
CHAR Acl[256]; // 256 is more than big enough
ULONG AclLength=256;
PSID WorldSid;
cchBuffer = 4096;
Buffer = RtlAllocateHeap( BaseSrvHeap,
MAKE_TAG( TMP_TAG ),
cchBuffer * sizeof( WCHAR )
);
if (Buffer == NULL) {
return (ULONG)STATUS_NO_MEMORY;
}
Status = RtlEnterCriticalSection( &BaseSrvDosDeviceCritSec );
if (!NT_SUCCESS( Status )) {
RtlFreeHeap( BaseSrvHeap, 0, Buffer );
return (ULONG)Status;
}
if (a->Flags & DDD_REMOVE_DEFINITION) {
DeleteRequest = TRUE;
}
else {
DeleteRequest = FALSE;
}
LinkHandle = NULL;
try {
s = Buffer;
cch = cchBuffer;
cchName = _snwprintf( s,
cch,
L\"\\\\??\\\\%wZ\",
&a->DeviceName
);
s += cchName + 1;
cch -= (cchName + 1);
RtlInitUnicodeString( &LinkName, Buffer );
InitializeObjectAttributes( &ObjectAttributes,
&LinkName,
OBJ_CASE_INSENSITIVE,
(HANDLE) NULL,
(PSECURITY_DESCRIPTOR)NULL
);
QueryNeeded = TRUE;
RevertToSelfNeeded = CsrImpersonateClient( NULL ); // This stacks client contexts
Status = NtOpenSymbolicLinkObject( &LinkHandle,
SYMBOLIC_LINK_QUERY | DELETE,
&ObjectAttributes
);
if (RevertToSelfNeeded) {
CsrRevertToSelf(); // This unstacks client contexts
}
if (Status == STATUS_OBJECT_NAME_NOT_FOUND) {
LinkHandle = NULL;
if (DeleteRequest) {
if (a->TargetPath.Length == 0) {
Status = STATUS_SUCCESS;
}
leave;
}
QueryNeeded = FALSE;
Status = STATUS_SUCCESS;
}
else
if (!NT_SUCCESS( Status )) {
LinkHandle = NULL;
leave;
}
if (a->TargetPath.Length != 0) {
cchValue = wcslen( Src = a->TargetPath.Buffer );
if ((cchValue + 1) >= cch) {
Status = STATUS_TOO_MANY_NAMES;
leave;
}
RtlMoveMemory( s, Src, (cchValue + 1) * sizeof( WCHAR ) );
pchValue = s;
s += cchValue + 1;
cch -= (cchValue + 1);
}
else {
pchValue = NULL;
cchValue = 0;
}
if (QueryNeeded) {
LinkValue.Length = 0;
LinkValue.MaximumLength = (USHORT)(cch * sizeof( WCHAR ));
LinkValue.Buffer = s;
ReturnedLength = 0;
Status = NtQuerySymbolicLinkObject( LinkHandle,
&LinkValue,
&ReturnedLength
);
if (ReturnedLength == (ULONG)LinkValue.MaximumLength) {
Status = STATUS_BUFFER_OVERFLOW;
}
if (!NT_SUCCESS( Status )) {
leave;
}
s[ ReturnedLength / sizeof( WCHAR ) ] = UNICODE_NULL;
LinkValue.MaximumLength = (USHORT)(ReturnedLength + sizeof( UNICODE_NULL ));
}
else {
if (DeleteRequest) {
RtlInitUnicodeString( &LinkValue, NULL );
}
else {
RtlInitUnicodeString( &LinkValue, s - (cchValue + 1) );
}
}
if (LinkHandle != NULL) {
Status = NtMakeTemporaryObject( LinkHandle );
NtClose( LinkHandle );
LinkHandle = NULL;
}
if (!NT_SUCCESS( Status )) {
leave;
}
if (DeleteRequest) {
Src = Dst = LinkValue.Buffer;
cchSrc = LinkValue.MaximumLength / sizeof( WCHAR );
cchDst = 0;
MatchFound = FALSE;
while (*Src) {
cchSrcStr = 0;
s = Src;
while (*Src++) {
cchSrcStr++;
}
if (!MatchFound) {
if ((a->Flags & DDD_EXACT_MATCH_ON_REMOVE &&
cchValue == cchSrcStr &&
!_wcsicmp( s, pchValue )
) ||
(!(a->Flags & DDD_EXACT_MATCH_ON_REMOVE) &&
(cchValue == 0 || !_wcsnicmp( s, pchValue, cchValue ))
)
) {
MatchFound = TRUE;
}
else {
goto CopySrc;
}
}
else {
CopySrc:
if (s != Dst) {
RtlMoveMemory( Dst, s, (cchSrcStr + 1) * sizeof( WCHAR ) );
}
Dst += cchSrcStr + 1;
}
}
*Dst++ = UNICODE_NULL;
LinkValue.Length = wcslen( LinkValue.Buffer ) * sizeof( UNICODE_NULL );
if (LinkValue.Length != 0) {
LinkValue.MaximumLength = (USHORT)((PCHAR)Dst - (PCHAR)LinkValue.Buffer);
}
}
else
if (QueryNeeded) {
LinkValue.Buffer -= (cchValue + 1);
LinkValue.Length = (USHORT)(cchValue * sizeof( WCHAR ));
LinkValue.MaximumLength += LinkValue.Length + sizeof( UNICODE_NULL );
}
//
// Create a new value for the link.
//
if (LinkValue.Length != 0) {
//
// Create the new symbolic link object with a security descriptor
// that grants world SYMBOLIC_LINK_QUERY access.
//
Status = RtlAllocateAndInitializeSid( &WorldSidAuthority,
1,
SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0,
&WorldSid
);
if (!NT_SUCCESS( Status )) {
leave;
}
Status = RtlCreateSecurityDescriptor( &SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION );
ASSERT(NT_SUCCESS(Status));
Status = RtlCreateAcl( (PACL)Acl,
AclLength,
ACL_REVISION2
);
ASSERT(NT_SUCCESS(Status));
Status = RtlAddAccessAllowedAce( (PACL)Acl,
ACL_REVISION2,
SYMBOLIC_LINK_QUERY | DELETE,
WorldSid
);
ASSERT(NT_SUCCESS(Status));
//
// Sid has been copied into the ACL
//
RtlFreeSid( WorldSid );
Status = RtlSetDaclSecurityDescriptor ( &SecurityDescriptor,
TRUE,
(PACL)Acl,
TRUE // Don\'t over-ride inherited protection
);
ASSERT(NT_SUCCESS(Status));
ObjectAttributes.SecurityDescriptor = &SecurityDescriptor;
ObjectAttributes.Attributes |= OBJ_PERMANENT;
Status = NtCreateSymbolicLinkObject( &LinkHandle,
SYMBOLIC_LINK_ALL_ACCESS,
&ObjectAttributes,
&LinkValue
);
if (NT_SUCCESS( Status )) {
NtClose( LinkHandle );
if (DeleteRequest && !MatchFound) {
Status = STATUS_OBJECT_NAME_NOT_FOUND;
}
}
LinkHandle = NULL;
}
}
finally {
if (LinkHandle != NULL) {
NtClose( LinkHandle );
}
RtlFreeHeap( BaseSrvHeap, 0, Buffer );
RtlLeaveCriticalSection( &BaseSrvDosDeviceCritSec );
}
return (ULONG)Status;
ReplyStatus; // get rid of unreferenced parameter warning message
}
-------------------
会者不难 难者不会啊
谢谢了
不过可能是我提问的方向有问题
我需要在非管理员用户下实现加载虚拟盘
但是DefineDosDevice
MJ001列出的代码恐怕我是无法运用了
再次感谢
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。