예제 #1
0
파일: advpack.c 프로젝트: Jactry/wine
/***********************************************************************
 *             TranslateInfStringW   (ADVPACK.@)
 *
 * Translates the value of a specified key in an inf file into the
 * current locale by expanding string macros.
 *
 * PARAMS
 *   pszInfFilename      [I] Filename of the inf file.
 *   pszInstallSection   [I]
 *   pszTranslateSection [I] Inf section where the key exists.
 *   pszTranslateKey     [I] Key to translate.
 *   pszBuffer           [O] Contains the translated string on exit.
 *   dwBufferSize        [I] Size on input of pszBuffer.
 *   pdwRequiredSize     [O] Length of the translated key.
 *   pvReserved          [I] Reserved, must be NULL.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: An hresult error code.
 */
HRESULT WINAPI TranslateInfStringW(LPCWSTR pszInfFilename, LPCWSTR pszInstallSection,
                LPCWSTR pszTranslateSection, LPCWSTR pszTranslateKey, LPWSTR pszBuffer,
                DWORD dwBufferSize, PDWORD pdwRequiredSize, PVOID pvReserved)
{
    HINF hInf;
    HRESULT hret = S_OK;

    TRACE("(%s, %s, %s, %s, %p, %d, %p, %p)\n",
          debugstr_w(pszInfFilename), debugstr_w(pszInstallSection),
          debugstr_w(pszTranslateSection), debugstr_w(pszTranslateKey),
          pszBuffer, dwBufferSize,pdwRequiredSize, pvReserved);

    if (!pszInfFilename || !pszTranslateSection ||
        !pszTranslateKey || !pdwRequiredSize)
        return E_INVALIDARG;

    hInf = SetupOpenInfFileW(pszInfFilename, NULL, INF_STYLE_WIN4, NULL);
    if (hInf == INVALID_HANDLE_VALUE)
        return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

    set_ldids(hInf, pszInstallSection, NULL);

    if (!SetupGetLineTextW(NULL, hInf, pszTranslateSection, pszTranslateKey,
                           pszBuffer, dwBufferSize, pdwRequiredSize))
    {
        if (dwBufferSize < *pdwRequiredSize)
            hret = E_NOT_SUFFICIENT_BUFFER;
        else
            hret = SPAPI_E_LINE_NOT_FOUND;
    }

    SetupCloseInfFile(hInf);
    return hret;
}
예제 #2
0
파일: query.c 프로젝트: GYGit/reactos
/***********************************************************************
 *            SetupQueryInfOriginalFileInformationW   (SETUPAPI.@)
 */
