Пример #1
0
static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig,
 LPCWSTR path, int depth, LPWSTR *appValue)
{
    UINT rc;

    TRACE("%p, %p, %s, %d, %p\n", package, sig, debugstr_w(path), depth,
     appValue);
    if (ACTION_IsFullPath(path))
    {
        if (sig->File)
            rc = ACTION_RecurseSearchDirectory(package, appValue, sig,
             path, depth);
        else
        {
            /* Recursively searching a directory makes no sense when the
             * directory to search is the thing you're trying to find.
             */
            rc = ACTION_CheckDirectory(package, path, appValue);
        }
    }
    else
    {
        WCHAR pathWithDrive[MAX_PATH] = { 'C',':','\\',0 };
        DWORD drives = GetLogicalDrives();
        int i;

        rc = ERROR_SUCCESS;
        *appValue = NULL;
        for (i = 0; rc == ERROR_SUCCESS && !*appValue && i < 26; i++)
            if (drives & (1 << i))
            {
                pathWithDrive[0] = 'A' + i;
                if (GetDriveTypeW(pathWithDrive) == DRIVE_FIXED)
                {
                    lstrcpynW(pathWithDrive + 3, path,
                              sizeof(pathWithDrive) / sizeof(pathWithDrive[0]) - 3);
                    if (sig->File)
                        rc = ACTION_RecurseSearchDirectory(package, appValue,
                         sig, pathWithDrive, depth);
                    else
                        rc = ACTION_CheckDirectory(package, pathWithDrive,
                         appValue);
                }
            }
    }
    TRACE("returning %d\n", rc);
    return rc;
}
Пример #2
0
static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig,
 LPCWSTR path, int depth, LPWSTR *appValue)
{
    UINT rc;
    DWORD attr;
    LPWSTR val = NULL;

    TRACE("%p, %p, %s, %d, %p\n", package, sig, debugstr_w(path), depth,
     appValue);

    if (ACTION_IsFullPath(path))
    {
        if (sig->File)
            rc = ACTION_RecurseSearchDirectory(package, &val, sig, path, depth);
        else
        {
            /* Recursively searching a directory makes no sense when the
             * directory to search is the thing you're trying to find.
             */
            rc = ACTION_CheckDirectory(package, path, &val);
        }
    }
    else
    {
        WCHAR pathWithDrive[MAX_PATH] = { 'C',':','\\',0 };
        DWORD drives = GetLogicalDrives();
        int i;

        rc = ERROR_SUCCESS;
        for (i = 0; rc == ERROR_SUCCESS && !val && i < 26; i++)
        {
            if (!(drives & (1 << i)))
                continue;

            pathWithDrive[0] = 'A' + i;
            if (GetDriveTypeW(pathWithDrive) != DRIVE_FIXED)
                continue;

            lstrcpynW(pathWithDrive + 3, path,
                      sizeof(pathWithDrive) / sizeof(pathWithDrive[0]) - 3);

            if (sig->File)
                rc = ACTION_RecurseSearchDirectory(package, &val, sig,
                                                   pathWithDrive, depth);
            else
                rc = ACTION_CheckDirectory(package, pathWithDrive, &val);
        }
    }

    attr = GetFileAttributesW(val);
    if (attr != INVALID_FILE_ATTRIBUTES &&
        (attr & FILE_ATTRIBUTE_DIRECTORY) &&
        val && val[lstrlenW(val) - 1] != '\\')
    {
        val = msi_realloc(val, (lstrlenW(val) + 2) * sizeof(WCHAR));
        if (!val)
            rc = ERROR_OUTOFMEMORY;
        else
            PathAddBackslashW(val);
    }

    *appValue = val;

    TRACE("returning %d\n", rc);
    return rc;
}
Пример #3
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;
}
Пример #4
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;
}