示例#1
0
文件: pyi_utils.c 项目: cbgp/diyabc
// TODO rename fuction and revisit
int pyi_get_temp_path(char *buffer)
{
    int i;
    char *ret;
    char prefix[16];
    wchar_t wchar_buffer[PATH_MAX];

    /*
     * Get path to Windows temporary directory.
     */
    GetTempPathW(PATH_MAX, wchar_buffer);
    pyi_win32_utils_to_utf8(buffer, wchar_buffer, PATH_MAX);

    sprintf(prefix, "_MEI%d", getpid());

    /*
     * Windows does not have a race-free function to create a temporary
     * directory. Thus, we rely on _tempnam, and simply try several times
     * to avoid stupid race conditions.
     */
    for (i=0;i<5;i++) {
        // TODO use race-free fuction - if any exists?
        ret = _tempnam(buffer, prefix);
        if (mkdir(ret) == 0) {
            strcpy(buffer, ret);
            free(ret);
            return 1;
        }
        free(ret);
    }
    return 0;
}
示例#2
0
char * GetWinErrorString(DWORD error_code) {
    wchar_t local_buffer[ERROR_STRING_MAX];
    DWORD result;

    if (error_code == 0) {
        error_code = GetLastError();
    }
    /* Note: Giving 0 to dwLanguageID means MAKELANGID(LANG_NEUTRAL,
     * SUBLANG_NEUTRAL), but we should use SUBLANG_DEFAULT instead of
     * SUBLANG_NEUTRAL. Please see the note written in
     * "Language Identifier Constants and Strings" on MSDN.
     * https://docs.microsoft.com/en-us/windows/desktop/intl/language-identifier-constants-and-strings
     */
    result = FormatMessageW(
        FORMAT_MESSAGE_FROM_SYSTEM, // dwFlags
        NULL,                       // lpSource
        error_code,                 // dwMessageID
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // dwLanguageID
        local_buffer,               // lpBuffer
        ERROR_STRING_MAX,           // nSize
        NULL                        // Arguments
        );

    if (!result) {
        FATAL_WINERROR("FormatMessageW", "No error messages generated.\n");
        return "PyInstaller: FormatMessageW failed.";
    }
    if (!pyi_win32_utils_to_utf8(errorString,
                                 local_buffer,
                                 ERROR_STRING_MAX)) {
        return "PyInstaller: pyi_win32_utils_to_utf8 failed.";
    }
    return errorString;
}
示例#3
0
文件: pyi_utils.c 项目: cbgp/diyabc
/* Return string copy of environment variable. */
char *pyi_getenv(const char *variable)
{
    char *env = NULL;

#ifdef _WIN32
    wchar_t * wenv = NULL;
    wchar_t * wvar = NULL;
    wchar_t buf1[PATH_MAX], buf2[PATH_MAX];
    DWORD rc;

    wvar = pyi_win32_utils_from_utf8(NULL, variable, 0);
    rc = GetEnvironmentVariableW(wvar, buf1, sizeof(buf1));
    if(rc > 0) {
        wenv = buf1;
        /* Expand environment variables like %VAR% in value. */
        rc = ExpandEnvironmentStringsW(wenv, buf2, sizeof(buf2));
        if(rc > 0) {
            wenv = buf1;
        }
    }
    if(wenv) {
        env = pyi_win32_utils_to_utf8(NULL, wenv, 0);
    }
#else
    /* Standard POSIX function. */
    env = getenv(variable);
#endif

    /* If the Python program we are about to run invokes another PyInstaller
     * one-file program as subprocess, this subprocess must not be fooled into
     * thinking that it is already unpacked. Therefore, PyInstaller deletes
     * the _MEIPASS2 variable from the environment in pyi_main().
     *
     * However, on some platforms (e.g. AIX) the Python function 'os.unsetenv()'
     * does not always exist. In these cases we cannot delete the _MEIPASS2
     * environment variable from Python but only set it to the empty string.
     * The code below takes into account that a variable may exist while its
     * value is only the empty string.
     *
     * Return copy of string to avoid modification of the process environment.
     */
    return (env && env[0]) ? strdup(env) : NULL;
}
示例#4
0
/*
 * Return full path to the current executable.
 * Executable is the .exe created by pyinstaller: path/myappname.exe
 * Because the calling process can set argv[0] to whatever it wants,
 * we use a few alternate methods to get the executable path.
 *
 * execfile - buffer where to put path to executable.
 * appname - usually the item argv[0].
 */
int
pyi_path_executable(char *execfile, const char *appname)
{
    char buffer[PATH_MAX];
    size_t result = -1;

#ifdef _WIN32
    wchar_t modulename_w[PATH_MAX];

    /* GetModuleFileNameW returns an absolute, fully qualified path
     */
    if (!GetModuleFileNameW(NULL, modulename_w, PATH_MAX)) {
        FATALERROR("Failed to get executable path. \nGetModuleFileNameW: %s",
                   GetWinErrorString());
        return -1;
    }

    if (!pyi_win32_utils_to_utf8(execfile, modulename_w, PATH_MAX)) {
        FATALERROR("Failed to convert executable path to UTF-8.",
                   GetWinErrorString());
        return -1;
    }

#elif __APPLE__
    uint32_t length = sizeof(buffer);

    /* Mac OS X has special function to obtain path to executable.
     * This may return a symlink.
     */
    if (_NSGetExecutablePath(buffer, &length) != 0) {
        FATALERROR("System error - unable to load!");
        return -1;
    }

    if (pyi_path_fullpath(execfile, PATH_MAX, buffer) == false) {
        VS("LOADER: Cannot get fullpath for %s\n", execfile);
        return -1;
    }

#else /* ifdef _WIN32 */
    result = -1;
    /* On Linux, FreeBSD, and Solaris, we try these /proc paths first
     */
    #if defined(__linux__)
    result = readlink("/proc/self/exe", execfile, PATH_MAX);  /* Linux */
    #elif defined(__FreeBSD__)
    result = readlink("/proc/curproc/file", execfile, PATH_MAX);  /* FreeBSD */
    #elif defined(__sun)
    result = readlink("/proc/self/path/a.out", execfile, PATH_MAX);  /* Solaris */
    #endif

    if (-1 != result) {
        /* execfile is not yet zero-terminated. result is the byte count. */
        *(execfile + result) = '\0';
    }
    else {
        /* No /proc path found or provided
         */
        if (appname[0] == PYI_SEP || strchr(appname, PYI_SEP)) {
            /* Absolute or relative path.
             * Convert to absolute and resolve symlinks.
             */
            if (pyi_path_fullpath(execfile, PATH_MAX, appname) == false) {
                VS("LOADER: Cannot get fullpath for %s\n", execfile);
                return -1;
            }
        }
        else {
            /* Not absolute or relative path, just program name. Search $PATH
             */
            result = pyi_search_path(buffer, appname);

            if (-1 == result) {
                /* Searching $PATH failed, user is crazy. */
                VS("LOADER: Searching $PATH failed for %s", appname);
                strcpy(buffer, appname);
            }

            if (pyi_path_fullpath(execfile, PATH_MAX, buffer) == false) {
                VS("LOADER: Cannot get fullpath for %s\n", execfile);
                return -1;
            }
        }
    }
#endif /* ifdef _WIN32 */
    VS("LOADER: executable is %s\n", execfile);
    return 0;
}