/*
 * Implementation of the AppSearch action of the Microsoft Installer (msi.dll)
 *
 * Copyright 2005 Juan Lang
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "msi.h"
#include "msiquery.h"
#include "winver.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "msipriv.h"
#include "action.h"

WINE_DEFAULT_DEBUG_CHANNEL(msi);

typedef struct tagMSISIGNATURE
{
    LPWSTR   Name;     /* NOT owned by this structure */
    LPWSTR   Property; /* NOT owned by this structure */
    LPWSTR   File;
    DWORD    MinVersionMS;
    DWORD    MinVersionLS;
    DWORD    MaxVersionMS;
    DWORD    MaxVersionLS;
    DWORD    MinSize;
    DWORD    MaxSize;
    FILETIME MinTime;
    FILETIME MaxTime;
    LPWSTR   Languages;
}MSISIGNATURE;

static void ACTION_VerStrToInteger(LPCWSTR verStr, PDWORD ms, PDWORD ls)
{
    const WCHAR *ptr;
    int x1 = 0, x2 = 0, x3 = 0, x4 = 0;

    x1 = atoiW(verStr);
    ptr = strchrW(verStr, '.');
    if (ptr)
    {
        x2 = atoiW(ptr + 1);
        ptr = strchrW(ptr + 1, '.');
    }
    if (ptr)
    {
        x3 = atoiW(ptr + 1);
        ptr = strchrW(ptr + 1, '.');
    }
    if (ptr)
        x4 = atoiW(ptr + 1);
    /* FIXME: byte-order dependent? */
    *ms = x1 << 16 | x2;
    *ls = x3 << 16 | x4;
}

/* Fills in sig with the the values from the Signature table, where name is the
 * signature to find.  Upon return, sig->File will be NULL if the record is not
 * found, and not NULL if it is found.
 * Warning: clears all fields in sig!
 * Returns ERROR_SUCCESS upon success (where not finding the record counts as
 * success), something else on error.
 */
static UINT ACTION_AppSearchGetSignature(MSIPACKAGE *package, MSISIGNATURE *sig,
 LPCWSTR name)
{
    MSIQUERY *view;
    UINT rc;
    static const WCHAR ExecSeqQuery[] =  {
   's','e','l','e','c','t',' ','*',' ',
   'f','r','o','m',' ',
   'S','i','g','n','a','t','u','r','e',' ',
   'w','h','e','r','e',' ','S','i','g','n','a','t','u','r','e',' ','=',' ',
   '\'','%','s','\'',0};

    TRACE("(package %p, sig %p)\n", package, sig);
    memset(sig, 0, sizeof(*sig));
    rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, name);
    if (rc == ERROR_SUCCESS)
    {
        MSIRECORD *row = 0;
        DWORD time;
        WCHAR *minVersion, *maxVersion;

        rc = MSI_ViewExecute(view, 0);
        if (rc != ERROR_SUCCESS)
        {
            TRACE("MSI_ViewExecute returned %d\n", rc);
            goto end;
        }
        rc = MSI_ViewFetch(view,&row);
        if (rc != ERROR_SUCCESS)
        {
            TRACE("MSI_ViewFetch returned %d\n", rc);
            rc = ERROR_SUCCESS;
            goto end;
        }

        /* get properties */
        sig->File = load_dynamic_stringW(row,2);
        minVersion = load_dynamic_stringW(row,3);
        if (minVersion)
        {
            ACTION_VerStrToInteger(minVersion, &sig->MinVersionMS,
             &sig->MinVersionLS);
            HeapFree(GetProcessHeap(), 0, minVersion);
        }
        maxVersion = load_dynamic_stringW(row,4);
        if (maxVersion)
        {
            ACTION_VerStrToInteger(maxVersion, &sig->MaxVersionMS,
             &sig->MaxVersionLS);
            HeapFree(GetProcessHeap(), 0, maxVersion);
        }
        sig->MinSize = MSI_RecordGetInteger(row,5);
        if (sig->MinSize == MSI_NULL_INTEGER)
            sig->MinSize = 0;
        sig->MaxSize = MSI_RecordGetInteger(row,6);
        if (sig->MaxSize == MSI_NULL_INTEGER)
            sig->MaxSize = 0;
        sig->Languages = load_dynamic_stringW(row,9);
        time = MSI_RecordGetInteger(row,7);
        if (time != MSI_NULL_INTEGER)
            DosDateTimeToFileTime(HIWORD(time), LOWORD(time), &sig->MinTime);
        time = MSI_RecordGetInteger(row,8);
        if (time != MSI_NULL_INTEGER)
            DosDateTimeToFileTime(HIWORD(time), LOWORD(time), &sig->MaxTime);
        TRACE("Found file name %s for Signature_ %s;\n",
         debugstr_w(sig->File), debugstr_w(name));
        TRACE("MinVersion is %d.%d.%d.%d\n", HIWORD(sig->MinVersionMS),
         LOWORD(sig->MinVersionMS), HIWORD(sig->MinVersionLS),
         LOWORD(sig->MinVersionLS));
        TRACE("MaxVersion is %d.%d.%d.%d\n", HIWORD(sig->MaxVersionMS),
         LOWORD(sig->MaxVersionMS), HIWORD(sig->MaxVersionLS),
         LOWORD(sig->MaxVersionLS));
        TRACE("MinSize is %ld, MaxSize is %ld;\n", sig->MinSize, sig->MaxSize);
        TRACE("Languages is %s\n", debugstr_w(sig->Languages));

end:
        msiobj_release(&row->hdr);
        MSI_ViewClose(view);
        msiobj_release(&view->hdr);
    }
    else
    {
        TRACE("MSI_OpenQuery returned %d\n", rc);
        rc = ERROR_SUCCESS;
    }

    TRACE("returning %d\n", rc);
    return rc;
}

