
/* Support for dynamic loading of extension modules */

#include "Python.h"
#include "pycore_fileutils.h"     // _Py_add_relfile()
#include "pycore_importdl.h"      // dl_funcptr
#include "pycore_interp.h"        // _PyInterpreterState_GetConfig()
#include "pycore_pystate.h"       // _PyInterpreterState_GET()

#include "patchlevel.h"           // PY_MAJOR_VERSION
#include <windows.h>

const char *_PyImport_DynLoadFiletab[] = {
    PYD_TAGGED_SUFFIX,
    PYD_UNTAGGED_SUFFIX,
    NULL
};

/* Function to return the name of the "python" DLL that the supplied module
   directly imports.  Looks through the list of imported modules and
   returns the first entry that starts with "python" (case sensitive) and
   is followed by nothing but numbers until the separator (period).

   Returns a pointer to the import name, or NULL if no matching name was
   located.

   This function parses through the PE header for the module as loaded in
   memory by the system loader.  The PE header is accessed as documented by
   Microsoft in the MSDN PE and COFF specification (2/99), and handles
   both PE32 and PE32+.  It only worries about the direct import table and
   not the delay load import table since it's unlikely an extension is
   going to be delay loading Python (after all, it's already loaded).

   If any magic values are not found (e.g., the PE header or optional
   header magic), then this function simply returns NULL. */

#define DWORD_AT(mem) (*(DWORD *)(mem))
#define WORD_AT(mem)  (*(WORD *)(mem))

