Exemplo n.º 1
0
/* Recursively searches the directory dir for files that match the signature
 * sig, up to (depth + 1) levels deep.  That is, if depth is 0, it searches dir
 * (and only dir).  If depth is 1, searches dir and its immediate
 * subdirectories.
 * Assumes sig->File is not NULL.
 * Returns ERROR_SUCCESS on success (which may include non-critical errors),
 * something else on failures which should halt the install.
 */
static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue,
 MSISIGNATURE *sig, LPCWSTR dir, int depth)
{
    HANDLE hFind;
    WIN32_FIND_DATAW findData;
    UINT rc = ERROR_SUCCESS;
    size_t dirLen = lstrlenW(dir), fileLen = lstrlenW(sig->File);
    WCHAR subpath[MAX_PATH];
    WCHAR *buf;
    DWORD len;

    static const WCHAR starDotStarW[] = { '*','.','*',0 };

    TRACE("Searching directory %s for file %s, depth %d\n", debugstr_w(dir),
          debugstr_w(sig->File), depth);

    if (depth < 0)
        return ERROR_SUCCESS;

    *appValue = NULL;
    /* We need the buffer in both paths below, so go ahead and allocate it
     * here.  Add two because we might need to add a backslash if the dir name
     * isn't backslash-terminated.
     */
    len = dirLen + max(fileLen, strlenW(starDotStarW)) + 2;
    buf = msi_alloc(len * sizeof(WCHAR));
    if (!buf)
        return ERROR_OUTOFMEMORY;

    lstrcpyW(buf, dir);
    PathAddBackslashW(buf);
    lstrcatW(buf, sig->File);

    hFind = FindFirstFileW(buf, &findData);
    if (hFind != INVALID_HANDLE_VALUE)
    {
        if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
        {
            BOOL matches;

            rc = ACTION_FileMatchesSig(sig, &findData, buf, &matches);
            if (rc == ERROR_SUCCESS && matches)
            {
                TRACE("found file, returning %s\n", debugstr_w(buf));
                *appValue = buf;
            }
        }
        FindClose(hFind);
    }

    if (rc == ERROR_SUCCESS && !*appValue)
    {
        lstrcpyW(buf, dir);
        PathAddBackslashW(buf);
        lstrcatW(buf, starDotStarW);

        hFind = FindFirstFileW(buf, &findData);
        if (hFind != INVALID_HANDLE_VALUE)
        {
            if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY &&
                lstrcmpW(findData.cFileName, szDot) &&
                lstrcmpW(findData.cFileName, szDotDot))
            {
                lstrcpyW(subpath, dir);
                PathAppendW(subpath, findData.cFileName);
                rc = ACTION_RecurseSearchDirectory(package, appValue, sig,
                                                   subpath, depth - 1);
            }

            while (rc == ERROR_SUCCESS && !*appValue &&
                   FindNextFileW(hFind, &findData) != 0)
            {
                if (!lstrcmpW(findData.cFileName, szDot) ||
                    !lstrcmpW(findData.cFileName, szDotDot))
                    continue;

                lstrcpyW(subpath, dir);
                PathAppendW(subpath, findData.cFileName);
                if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                    rc = ACTION_RecurseSearchDirectory(package, appValue,
                                                       sig, subpath, depth - 1);
            }

            FindClose(hFind);
        }
    }

    if (*appValue != buf)
        msi_free(buf);

    return rc;
}
Exemplo n.º 2
0
/* Recursively searches the directory dir for files that match the signature
 * sig, up to (depth + 1) levels deep.  That is, if depth is 0, it searches dir
 * (and only dir).  If depth is 1, searches dir and its immediate
 * subdirectories.
 * Assumes sig->File is not NULL.
 * Returns ERROR_SUCCESS on success (which may include non-critical errors),
 * something else on failures which should halt the install.
 */
static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue,
 MSISIGNATURE *sig, LPCWSTR dir, int depth)
{
    static const WCHAR starDotStarW[] = { '*','.','*',0 };
    UINT rc = ERROR_SUCCESS;
    size_t dirLen = lstrlenW(dir), fileLen = lstrlenW(sig->File);
    WCHAR *buf;

    TRACE("Searching directory %s for file %s, depth %d\n", debugstr_w(dir),
     debugstr_w(sig->File), depth);

    if (depth < 0)
        return ERROR_INVALID_PARAMETER;

    *appValue = NULL;
    /* We need the buffer in both paths below, so go ahead and allocate it
     * here.  Add two because we might need to add a backslash if the dir name
     * isn't backslash-terminated.
     */
    buf = msi_alloc( (dirLen + max(fileLen, lstrlenW(starDotStarW)) + 2) * sizeof(WCHAR));
    if (buf)
    {
        /* a depth of 0 implies we should search dir, so go ahead and search */
        HANDLE hFind;
        WIN32_FIND_DATAW findData;

        memcpy(buf, dir, dirLen * sizeof(WCHAR));
        if (buf[dirLen - 1] != '\\')
            buf[dirLen++ - 1] = '\\';
        memcpy(buf + dirLen, sig->File, (fileLen + 1) * sizeof(WCHAR));
        hFind = FindFirstFileW(buf, &findData);
        if (hFind != INVALID_HANDLE_VALUE)
        {
            BOOL matches;

            /* assuming Signature can't contain wildcards for the file name,
             * so don't bother with FindNextFileW here.
             */
            if (!(rc = ACTION_FileMatchesSig(sig, &findData, buf, &matches))
             && matches)
            {
                TRACE("found file, returning %s\n", debugstr_w(buf));
                *appValue = buf;
            }
            FindClose(hFind);
        }
        if (rc == ERROR_SUCCESS && !*appValue && depth > 0)
        {
            HANDLE hFind;
            WIN32_FIND_DATAW findData;

            memcpy(buf, dir, dirLen * sizeof(WCHAR));
            if (buf[dirLen - 1] != '\\')
                buf[dirLen++ - 1] = '\\';
            lstrcpyW(buf + dirLen, starDotStarW);
            hFind = FindFirstFileW(buf, &findData);
            if (hFind != INVALID_HANDLE_VALUE)
            {
                if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                    rc = ACTION_RecurseSearchDirectory(package, appValue, sig,
                     findData.cFileName, depth - 1);
                while (rc == ERROR_SUCCESS && !*appValue &&
                 FindNextFileW(hFind, &findData) != 0)
                {
                    if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                        rc = ACTION_RecurseSearchDirectory(package, appValue,
                         sig, findData.cFileName, depth - 1);
                }
                FindClose(hFind);
            }
        }
        if (!*appValue)
            msi_free(buf);
    }
    else
        rc = ERROR_OUTOFMEMORY;

    return rc;
}