BOOL WINAPI SetupQueryInfOriginalFileInformationW(
    PSP_INF_INFORMATION InfInformation, UINT InfIndex,
    PSP_ALTPLATFORM_INFO AlternativePlatformInfo,
    PSP_ORIGINAL_FILE_INFO_W OriginalFileInfo)
{
    LPCWSTR inf_name;
    LPCWSTR inf_path;
    HINF hinf;
    static const WCHAR wszVersion[] = { 'V','e','r','s','i','o','n',0 };
    static const WCHAR wszCatalogFile[] = { 'C','a','t','a','l','o','g','F','i','l','e',0 };

    FIXME("(%p, %d, %p, %p): semi-stub\n", InfInformation, InfIndex,
        AlternativePlatformInfo, OriginalFileInfo);

    if (OriginalFileInfo->cbSize != sizeof(*OriginalFileInfo))
    {
        WARN("incorrect OriginalFileInfo->cbSize of %d\n", OriginalFileInfo->cbSize);
        SetLastError(ERROR_INVALID_USER_BUFFER);
        return FALSE;
    }

    inf_path = (LPWSTR)InfInformation->VersionData;

    /* FIXME: we should get OriginalCatalogName from CatalogFile line in
     * the original inf file and cache it, but that would require building a
     * .pnf file. */
    hinf = SetupOpenInfFileW(inf_path, NULL, INF_STYLE_WIN4, NULL);
    if (hinf == INVALID_HANDLE_VALUE) return FALSE;

    if (!SetupGetLineTextW(NULL, hinf, wszVersion, wszCatalogFile,
                           OriginalFileInfo->OriginalCatalogName,
                           sizeof(OriginalFileInfo->OriginalCatalogName)/sizeof(OriginalFileInfo->OriginalCatalogName[0]),
                           NULL))
    {
        OriginalFileInfo->OriginalCatalogName[0] = '\0';
    }
    SetupCloseInfFile(hinf);

    /* FIXME: not quite correct as we just return the same file name as
     * destination (copied) inf file, not the source (original) inf file.
     * to fix it properly would require building a .pnf file */
    /* file name is stored in VersionData field of InfInformation */
    inf_name = strrchrW(inf_path, '\\');
    if (inf_name) inf_name++;
    else inf_name = inf_path;

    strcpyW(OriginalFileInfo->OriginalInfName, inf_name);

    return TRUE;
}
예제 #3
0
파일: install.c 프로젝트: Barrell/wine
/* Advanced INF callbacks */
static HRESULT del_dirs_callback(HINF hinf, PCWSTR field, const void *arg)
{
    INFCONTEXT context;
    HRESULT hr = S_OK;
    DWORD size;

    BOOL ok = SetupFindFirstLineW(hinf, field, NULL, &context);
    
    for (; ok; ok = SetupFindNextLine(&context, &context))
    {
        WCHAR directory[MAX_INF_STRING_LENGTH];

        if (!SetupGetLineTextW(&context, NULL, NULL, NULL, directory,
                               MAX_INF_STRING_LENGTH, &size))
            continue;

        if (DelNodeW(directory, ADN_DEL_IF_EMPTY) != S_OK)
            hr = E_FAIL;
    }

    return hr;
}
예제 #4
0
파일: install.c 프로젝트: Barrell/wine
static HRESULT run_setup_commands_callback(HINF hinf, PCWSTR field, const void *arg)
{
    const ADVInfo *info = (const ADVInfo *)arg;
    INFCONTEXT context;
    HRESULT hr = S_OK;
    DWORD size;

    BOOL ok = SetupFindFirstLineW(hinf, field, NULL, &context);

    for (; ok; ok = SetupFindNextLine(&context, &context))
    {
        WCHAR buffer[MAX_INF_STRING_LENGTH];

        if (!SetupGetLineTextW(&context, NULL, NULL, NULL, buffer,
                               MAX_INF_STRING_LENGTH, &size))
            continue;

        if (launch_exe(buffer, info->working_dir, NULL) != S_OK)
            hr = E_FAIL;
    }

    return hr;
}
예제 #5
0
파일: advpack.c 프로젝트: Jactry/wine
/***********************************************************************
 *             TranslateInfStringExW   (ADVPACK.@)
 *
 * Using a handle to an INF file opened with OpenINFEngine, translates
 * the value of a specified key in an inf file into the current locale
 * by expanding string macros.
 *
 * PARAMS
 *   hInf                [I] Handle to the INF file.
 *   pszInfFilename      [I] Filename of the INF file.
 *   pszTranslateSection [I] Inf section where the key exists.
 *   pszTranslateKey     [I] Key to translate.
 *   pszBuffer           [O] Contains the translated string on exit.
 *   dwBufferSize        [I] Size on input of pszBuffer.
 *   pdwRequiredSize     [O] Length of the translated key.
 *   pvReserved          [I] Reserved.  Must be NULL.
 *
 * RETURNS
 *   Success: S_OK.
 *   Failure: E_FAIL.
 *
 * NOTES
 *   To use TranslateInfStringEx to translate an INF file continuously,
 *   open the INF file with OpenINFEngine, call TranslateInfStringEx as
 *   many times as needed, then release the handle with CloseINFEngine.
 *   When translating more than one keys, this method is more efficient
 *   than calling TranslateInfString, because the INF file is only
 *   opened once.
 */