static char *GetPythonImport (HINSTANCE hModule)
{
    unsigned char *dllbase, *import_data, *import_name;
    DWORD pe_offset, opt_offset;
    WORD opt_magic;
    int num_dict_off, import_off;

    /* Safety check input */
    if (hModule == NULL) {
        return NULL;
    }

    /* Module instance is also the base load address.  First portion of
       memory is the MS-DOS loader, which holds the offset to the PE
       header (from the load base) at 0x3C */
    dllbase = (unsigned char *)hModule;
    pe_offset = DWORD_AT(dllbase + 0x3C);

    /* The PE signature must be "PE\0\0" */
    if (memcmp(dllbase+pe_offset,"PE\0\0",4)) {
        return NULL;
    }

    /* Following the PE signature is the standard COFF header (20
       bytes) and then the optional header.  The optional header starts
       with a magic value of 0x10B for PE32 or 0x20B for PE32+ (PE32+
       uses 64-bits for some fields).  It might also be 0x107 for a ROM
       image, but we don't process that here.

       The optional header ends with a data dictionary that directly
       points to certain types of data, among them the import entries
       (in the second table entry). Based on the header type, we
       determine offsets for the data dictionary count and the entry
       within the dictionary pointing to the imports. */

    opt_offset = pe_offset + 4 + 20;
    opt_magic = WORD_AT(dllbase+opt_offset);
    if (opt_magic == 0x10B) {
        /* PE32 */
        num_dict_off = 92;
        import_off   = 104;
    } else if (opt_magic == 0x20B) {
        /* PE32+ */
        num_dict_off = 108;
        import_off   = 120;
    } else {
        /* Unsupported */
        return NULL;
    }

    /* Now if an import table exists, offset to it and walk the list of
       imports.  The import table is an array (ending when an entry has
       empty values) of structures (20 bytes each), which contains (at
       offset 12) a relative address (to the module base) at which a
       string constant holding the import name is located. */

    if (DWORD_AT(dllbase + opt_offset + num_dict_off) >= 2) {
        /* We have at least 2 tables - the import table is the second
           one.  But still it may be that the table size is zero */
        if (0 == DWORD_AT(dllbase + opt_offset + import_off + sizeof(DWORD)))
            return NULL;
        import_data = dllbase + DWORD_AT(dllbase +
                                         opt_offset +
                                         import_off);
        while (DWORD_AT(import_data)) {
            import_name = dllbase + DWORD_AT(import_data+12);
            if (strlen(import_name) >= 6 &&
                !strncmp(import_name,"python",6)) {
                char *pch;

                /* Don't claim that python3.dll is a Python DLL. */
#ifdef Py_DEBUG
                if (strcmp(import_name, "python3_d.dll") == 0) {
#else
                if (strcmp(import_name, "python3.dll") == 0) {
#endif
                    import_data += 20;
                    continue;
                }

                /* Ensure python prefix is followed only
                   by numbers to the end of the basename */
                pch = import_name + 6;
#ifdef Py_DEBUG
                while (*pch && pch[0] != '_' && pch[1] != 'd' && pch[2] != '.') {
#else
                while (*pch && *pch != '.') {
#endif
                    if (*pch >= '0' && *pch <= '9') {
                        pch++;
                    } else {
                        pch = NULL;
                        break;
                    }
                }

                if (pch) {
                    /* Found it - return the name */
                    return import_name;
                }
            }
            import_data += 20;
        }
    }

    return NULL;
}

#ifdef Py_ENABLE_SHARED
/* Load python3.dll before loading any extension module that might refer
   to it. That way, we can be sure that always the python3.dll corresponding
   to this python DLL is loaded, not a python3.dll that might be on the path
   by chance.
   Return whether the DLL was found.
   On free-threaded builds, PY3_DLLNAME is undefined and this is a no-op.
   _Py_CheckPython3t will check for python3t.dll in that case.
*/
extern HMODULE PyWin_DLLhModule;
static int
_Py_CheckPython3(void)
{
#ifndef PY3_DLLNAME
    return 1;
#else
    static int python3_checked = 0;
    static HANDLE hPython3;
    #define MAXPATHLEN 512
    if (python3_checked) {
        return hPython3 != NULL;
    }
    python3_checked = 1;

#ifndef MS_WINDOWS_DESKTOP
    // LoadPackagedLibrary doesn't accept absolute paths so load dll name from current app dir
    hPython3 = LoadPackagedLibrary(PY3_DLLNAME, 0);
#else
    wchar_t py3path[MAXPATHLEN + 1];
    /* If there is a python3.dll next to the python3y.dll,
       use that DLL */
    if (PyWin_DLLhModule && GetModuleFileNameW(PyWin_DLLhModule, py3path, MAXPATHLEN)) {
        wchar_t *p = wcsrchr(py3path, L'\\');

        if (p) {
            wcscpy(p + 1, PY3_DLLNAME L".dll");
            hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
            if (hPython3) {
                return 1;
            }
        }
    }

    /* If we can locate python3.dll in our application dir,
       use that DLL */
    hPython3 = LoadLibraryExW(PY3_DLLNAME L".dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
    if (hPython3 != NULL) {
        return 1;
    }

    /* For back-compat, also search {sys.prefix}\DLLs, though
       that has not been a normal install layout for a while */
    PyInterpreterState *interp = _PyInterpreterState_GET();
    PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp);
    assert(config->prefix);
    if (config->prefix) {
        wcscpy_s(py3path, MAXPATHLEN, config->prefix);
        if (py3path[0] && _Py_add_relfile(py3path, L"DLLs\\" PY3_DLLNAME L".dll", MAXPATHLEN) >= 0) {
            hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
        }
    }
#endif

    return hPython3 != NULL;
    #undef MAXPATHLEN
#endif /* PY3_DLLNAME */
}

/* To support extensions that can load with both abi3 and abi3t, we also need to
 * preload python3t.dll. Due to 3.15 still supporting intermingled layouts, the
 * check is a bit more complicated on that version as we need to try loading
 * from a subdirectory first in case the adjacent python3t.dll is meant for
 * python315t.dll (and we are python315.dll).
 */
static int
_Py_CheckPython3t(void)
{
#ifndef ABI3T_DLLNAME
    return 1;
#else
#if defined(PY3_DLLNAME) && PY_MAJOR_VERSION==3 && PY_MINOR_VERSION==15
    /* GIL-enabled builds of 3.15 might have a python3t.dll adjacent that is for
       a free-threaded build. So we first check in a subdirectory in that case.
       If it's not there, we'll look adjacent. */
    #define ABI3T_COMPAT_DLLNAME L"abi3t-compat\\" ABI3T_DLLNAME L".dll"
#endif
    static int python3t_checked = 0;
    static HANDLE hPython3t;
    #define MAXPATHLEN 512
    wchar_t py3path[MAXPATHLEN+1];
    if (python3t_checked) {
        return hPython3t != NULL;
    }
    python3t_checked = 1;

    /* If there is a python3t.dll [in the abi3t-compat dir] next to the
       python3y.dll, use that DLL */
    if (PyWin_DLLhModule && GetModuleFileNameW(PyWin_DLLhModule, py3path, MAXPATHLEN)) {
        wchar_t *p = wcsrchr(py3path, L'\\');

        if (p) {
#ifdef ABI3T_COMPAT_DLLNAME
            wcscpy(p + 1, ABI3T_COMPAT_DLLNAME);
            hPython3t = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
            if (hPython3t == NULL)
#endif
            {
                wcscpy(p + 1, ABI3T_DLLNAME L".dll");
                hPython3t = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
            }
            if (hPython3t) {
                return 1;
            }
        }
    }

    /* If we can locate python3.dll in our application dir,
       use that DLL */
#ifdef ABI3T_COMPAT_DLLNAME
    hPython3t = LoadLibraryExW(ABI3T_COMPAT_DLLNAME, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
    #undef ABI3T_COMPAT_DLLNAME
    if (hPython3t == NULL)
#endif
    {
        hPython3t = LoadLibraryExW(ABI3T_DLLNAME L".dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
    }
    return hPython3t != NULL;
    #undef MAXPATHLEN
#endif /* ABI3T_DLLNAME */
}

#endif /* Py_ENABLE_SHARED */

static wchar_t* _Py_AbsolutePath_To_RelativePath(wchar_t* abs_path)
{
    wchar_t* rel_path = NULL;
    wchar_t process_path[512] = { 0 };
    if (GetModuleFileNameW(NULL, process_path, 512))
    {
        wchar_t* path = wcsrchr(process_path, L'\\');
        path[1] = L'\0'; // strip process name
        if (wcsstr(abs_path, process_path))
          rel_path = &abs_path[wcslen(process_path)];
    }
    return rel_path;
}

dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
                                              const char *shortname,
                                              PyObject *pathname, FILE *fp)
{
    dl_funcptr p;
    char funcname[258], *import_python;

#ifdef Py_ENABLE_SHARED
    _Py_CheckPython3();
    _Py_CheckPython3t();
#endif /* Py_ENABLE_SHARED */

    wchar_t *wpathname = PyUnicode_AsWideCharString(pathname, NULL);
    if (wpathname == NULL)
        return NULL;

    PyOS_snprintf(funcname, sizeof(funcname), "%.20s_%.200s", prefix, shortname);

    {
        HINSTANCE hDLL = NULL;
#ifdef MS_WINDOWS_DESKTOP
        unsigned int old_mode;

        /* Don't display a message box when Python can't load a DLL */
        old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
#endif

        Py_BEGIN_ALLOW_THREADS
#ifndef MS_WINDOWS_DESKTOP
        // UWP does not allow absolute paths due security restrictions.
        // If path is contained inside process path (sub folder), use the relative path instead.
        wchar_t* rel_path = _Py_AbsolutePath_To_RelativePath(wpathname);
        if (rel_path)
            hDLL = LoadPackagedLibrary(rel_path, 0);
        else
            hDLL = LoadPackagedLibrary(wpathname, 0);
#else
        /* bpo-36085: We use LoadLibraryEx with restricted search paths
           to avoid DLL preloading attacks and enable use of the
           AddDllDirectory function. We add SEARCH_DLL_LOAD_DIR to
           ensure DLLs adjacent to the PYD are preferred. */
        hDLL = LoadLibraryExW(wpathname, NULL,
                              LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
                              LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
#endif
        Py_END_ALLOW_THREADS
        PyMem_Free(wpathname);

#ifdef MS_WINDOWS_DESKTOP
        /* restore old error mode settings */
        SetErrorMode(old_mode);
#endif

        if (hDLL==NULL){
            PyObject *message;
            unsigned int errorCode;

            /* Get an error string from Win32 error code */
            wchar_t theInfo[256]; /* Pointer to error text
                                  from system */
            int theLength; /* Length of error text */

            errorCode = GetLastError();

            theLength = FormatMessageW(
                FORMAT_MESSAGE_FROM_SYSTEM |
                FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */
                NULL, /* message source */
                errorCode, /* the message (error) ID */
                MAKELANGID(LANG_NEUTRAL,
                           SUBLANG_DEFAULT),
                           /* Default language */
                theInfo, /* the buffer */
                sizeof(theInfo) / sizeof(wchar_t), /* size in wchars */
                NULL); /* no additional format args. */

            /* Problem: could not get the error message.
               This should not happen if called correctly. */
            if (theLength == 0) {
                message = PyUnicode_FromFormat(
                    "DLL load failed with error code %u while importing %s",
                    errorCode, shortname);
            } else {
                /* For some reason a \r\n
                   is appended to the text */
                if (theLength >= 2 &&
                    theInfo[theLength-2] == '\r' &&
                    theInfo[theLength-1] == '\n') {
                    theLength -= 2;
                    theInfo[theLength] = '\0';
                }
                message = PyUnicode_FromFormat(
                    "DLL load failed while importing %s: ", shortname);

                PyUnicode_AppendAndDel(&message,
                    PyUnicode_FromWideChar(
                        theInfo,
                        theLength));
            }
            if (message != NULL) {
                PyObject *shortname_obj = PyUnicode_FromString(shortname);
                PyErr_SetImportError(message, shortname_obj, pathname);
                Py_XDECREF(shortname_obj);
                Py_DECREF(message);
            }
            return NULL;
        } else {
            char buffer[256];

            PyOS_snprintf(buffer, sizeof(buffer),
#ifdef Py_DEBUG
                          "python%d%d_d.dll",
#else
                          "python%d%d.dll",
#endif
                          PY_MAJOR_VERSION,PY_MINOR_VERSION);
            import_python = GetPythonImport(hDLL);

            if (import_python &&
                _stricmp(buffer,import_python)) {
                PyErr_Format(PyExc_ImportError,
                             "Module use of %.150s conflicts "
                             "with this version of Python.",
                             import_python);
                Py_BEGIN_ALLOW_THREADS
                FreeLibrary(hDLL);
                Py_END_ALLOW_THREADS
                return NULL;
            }
        }
        Py_BEGIN_ALLOW_THREADS
        p = GetProcAddress(hDLL, funcname);
        Py_END_ALLOW_THREADS
    }

    return p;
}
