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

DWORD WINAPI SearchPathA ( IN LPCSTR  lpPath,
IN LPCSTR  lpFileName,
IN LPCSTR  lpExtension,
IN DWORD  nBufferLength,
IN LPSTR  lpBuffer,
OUT LPSTR lpFilePart 
)

Definition at line 1118 of file path.c.

Referenced by FindDebugInfoFile(), FindExecutableImageEx(), LoadModule(), MapAndLoad(), and PathSearchAndQualifyA().

{
    PUNICODE_STRING FileNameString;
    UNICODE_STRING PathString, ExtensionString;
    NTSTATUS Status;
    ULONG PathSize, FilePartSize, AnsiLength;
    PWCHAR LocalFilePart, Buffer;
    PWCHAR* FilePart;

    /* If the caller wants filepart, use a local wide buffer since this is A */
    FilePart = lpFilePart != NULL ? &LocalFilePart : NULL;

    /* Initialize stuff for Quickie */
    PathSize = 0;
    Buffer = NULL;
    ExtensionString.Buffer = PathString.Buffer = NULL;

    /* Get the UNICODE_STRING file name */
    FileNameString = Basep8BitStringToStaticUnicodeString(lpFileName);
    if (!FileNameString) return 0;

    /* Did the caller specify an extension */
    if (lpExtension)
    {
        /* Yup, convert it into UNICODE_STRING */
        Status = Basep8BitStringToDynamicUnicodeString(&ExtensionString,
                                                       lpExtension);
        if (!NT_SUCCESS(Status)) goto Quickie;
    }

    /* Did the caller specify a path */
    if (lpPath)
    {
        /* Yup, convert it into UNICODE_STRING */
        Status = Basep8BitStringToDynamicUnicodeString(&PathString, lpPath);
        if (!NT_SUCCESS(Status)) goto Quickie;
    }

    /* Allocate our output buffer */
    Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nBufferLength * sizeof(WCHAR));
    if (!Buffer)
    {
        /* It failed, bail out */
        BaseSetLastNTError(STATUS_NO_MEMORY);
        goto Quickie;
    }

    /* Now run the Wide search with the input buffer lengths */
    PathSize = SearchPathW(PathString.Buffer,
                           FileNameString->Buffer,
                           ExtensionString.Buffer,
                           nBufferLength,
                           Buffer,
                           FilePart);
    if (PathSize <= nBufferLength)
    {
        /* It fits, but is it empty? If so, bail out */
        if (!PathSize) goto Quickie;

        /* The length above is inexact, we need it in ANSI */
        Status = RtlUnicodeToMultiByteSize(&AnsiLength, Buffer, PathSize * sizeof(WCHAR));
        if (!NT_SUCCESS(Status))
        {
            /* Conversion failed, fail the call */
            PathSize = 0;
            BaseSetLastNTError(Status);
            goto Quickie;
        }

        /* If the correct ANSI size is too big, return requird length plus a NULL */
        if (AnsiLength >= nBufferLength)
        {
            PathSize = AnsiLength + 1;
            goto Quickie;
        }

        /* Now apply the final conversion to ANSI */
        Status = RtlUnicodeToMultiByteN(lpBuffer,
                                        nBufferLength - 1,
                                        &AnsiLength,
                                        Buffer,
                                        PathSize * sizeof(WCHAR));
        if (!NT_SUCCESS(Status))
        {
            /* Conversion failed, fail the whole call */
            PathSize = 0;
            BaseSetLastNTError(STATUS_NO_MEMORY);
            goto Quickie;
        }

        /* NULL-terminate and return the real ANSI length */
        lpBuffer[AnsiLength] = ANSI_NULL;
        PathSize = AnsiLength;

        /* Now check if the user wanted file part size as well */
        if (lpFilePart)
        {
            /* If we didn't get a file part, clear the caller's */
            if (!LocalFilePart)
            {
                *lpFilePart = NULL;
            }
            else
            {
                /* Yep, so in this case get the length of the file part too */
                Status = RtlUnicodeToMultiByteSize(&FilePartSize,
                                                   Buffer,
                                                   (LocalFilePart - Buffer) *
                                                   sizeof(WCHAR));
                if (!NT_SUCCESS(Status))
                {
                    /* We failed to do that, so fail the whole call */
                    BaseSetLastNTError(Status);
                    PathSize = 0;
                }

                /* Return the file part buffer */
                *lpFilePart = lpBuffer + FilePartSize;
            }
        }
    }
    else
    {
        /* Our initial buffer guess was too small, allocate a bigger one */
        RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
        Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, PathSize * sizeof(WCHAR));
        if (!Buffer)
        {
            /* Out of memory, fail everything */
            BaseSetLastNTError(STATUS_NO_MEMORY);
            goto Quickie;
        }

        /* Do the search again -- it will fail, we just want the path size */
        PathSize = SearchPathW(PathString.Buffer,
                               FileNameString->Buffer,
                               ExtensionString.Buffer,
                               PathSize,
                               Buffer,
                               FilePart);
        if (!PathSize) goto Quickie;

        /* Convert it to a correct size */
        Status = RtlUnicodeToMultiByteSize(&PathSize, Buffer, PathSize * sizeof(WCHAR));
        if (NT_SUCCESS(Status))
        {
            /* Make space for the NULL-char */
            PathSize++;
        }
        else
        {
            /* Conversion failed for some reason, fail the call */
            BaseSetLastNTError(Status);
            PathSize = 0;
        }
    }

Quickie:
    /* Cleanup/complete path */
    if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
    if (ExtensionString.Buffer) RtlFreeUnicodeString(&ExtensionString);
    if (PathString.Buffer) RtlFreeUnicodeString(&PathString);
    return PathSize;
}

Generated on Sun May 27 2012 04:45:58 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.