⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 install.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Implementation of VERSION.DLL - File Installer routines
 *
 * Copyright 1996,1997 Marcus Meissner
 * Copyright 1997 David Cuthbert
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * TODO
 *   o Check the installation functions.
 */

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "winver.h"
#include "winnls.h"
#include "wine/unicode.h"
#include "winerror.h"
#include "lzexpand.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ver);


/******************************************************************************
 *   testFileExistenceA
 *
 *   Tests whether a given path/file combination exists.  If the file does
 *   not exist, the return value is zero.  If it does exist, the return
 *   value is non-zero.
 *
 *   Revision history
 *      30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu)
 *         Original implementation
 *
 */
static int testFileExistenceA( char const * path, char const * file, BOOL excl )
{
    char  filename[1024];
    int  filenamelen;
    OFSTRUCT  fileinfo;

    fileinfo.cBytes = sizeof(OFSTRUCT);

    strcpy(filename, path);
    filenamelen = strlen(filename);

    /* Add a trailing \ if necessary */
    if(filenamelen) {
	if(filename[filenamelen - 1] != '\\')
	    strcat(filename, "\\");
    }
    else /* specify the current directory */
	strcpy(filename, ".\\");

    /* Create the full pathname */
    strcat(filename, file);

    return (OpenFile(filename, &fileinfo,
                     OF_EXIST | (excl ? OF_SHARE_EXCLUSIVE : 0)) != HFILE_ERROR);
}

/******************************************************************************
 *   testFileExistenceW
 */
static int testFileExistenceW( const WCHAR *path, const WCHAR *file, BOOL excl )
{
    char *filename;
    DWORD pathlen, filelen;
    int ret;
    OFSTRUCT fileinfo;

    fileinfo.cBytes = sizeof(OFSTRUCT);

    pathlen = WideCharToMultiByte( CP_ACP, 0, path, -1, NULL, 0, NULL, NULL );
    filelen = WideCharToMultiByte( CP_ACP, 0, file, -1, NULL, 0, NULL, NULL );
    filename = HeapAlloc( GetProcessHeap(), 0, pathlen+filelen+2 );

    WideCharToMultiByte( CP_ACP, 0, path, -1, filename, pathlen, NULL, NULL );
    /* Add a trailing \ if necessary */
    if (pathlen > 1)
    {
        if (filename[pathlen-2] != '\\') strcpy( &filename[pathlen-1], "\\" );
    }
    else /* specify the current directory */
        strcpy(filename, ".\\");

    WideCharToMultiByte( CP_ACP, 0, file, -1, filename+strlen(filename), filelen, NULL, NULL );

    ret = (OpenFile(filename, &fileinfo,
                    OF_EXIST | (excl ? OF_SHARE_EXCLUSIVE : 0)) != HFILE_ERROR);
    HeapFree( GetProcessHeap(), 0, filename );
    return ret;
}

/*****************************************************************************
 *   VerFindFileA [VERSION.@]
 *
 *   Determines where to install a file based on whether it locates another
 *   version of the file in the system.  The values VerFindFile returns are
 *   used in a subsequent call to the VerInstallFile function.
 *
 *   Revision history:
 *      30-May-1997   Dave Cuthbert (dacut@ece.cmu.edu)
 *         Reimplementation of VerFindFile from original stub.
 */