static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, BOOL *appFound,
 MSISIGNATURE *sig)
{
    MSIQUERY *view;
    UINT rc;
    static const WCHAR ExecSeqQuery[] =  {
   's','e','l','e','c','t',' ','*',' ',
   'f','r','o','m',' ',
   'C','o','m','p','L','o','c','a','t','o','r',' ',
   'w','h','e','r','e',' ','S','i','g','n','a','t','u','r','e','_',' ','=',' ',
   '\'','%','s','\'',0};

    TRACE("(package %p, appFound %p, sig %p)\n", package, appFound, sig);
    *appFound = FALSE;
    rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, sig->Name);
    if (rc == ERROR_SUCCESS)
    {
        MSIRECORD *row = 0;
        WCHAR guid[50];
        DWORD sz;

        rc = MSI_ViewExecute(view, 0);
        if (rc != ERROR_SUCCESS)
        {
            TRACE("MSI_ViewExecute returned %d\n", rc);
            goto end;
        }
        rc = MSI_ViewFetch(view,&row);
        if (rc != ERROR_SUCCESS)
        {
            TRACE("MSI_ViewFetch returned %d\n", rc);
            rc = ERROR_SUCCESS;
            goto end;
        }

        /* get GUID */
        guid[0] = 0;
        sz=sizeof(guid)/sizeof(guid[0]);
        rc = MSI_RecordGetStringW(row,2,guid,&sz);
        if (rc != ERROR_SUCCESS)
        {
            ERR("Error is %x\n",rc);
            goto end;
        }
        FIXME("AppSearch unimplemented for CompLocator table (GUID %s)\n",
         debugstr_w(guid));

end:
        msiobj_release(&row->hdr);
        MSI_ViewClose(view);
        msiobj_release(&view->hdr);
    }
    else
    {
        TRACE("MSI_OpenQuery returned %d\n", rc);
        rc = ERROR_SUCCESS;
    }

    TRACE("returning %d\n", rc);
    return rc;
}

static UINT ACTION_AppSearchReg(MSIPACKAGE *package, BOOL *appFound,
 MSISIGNATURE *sig)
{
    MSIQUERY *view;
    UINT rc;
    static const WCHAR ExecSeqQuery[] =  {
   's','e','l','e','c','t',' ','*',' ',
   'f','r','o','m',' ',
   'R','e','g','L','o','c','a','t','o','r',' ',
   'w','h','e','r','e',' ','S','i','g','n','a','t','u','r','e','_',' ','=',' ',
   '\'','%','s','\'',0};

    TRACE("(package %p, appFound %p, sig %p)\n", package, appFound, sig);
    *appFound = FALSE;
    rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, sig->Name);
    if (rc == ERROR_SUCCESS)
    {
        MSIRECORD *row = 0;
        LPWSTR keyPath;

        rc = MSI_ViewExecute(view, 0);
        if (rc != ERROR_SUCCESS)
        {
            TRACE("MSI_ViewExecute returned %d\n", rc);
            goto end;
        }
        rc = MSI_ViewFetch(view,&row);
        if (rc != ERROR_SUCCESS)
        {
            TRACE("MSI_ViewFetch returned %d\n", rc);
            rc = ERROR_SUCCESS;
            goto end;
        }

        /* get key path */
        keyPath = load_dynamic_stringW(row,3);
        FIXME("AppSearch unimplemented for RegLocator (key path %s)\n",
         debugstr_w(keyPath));
        HeapFree(GetProcessHeap(), 0, keyPath);

end:
        msiobj_release(&row->hdr);
        MSI_ViewClose(view);
        msiobj_release(&view->hdr);
    }
    else
    {
        TRACE("MSI_OpenQuery returned %d\n", rc);
        rc = ERROR_SUCCESS;
    }

    TRACE("returning %d\n", rc);
    return rc;
}

