Index: ntoskrnl/io/pnpmgr/plugplay.c =================================================================== --- ntoskrnl/io/pnpmgr/plugplay.c (revision 67211) +++ ntoskrnl/io/pnpmgr/plugplay.c (working copy) @@ -164,50 +164,67 @@ } static NTSTATUS -IopCaptureUnicodeString(PUNICODE_STRING DstName, PUNICODE_STRING SrcName) +IopCaptureUnicodeString(PUNICODE_STRING DstName, UNICODE_STRING volatile * SrcName) { - NTSTATUS Status = STATUS_SUCCESS; - volatile UNICODE_STRING Name; + // The struct SrcName can reside in kernel or user memory. The string + // SrcName->Buffer must reside in user memory or this function will fail. + // On successful return, the caller is responsible for releasing DstName->Buffer. - Name.Buffer = NULL; + BOOLEAN InvalidParams; + UNICODE_STRING Name; + PWSTR SrcBuf; + _SEH2_TRY { Name.Length = SrcName->Length; Name.MaximumLength = SrcName->MaximumLength; - if (Name.Length > Name.MaximumLength) + + InvalidParams = (Name.Length > Name.MaximumLength); + if (FALSE != InvalidParams) { - Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; } - if (Name.MaximumLength) + if (Name.Length != 0) { - ProbeForRead(SrcName->Buffer, - Name.MaximumLength, - sizeof(WCHAR)); - Name.Buffer = ExAllocatePool(NonPagedPool, Name.MaximumLength); - if (Name.Buffer == NULL) - { - Status = STATUS_INSUFFICIENT_RESOURCES; - _SEH2_LEAVE; - } - - memcpy(Name.Buffer, SrcName->Buffer, Name.MaximumLength); + SrcBuf = SrcName->Buffer; + ProbeForRead(SrcBuf, Name.Length, sizeof(WCHAR)); } - - *DstName = Name; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - if (Name.Buffer) + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + if (FALSE != InvalidParams) + { + return STATUS_INVALID_PARAMETER; + } + + Name.MaximumLength = Name.Length; + Name.Buffer = ExAllocatePool(NonPagedPool, Name.MaximumLength); + if (Name.Buffer == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + if (Name.Length != 0) + { + _SEH2_TRY { + RtlCopyMemory(Name.Buffer, SrcBuf, Name.Length); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { ExFreePool(Name.Buffer); + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } - Status = _SEH2_GetExceptionCode(); + _SEH2_END; } - _SEH2_END; - return Status; + *DstName = Name; + return STATUS_SUCCESS; } static NTSTATUS @@ -261,7 +278,7 @@ { SymbolicLinkList += wcslen(SymbolicLinkList) + (sizeof(UNICODE_NULL) / sizeof(WCHAR)); } - TotalLength = ((SymbolicLinkList - LinkList + 1) * sizeof(WCHAR)); + TotalLength = ((ULONG)(SymbolicLinkList - LinkList) + 1) * sizeof(WCHAR); _SEH2_TRY {