DWORD WINAPI VerFindFileA(
    DWORD flags,
    LPSTR lpszFilename,
    LPSTR lpszWinDir,
    LPSTR lpszAppDir,
    LPSTR lpszCurDir,
    UINT *lpuCurDirLen,
    LPSTR lpszDestDir,
    UINT *lpuDestDirLen )
{
    DWORD  retval = 0;
    const char *curDir;
    const char *destDir;
    unsigned int  curDirSizeReq;
    unsigned int  destDirSizeReq;
    char  systemDir[MAX_PATH];

    /* Print out debugging information */
    TRACE("flags = %x filename=%s windir=%s appdir=%s curdirlen=%p(%u) destdirlen=%p(%u)\n",
          flags, debugstr_a(lpszFilename), debugstr_a(lpszWinDir), debugstr_a(lpszAppDir),
          lpuCurDirLen, lpuCurDirLen ? *lpuCurDirLen : 0,
          lpuDestDirLen, lpuDestDirLen ? *lpuDestDirLen : 0 );

    /* Figure out where the file should go; shared files default to the
       system directory */

    GetSystemDirectoryA(systemDir, sizeof(systemDir));
    curDir = "";
    destDir = "";

    if(flags & VFFF_ISSHAREDFILE)
    {
        destDir = systemDir;
        /* Were we given a filename?  If so, try to find the file. */
        if(lpszFilename)
        {
            if(testFileExistenceA(destDir, lpszFilename, FALSE)) curDir = destDir;
            else if(lpszAppDir && testFileExistenceA(lpszAppDir, lpszFilename, FALSE))
            {
                curDir = lpszAppDir;
                retval |= VFF_CURNEDEST;
            }
        }
    }
    else /* not a shared file */
    {
        if(lpszAppDir)
        {
            destDir = lpszAppDir;
            if(lpszFilename)
            {
                if(testFileExistenceA(destDir, lpszFilename, FALSE)) curDir = destDir;
                else if(testFileExistenceA(systemDir, lpszFilename, FALSE))
                {
                    curDir = systemDir;
                    retval |= VFF_CURNEDEST;
                }
            }
        }
    }

    /* Check to see if the file exists and is inuse by another application */
    if (lpszFilename && testFileExistenceA(curDir, lpszFilename, FALSE)) {
        if (lpszFilename && !testFileExistenceA(curDir, lpszFilename, TRUE))
           retval |= VFF_FILEINUSE;
    }

    curDirSizeReq = strlen(curDir) + 1;
    destDirSizeReq = strlen(destDir) + 1;

    /* Make sure that the pointers to the size of the buffers are
       valid; if not, do NOTHING with that buffer.  If that pointer
       is valid, then make sure that the buffer pointer is valid, too! */

    if(lpuDestDirLen && lpszDestDir)
    {
        if (*lpuDestDirLen < destDirSizeReq) retval |= VFF_BUFFTOOSMALL;
        lstrcpynA(lpszDestDir, destDir, *lpuDestDirLen);
        *lpuDestDirLen = destDirSizeReq;
    }
    if(lpuCurDirLen && lpszCurDir)
    {
        if(*lpuCurDirLen < curDirSizeReq) retval |= VFF_BUFFTOOSMALL;
        lstrcpynA(lpszCurDir, curDir, *lpuCurDirLen);
        *lpuCurDirLen = curDirSizeReq;
    }

    TRACE("ret = %u (%s%s%s) curdir=%s destdir=%s\n", retval,
          (retval & VFF_CURNEDEST) ? "VFF_CURNEDEST " : "",
          (retval & VFF_FILEINUSE) ? "VFF_FILEINUSE " : "",
          (retval & VFF_BUFFTOOSMALL) ? "VFF_BUFFTOOSMALL " : "",
          debugstr_a(lpszCurDir), debugstr_a(lpszDestDir));

    return retval;
}

/*****************************************************************************
 * VerFindFileW						[VERSION.@]
 */
DWORD WINAPI VerFindFileW( DWORD flags,LPWSTR lpszFilename,LPWSTR lpszWinDir,
                           LPWSTR lpszAppDir, LPWSTR lpszCurDir,UINT *lpuCurDirLen,
                           LPWSTR lpszDestDir,UINT *lpuDestDirLen )
{
    static const WCHAR emptyW;
    DWORD retval = 0;
    const WCHAR *curDir;
    const WCHAR *destDir;
    unsigned int curDirSizeReq;
    unsigned int destDirSizeReq;
    WCHAR systemDir[MAX_PATH];

    /* Print out debugging information */
    TRACE("flags = %x filename=%s windir=%s appdir=%s curdirlen=%p(%u) destdirlen=%p(%u)\n",
          flags, debugstr_w(lpszFilename), debugstr_w(lpszWinDir), debugstr_w(lpszAppDir),
          lpuCurDirLen, lpuCurDirLen ? *lpuCurDirLen : 0,
          lpuDestDirLen, lpuDestDirLen ? *lpuDestDirLen : 0 );

    /* Figure out where the file should go; shared files default to the
       system directory */

    GetSystemDirectoryW(systemDir, sizeof(systemDir)/sizeof(WCHAR));
    curDir = &emptyW;
    destDir = &emptyW;

    if(flags & VFFF_ISSHAREDFILE)
    {
        destDir = systemDir;
        /* Were we given a filename?  If so, try to find the file. */
        if(lpszFilename)
        {
            if(testFileExistenceW(destDir, lpszFilename, FALSE)) curDir = destDir;
            else if(lpszAppDir && testFileExistenceW(lpszAppDir, lpszFilename, FALSE))
            {
                curDir = lpszAppDir;
                retval |= VFF_CURNEDEST;
            }
        }
    }
    else /* not a shared file */
    {
        if(lpszAppDir)
        {
            destDir = lpszAppDir;
            if(lpszFilename)
            {
                if(testFileExistenceW(destDir, lpszFilename, FALSE)) curDir = destDir;
                else if(testFileExistenceW(systemDir, lpszFilename, FALSE))
                {
                    curDir = systemDir;
                    retval |= VFF_CURNEDEST;
                }
            }
        }
    }

    if (lpszFilename && !testFileExistenceW(curDir, lpszFilename, TRUE))
        retval |= VFF_FILEINUSE;

    curDirSizeReq = strlenW(curDir) + 1;
    destDirSizeReq = strlenW(destDir) + 1;

    /* Make sure that the pointers to the size of the buffers are
       valid; if not, do NOTHING with that buffer.  If that pointer
       is valid, then make sure that the buffer pointer is valid, too! */

    if(lpuDestDirLen && lpszDestDir)
    {
        if (*lpuDestDirLen < destDirSizeReq) retval |= VFF_BUFFTOOSMALL;
        lstrcpynW(lpszDestDir, destDir, *lpuDestDirLen);
        *lpuDestDirLen = destDirSizeReq;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -