
/* Support for dynamic loading of extension modules */

#include <windows.h>
#include <direct.h>
#include <ctype.h>

#include "Python.h"
#include "importdl.h"

const struct filedescr _PyImport_DynLoadFiletab[] = {
#ifdef _DEBUG
	{"_d.pyd", "rb", C_EXTENSION},
	{"_d.dll", "rb", C_EXTENSION},
#else
	{".pyd", "rb", C_EXTENSION},
	{".dll", "rb", C_EXTENSION},
#endif
	{0, 0}
};


/* Case insensitive string compare, to avoid any dependencies on particular
   C RTL implementations */

static int strcasecmp (char *string1, char *string2)
{ 
	int first, second;

	do {
		first  = tolower(*string1);
		second = tolower(*string2);
		string1++;
		string2++;
	} while (first && first == second);

	return (first - second);
} 


/* 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) {
		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;

				/* Ensure python prefix is followed only
				   by numbers to the end of the basename */
				pch = import_name + 6;
				while (*pch && *pch != '.') {
					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;
}


dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
				    const char *pathname, FILE *fp)
{
	dl_funcptr p;
	char funcname[258], *import_python;

	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);

	{
		HINSTANCE hDLL = NULL;
		char pathbuf[260];
		LPTSTR dummy;
		/* We use LoadLibraryEx so Windows looks for dependent DLLs 
		    in directory of pathname first.  However, Windows95
		    can sometimes not work correctly unless the absolute
		    path is used.  If GetFullPathName() fails, the LoadLibrary
		    will certainly fail too, so use its error code */
		if (GetFullPathName(pathname,
				    sizeof(pathbuf),
				    pathbuf,
				    &dummy))
			/* XXX This call doesn't exist in Windows CE */
			hDLL = LoadLibraryEx(pathname, NULL,
					     LOAD_WITH_ALTERED_SEARCH_PATH);
		if (hDLL==NULL){
			char errBuf[256];
			unsigned int errorCode;

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

			errorCode = GetLastError();

			theLength = FormatMessage(
				FORMAT_MESSAGE_FROM_SYSTEM, /* flags */
				NULL, /* message source */
				errorCode, /* the message (error) ID */
				0, /* default language environment */
				(LPTSTR) theInfo, /* the buffer */
				sizeof(theInfo), /* the buffer size */
				NULL); /* no additional format args. */

			/* Problem: could not get the error message.
			   This should not happen if called correctly. */
			if (theLength == 0) {
				PyOS_snprintf(errBuf, sizeof(errBuf),
				      "DLL load failed with error code %d",
					      errorCode);
			} else {
				size_t len;
				/* 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';
				}
				strcpy(errBuf, "DLL load failed: ");
				len = strlen(errBuf);
				strncpy(errBuf+len, theInfo,
					sizeof(errBuf)-len);
				errBuf[sizeof(errBuf)-1] = '\0';
			}
			PyErr_SetString(PyExc_ImportError, errBuf);
		return NULL;
		} else {
			char buffer[256];

			PyOS_snprintf(buffer, sizeof(buffer), "python%d%d.dll",
				PY_MAJOR_VERSION,PY_MINOR_VERSION);
			import_python = GetPythonImport(hDLL);

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

	return p;
}