static UINT ACTION_AppSearchIni(MSIPACKAGE *package, BOOL *appFound,
 MSISIGNATURE *sig)
{
    MSIQUERY *view;
    UINT rc;
    static const WCHAR ExecSeqQuery[] =  {
   's','e','l','e','c','t',' ','*',' ',
   'f','r','o','m',' ',
   'I','n','i','L','o','c','a','t','o','r',' ',
   'w','h','e','r','e',' ','S','i','g','n','a','t','u','r','e','_',' ','=',' ',
   '\'','%','s','\'',0};

    TRACE("(package %p, appFound %p, sig %p)\n", package, appFound, sig);
    *appFound = FALSE;
    rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, sig->Name);
    if (rc == ERROR_SUCCESS)
    {
        MSIRECORD *row = 0;
        LPWSTR fileName;

        rc = MSI_ViewExecute(view, 0);
        if (rc != ERROR_SUCCESS)
        {
            TRACE("MSI_ViewExecute returned %d\n", rc);
            goto end;
        }
        rc = MSI_ViewFetch(view,&row);
        if (rc != ERROR_SUCCESS)
        {
            TRACE("MSI_ViewFetch returned %d\n", rc);
            rc = ERROR_SUCCESS;
            goto end;
        }

        /* get file name */
        fileName = load_dynamic_stringW(row,2);
        FIXME("AppSearch unimplemented for IniLocator (ini file name %s)\n",
         debugstr_w(fileName));
        HeapFree(GetProcessHeap(), 0, fileName);

end:
        msiobj_release(&row->hdr);
        MSI_ViewClose(view);
        msiobj_release(&view->hdr);
    }
    else
    {
        TRACE("MSI_OpenQuery returned %d\n", rc);
        rc = ERROR_SUCCESS;
    }


    TRACE("returning %d\n", rc);
    return rc;
}

/* Expands the value in src into a path without property names and only
 * containing long path names into dst.  Replaces at most len characters of dst,
 * and always NULL-terminates dst if dst is not NULL and len >= 1.
 * May modify src.
 * Assumes src and dst are non-overlapping.
 * FIXME: return code probably needed:
 * - what does AppSearch return if the table values are invalid?
 * - what if dst is too small?
 */
static void ACTION_ExpandAnyPath(MSIPACKAGE *package, WCHAR *src, WCHAR *dst,
 size_t len)
{
    WCHAR *ptr;
    size_t copied = 0;

    if (!src || !dst || !len)
        return;

    /* Ignore the short portion of the path, don't think we can use it anyway */
    if ((ptr = strchrW(src, '|')))
        ptr++;
    else
        ptr = src;
    while (*ptr && copied < len - 1)
    {
        WCHAR *prop = strchrW(ptr, '[');

        if (prop)
        {
            WCHAR *propEnd = strchrW(prop + 1, ']');

            if (!propEnd)
            {
                WARN("Unterminated property name in AnyPath: %s\n",
                 debugstr_w(prop));
                break;
            }
            else
            {
                DWORD propLen;

                *propEnd = 0;
                propLen = len - copied - 1;
                MSI_GetPropertyW(package, prop + 1, dst + copied, &propLen);
                ptr = propEnd + 1;
                copied += propLen;
            }
        }
        else
        {
            size_t toCopy = min(strlenW(ptr) + 1, len - copied - 1);

            memcpy(dst + copied, ptr, toCopy * sizeof(WCHAR));
            ptr += toCopy;
            copied += toCopy;
        }
    }
    *(dst + copied) = '\0';
}

/* Sets *matches to whether the file (whose path is filePath) matches the
 * versions set in sig.
 * Return ERROR_SUCCESS in case of success (whether or not the file matches),
 * something else if a install-halting error occurs.
 */
static UINT ACTION_FileVersionMatches(MSISIGNATURE *sig, LPCWSTR filePath,
 BOOL *matches)
{
    UINT rc = ERROR_SUCCESS;

    *matches = FALSE;
    if (sig->Languages)
    {
        FIXME(": need to check version for languages %s\n",
         debugstr_w(sig->Languages));
    }
    else
    {
        DWORD zero, size = GetFileVersionInfoSizeW(filePath, &zero);

        if (size)
        {
            LPVOID buf = HeapAlloc(GetProcessHeap(), 0, size);

            if (buf)
            {
                static const WCHAR rootW[] = { '\\',0 };
                UINT versionLen;
                LPVOID subBlock = NULL;

                if (GetFileVersionInfoW(filePath, 0, size, buf))
                    VerQueryValueW(buf, rootW, &subBlock, &versionLen);
                if (subBlock)
                {
                    VS_FIXEDFILEINFO *info =
                     (VS_FIXEDFILEINFO *)subBlock;

                    TRACE("Comparing file version %d.%d.%d.%d:\n",
                     HIWORD(info->dwFileVersionMS),
                     LOWORD(info->dwFileVersionMS),
                     HIWORD(info->dwFileVersionLS),
                     LOWORD(info->dwFileVersionLS));
                    if (info->dwFileVersionMS < sig->MinVersionMS
                     || (info->dwFileVersionMS == sig->MinVersionMS &&
                     info->dwFileVersionLS < sig->MinVersionLS))
                    {
                        TRACE("Less than minimum version %d.%d.%d.%d\n",
                         HIWORD(sig->MinVersionMS),
                         LOWORD(sig->MinVersionMS),
                         HIWORD(sig->MinVersionLS),
                         LOWORD(sig->MinVersionLS));
                    }
                    else if (info->dwFileVersionMS < sig->MinVersionMS
                     || (info->dwFileVersionMS == sig->MinVersionMS &&
                     info->dwFileVersionLS < sig->MinVersionLS))
                    {
                        TRACE("Greater than minimum version %d.%d.%d.%d\n",
                         HIWORD(sig->MaxVersionMS),
                         LOWORD(sig->MaxVersionMS),
                         HIWORD(sig->MaxVersionLS),
                         LOWORD(sig->MaxVersionLS));
                    }
                    else
                        *matches = TRUE;
                }
                HeapFree(GetProcessHeap(), 0, buf);
            }
            else
                rc = ERROR_OUTOFMEMORY;
        }
    }
    return rc;
}

/* Sets *matches to whether the file in findData matches that in sig.
 * fullFilePath is assumed to be the full path of the file specified in
 * findData, which may be necessary to compare the version.
 * Return ERROR_SUCCESS in case of success (whether or not the file matches),
 * something else if a install-halting error occurs.
 */
static UINT ACTION_FileMatchesSig(MSISIGNATURE *sig,
 LPWIN32_FIND_DATAW findData, LPCWSTR fullFilePath, BOOL *matches)
{
    UINT rc = ERROR_SUCCESS;

    *matches = TRUE;
    /* assumes the caller has already ensured the filenames match, so check
     * the other fields..
     */
    if (sig->MinTime.dwLowDateTime || sig->MinTime.dwHighDateTime)
    {
        if (findData->ftCreationTime.dwHighDateTime <
         sig->MinTime.dwHighDateTime ||
         (findData->ftCreationTime.dwHighDateTime == sig->MinTime.dwHighDateTime
         && findData->ftCreationTime.dwLowDateTime <
         sig->MinTime.dwLowDateTime))
            *matches = FALSE;
    }
    if (*matches && (sig->MaxTime.dwLowDateTime || sig->MaxTime.dwHighDateTime))
    {
        if (findData->ftCreationTime.dwHighDateTime >
         sig->MaxTime.dwHighDateTime ||
         (findData->ftCreationTime.dwHighDateTime == sig->MaxTime.dwHighDateTime
         && findData->ftCreationTime.dwLowDateTime >
         sig->MaxTime.dwLowDateTime))
            *matches = FALSE;
    }
    if (*matches && sig->MinSize && findData->nFileSizeLow < sig->MinSize)
        *matches = FALSE;
    if (*matches && sig->MaxSize && findData->nFileSizeLow > sig->MaxSize)
        *matches = FALSE;
    if (*matches && (sig->MinVersionMS || sig->MinVersionLS ||
     sig->MaxVersionMS || sig->MaxVersionLS))
        rc = ACTION_FileVersionMatches(sig, fullFilePath, matches);
    return rc;
}

