ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

NTSTATUS NTAPI ObpParseSymbolicLink ( IN PVOID  ParsedObject,
IN PVOID  ObjectType,
IN OUT PACCESS_STATE  AccessState,
IN KPROCESSOR_MODE  AccessMode,
IN ULONG  Attributes,
IN OUT PUNICODE_STRING  FullPath,
IN OUT PUNICODE_STRING  RemainingName,
IN OUT PVOID Context  OPTIONAL,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos  OPTIONAL,
OUT PVOID NextObject 
)

Definition at line 363 of file oblink.c.

Referenced by ObInitSystem(), and ObpLookupObjectName().

{
    POBJECT_SYMBOLIC_LINK SymlinkObject = (POBJECT_SYMBOLIC_LINK)ParsedObject;
    PUNICODE_STRING TargetPath;
    PWSTR NewTargetPath;
    ULONG LengthUsed, MaximumLength, TempLength;
    NTSTATUS Status;
    PAGED_CODE();

    /* Assume failure */
    *NextObject = NULL;

    /* Check if we're out of name to parse */
    if (!RemainingName->Length)
    {
        /* Check if we got an object type */
        if (ObjectType)
        {
            /* Reference the object only */
            Status = ObReferenceObjectByPointer(ParsedObject,
                                                0,
                                                ObjectType,
                                                AccessMode);
            if (NT_SUCCESS(Status))
            {
                /* Return it */
                *NextObject = ParsedObject;
            }

            if ((NT_SUCCESS(Status)) || (Status != STATUS_OBJECT_TYPE_MISMATCH))
            {
                /* Fail */
                return Status;
            }
        }
    }
    else if (RemainingName->Buffer[0] != OBJ_NAME_PATH_SEPARATOR)
    {
        /* Symbolic links must start with a backslash */
        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;
    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)
    {
        /* It's not, allocate a new one */
        MaximumLength = LengthUsed + sizeof(WCHAR);
        NewTargetPath = ExAllocatePoolWithTag(NonPagedPool,
                                              MaximumLength,
                                              TAG_SYMLINK_TTARGET);
        if (!NewTargetPath) return STATUS_INSUFFICIENT_RESOURCES;
    }
    else
    {
        /* It is! Reuse the name... */
        MaximumLength = FullPath->MaximumLength;
        NewTargetPath = FullPath->Buffer;
    }

    /* Make sure we have a length */
    if (RemainingName->Length)
    {
        /* Copy the new path */
        RtlMoveMemory((PVOID)((ULONG_PTR)NewTargetPath + TempLength),
                      RemainingName->Buffer,
                      RemainingName->Length);
    }

    /* Copy the target path and null-terminate it */
    RtlCopyMemory(NewTargetPath, TargetPath->Buffer, TempLength);
    NewTargetPath[LengthUsed / sizeof(WCHAR)] = UNICODE_NULL;

    /* If the optimization didn't work, free the old buffer */
    if (NewTargetPath != FullPath->Buffer) ExFreePool(FullPath->Buffer);

    /* Update the path values */
    FullPath->Length = (USHORT)LengthUsed;
    FullPath->MaximumLength = (USHORT)MaximumLength;
    FullPath->Buffer = NewTargetPath;

    /* Tell the parse routine to start reparsing */
    return STATUS_REPARSE;
}

Generated on Mon May 28 2012 06:08:55 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.