Blame ms/uplink.c

Packit Service 084de1
/*
Packit Service 084de1
 * Copyright 2004-2019 The OpenSSL Project Authors. All Rights Reserved.
Packit Service 084de1
 *
Packit Service 084de1
 * Licensed under the OpenSSL license (the "License").  You may not use
Packit Service 084de1
 * this file except in compliance with the License.  You can obtain a copy
Packit Service 084de1
 * in the file LICENSE in the source distribution or at
Packit Service 084de1
 * https://www.openssl.org/source/license.html
Packit Service 084de1
 */
Packit Service 084de1
Packit Service 084de1
#if (defined(_WIN64) || defined(_WIN32_WCE)) && !defined(UNICODE)
Packit Service 084de1
# define UNICODE
Packit Service 084de1
#endif
Packit Service 084de1
#if defined(UNICODE) && !defined(_UNICODE)
Packit Service 084de1
# define _UNICODE
Packit Service 084de1
#endif
Packit Service 084de1
#if defined(_UNICODE) && !defined(UNICODE)
Packit Service 084de1
# define UNICODE
Packit Service 084de1
#endif
Packit Service 084de1
Packit Service 084de1
#include <windows.h>
Packit Service 084de1
#include <tchar.h>
Packit Service 084de1
#include <stdio.h>
Packit Service 084de1
#include "uplink.h"
Packit Service 084de1
void OPENSSL_showfatal(const char *, ...);
Packit Service 084de1
Packit Service 084de1
static TCHAR msg[128];
Packit Service 084de1
Packit Service 084de1
static void unimplemented(void)
Packit Service 084de1
{
Packit Service 084de1
    OPENSSL_showfatal(sizeof(TCHAR) == sizeof(char) ? "%s\n" : "%S\n", msg);
Packit Service 084de1
    TerminateProcess(GetCurrentProcess(), 1);
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
void OPENSSL_Uplink(volatile void **table, int index)
Packit Service 084de1
{
Packit Service 084de1
    static HMODULE volatile apphandle = NULL;
Packit Service 084de1
    static void **volatile applinktable = NULL;
Packit Service 084de1
    int len;
Packit Service 084de1
    void (*func) (void) = unimplemented;
Packit Service 084de1
    HANDLE h;
Packit Service 084de1
    void **p;
Packit Service 084de1
Packit Service 084de1
    /*
Packit Service 084de1
     * Note that the below code is not MT-safe in respect to msg buffer, but
Packit Service 084de1
     * what's the worst thing that can happen? Error message might be
Packit Service 084de1
     * misleading or corrupted. As error condition is fatal and should never
Packit Service 084de1
     * be risen, I accept the risk...
Packit Service 084de1
     */
Packit Service 084de1
    /*
Packit Service 084de1
     * One can argue that I should have used InterlockedExchangePointer or
Packit Service 084de1
     * something to update static variables and table[]. Well, store
Packit Service 084de1
     * instructions are as atomic as they can get and assigned values are
Packit Service 084de1
     * effectively constant... So that volatile qualifier should be
Packit Service 084de1
     * sufficient [it prohibits compiler to reorder memory access
Packit Service 084de1
     * instructions].
Packit Service 084de1
     */
Packit Service 084de1
    do {
Packit Service 084de1
        len = _sntprintf(msg, sizeof(msg) / sizeof(TCHAR),
Packit Service 084de1
                         _T("OPENSSL_Uplink(%p,%02X): "), table, index);
Packit Service 084de1
        _tcscpy(msg + len, _T("unimplemented function"));
Packit Service 084de1
Packit Service 084de1
        if ((h = apphandle) == NULL) {
Packit Service 084de1
            if ((h = GetModuleHandle(NULL)) == NULL) {
Packit Service 084de1
                apphandle = (HMODULE) - 1;
Packit Service 084de1
                _tcscpy(msg + len, _T("no host application"));
Packit Service 084de1
                break;
Packit Service 084de1
            }
Packit Service 084de1
            apphandle = h;
Packit Service 084de1
        }
Packit Service 084de1
        if ((h = apphandle) == (HMODULE) - 1) /* revalidate */
Packit Service 084de1
            break;
Packit Service 084de1
Packit Service 084de1
        if (applinktable == NULL) {
Packit Service 084de1
            void **(*applink) ();
Packit Service 084de1
Packit Service 084de1
            applink = (void **(*)())GetProcAddress(h, "OPENSSL_Applink");
Packit Service 084de1
            if (applink == NULL) {
Packit Service 084de1
                apphandle = (HMODULE) - 1;
Packit Service 084de1
                _tcscpy(msg + len, _T("no OPENSSL_Applink"));
Packit Service 084de1
                break;
Packit Service 084de1
            }
Packit Service 084de1
            p = (*applink) ();
Packit Service 084de1
            if (p == NULL) {
Packit Service 084de1
                apphandle = (HMODULE) - 1;
Packit Service 084de1
                _tcscpy(msg + len, _T("no ApplinkTable"));
Packit Service 084de1
                break;
Packit Service 084de1
            }
Packit Service 084de1
            applinktable = p;
Packit Service 084de1
        } else
Packit Service 084de1
            p = applinktable;
Packit Service 084de1
Packit Service 084de1
        if (index > (int)p[0])
Packit Service 084de1
            break;
Packit Service 084de1
Packit Service 084de1
        if (p[index])
Packit Service 084de1
            func = p[index];
Packit Service 084de1
    } while (0);
Packit Service 084de1
Packit Service 084de1
    table[index] = func;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
#if defined(_MSC_VER) && defined(_M_IX86)
Packit Service 084de1
# define LAZY(i)         \
Packit Service 084de1
__declspec(naked) static void lazy##i (void) {  \
Packit Service 084de1
        _asm    push i                          \
Packit Service 084de1
        _asm    push OFFSET OPENSSL_UplinkTable \
Packit Service 084de1
        _asm    call OPENSSL_Uplink             \
Packit Service 084de1
        _asm    add  esp,8                      \
Packit Service 084de1
        _asm    jmp  OPENSSL_UplinkTable+4*i    }
Packit Service 084de1
Packit Service 084de1
# if APPLINK_MAX>25
Packit Service 084de1
#  error "Add more stubs..."
Packit Service 084de1
# endif
Packit Service 084de1
/* make some in advance... */
Packit Service 084de1
LAZY(1) LAZY(2) LAZY(3) LAZY(4) LAZY(5)
Packit Service 084de1
    LAZY(6) LAZY(7) LAZY(8) LAZY(9) LAZY(10)
Packit Service 084de1
    LAZY(11) LAZY(12) LAZY(13) LAZY(14) LAZY(15)
Packit Service 084de1
    LAZY(16) LAZY(17) LAZY(18) LAZY(19) LAZY(20)
Packit Service 084de1
    LAZY(21) LAZY(22) LAZY(23) LAZY(24) LAZY(25)
Packit Service 084de1
void *OPENSSL_UplinkTable[] = {
Packit Service 084de1
    (void *)APPLINK_MAX,
Packit Service 084de1
    lazy1, lazy2, lazy3, lazy4, lazy5,
Packit Service 084de1
    lazy6, lazy7, lazy8, lazy9, lazy10,
Packit Service 084de1
    lazy11, lazy12, lazy13, lazy14, lazy15,
Packit Service 084de1
    lazy16, lazy17, lazy18, lazy19, lazy20,
Packit Service 084de1
    lazy21, lazy22, lazy23, lazy24, lazy25,
Packit Service 084de1
};
Packit Service 084de1
#endif
Packit Service 084de1
Packit Service 084de1
#ifdef SELFTEST
Packit Service 084de1
main()
Packit Service 084de1
{
Packit Service 084de1
    UP_fprintf(UP_stdout, "hello, world!\n");
Packit Service 084de1
}
Packit Service 084de1
#endif