/* 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, BOOL *appFound,
 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;

    *appFound = FALSE;
    /* 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 = HeapAlloc(GetProcessHeap(), 0,
     (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, setting %s to %s\n",
                 debugstr_w(sig->Property), debugstr_w(buf));
                rc = MSI_SetPropertyW(package, sig->Property, buf);
                *appFound = TRUE;
            }
            FindClose(hFind);
        }
        if (rc == ERROR_SUCCESS && !*appFound && 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, appFound,
                     sig, findData.cFileName, depth - 1);
                while (rc == ERROR_SUCCESS && !*appFound &&
                 FindNextFileW(hFind, &findData) != 0)
                {
                    if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                        rc = ACTION_RecurseSearchDirectory(package, appFound,
                         sig, findData.cFileName, depth - 1);
                }
                FindClose(hFind);
            }
        }
        HeapFree(GetProcessHeap(), 0, buf);
    }
    else
        rc = ERROR_OUTOFMEMORY;

    return rc;
}

static UINT ACTION_CheckDirectory(MSIPACKAGE *package, MSISIGNATURE *sig,
 LPCWSTR dir)
{
    UINT rc = ERROR_SUCCESS;

    if (GetFileAttributesW(dir) & FILE_ATTRIBUTE_DIRECTORY)
    {
        TRACE("directory exists, setting %s to %s\n",
         debugstr_w(sig->Property), debugstr_w(dir));
        rc = MSI_SetPropertyW(package, sig->Property, dir);
    }
    return rc;
}

static BOOL ACTION_IsFullPath(LPCWSTR path)
{
    WCHAR first = toupperW(path[0]);
    BOOL ret;

    if (first >= 'A' && first <= 'Z' && path[1] == ':')
        ret = TRUE;
    else if (path[0] == '\\' && path[1] == '\\')
        ret = TRUE;
    else
        ret = FALSE;
    return ret;
}

static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig,
 LPCWSTR expanded, int depth)
{
    UINT rc;
    BOOL found;

    TRACE("%p, %p, %s, %d\n", package, sig, debugstr_w(expanded), depth);
    if (ACTION_IsFullPath(expanded))
    {
        if (sig->File)
            rc = ACTION_RecurseSearchDirectory(package, &found, sig,
             expanded, 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, sig, expanded);
        }
    }
    else
    {
        WCHAR pathWithDrive[MAX_PATH] = { 'C',':','\\',0 };
        DWORD drives = GetLogicalDrives();
        int i;

        rc = ERROR_SUCCESS;
        found = FALSE;
        for (i = 0; rc == ERROR_SUCCESS && !found && i < 26; i++)
            if (drives & (1 << drives))
            {
                pathWithDrive[0] = 'A' + i;
                if (GetDriveTypeW(pathWithDrive) == DRIVE_FIXED)
                {
                    strncpyW(pathWithDrive + 3, expanded,
                     sizeof(pathWithDrive) / sizeof(pathWithDrive[0]) - 3);
                    if (sig->File)
                        rc = ACTION_RecurseSearchDirectory(package, &found, sig,
                         pathWithDrive, depth);
                    else
                        rc = ACTION_CheckDirectory(package, sig, pathWithDrive);
                }
            }
    }
    TRACE("returning %d\n", rc);
    return rc;
}

static UINT ACTION_AppSearchDr(MSIPACKAGE *package, MSISIGNATURE *sig)
{
    MSIQUERY *view;
    UINT rc;
    static const WCHAR ExecSeqQuery[] =  {
   's','e','l','e','c','t',' ','*',' ',
   'f','r','o','m',' ',
   'D','r','L','o','c','a','t','o','r',' ',
   'w','h','e','r','e',' ','S','i','g','n','a','t','u','r','e','_',' ','=',' ',
   '\'','%','s','\'',0};

    TRACE("(package %p, sig %p)\n", package, sig);
    rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, sig->Name);
    if (rc == ERROR_SUCCESS)
    {
        MSIRECORD *row = 0;
        WCHAR buffer[MAX_PATH], expanded[MAX_PATH];
        DWORD sz;
        int depth;

        rc = MSI_ViewExecute(view, 0);
        if (rc != ERROR_SUCCESS)
        {
            TRACE("MSI_ViewExecute returned %d\n", rc);
            goto end;
        }
        rc = MSI_ViewFetch(view,&row);
        if (rc != ERROR_SUCCESS)
        {
            TRACE("MSI_ViewFetch returned %d\n", rc);
            rc = ERROR_SUCCESS;
            goto end;
        }

        /* check whether parent is set */
        buffer[0] = 0;
        sz=sizeof(buffer)/sizeof(buffer[0]);
        rc = MSI_RecordGetStringW(row,2,buffer,&sz);
        if (rc != ERROR_SUCCESS)
        {
            ERR("Error is %x\n",rc);
            goto end;
        }
        else if (buffer[0])
        {
            FIXME(": searching parent (%s) unimplemented\n",
             debugstr_w(buffer));
            goto end;
        }
        /* no parent, now look for path */
        buffer[0] = 0;
        sz=sizeof(buffer)/sizeof(buffer[0]);
        rc = MSI_RecordGetStringW(row,3,buffer,&sz);
        if (rc != ERROR_SUCCESS)
        {
            ERR("Error is %x\n",rc);
            goto end;
        }
        if (MSI_RecordIsNull(row,4))
            depth = 0;
        else
            depth = MSI_RecordGetInteger(row,4);
        ACTION_ExpandAnyPath(package, buffer, expanded,
         sizeof(expanded) / sizeof(expanded[0]));
        rc = ACTION_SearchDirectory(package, sig, expanded, depth);

