HRESULT FindTypeInDirectory()

in src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/typeresolution.cpp [203:368]


    HRESULT FindTypeInDirectory(
        _In_ IMetaDataDispenserEx* pMetaDataDispenser,
        _In_ PCWSTR pszFullName,
        _In_ PCWSTR pszDirectoryPath,
        _Out_opt_ HSTRING* phstrMetaDataFilePath,
        _COM_Outptr_opt_result_maybenull_ IMetaDataImport2** ppMetaDataImport,
        _Out_opt_ mdTypeDef* pmdTypeDef)
    {
        HRESULT hr;

        wchar_t szCandidateFilePath[MAX_PATH + 1] = { 0 };
        wchar_t szCandidateFileName[MAX_PATH + 1] = { 0 };
        PWSTR pszLastDot;

        hr = StringCchCopy(szCandidateFileName, ARRAYSIZE(szCandidateFileName), pszFullName);

        if (SUCCEEDED(hr))
        {
            // To resolve type SomeNamespace.B.C, first check if SomeNamespace.B.C is a type or
            // a namespace in the metadata files in the directory in this order:
            // 1. SomeNamespace.B.C.WinMD
            // 2. SomeNamespace.B.WinMD
            // 3. SomeNamespace.WinMD
            do
            {
                pszLastDot = nullptr;

                hr = StringCchPrintfEx(
                    szCandidateFilePath,
                    ARRAYSIZE(szCandidateFilePath),
                    nullptr,
                    nullptr,
                    0,
                    METADATA_FILE_PATH_FORMAT,
                    pszDirectoryPath,
                    szCandidateFileName);

                if (SUCCEEDED(hr))
                {
                    hr = FindTypeInMetaDataFile(
                        pMetaDataDispenser,
                        pszFullName,
                        szCandidateFilePath,
                        TRO_RESOLVE_TYPE_AND_NAMESPACE,
                        ppMetaDataImport,
                        pmdTypeDef);

                    if (SUCCEEDED(hr))
                    {
                        if (phstrMetaDataFilePath != nullptr)
                        {
                            hr = WindowsCreateString(
                                szCandidateFilePath,
                                static_cast<UINT32>(wcslen(szCandidateFilePath)),
                                phstrMetaDataFilePath);
                        }
                        break;
                    }
                }

                hr = RO_E_METADATA_NAME_NOT_FOUND;
                pszLastDot = wcsrchr(szCandidateFileName, '.');

                if (pszLastDot != nullptr)
                {
                    *pszLastDot = '\0';
                }
            } while (pszLastDot != nullptr);

            // If name was not found when searching in the "upward direction", then
            // the name might be a namespace name in a down-level file.
            if (hr == RO_E_METADATA_NAME_NOT_FOUND)
            {
                wchar_t szFilePathSearchTemplate[MAX_PATH + 1] = { 0 };

                hr = StringCchPrintfEx(
                    szFilePathSearchTemplate,
                    ARRAYSIZE(szFilePathSearchTemplate),
                    nullptr,
                    nullptr,
                    0,
                    METADATA_FILE_SEARCH_FORMAT,
                    pszDirectoryPath,
                    pszFullName);

                if (SUCCEEDED(hr))
                {
                    WIN32_FIND_DATA fd;
                    HANDLE hFindFile;

                    // Search in all files in the directory whose name begin with the input string.
                    hFindFile = FindFirstFile(szFilePathSearchTemplate, &fd);

                    if (hFindFile != INVALID_HANDLE_VALUE)
                    {
                        PWSTR pszFilePathPart;
                        size_t cchRemaining;

                        do
                        {
                            if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                            {
                                continue;
                            }

                            pszFilePathPart = szCandidateFilePath;
                            cchRemaining = ARRAYSIZE(szCandidateFilePath);
                            hr = StringCchCopyEx(
                                pszFilePathPart,
                                cchRemaining,
                                pszDirectoryPath,
                                &pszFilePathPart,
                                &cchRemaining,
                                0);

                            if (SUCCEEDED(hr))
                            {
                                hr = StringCchCopyEx(
                                    pszFilePathPart,
                                    cchRemaining,
                                    fd.cFileName,
                                    &pszFilePathPart,
                                    &cchRemaining,
                                    0);
                            }

                            if (SUCCEEDED(hr))
                            {
                                hr = FindTypeInMetaDataFile(
                                    pMetaDataDispenser,
                                    pszFullName,
                                    szCandidateFilePath,
                                    TRO_RESOLVE_NAMESPACE,
                                    ppMetaDataImport,
                                    pmdTypeDef);

                                if (hr == S_OK)
                                {
                                    hr = E_UNEXPECTED;
                                    break;
                                }

                                if (hr == RO_E_METADATA_NAME_IS_NAMESPACE)
                                {
                                    break;
                                }
                            }
                        } while (FindNextFile(hFindFile, &fd));

                        FindClose(hFindFile);
                    }
                    else
                    {
                        hr = RO_E_METADATA_NAME_NOT_FOUND;
                    }
                }
            }
        }

        if (hr == STRSAFE_E_INSUFFICIENT_BUFFER)
        {
            hr = RO_E_METADATA_NAME_NOT_FOUND;
        }

        return hr;
    }