Author: fireball Date: Tue May 10 15:09:36 2011 New Revision: 51665
URL: http://svn.reactos.org/svn/reactos?rev=51665&view=rev Log: [NTOSKRNL] - Make ObpParseSymbolicLink properly handle the case when target path has a trailing path separator. Based on findings by Samarunraj. See issue #993 for more details.
Modified: trunk/reactos/ntoskrnl/ob/oblink.c
Modified: trunk/reactos/ntoskrnl/ob/oblink.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/oblink.c?rev=51... ============================================================================== --- trunk/reactos/ntoskrnl/ob/oblink.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ob/oblink.c [iso-8859-1] Tue May 10 15:09:36 2011 @@ -374,7 +374,7 @@ POBJECT_SYMBOLIC_LINK SymlinkObject = (POBJECT_SYMBOLIC_LINK)ParsedObject; PUNICODE_STRING TargetPath; PWSTR NewTargetPath; - ULONG LengthUsed, MaximumLength; + ULONG LengthUsed, MaximumLength, TempLength; NTSTATUS Status; PAGED_CODE();
@@ -411,9 +411,39 @@ return STATUS_OBJECT_TYPE_MISMATCH; }
+ /* Check if this symlink is bound to a specific object */ + if (SymlinkObject->LinkTargetObject) + { + UNIMPLEMENTED; + } + /* Set the target path and length */ TargetPath = &SymlinkObject->LinkTarget; - LengthUsed = TargetPath->Length + RemainingName->Length; + TempLength = TargetPath->Length; + + /* + * Strip off the extra trailing '', if we don't do this we will end up + * adding a extra '' between TargetPath and RemainingName + * causing caller's like ObpLookupObjectName() to fail. + */ + if (TempLength && RemainingName->Length) + { + /* The target and remaining names aren't empty, so check for slashes */ + if ((TargetPath->Buffer[TempLength / sizeof(WCHAR) - 1] == + OBJ_NAME_PATH_SEPARATOR) && + (RemainingName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)) + { + /* Reduce the length by one to cut off the extra '' */ + TempLength -= sizeof(OBJ_NAME_PATH_SEPARATOR); + } + } + + /* Calculate the new length */ + LengthUsed = TempLength + RemainingName->Length; + + /* Check if it's not too much */ + if (LengthUsed > 0xFFF0) + return STATUS_NAME_TOO_LONG;
/* Optimization: check if the new name is shorter */ if (FullPath->MaximumLength <= LengthUsed) @@ -436,13 +466,13 @@ if (RemainingName->Length) { /* Copy the new path */ - RtlMoveMemory((PVOID)((ULONG_PTR)NewTargetPath + TargetPath->Length), + RtlMoveMemory((PVOID)((ULONG_PTR)NewTargetPath + TempLength), RemainingName->Buffer, RemainingName->Length); }
/* Copy the target path and null-terminate it */ - RtlCopyMemory(NewTargetPath, TargetPath->Buffer, TargetPath->Length); + RtlCopyMemory(NewTargetPath, TargetPath->Buffer, TempLength); NewTargetPath[LengthUsed / sizeof(WCHAR)] = UNICODE_NULL;
/* If the optimization didn't work, free the old buffer */