HRESULT WINAPI TranslateInfStringExW(HINF hInf, LPCWSTR pszInfFilename,
                                     LPCWSTR pszTranslateSection, LPCWSTR pszTranslateKey,
                                     LPWSTR pszBuffer, DWORD dwBufferSize,
                                     PDWORD pdwRequiredSize, PVOID pvReserved)
{
    TRACE("(%p, %s, %s, %s, %p, %d, %p, %p)\n", hInf, debugstr_w(pszInfFilename),
          debugstr_w(pszTranslateSection), debugstr_w(pszTranslateKey),
          pszBuffer, dwBufferSize, pdwRequiredSize, pvReserved);

    if (!hInf || !pszInfFilename || !pszTranslateSection || !pszTranslateKey)
        return E_INVALIDARG;

    if (!SetupGetLineTextW(NULL, hInf, pszTranslateSection, pszTranslateKey,
                           pszBuffer, dwBufferSize, pdwRequiredSize))
    {
        if (dwBufferSize < *pdwRequiredSize)
            return E_NOT_SUFFICIENT_BUFFER;

        return SPAPI_E_LINE_NOT_FOUND;
    }

    return S_OK;   
}
예제 #6
0
파일: install.c 프로젝트: Barrell/wine
static HRESULT per_user_install_callback(HINF hinf, PCWSTR field, const void *arg)
{
    PERUSERSECTIONW per_user;
    INFCONTEXT context;
    DWORD size;

    static const WCHAR disp_name[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
    static const WCHAR version[] = {'V','e','r','s','i','o','n',0};
    static const WCHAR is_installed[] = {'I','s','I','n','s','t','a','l','l','e','d',0};
    static const WCHAR comp_id[] = {'C','o','m','p','o','n','e','n','t','I','D',0};
    static const WCHAR guid[] = {'G','U','I','D',0};
    static const WCHAR locale[] = {'L','o','c','a','l','e',0};
    static const WCHAR stub_path[] = {'S','t','u','b','P','a','t','h',0};

    per_user.bRollback = FALSE;
    per_user.dwIsInstalled = 0;

    SetupGetLineTextW(NULL, hinf, field, disp_name, per_user.szDispName,
                     sizeof(per_user.szDispName) / sizeof(WCHAR), &size);

    SetupGetLineTextW(NULL, hinf, field, version, per_user.szVersion,
                     sizeof(per_user.szVersion) / sizeof(WCHAR), &size);

    if (SetupFindFirstLineW(hinf, field, is_installed, &context))
    {
        SetupGetIntField(&context, 1, (PINT)&per_user.dwIsInstalled);
    }

    SetupGetLineTextW(NULL, hinf, field, comp_id, per_user.szCompID,
                     sizeof(per_user.szCompID) / sizeof(WCHAR), &size);

    SetupGetLineTextW(NULL, hinf, field, guid, per_user.szGUID,
                     sizeof(per_user.szGUID) / sizeof(WCHAR), &size);

    SetupGetLineTextW(NULL, hinf, field, locale, per_user.szLocale,
                     sizeof(per_user.szLocale) / sizeof(WCHAR), &size);

    SetupGetLineTextW(NULL, hinf, field, stub_path, per_user.szStub,
                     sizeof(per_user.szStub) / sizeof(WCHAR), &size);

    return SetPerUserSecValuesW(&per_user);
}
예제 #7
0
/***********************************************************************
 *      SetupCopyOEMInfW  (SETUPAPI.@)
 */
BOOL WINAPI SetupCopyOEMInfW( PCWSTR source, PCWSTR location,
                              DWORD media_type, DWORD style, PWSTR dest,
                              DWORD buffer_size, PDWORD required_size, PWSTR *component )
{
    BOOL ret = FALSE;
    WCHAR target[MAX_PATH], catalog_file[MAX_PATH], *p;
    static const WCHAR inf[] = { '\\','i','n','f','\\',0 };
    static const WCHAR wszVersion[] = { 'V','e','r','s','i','o','n',0 };
    static const WCHAR wszCatalogFile[] = { 'C','a','t','a','l','o','g','F','i','l','e',0 };
    DWORD size;
    HINF hinf;

    TRACE("%s, %s, %d, %d, %p, %d, %p, %p\n", debugstr_w(source), debugstr_w(location),
          media_type, style, dest, buffer_size, required_size, component);

    if (!source)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    /* check for a relative path */
    if (!(*source == '\\' || (*source && source[1] == ':')))
    {
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    if (!GetWindowsDirectoryW( target, sizeof(target)/sizeof(WCHAR) )) return FALSE;

    strcatW( target, inf );
    if ((p = strrchrW( source, '\\' )))
        strcatW( target, p + 1 );

    /* does the file exist already? */
    if ((GetFileAttributesW( target ) != INVALID_FILE_ATTRIBUTES) &&
        !(style & SP_COPY_NOOVERWRITE))
    {
        static const WCHAR oem[] = { 'o','e','m',0 };
        unsigned int i;
        LARGE_INTEGER source_file_size;
        HANDLE source_file;

        source_file = CreateFileW( source, FILE_READ_DATA | FILE_READ_ATTRIBUTES,
                                   FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                                   NULL, OPEN_EXISTING, 0, NULL );
        if (source_file == INVALID_HANDLE_VALUE)
            return FALSE;

        if (!GetFileSizeEx( source_file, &source_file_size ))
        {
            CloseHandle( source_file );
            return FALSE;
        }

        p = strrchrW( target, '\\' ) + 1;
        memcpy( p, oem, sizeof(oem) );
        p += sizeof(oem)/sizeof(oem[0]) - 1;

        /* generate OEMnnn.inf ending */
        for (i = 0; i < OEM_INDEX_LIMIT; i++)
        {
            static const WCHAR format[] = { '%','u','.','i','n','f',0 };
            HANDLE dest_file;
            LARGE_INTEGER dest_file_size;

            wsprintfW( p, format, i );
            dest_file = CreateFileW( target, FILE_READ_DATA | FILE_READ_ATTRIBUTES,
                                     FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                                     NULL, OPEN_EXISTING, 0, NULL );
            /* if we found a file name that doesn't exist then we're done */
            if (dest_file == INVALID_HANDLE_VALUE)
                break;
            /* now check if the same inf file has already been copied to the inf
             * directory. if so, use that file and don't create a new one */
            if (!GetFileSizeEx( dest_file, &dest_file_size ) ||
                (dest_file_size.QuadPart != source_file_size.QuadPart) ||
                compare_files( source_file, dest_file ))
            {
                CloseHandle( dest_file );
                continue;
            }
            CloseHandle( dest_file );
            break;
        }

        CloseHandle( source_file );
        if (i == OEM_INDEX_LIMIT)
        {
            SetLastError( ERROR_FILENAME_EXCED_RANGE );
            return FALSE;
        }
    }

    hinf = SetupOpenInfFileW( source, NULL, INF_STYLE_WIN4, NULL );
    if (hinf == INVALID_HANDLE_VALUE) return FALSE;

    if (SetupGetLineTextW( NULL, hinf, wszVersion, wszCatalogFile, catalog_file,
                           sizeof(catalog_file)/sizeof(catalog_file[0]), NULL ))
    {
        WCHAR source_cat[MAX_PATH];
        strcpyW( source_cat, source );

        p = strrchrW( source_cat, '\\' );
        if (p) p++;
        else p = source_cat;

        strcpyW( p, catalog_file );

        FIXME("install catalog file %s\n", debugstr_w( source_cat ));
    }
    SetupCloseInfFile( hinf );

    if (!(ret = CopyFileW( source, target, (style & SP_COPY_NOOVERWRITE) != 0 )))
        return ret;

    if (style & SP_COPY_DELETESOURCE)
        DeleteFileW( source );

    size = strlenW( target ) + 1;
    if (dest)
    {
        if (buffer_size >= size)
        {
            strcpyW( dest, target );
        }
        else
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            ret = FALSE;
        }
    }

    if (component) *component = p + 1;
    if (required_size) *required_size = size;
    if (ret) SetLastError(ERROR_SUCCESS);

    return ret;
}
예제 #8
0
파일: advpack.c 프로젝트: Jactry/wine
/* loads the LDIDs specified in the install section of an INF */
void set_ldids(HINF hInf, LPCWSTR pszInstallSection, LPCWSTR pszWorkingDir)
{
    WCHAR field[MAX_FIELD_LENGTH];
    WCHAR line[MAX_FIELD_LENGTH];
    WCHAR dest[MAX_PATH];
    INFCONTEXT context;
    DWORD size;
    int ldid;

    static const WCHAR source_dir[] = {'S','o','u','r','c','e','D','i','r',0};

    static const WCHAR custDestW[] = {
        'C','u','s','t','o','m','D','e','s','t','i','n','a','t','i','o','n',0
    };

    if (!SetupGetLineTextW(NULL, hInf, pszInstallSection, custDestW,
                           field, MAX_FIELD_LENGTH, &size))
        return;

    if (!SetupFindFirstLineW(hInf, field, NULL, &context))
        return;

    do
    {
        LPWSTR value, ptr, key, key_copy = NULL;
        DWORD flags = 0;

        SetupGetLineTextW(&context, NULL, NULL, NULL,
                          line, MAX_FIELD_LENGTH, &size);

        /* SetupGetLineTextW returns the value if there is only one key, but
         * returns the whole line if there is more than one key
         */
        if (!(value = strchrW(line, '=')))
        {
            SetupGetStringFieldW(&context, 0, NULL, 0, &size);
            key = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
            key_copy = key;
            SetupGetStringFieldW(&context, 0, key, size, &size);
            value = line;
        }
        else
        {
            key = line;
            *(value++) = '\0';
        }

        /* remove leading whitespace from the value */
        while (*value == ' ')
            value++;

        /* Extract the flags */
        ptr = strchrW(value, ',');
        if (ptr) {
            *ptr = '\0';
            flags = atolW(ptr+1);
        }

        /* set dest to pszWorkingDir if key is SourceDir */
        if (pszWorkingDir && !lstrcmpiW(value, source_dir))
            lstrcpynW(dest, pszWorkingDir, MAX_PATH);
        else
            get_dest_dir(hInf, value, dest, MAX_PATH);

        /* If prompting required, provide dialog to request path */
        if (flags & 0x04)
            FIXME("Need to support changing paths - default will be used\n");

        /* set all ldids to dest */
        while ((ptr = get_parameter(&key, ',', FALSE)))
        {
            ldid = atolW(ptr);
            SetupSetDirectoryIdW(hInf, ldid, dest);
        }
        HeapFree(GetProcessHeap(), 0, key_copy);
    } while (SetupFindNextLine(&context, &context));
}