end:
        msiobj_release(&row->hdr);
        MSI_ViewClose(view);
        msiobj_release(&view->hdr);
    }
    else
    {
        TRACE("MSI_OpenQuery returned %d\n", rc);
        rc = ERROR_SUCCESS;
    }


    TRACE("returning %d\n", rc);
    return rc;
}

/* http://msdn.microsoft.com/library/en-us/msi/setup/appsearch_table.asp
 * is the best reference for the AppSearch table and how it's used.
 */
UINT ACTION_AppSearch(MSIPACKAGE *package)
{
    MSIQUERY *view;
    UINT rc;
    static const WCHAR ExecSeqQuery[] =  {
   's','e','l','e','c','t',' ','*',' ',
   'f','r','o','m',' ',
   'A','p','p','S','e','a','r','c','h',0};

    rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery);
    if (rc == ERROR_SUCCESS)
    {
        MSIRECORD *row = 0;
        WCHAR propBuf[0x100], sigBuf[0x100];
        DWORD sz;
        MSISIGNATURE sig;
        BOOL appFound = FALSE;

        rc = MSI_ViewExecute(view, 0);
        if (rc != ERROR_SUCCESS)
            goto end;

        while (!rc)
        {
            rc = MSI_ViewFetch(view,&row);
            if (rc != ERROR_SUCCESS)
            {
                rc = ERROR_SUCCESS;
                break;
            }

            /* get property and signature */
            propBuf[0] = 0;
            sz=sizeof(propBuf)/sizeof(propBuf[0]);
            rc = MSI_RecordGetStringW(row,1,propBuf,&sz);
            if (rc != ERROR_SUCCESS)
            {
                ERR("Error is %x\n",rc);
                msiobj_release(&row->hdr);
                break;
            }
            sigBuf[0] = 0;
            sz=sizeof(sigBuf)/sizeof(sigBuf[0]);
            rc = MSI_RecordGetStringW(row,2,sigBuf,&sz);
            if (rc != ERROR_SUCCESS)
            {
                ERR("Error is %x\n",rc);
                msiobj_release(&row->hdr);
                break;
            }
            TRACE("Searching for Property %s, Signature_ %s\n",
             debugstr_w(propBuf), debugstr_w(sigBuf));
            /* This clears all the fields, so set Name and Property afterward */
            rc = ACTION_AppSearchGetSignature(package, &sig, sigBuf);
            sig.Name = sigBuf;
            sig.Property = propBuf;
            if (rc == ERROR_SUCCESS)
            {
                rc = ACTION_AppSearchComponents(package, &appFound, &sig);
                if (rc == ERROR_SUCCESS && !appFound)
                {
                    rc = ACTION_AppSearchReg(package, &appFound, &sig);
                    if (rc == ERROR_SUCCESS && !appFound)
                    {
                        rc = ACTION_AppSearchIni(package, &appFound, &sig);
                        if (rc == ERROR_SUCCESS && !appFound)
                            rc = ACTION_AppSearchDr(package, &sig);
                    }
                }
            }
            HeapFree(GetProcessHeap(), 0, sig.File);
            HeapFree(GetProcessHeap(), 0, sig.Languages);
            msiobj_release(&row->hdr);
        }

end:
        MSI_ViewClose(view);
        msiobj_release(&view->hdr);
    }
    else
        rc = ERROR_SUCCESS;

    return rc;
}
