From: <mha...@us...> - 2008-08-28 03:56:02
|
Revision: 670 http://py2exe.svn.sourceforge.net/py2exe/?rev=670&view=rev Author: mhammond Date: 2008-08-28 03:56:11 +0000 (Thu, 28 Aug 2008) Log Message: ----------- [ 2038411 ] copy manifest to target executables and allow user-specified UAC settings for the target. Modified Paths: -------------- trunk/py2exe/ChangeLog trunk/py2exe/py2exe/build_exe.py trunk/py2exe/source/py2exe_util.c Added Paths: ----------- trunk/py2exe/py2exe/samples/user_access_control/ trunk/py2exe/py2exe/samples/user_access_control/README.txt trunk/py2exe/py2exe/samples/user_access_control/hello.py trunk/py2exe/py2exe/samples/user_access_control/setup.py Modified: trunk/py2exe/ChangeLog =================================================================== --- trunk/py2exe/ChangeLog 2008-08-05 05:15:40 UTC (rev 669) +++ trunk/py2exe/ChangeLog 2008-08-28 03:56:11 UTC (rev 670) @@ -1,3 +1,13 @@ +2008-08-28 Mark Hammond <mha...@sk...> + + * Copy the manifest, if any, from the 'template' into the targets + to ensure embedded assembly references, as required for python 2.6 based + apps, are copied. + + * Allow each target to specify Vista User Access Control flags. For + example, specifying 'uac_execution_info="requireAdministrator"' would + force elevation for the final executable. + 2008-05-19 Jimmy Retzlaff <ji...@re...> * Bump version number to 0.6.8. Modified: trunk/py2exe/py2exe/build_exe.py =================================================================== --- trunk/py2exe/py2exe/build_exe.py 2008-08-05 05:15:40 UTC (rev 669) +++ trunk/py2exe/py2exe/build_exe.py 2008-08-28 03:56:11 UTC (rev 670) @@ -16,6 +16,7 @@ import sets import tempfile import struct +import re is_win64 = struct.calcsize("P") == 8 @@ -34,7 +35,12 @@ # resource constants RT_BITMAP=2 +RT_MANIFEST=24 +# Pattern for modifying the 'requestedExecutionLevel' in the manifest. Groups +# are setup so all text *except* for the values is matched. +pat_manifest_uac = re.compile(r'(^.*<requestedExecutionLevel level=")([^"])*(" uiAccess=")([^"])*(".*$)') + # note: we cannot use the list from imp.get_suffixes() because we want # .pyc and .pyo, independent of the optimize flag. _py_suffixes = ['.py', '.pyo', '.pyc', '.pyw'] @@ -85,6 +91,15 @@ # A very loosely defined "target". We assume either a "script" or "modules" # attribute. Some attributes will be target specific. class Target: + # A custom requestedExecutionLevel for the User Access Control portion + # of the manifest for the target. May be a string, which will be used for + # the 'requestedExecutionLevel' portion and False for 'uiAccess', or a tuple + # of (string, bool) which specifies both values. If specified and the + # target's 'template' executable has no manifest (ie, python 2.5 and + # earlier), then a default manifest is created, otherwise the manifest from + # the template is copied then updated. + uac_info = None + def __init__(self, **kw): self.__dict__.update(kw) # If modules is a simple string, assume they meant list @@ -719,6 +734,58 @@ } return self.build_executable(target, template, arcname, None, vars) + def build_manifest(self, target, template): + # Optionally return a manifest to be included in the target executable. + # Note for Python 2.6 and later, its *necessary* to include a manifest + # which correctly references the CRT. For earlier versions, a manifest + # is optional, and only necessary to customize things like + # Vista's User Access Control 'requestedExecutionLevel' setting, etc. + default_manifest = """ + <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel> + </requestedPrivileges> + </security> + </trustInfo> + </assembly> + """ + from py2exe_util import load_resource + if os.path.splitext(template)[1]==".exe": + rid = 1 + else: + rid = 2 + try: + # Manfiests have resource type of 24, and ID of either 1 or 2. + mfest = load_resource(ensure_unicode(template), RT_MANIFEST, rid) + # we consider the manifest 'changed' as we know we clobber all + # resources including the existing manifest - so this manifest must + # get written even if we make no other changes. + changed = True + except RuntimeError: + mfest = default_manifest + # in this case the template had no existing manifest, so its + # not considered 'changed' unless we make further changes later. + changed = False + # update the manifest according to our options. + # for now a regex will do. + if target.uac_info: + changed = True + if isinstance(target.uac_info, tuple): + exec_level, ui = target.uac_info + else: + exec_level = target.uac_info + ui = False + new_lines = [] + for line in mfest.splitlines(): + repl = r'\1%s\3%s\5' % (exec_level, ui) + new_lines.append(re.sub(pat_manifest_uac, repl, line)) + mfest = "".join(new_lines) + if not changed: + return None, None + return mfest, rid + def build_executable(self, target, template, arcname, script, vars={}): # Build an executable for the target # template is the exe-stub to use, and arcname is the zipfile @@ -827,6 +894,13 @@ if not self.dry_run: add_icon(ensure_unicode(exe_path), ensure_unicode(ico_filename), ico_id) + # a manifest + mfest, mfest_id = self.build_manifest(target, src) + if mfest: + self.announce("add manifest, %d bytes" % len(mfest)) + if not self.dry_run: + add_resource(ensure_unicode(exe_path), mfest, RT_MANIFEST, mfest_id, False) + for res_type, res_id, data in getattr(target, "other_resources", []): if not self.dry_run: if isinstance(res_type, basestring): @@ -960,13 +1034,17 @@ images = dlls + templates self.announce("Resolving binary dependencies:") + excludes_use = dll_excludes[:] + # The MSVCRT modules are never found when using VS2008+ + if sys.version_info > (2,6): + excludes_use.append("msvcr90.dll") # we add python.exe (aka sys.executable) to the list of images # to scan for dependencies, but remove it later again from the # results list. In this way pythonXY.dll is collected, and # also the libraries it depends on. alldlls, warnings, other_depends = \ - bin_depends(loadpath, images + [sys.executable], dll_excludes) + bin_depends(loadpath, images + [sys.executable], excludes_use) alldlls.remove(sys.executable) for dll in alldlls: self.announce(" %s" % dll) Added: trunk/py2exe/py2exe/samples/user_access_control/README.txt =================================================================== --- trunk/py2exe/py2exe/samples/user_access_control/README.txt (rev 0) +++ trunk/py2exe/py2exe/samples/user_access_control/README.txt 2008-08-28 03:56:11 UTC (rev 670) @@ -0,0 +1,54 @@ +This is a sample for how to control Vista's user-access-control for your +py2exe created programs. + +Execute 'python setup.py py2exe' to create various executables, all with +different manifest values. Each of these may behave slightly differently +when executed under Vista. + +Important: +---------- + +There is an important difference between Python 2.6 versus +earlier versions. + +Python 2.5 and before created executables will not have a manifest +by default, meaning a backwards compatibility virtualization mode +may be used by default. However, if you specify any value for 'uac_info' +this virtualization will be disabled as it will cause a manifest to be +created for the executable. + +To demonstrate on Vista: + +* Using an elevated process, create a temp directory under "C:\Program Files" + and copy the generated 'dist' directory to that temp dir. + +* From a non-elevated command-prompt, execute: + c:\Program Files\temp\not_specified.exe -e foo + + You will see an error dialog due to 'foo' being written to stderr. The + error dialog will tell you the log file was written to the + "C:\Program Files\temp" directory, but that log file will not exist + in that directory - instead, it will be in the + "C:\Users\{username}\AppData\Local\VirtualStore\Program Files (x86)\temp" + directory - Windows has virtualized the file-system. Similar things will + be able to be demonstrated with the registry. + +* From a non-elevated command-prompt, execute: + c:\Program Files\temp\as_invoker.exe -e foo + + You will see an error dialog, but it will be slightly different - it + will relate to a failure to open the log file in the "c:\Program Files\temp" + directory. In this case, Windows has *not* virtualized the file-system but + your process does not have permission to write in that directory, so it + fails to write a log file at all. + +* From a non-elevated command-prompt, execute: + c:\Program Files\temp\admin_required.exe -e foo + + You will be prompted to elevate the process, then a log file will be + written to "C:\Program Files\temp" as the permissions exists in the + elevated process. + +NOTE: For Python 2.6 and later there is always a manifest, so virtualization +is always disabled. In other words, in Python 2.6, not_specified.exe will +work exactly like as_invoker.exe does for all versions. Added: trunk/py2exe/py2exe/samples/user_access_control/hello.py =================================================================== --- trunk/py2exe/py2exe/samples/user_access_control/hello.py (rev 0) +++ trunk/py2exe/py2exe/samples/user_access_control/hello.py 2008-08-28 03:56:11 UTC (rev 670) @@ -0,0 +1,28 @@ +import sys +import optparse + +def main(): + parser = optparse.OptionParser() + # Main point here is showing that writing to stderr + # currently forces py2exe to write a .log file next + # to the executable, but that might not always work. + # README.txt relies on that to demonstrate different + # behaviour for the different manifest values, so + # if this changes, be sure to also ensure README.txt + # stays accurate. + parser.add_option("-e", "--write-err", + action="store", + help="a message to write to stderr.") + + parser.add_option("-o", "--write-out", + action="store", + help="a message to write to stdout.") + + opts, args = parser.parse_args() + if opts.write_err: + sys.stderr.write(opts.write_err + "\n") + if opts.write_out: + sys.stderr.write(opts.write_out+ "\n") + +if __name__=='__main__': + main() Added: trunk/py2exe/py2exe/samples/user_access_control/setup.py =================================================================== --- trunk/py2exe/py2exe/samples/user_access_control/setup.py (rev 0) +++ trunk/py2exe/py2exe/samples/user_access_control/setup.py 2008-08-28 03:56:11 UTC (rev 670) @@ -0,0 +1,46 @@ +# A simple setup script to create various executables with +# different User Access Control flags in the manifest. + +# Run the build process by entering 'setup.py py2exe' or +# 'python setup.py py2exe' in a console prompt. +# +# If everything works well, you should find a subdirectory named 'dist' +# containing lots of executables + +from distutils.core import setup +import py2exe + +# The targets to build + +# create a target that says nothing about UAC - On Python 2.6+, this +# should be identical to "asInvoker" below. However, for 2.5 and +# earlier it will force the app into compatibility mode (as no +# manifest will exist at all in the target.) +t1 = dict(script="hello.py", + dest_base="not_specified") +# targets with different values for requestedExecutionLevel +t2 = dict(script="hello.py", + dest_base="as_invoker", + uac_info="asInvoker") +t3 = dict(script="hello.py", + dest_base="highest_available", + uac_info="highestAvailable") +t4 = dict(script="hello.py", + dest_base="require_admin", + uac_info="requireAdministrator") +console = [t1, t2, t3, t4] + +# hack to make windows copies of them all too, but +# with '_w' on the tail of the executable. +windows = [t1.copy(), t2.copy(), t3.copy(), t4.copy()] +for t in windows: + t['dest_base'] += "_w" + +setup( + version = "0.5.0", + description = "py2exe user-access-control sample script", + name = "py2exe samples", + # targets to build + windows = windows, + console = console, + ) Modified: trunk/py2exe/source/py2exe_util.c =================================================================== --- trunk/py2exe/source/py2exe_util.c 2008-08-05 05:15:40 UTC (rev 669) +++ trunk/py2exe/source/py2exe_util.c 2008-08-28 03:56:11 UTC (rev 670) @@ -357,6 +357,62 @@ return NULL; } +static PyObject *load_resource(PyObject *self, PyObject *args) +{ + PyObject *ret = NULL; + Py_UNICODE *exename; + HANDLE hMod = NULL; + HRSRC hrsrc = NULL; + HGLOBAL hglob = 0; + LPVOID res_ptr = NULL; + DWORD res_size = 0; + PyObject *py_res_type, *py_res_id; + Py_UNICODE *res_type; + Py_UNICODE *res_id; + WORD wLanguage = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); + + if (!PyArg_ParseTuple(args, "uOO|H", + &exename, &py_res_type, &py_res_id, &wLanguage)) + return NULL; + + res_type = PyObject_AsRESOURCEID(py_res_type); + if (res_type==NULL) + return NULL; + + res_id = PyObject_AsRESOURCEID(py_res_id); + if (res_id==NULL) + return NULL; + + // Note lack of function pointers - this was added after win9x support was + // dropped. + if (!(hMod = LoadLibraryExW(exename, NULL, LOAD_LIBRARY_AS_DATAFILE))) + return SystemError(GetLastError(), "LoadLibraryExW"); + + // from here. take care to exit via 'done' + if (!(hrsrc = FindResourceExW(hMod, res_type, res_id, wLanguage))) { + SystemError(GetLastError(), "FindResourceEx"); + goto done; + } + if (0 == (res_size = SizeofResource(hMod, hrsrc))) { + SystemError(GetLastError(), "SizeofResource"); + goto done; + } + if (0 == (hglob = LoadResource(hMod, hrsrc))) { + SystemError(GetLastError(), "LoadResource"); + goto done; + } + if (0 == (res_ptr = LockResource(hglob))) { + SystemError(GetLastError(), "LockResource"); + goto done; + } + ret = PyString_FromStringAndSize((char *)res_ptr, res_size); +done: + if (hMod) + FreeLibrary(hMod); + // nothing else to clean up (no Unlock/UnloadResource exist) + return ret; +} + /*********************************************************************************** * * Dependency tracker @@ -510,6 +566,9 @@ "Return a list containing the dlls needed to run 'executable'.\n" "The dlls are searched along 'loadpath'\n" "or windows default loadpath", }, + { "load_resource", load_resource, METH_VARARGS, + "load_resource(executable, res_type, res_id[, language]) -> string\n\n" + "Load the specified resource from 'executable'", }, { NULL, NULL }, /* Sentinel */ }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2008-11-01 12:37:32
|
Revision: 674 http://py2exe.svn.sourceforge.net/py2exe/?rev=674&view=rev Author: theller Date: 2008-11-01 12:37:24 +0000 (Sat, 01 Nov 2008) Log Message: ----------- Changed sample to use the wx package instead of the old wxPython package. Modified Paths: -------------- trunk/py2exe/ChangeLog trunk/py2exe/py2exe/samples/singlefile/gui/test_wx.py Modified: trunk/py2exe/ChangeLog =================================================================== --- trunk/py2exe/ChangeLog 2008-11-01 12:29:42 UTC (rev 673) +++ trunk/py2exe/ChangeLog 2008-11-01 12:37:24 UTC (rev 674) @@ -1,3 +1,8 @@ +2008-11-01 Thomas Heller <th...@py...> + + * Changed the py2exe\samples\singlefile\gui\test_wx.py sample to + use the wx package instead of the old wxPython package. + 2008-08-28 Mark Hammond <mha...@sk...> * Copy the manifest, if any, from the 'template' into the targets Modified: trunk/py2exe/py2exe/samples/singlefile/gui/test_wx.py =================================================================== --- trunk/py2exe/py2exe/samples/singlefile/gui/test_wx.py 2008-11-01 12:29:42 UTC (rev 673) +++ trunk/py2exe/py2exe/samples/singlefile/gui/test_wx.py 2008-11-01 12:37:24 UTC (rev 674) @@ -1,31 +1,32 @@ -from wxPython.wx import * +import sys +import wx # By default the executables created by py2exe write output to stderr # into a logfile and display a messagebox at program end when there # has been any output. This logger silently overrides the default -# behaviour by silently shallowing everything. +# behaviour by silently swallowing everything. -class logger: - def write(self, text): - pass # silently ignore everything +if hasattr(sys, "frozen"): + class logger: + def write(self, text): + pass # silently ignore everything -import sys -sys.stdout = sys.stderr = logger() + sys.stdout = sys.stderr = logger() -class MyFrame(wxFrame): - def __init__(self, parent, ID, title, pos=wxDefaultPosition, - size=(200, 200), style=wxDEFAULT_FRAME_STYLE): - wxFrame.__init__(self, parent, ID, title, pos, size, style) - panel = wxPanel(self, -1) +class MyFrame(wx.Frame): + def __init__(self, parent, ID, title, pos=wx.DefaultPosition, + size=(200, 200), style=wx.DEFAULT_FRAME_STYLE): + wx.Frame.__init__(self, parent, ID, title, pos, size, style) + panel = wx.Panel(self, -1) - button = wxButton(panel, 1003, "Close Me") - button.SetPosition(wxPoint(15, 15)) - EVT_BUTTON(self, 1003, self.OnCloseMe) - EVT_CLOSE(self, self.OnCloseWindow) + button = wx.Button(panel, 1003, "Close Me") + button.SetPosition(wx.Point(15, 15)) + wx.EVT_BUTTON(self, 1003, self.OnCloseMe) + wx.EVT_CLOSE(self, self.OnCloseWindow) - button = wxButton(panel, 1004, "Press Me") - button.SetPosition(wxPoint(15, 45)) - EVT_BUTTON(self, 1004, self.OnPressMe) + button = wx.Button(panel, 1004, "Press Me") + button.SetPosition(wx.Point(15, 45)) + wx.EVT_BUTTON(self, 1004, self.OnPressMe) def OnCloseMe(self, event): self.Close(True) @@ -37,12 +38,13 @@ def OnCloseWindow(self, event): self.Destroy() -class MyApp(wxApp): +class MyApp(wx.App): def OnInit(self): - frame = MyFrame(NULL, -1, "Hello from wxPython") - frame.Show(true) + frame = MyFrame(None, -1, "Hello from wxPython") + frame.Show(True) self.SetTopWindow(frame) - return true + return True -app = MyApp(0) -app.MainLoop() +if __name__ == "__main__": + app = MyApp(0) + app.MainLoop() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2008-11-07 06:49:46
|
Revision: 675 http://py2exe.svn.sourceforge.net/py2exe/?rev=675&view=rev Author: theller Date: 2008-11-07 06:49:39 +0000 (Fri, 07 Nov 2008) Log Message: ----------- Fix modulefinder crash on certain relative imports. Modified Paths: -------------- trunk/py2exe/ChangeLog trunk/py2exe/py2exe/mf.py trunk/py2exe/test/relative_import/x/__init__.py trunk/py2exe/test/test_relative_import.py Modified: trunk/py2exe/ChangeLog =================================================================== --- trunk/py2exe/ChangeLog 2008-11-01 12:37:24 UTC (rev 674) +++ trunk/py2exe/ChangeLog 2008-11-07 06:49:39 UTC (rev 675) @@ -1,3 +1,7 @@ +2008-11-06 Thomas Heller <th...@py...> + + * Fixed a modulefinder crash on certain relative imports. + 2008-11-01 Thomas Heller <th...@py...> * Changed the py2exe\samples\singlefile\gui\test_wx.py sample to Modified: trunk/py2exe/py2exe/mf.py =================================================================== --- trunk/py2exe/py2exe/mf.py 2008-11-01 12:37:24 UTC (rev 674) +++ trunk/py2exe/py2exe/mf.py 2008-11-07 06:49:39 UTC (rev 675) @@ -318,7 +318,10 @@ def _add_badmodule(self, name, caller): if name not in self.badmodules: self.badmodules[name] = {} - self.badmodules[name][caller.__name__] = 1 + if caller: + self.badmodules[name][caller.__name__] = 1 + else: + self.badmodules[name]["-"] = 1 def _safe_import_hook(self, name, caller, fromlist, level=-1): # wrapper for self.import_hook() that won't raise ImportError Modified: trunk/py2exe/test/relative_import/x/__init__.py =================================================================== --- trunk/py2exe/test/relative_import/x/__init__.py 2008-11-01 12:37:24 UTC (rev 674) +++ trunk/py2exe/test/relative_import/x/__init__.py 2008-11-07 06:49:39 UTC (rev 675) @@ -2,3 +2,5 @@ import sys as a from .. import sys as b + +def foo(): pass Modified: trunk/py2exe/test/test_relative_import.py =================================================================== --- trunk/py2exe/test/test_relative_import.py 2008-11-01 12:37:24 UTC (rev 674) +++ trunk/py2exe/test/test_relative_import.py 2008-11-07 06:49:39 UTC (rev 675) @@ -1,4 +1,5 @@ import relative_import.x +import relative_import.x.module if __name__ == "__main__": print relative_import.x.a.maxint This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jr...@us...> - 2008-11-10 07:32:50
|
Revision: 677 http://py2exe.svn.sourceforge.net/py2exe/?rev=677&view=rev Author: jretz Date: 2008-11-10 07:32:43 +0000 (Mon, 10 Nov 2008) Log Message: ----------- Updated version numbers, news, and copyright dates in preparation for the 0.6.9 release. Modified Paths: -------------- trunk/py2exe/ANNOUNCE trunk/py2exe/docs/LICENSE.txt trunk/py2exe/docs/py2exe.txt trunk/py2exe/py2exe/__init__.py trunk/py2exe/setup.py Modified: trunk/py2exe/ANNOUNCE =================================================================== --- trunk/py2exe/ANNOUNCE 2008-11-10 07:27:18 UTC (rev 676) +++ trunk/py2exe/ANNOUNCE 2008-11-10 07:32:43 UTC (rev 677) @@ -1,4 +1,4 @@ -py2exe 0.6.8 released +py2exe 0.6.9 released ===================== py2exe is a Python distutils extension which converts Python scripts @@ -6,6 +6,24 @@ Python installation. Console and Windows (GUI) applications, Windows NT services, exe and dll COM servers are supported. +Changes in 0.6.9: + + * Binaries for Python 2.6. + + * Fixed a modulefinder crash on certain relative imports. + + * Changed the py2exe\samples\singlefile\gui\test_wx.py sample to + use the wx package instead of the old wxPython package. + + * Copy the manifest, if any, from the 'template' into the targets + to ensure embedded assembly references, as required for python 2.6 based + apps, are copied. + + * Allow each target to specify Vista User Access Control flags. For + example, specifying 'uac_execution_info="requireAdministrator"' would + force elevation for the final executable. + + Changes in 0.6.8: * Support for relative imports. Modified: trunk/py2exe/docs/LICENSE.txt =================================================================== --- trunk/py2exe/docs/LICENSE.txt 2008-11-10 07:27:18 UTC (rev 676) +++ trunk/py2exe/docs/LICENSE.txt 2008-11-10 07:32:43 UTC (rev 677) @@ -1,4 +1,4 @@ -Copyright (c) 2000-2005 Thomas Heller, Mark Hammond, Jimmy Retzlaff +Copyright (c) 2000-2008 Thomas Heller, Mark Hammond, Jimmy Retzlaff Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Modified: trunk/py2exe/docs/py2exe.txt =================================================================== --- trunk/py2exe/docs/py2exe.txt 2008-11-10 07:27:18 UTC (rev 676) +++ trunk/py2exe/docs/py2exe.txt 2008-11-10 07:32:43 UTC (rev 677) @@ -7,14 +7,16 @@ .. _setup-script: http://www.python.org/doc/current/dist/setup-script.html -.. _py2exe-0.6.8.win32-py2.3.exe: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.8.win32-py2.3.exe?download +.. _py2exe-0.6.9.win32-py2.3.exe: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win32-py2.3.exe?download -.. _py2exe-0.6.8.win32-py2.4.exe: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.8.win32-py2.4.exe?download +.. _py2exe-0.6.9.win32-py2.4.exe: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win32-py2.4.exe?download -.. _py2exe-0.6.8.win32-py2.5.exe: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.8.win32-py2.5.exe?download +.. _py2exe-0.6.9.win32-py2.5.exe: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win32-py2.5.exe?download -.. _py2exe-0.6.8.win64-py2.5.amd64.msi: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.8.win64-py2.5.amd64.msi?download +.. _py2exe-0.6.9.win64-py2.5.amd64.msi: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.0.win64-py2.5.amd64.msi?download +.. _py2exe-0.6.9.win32-py2.6.exe: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win32-py2.6.exe?download + .. _WIKI: http://starship.python.net/crew/theller/moin.cgi/Py2Exe .. _SourceForge: http://sourceforge.net/projects/py2exe/ @@ -59,6 +61,18 @@ News ---- +**py2exe 0.6.9 released (2008/11/15)** + +Binaries for Python 2.6. + +Fixed a modulefinder crash on certain relative imports. + +Changed the py2exe\samples\singlefile\gui\test_wx.py sample to use the wx package instead of the old wxPython package. + +Copy the manifest, if any, from the 'template' into the targets to ensure embedded assembly references, as required for python 2.6 based apps, are copied. + +Allow each target to specify Vista User Access Control flags. For example, specifying 'uac_execution_info="requireAdministrator"' would force elevation for the final executable. + **py2exe 0.6.8 released (2008/06/15)** Support for relative imports. @@ -396,9 +410,11 @@ Installing py2exe ----------------- -Download and run the installer py2exe-0.6.8.win32-py2.3.exe_ (for -Python 2.3), py2exe-0.6.8.win32-py2.4.exe_ (for -Python 2.4), py2exe-0.6.8.win32-py2.5.exe_ (for Python 2.5), or py2exe-0.6.8.win64-py2.5.amd64.msi_ (for 64-bit Python 2.5). +Download and run the installer py2exe-0.6.9.win32-py2.3.exe_ (for +Python 2.3), py2exe-0.6.9.win32-py2.4.exe_ (for +Python 2.4), py2exe-0.6.9.win32-py2.5.exe_ (for Python 2.5), +py2exe-0.6.9.win64-py2.5.amd64.msi_ (for 64-bit Python 2.5), or +py2exe-0.6.9.win32-py2.6.exe_ (for Python 2.6). This installs **py2exe** together with some samples, the samples are in the ``lib\site-packages\py2exe\samples`` subdirectory. Modified: trunk/py2exe/py2exe/__init__.py =================================================================== --- trunk/py2exe/py2exe/__init__.py 2008-11-10 07:27:18 UTC (rev 676) +++ trunk/py2exe/py2exe/__init__.py 2008-11-10 07:32:43 UTC (rev 677) @@ -62,7 +62,7 @@ # special one contained in this module. # -__version__ = "0.6.8" +__version__ = "0.6.9" import distutils.dist, distutils.core, distutils.command, build_exe, sys Modified: trunk/py2exe/setup.py =================================================================== --- trunk/py2exe/setup.py 2008-11-10 07:27:18 UTC (rev 676) +++ trunk/py2exe/setup.py 2008-11-10 07:32:43 UTC (rev 677) @@ -1,6 +1,6 @@ #!/usr/bin/python ## -## Copyright (c) 2000-2005 Thomas Heller, Jimmy Retzlaff +## Copyright (c) 2000-2008 Thomas Heller, Jimmy Retzlaff ## ## Permission is hereby granted, free of charge, to any person obtaining ## a copy of this software and associated documentation files (the This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jr...@us...> - 2008-11-16 06:07:46
|
Revision: 679 http://py2exe.svn.sourceforge.net/py2exe/?rev=679&view=rev Author: jretz Date: 2008-11-16 06:07:44 +0000 (Sun, 16 Nov 2008) Log Message: ----------- Include mention of Python 2.7 in ANNOUNCE and py2exe.txt. Modified Paths: -------------- trunk/py2exe/ANNOUNCE trunk/py2exe/docs/py2exe.txt Modified: trunk/py2exe/ANNOUNCE =================================================================== --- trunk/py2exe/ANNOUNCE 2008-11-10 18:32:49 UTC (rev 678) +++ trunk/py2exe/ANNOUNCE 2008-11-16 06:07:44 UTC (rev 679) @@ -8,7 +8,7 @@ Changes in 0.6.9: - * Binaries for Python 2.6. + * Binaries for Python 2.6 and Python 2.7. * Fixed a modulefinder crash on certain relative imports. Modified: trunk/py2exe/docs/py2exe.txt =================================================================== --- trunk/py2exe/docs/py2exe.txt 2008-11-10 18:32:49 UTC (rev 678) +++ trunk/py2exe/docs/py2exe.txt 2008-11-16 06:07:44 UTC (rev 679) @@ -13,10 +13,16 @@ .. _py2exe-0.6.9.win32-py2.5.exe: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win32-py2.5.exe?download -.. _py2exe-0.6.9.win64-py2.5.amd64.msi: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.0.win64-py2.5.amd64.msi?download +.. _py2exe-0.6.9.win64-py2.5.amd64.msi: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win64-py2.5.amd64.msi?download .. _py2exe-0.6.9.win32-py2.6.exe: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win32-py2.6.exe?download +.. _py2exe-0.6.9.win64-py2.6.amd64.msi: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win64-py2.6.amd64.msi?download + +.. _py2exe-0.6.9.win32-py2.7.exe: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win32-py2.7.exe?download + +.. _py2exe-0.6.9.win64-py2.7.amd64.msi: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win64-py2.7.amd64.msi?download + .. _WIKI: http://www.py2exe.org/ .. _SourceForge: http://sourceforge.net/projects/py2exe/ @@ -63,7 +69,7 @@ **py2exe 0.6.9 released (2008/11/15)** -Binaries for Python 2.6. +Binaries for Python 2.6 and Python 2.7. Fixed a modulefinder crash on certain relative imports. @@ -413,8 +419,11 @@ Download and run the installer py2exe-0.6.9.win32-py2.3.exe_ (for Python 2.3), py2exe-0.6.9.win32-py2.4.exe_ (for Python 2.4), py2exe-0.6.9.win32-py2.5.exe_ (for Python 2.5), -py2exe-0.6.9.win64-py2.5.amd64.msi_ (for 64-bit Python 2.5), or -py2exe-0.6.9.win32-py2.6.exe_ (for Python 2.6). +py2exe-0.6.9.win64-py2.5.amd64.msi_ (for 64-bit Python 2.5), +py2exe-0.6.9.win32-py2.6.exe_ (for Python 2.6), +py2exe-0.6.9.win64-py2.6.amd64.msi_ (for 64-bit Python 2.6), +py2exe-0.6.9.win32-py2.7.exe_ (for Python 2.7), or +py2exe-0.6.9.win64-py2.7.amd64.msi_ (for 64-bit Python 2.7). This installs **py2exe** together with some samples, the samples are in the ``lib\site-packages\py2exe\samples`` subdirectory. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jr...@us...> - 2008-11-16 06:44:13
|
Revision: 680 http://py2exe.svn.sourceforge.net/py2exe/?rev=680&view=rev Author: jretz Date: 2008-11-16 06:44:11 +0000 (Sun, 16 Nov 2008) Log Message: ----------- Fix references to 64-bit installer filenames. Modified Paths: -------------- trunk/py2exe/ANNOUNCE trunk/py2exe/docs/py2exe.txt Modified: trunk/py2exe/ANNOUNCE =================================================================== --- trunk/py2exe/ANNOUNCE 2008-11-16 06:07:44 UTC (rev 679) +++ trunk/py2exe/ANNOUNCE 2008-11-16 06:44:11 UTC (rev 680) @@ -12,16 +12,16 @@ * Fixed a modulefinder crash on certain relative imports. - * Changed the py2exe\samples\singlefile\gui\test_wx.py sample to - use the wx package instead of the old wxPython package. + * Changed the py2exe\samples\singlefile\gui\test_wx.py sample to + use the wx package instead of the old wxPython package. - * Copy the manifest, if any, from the 'template' into the targets - to ensure embedded assembly references, as required for python 2.6 based - apps, are copied. + * Copy the manifest, if any, from the 'template' into the targets + to ensure embedded assembly references, as required for python 2.6 based + apps, are copied. - * Allow each target to specify Vista User Access Control flags. For - example, specifying 'uac_execution_info="requireAdministrator"' would - force elevation for the final executable. + * Allow each target to specify Vista User Access Control flags. For + example, specifying 'uac_execution_info="requireAdministrator"' would + force elevation for the final executable. Changes in 0.6.8: Modified: trunk/py2exe/docs/py2exe.txt =================================================================== --- trunk/py2exe/docs/py2exe.txt 2008-11-16 06:07:44 UTC (rev 679) +++ trunk/py2exe/docs/py2exe.txt 2008-11-16 06:44:11 UTC (rev 680) @@ -17,11 +17,11 @@ .. _py2exe-0.6.9.win32-py2.6.exe: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win32-py2.6.exe?download -.. _py2exe-0.6.9.win64-py2.6.amd64.msi: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win64-py2.6.amd64.msi?download +.. _py2exe-0.6.9.win64-py2.6.amd64.exe: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win64-py2.6.amd64.exe?download .. _py2exe-0.6.9.win32-py2.7.exe: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win32-py2.7.exe?download -.. _py2exe-0.6.9.win64-py2.7.amd64.msi: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win64-py2.7.amd64.msi?download +.. _py2exe-0.6.9.win64-py2.7.amd64.exe: http://prdownloads.sourceforge.net/py2exe/py2exe-0.6.9.win64-py2.7.amd64.exe?download .. _WIKI: http://www.py2exe.org/ @@ -421,9 +421,9 @@ Python 2.4), py2exe-0.6.9.win32-py2.5.exe_ (for Python 2.5), py2exe-0.6.9.win64-py2.5.amd64.msi_ (for 64-bit Python 2.5), py2exe-0.6.9.win32-py2.6.exe_ (for Python 2.6), -py2exe-0.6.9.win64-py2.6.amd64.msi_ (for 64-bit Python 2.6), +py2exe-0.6.9.win64-py2.6.amd64.exe_ (for 64-bit Python 2.6), py2exe-0.6.9.win32-py2.7.exe_ (for Python 2.7), or -py2exe-0.6.9.win64-py2.7.amd64.msi_ (for 64-bit Python 2.7). +py2exe-0.6.9.win64-py2.7.amd64.exe_ (for 64-bit Python 2.7). This installs **py2exe** together with some samples, the samples are in the ``lib\site-packages\py2exe\samples`` subdirectory. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mha...@us...> - 2008-12-14 23:44:55
|
Revision: 684 http://py2exe.svn.sourceforge.net/py2exe/?rev=684&view=rev Author: mhammond Date: 2008-12-14 23:44:53 +0000 (Sun, 14 Dec 2008) Log Message: ----------- Fix via the mailing list to fix strange icons being displayed on Vista. Modified Paths: -------------- trunk/py2exe/ChangeLog trunk/py2exe/source/py2exe_util.c Modified: trunk/py2exe/ChangeLog =================================================================== --- trunk/py2exe/ChangeLog 2008-11-16 07:23:46 UTC (rev 683) +++ trunk/py2exe/ChangeLog 2008-12-14 23:44:53 UTC (rev 684) @@ -1,3 +1,7 @@ +2008-12-15 Mark Hammond + + * Fix via the mailing list to fix strange icons being displayed on Vista. + 2008-11-06 Thomas Heller <th...@py...> * Fixed a modulefinder crash on certain relative imports. Modified: trunk/py2exe/source/py2exe_util.c =================================================================== --- trunk/py2exe/source/py2exe_util.c 2008-11-16 07:23:46 UTC (rev 683) +++ trunk/py2exe/source/py2exe_util.c 2008-12-14 23:44:53 UTC (rev 684) @@ -183,7 +183,7 @@ static PyObject* do_add_icon(Py_UNICODE *exename, Py_UNICODE *iconame, int icoid, BOOL bDelete) { - static rt_icon_id = 0; + static rt_icon_id = 1; /* from the .ico file */ ICONDIRHEADER *pidh; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mha...@us...> - 2009-04-10 01:55:06
|
Revision: 686 http://py2exe.svn.sourceforge.net/py2exe/?rev=686&view=rev Author: mhammond Date: 2009-04-10 01:55:05 +0000 (Fri, 10 Apr 2009) Log Message: ----------- Fix crash when a Python 2.5 built app was installed over a Python 2.4 built app. The app would crash as Python 2.5 loaded Python 2.4's zlib.pyd; zlib is builtin in Python 2.5 and later, so no 2.5 version of zlib.pyd exists. Modified Paths: -------------- trunk/py2exe/ChangeLog trunk/py2exe/setup.py trunk/py2exe/source/start.c Modified: trunk/py2exe/ChangeLog =================================================================== --- trunk/py2exe/ChangeLog 2009-04-10 01:48:01 UTC (rev 685) +++ trunk/py2exe/ChangeLog 2009-04-10 01:55:05 UTC (rev 686) @@ -1,3 +1,9 @@ +2008-04-10 Mark Hammond + + * If a Python 2.5 built app was installed over a Python 2.4 built app, + the app would crash as Python 2.5 loaded Python 2.4's zlib.pyd; zlib is + builtin in Python 2.5 and later, so no 2.5 version of zlib.pyd exists. + 2008-12-15 Mark Hammond * Fix via the mailing list to fix strange icons being displayed on Vista. Modified: trunk/py2exe/setup.py =================================================================== --- trunk/py2exe/setup.py 2009-04-10 01:48:01 UTC (rev 685) +++ trunk/py2exe/setup.py 2009-04-10 01:55:05 UTC (rev 686) @@ -336,6 +336,8 @@ else: macros = [("PYTHONDLL", '\\"PYTHON%d%d.DLL\\"' % sys.version_info[:2]), ("PYTHONCOM", '\\"pythoncom%d%d.dll\\"' % sys.version_info[:2])] +if 'zlib' in sys.builtin_module_names: + macros.append(("PYZLIB_BUILTIN", None)) ##macros.append(("AS_PY2EXE_BUILTIN", "1")) # for runtime linking python.dll in _memimporter.c depends = ["source/import-tab.c", "source/import-tab.h"] Modified: trunk/py2exe/source/start.c =================================================================== --- trunk/py2exe/source/start.c 2009-04-10 01:48:01 UTC (rev 685) +++ trunk/py2exe/source/start.c 2009-04-10 01:55:05 UTC (rev 686) @@ -439,7 +439,13 @@ } } + // If zlib is builtin to pythonxx.dll, we don't need to take any + // special action (and worse, if it so happens an old version of + // the app built with python 2.4 is installed, we might attempt to + // load that python24 pyd, causing death...) +#ifndef PYZLIB_BUILTIN _TryLoadZlib(hmod); +#endif return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2009-08-14 19:44:00
|
Revision: 687 http://py2exe.svn.sourceforge.net/py2exe/?rev=687&view=rev Author: theller Date: 2009-08-14 19:43:50 +0000 (Fri, 14 Aug 2009) Log Message: ----------- Fix a DeprecationWarning in Python2.6. Modified Paths: -------------- trunk/py2exe/ChangeLog trunk/py2exe/py2exe/build_exe.py Modified: trunk/py2exe/ChangeLog =================================================================== --- trunk/py2exe/ChangeLog 2009-04-10 01:55:05 UTC (rev 686) +++ trunk/py2exe/ChangeLog 2009-08-14 19:43:50 UTC (rev 687) @@ -1,3 +1,8 @@ +2009-08-14 Thomas Heller <th...@py...> + + * Fix 'DeprecationWarning: the sets module is deprecated' in Python 2.6, + when building an executable. + 2008-04-10 Mark Hammond * If a Python 2.5 built app was installed over a Python 2.4 built app, Modified: trunk/py2exe/py2exe/build_exe.py =================================================================== --- trunk/py2exe/py2exe/build_exe.py 2009-04-10 01:55:05 UTC (rev 686) +++ trunk/py2exe/py2exe/build_exe.py 2009-08-14 19:43:50 UTC (rev 687) @@ -13,7 +13,10 @@ import sys, os, imp, types, stat import marshal import zipfile -import sets +try: + set +except NameError: + from sets import Set as set import tempfile import struct import re @@ -660,7 +663,7 @@ # make sure all targets use the same directory, this is # also the directory where the pythonXX.dll must reside - paths = sets.Set() + paths = set() for target in dist.com_server + dist.service \ + dist.windows + dist.console + dist.isapi: paths.add(os.path.dirname(target.get_dest_base())) @@ -1032,7 +1035,7 @@ # so the loadpath must be extended by our python path. loadpath = loadpath + ';' + ';'.join(pypath) - templates = sets.Set() + templates = set() if self.distribution.console: templates.add(self.get_console_template()) if self.distribution.windows: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2010-04-26 07:22:55
|
Revision: 688 http://py2exe.svn.sourceforge.net/py2exe/?rev=688&view=rev Author: theller Date: 2010-04-26 07:22:49 +0000 (Mon, 26 Apr 2010) Log Message: ----------- Fix compiler warnings. Modified Paths: -------------- trunk/py2exe/setup.py trunk/py2exe/source/MemoryModule.c trunk/py2exe/source/py2exe_util.c Modified: trunk/py2exe/setup.py =================================================================== --- trunk/py2exe/setup.py 2009-08-14 19:43:50 UTC (rev 687) +++ trunk/py2exe/setup.py 2010-04-26 07:22:49 UTC (rev 688) @@ -332,10 +332,12 @@ if _is_debug_build(): macros = [("PYTHONDLL", '\\"PYTHON%d%d_d.DLL\\"' % sys.version_info[:2]), - ("PYTHONCOM", '\\"pythoncom%d%d_d.dll\\"' % sys.version_info[:2])] + ("PYTHONCOM", '\\"pythoncom%d%d_d.dll\\"' % sys.version_info[:2]), + ("_CRT_SECURE_NO_WARNINGS", '1')] else: macros = [("PYTHONDLL", '\\"PYTHON%d%d.DLL\\"' % sys.version_info[:2]), - ("PYTHONCOM", '\\"pythoncom%d%d.dll\\"' % sys.version_info[:2])] + ("PYTHONCOM", '\\"pythoncom%d%d.dll\\"' % sys.version_info[:2]), + ("_CRT_SECURE_NO_WARNINGS", '1')] if 'zlib' in sys.builtin_module_names: macros.append(("PYZLIB_BUILTIN", None)) Modified: trunk/py2exe/source/MemoryModule.c =================================================================== --- trunk/py2exe/source/MemoryModule.c 2009-08-14 19:43:50 UTC (rev 687) +++ trunk/py2exe/source/MemoryModule.c 2010-04-26 07:22:49 UTC (rev 688) @@ -102,7 +102,7 @@ MEMORYMODULE *p = loaded; while (p) { // If already loaded, only increment the reference count - if (0 == stricmp(lpModuleName, p->name)) { + if (0 == _stricmp(lpModuleName, p->name)) { return (HMODULE)p; } p = p->next; @@ -121,7 +121,7 @@ while (p) { // If already loaded, only increment the reference count - if (0 == stricmp(lpFileName, p->name)) { + if (0 == _stricmp(lpFileName, p->name)) { p->refcount++; return (HMODULE)p; } @@ -435,7 +435,7 @@ while (p) { // If already loaded, only increment the reference count - if (0 == stricmp(name, p->name)) { + if (0 == _stricmp(name, p->name)) { p->refcount++; return (HMODULE)p; } @@ -493,7 +493,7 @@ result->initialized = 0; result->next = result->prev = NULL; result->refcount = 1; - result->name = strdup(name); + result->name = _strdup(name); result->name_table = NULL; // XXX: is it correct to commit the complete memory region at once? @@ -570,12 +570,12 @@ int _compare(const struct NAME_TABLE *p1, const struct NAME_TABLE *p2) { - return stricmp(p1->name, p2->name); + return _stricmp(p1->name, p2->name); } int _find(const char **name, const struct NAME_TABLE *p) { - return stricmp(*name, p->name); + return _stricmp(*name, p->name); } struct NAME_TABLE *GetNameTable(PMEMORYMODULE module) Modified: trunk/py2exe/source/py2exe_util.c =================================================================== --- trunk/py2exe/source/py2exe_util.c 2009-08-14 19:43:50 UTC (rev 687) +++ trunk/py2exe/source/py2exe_util.c 2010-04-26 07:22:49 UTC (rev 688) @@ -430,8 +430,8 @@ BOOL __stdcall StatusRoutine(IMAGEHLP_STATUS_REASON reason, PSTR ImageName, PSTR DllName, - ULONG Va, - ULONG Parameter) + ULONG_PTR Va, + ULONG_PTR Parameter) { DWORD result; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mha...@us...> - 2012-02-04 07:21:53
|
Revision: 692 http://py2exe.svn.sourceforge.net/py2exe/?rev=692&view=rev Author: mhammond Date: 2012-02-04 07:21:46 +0000 (Sat, 04 Feb 2012) Log Message: ----------- some syntax modernizations on the road to py3k Modified Paths: -------------- trunk/py2exe/py2exe/boot_com_servers.py trunk/py2exe/py2exe/boot_ctypes_com_server.py trunk/py2exe/py2exe/boot_service.py trunk/py2exe/py2exe/build_exe.py trunk/py2exe/py2exe/resources/StringTables.py trunk/py2exe/py2exe/resources/VersionInfo.py trunk/py2exe/py2exe/samples/pywin32/com_typelib/pre_gen/wscript/wsh-typelib-stubs.py trunk/py2exe/sandbox/test/hello.py Modified: trunk/py2exe/py2exe/boot_com_servers.py =================================================================== --- trunk/py2exe/py2exe/boot_com_servers.py 2012-02-04 07:08:51 UTC (rev 691) +++ trunk/py2exe/py2exe/boot_com_servers.py 2012-02-04 07:21:46 UTC (rev 692) @@ -50,7 +50,7 @@ def get_classes(module): return [ob - for ob in module.__dict__.values() + for ob in module.__dict__.itervalues() if hasattr(ob, "_reg_progid_") ] Modified: trunk/py2exe/py2exe/boot_ctypes_com_server.py =================================================================== --- trunk/py2exe/py2exe/boot_ctypes_com_server.py 2012-02-04 07:08:51 UTC (rev 691) +++ trunk/py2exe/py2exe/boot_ctypes_com_server.py 2012-02-04 07:21:46 UTC (rev 692) @@ -52,7 +52,7 @@ def get_classes(module): return [ob - for ob in module.__dict__.values() + for ob in module.__dict__.itervalues() if hasattr(ob, "_reg_progid_") ] Modified: trunk/py2exe/py2exe/boot_service.py =================================================================== --- trunk/py2exe/py2exe/boot_service.py 2012-02-04 07:08:51 UTC (rev 691) +++ trunk/py2exe/py2exe/boot_service.py 2012-02-04 07:21:46 UTC (rev 692) @@ -20,12 +20,12 @@ # This makes it possible to have a dotted name work the # way you'd expect. mod = __import__(name, globals(), locals(), ['DUMMY']) - for ob in mod.__dict__.values(): + for ob in mod.__dict__.itervalues(): if hasattr(ob, "_svc_name_"): service_klasses.append(ob) if not service_klasses: - raise RuntimeError, "No service classes found" + raise RuntimeError("No service classes found") # Event source records come from servicemanager evtsrc_dll = os.path.abspath(servicemanager.__file__) @@ -79,12 +79,12 @@ try: opts.append((arg, args[1])) except IndexError: - raise GetoptError, "option '%s' requires an argument" % args[0] + raise GetoptError("option '%s' requires an argument" % args[0]) args = args[1:] elif arg in options: opts.append((arg, '')) else: - raise GetoptError, "invalid option '%s'" % args[0] + raise GetoptError("invalid option '%s'" % args[0]) args = args[1:] else: arguments.append(args[0]) Modified: trunk/py2exe/py2exe/build_exe.py =================================================================== --- trunk/py2exe/py2exe/build_exe.py 2012-02-04 07:08:51 UTC (rev 691) +++ trunk/py2exe/py2exe/build_exe.py 2012-02-04 07:21:46 UTC (rev 692) @@ -125,9 +125,9 @@ getattr(self, "icon_resources", []) for r_id, r_filename in resources: if type(r_id) != type(0): - raise DistutilsOptionError, "Resource ID must be an integer" + raise DistutilsOptionError("Resource ID must be an integer") if not os.path.isfile(r_filename): - raise DistutilsOptionError, "Resource filename '%s' does not exist" % r_filename + raise DistutilsOptionError("Resource filename '%s' does not exist" % r_filename) def FixupTargets(targets, default_attribute): if not targets: @@ -140,8 +140,8 @@ else: d = getattr(target_def, "__dict__", target_def) if not d.has_key(default_attribute): - raise DistutilsOptionError, \ - "This target class requires an attribute '%s'" % default_attribute + raise DistutilsOptionError( + "This target class requires an attribute '%s'" % default_attribute) target = Target(**d) target.validate() ret.append(target) @@ -214,18 +214,14 @@ self.ignores = fancy_split(self.ignores) self.bundle_files = int(self.bundle_files) if self.bundle_files < 1 or self.bundle_files > 3: - raise DistutilsOptionError, \ - "bundle-files must be 1, 2, or 3, not %s" % self.bundle_files + raise DistutilsOptionError("bundle-files must be 1, 2, or 3, not %s" % self.bundle_files) if is_win64 and self.bundle_files < 3: - raise DistutilsOptionError, \ - "bundle-files %d not yet supported on win64" % self.bundle_files + raise DistutilsOptionError("bundle-files %d not yet supported on win64" % self.bundle_files) if self.skip_archive: if self.compressed: - raise DistutilsOptionError, \ - "can't compress when skipping archive" + raise DistutilsOptionError("can't compress when skipping archive") if self.distribution.zipfile is None: - raise DistutilsOptionError, \ - "zipfile cannot be None when skipping archive" + raise DistutilsOptionError("zipfile cannot be None when skipping archive") # includes is stronger than excludes for m in self.includes: if m in self.excludes: @@ -291,8 +287,8 @@ try: result = orig_compile(source, filename, *args) except Exception, details: - raise DistutilsError, "compiling '%s' failed\n %s: %s" % \ - (filename, details.__class__.__name__, details) + raise DistutilsError("compiling '%s' failed\n %s: %s" % \ + (filename, details.__class__.__name__, details)) return result __builtin__.compile = my_compile @@ -674,14 +670,12 @@ paths.add(os.path.dirname(target.get_dest_base())) if len(paths) > 1: - raise DistutilsOptionError, \ - "all targets must use the same directory: %s" % \ - [p for p in paths] + raise DistutilsOptionError("all targets must use the same directory: %s" % \ + [p for p in paths]) if paths: exe_dir = paths.pop() # the only element if os.path.isabs(exe_dir): - raise DistutilsOptionError, \ - "exe directory must be relative: %s" % exe_dir + raise DistutilsOptionError("exe directory must be relative: %s" % exe_dir) self.exe_dir = os.path.join(self.dist_dir, exe_dir) self.mkpath(self.exe_dir) else: @@ -711,11 +705,11 @@ # import the script with every side effect :) __import__(module_name) mod = sys.modules[module_name] - for name, klass in mod.__dict__.items(): + for name, klass in mod.__dict__.iteritems(): if hasattr(klass, "_svc_name_"): break else: - raise RuntimeError, "No services in module" + raise RuntimeError("No services in module") deps = () if hasattr(klass, "_svc_deps_"): deps = klass._svc_deps_ @@ -728,7 +722,7 @@ cmdline_style = getattr(target, "cmdline_style", "py2exe") if cmdline_style not in ["py2exe", "pywin32", "custom"]: - raise RuntimeError, "cmdline_handler invalid" + raise RuntimeError("cmdline_handler invalid") vars = {"service_module_names" : target.modules, "cmdline_style": cmdline_style, @@ -838,7 +832,7 @@ code_objects.append( compile("import zipextimporter; zipextimporter.install()", "<install zipextimporter>", "exec")) - for var_name, var_val in vars.items(): + for var_name, var_val in vars.iteritems(): code_objects.append( compile("%s=%r\n" % (var_name, var_val), var_name, "exec") ) @@ -1093,14 +1087,14 @@ } def parse_mf_results(self, mf): - for name, imports in self.get_hidden_imports().items(): - if name in mf.modules.keys(): + for name, imports in self.get_hidden_imports().iteritems(): + if name in mf.modules: for mod in imports: mf.import_hook(mod) tcl_src_dir = tcl_dst_dir = None if "Tkinter" in mf.modules.keys(): - import Tkinter + import tkinter import _tkinter tk = _tkinter.create() tcl_dir = tk.call("info", "library") @@ -1119,7 +1113,7 @@ extensions = [] builtins = [] - for item in mf.modules.values(): + for item in mf.modules.itervalues(): # There may be __main__ modules (from mf.run_script), but # we don't need them in the zipfile we build. if item.__name__ == "__main__": @@ -1161,19 +1155,19 @@ if sys.platform == "win32": # pythoncom and pywintypes are imported via LoadLibrary calls, # help py2exe to include the dlls: - if "pythoncom" in modules.keys(): + if "pythoncom" in modules: import pythoncom dlls.add(pythoncom.__file__) - if "pywintypes" in modules.keys(): + if "pywintypes" in modules: import pywintypes dlls.add(pywintypes.__file__) self.copy_w9xpopen(modules, dlls) else: - raise DistutilsError, "Platform %s not yet implemented" % sys.platform + raise DistutilsError("Platform %s not yet implemented" % sys.platform) def copy_w9xpopen(self, modules, dlls): # Using popen requires (on Win9X) the w9xpopen.exe helper executable. - if "os" in modules.keys() or "popen2" in modules.keys(): + if "os" in modules or "popen2" in modules: if is_debug_build: fname = os.path.join(os.path.dirname(sys.executable), "w9xpopen_d.exe") else: @@ -1274,7 +1268,7 @@ "w9xpopen%s.exe" % (is_debug_build and "_d" or ""), "msvcr71%s.dll" % (is_debug_build and "d" or "")] else: - raise DistutilsError, "Platform %s not yet implemented" % sys.platform + raise DistutilsError("Platform %s not yet implemented" % sys.platform) def find_needed_modules(self, mf, files, modules): # feed Modulefinder with everything, and return it. @@ -1414,10 +1408,10 @@ del self._dict[fname.upper()] def __contains__(self, fname): - return fname.upper() in self._dict.keys() + return fname.upper() in self._dict def __getitem__(self, index): - key = self._dict.keys()[index] + key = list(self._dict.keys())[index] return self._dict[key] def __len__(self): @@ -1443,7 +1437,7 @@ dependents.add(image) abs_image = os.path.abspath(image) loadpath = os.path.dirname(abs_image) + ';' + path - for result in py2exe_util.depends(image, loadpath).items(): + for result in py2exe_util.depends(image, loadpath).iteritems(): dll, uses_import_module = result if os.path.basename(dll).lower() not in excluded_dlls: if isSystemDLL(dll): @@ -1503,12 +1497,12 @@ import struct file = open(pathname, "rb") if file.read(2) != "MZ": - raise Exception, "Seems not to be an exe-file" + raise Exception("Seems not to be an exe-file") file.seek(0x3C) pe_ofs = struct.unpack("i", file.read(4))[0] file.seek(pe_ofs) if file.read(4) != "PE\000\000": - raise Exception, ("Seems not to be an exe-file", pathname) + raise Exception("Seems not to be an exe-file", pathname) file.read(20 + 28) # COFF File Header, offset of ImageBase in Optional Header imagebase = struct.unpack("I", file.read(4))[0] return not (imagebase < 0x70000000) @@ -1538,14 +1532,14 @@ for f in py_files: script.write("Module(%s, %s, %s),\n" % \ - (`f.__name__`, `f.__file__`, `f.__path__`)) + (repr(f.__name__), repr(f.__file__), repr(f.__path__))) script.write("]\n") script.write(""" byte_compile(files, optimize=%s, force=%s, target_dir=%s, verbose=%s, dry_run=0, direct=1) -""" % (`optimize`, `force`, `target_dir`, `verbose`)) +""" % (repr(optimize), repr(force), repr(target_dir), repr(verbose))) script.close() @@ -1659,7 +1653,7 @@ makepy.GenerateFromTypeLibSpec(tlb_info, bForDemand = False) # Now get the module, and build all sub-modules. mod = gencache.GetModuleForTypelib(*tlb_info) - for clsid, name in mod.CLSIDToPackageMap.items(): + for clsid, name in mod.CLSIDToPackageMap.iteritems(): try: gencache.GetModuleForCLSID(clsid) num += 1 @@ -1708,7 +1702,7 @@ cmd[0](cmd[1]) # remove dir from cache if it's already there abspath = os.path.abspath(cmd[1]) - if _path_created.has_key(abspath): + if abspath in _path_created: del _path_created[abspath] except (IOError, OSError), exc: if verbose: Modified: trunk/py2exe/py2exe/resources/StringTables.py =================================================================== --- trunk/py2exe/py2exe/resources/StringTables.py 2012-02-04 07:08:51 UTC (rev 691) +++ trunk/py2exe/py2exe/resources/StringTables.py 2012-02-04 07:21:46 UTC (rev 692) @@ -47,7 +47,7 @@ try: import pywintypes except ImportError: - raise ImportError, "Could not import StringTables, no unicode available" + raise ImportError("Could not import StringTables, no unicode available") if _use_unicode: @@ -90,7 +90,7 @@ def binary(self): import struct sections = [] - for key, sect in self.sections().items(): + for key, sect in self.sections().iteritems(): data = "" for i in range(16): ustr = w32_uc(sect.get(i, "")) Modified: trunk/py2exe/py2exe/resources/VersionInfo.py =================================================================== --- trunk/py2exe/py2exe/resources/VersionInfo.py 2012-02-04 07:08:51 UTC (rev 691) +++ trunk/py2exe/py2exe/resources/VersionInfo.py 2012-02-04 07:21:46 UTC (rev 692) @@ -92,7 +92,7 @@ self.dwFileVersionMS = int(fields[0]) * 65536 + int(fields[1]) self.dwFileVersionLS = int(fields[2]) * 65536 + int(fields[3]) except ValueError: - raise VersionError, "could not parse version number '%s'" % version + raise VersionError("could not parse version number '%s'" % version) def __str__(self): return struct.pack(self.fmt, @@ -145,7 +145,8 @@ wType = 1 items = () - def __init__(self, (name, value)): + def __init__(self, name_value): + (name, value) = name_value self.name = name if value: self.value = value + '\000' # strings must be zero terminated Modified: trunk/py2exe/py2exe/samples/pywin32/com_typelib/pre_gen/wscript/wsh-typelib-stubs.py =================================================================== --- trunk/py2exe/py2exe/samples/pywin32/com_typelib/pre_gen/wscript/wsh-typelib-stubs.py 2012-02-04 07:08:51 UTC (rev 691) +++ trunk/py2exe/py2exe/samples/pywin32/com_typelib/pre_gen/wscript/wsh-typelib-stubs.py 2012-02-04 07:21:46 UTC (rev 692) @@ -157,7 +157,7 @@ return win32com.client.util.WrapEnum(self._oleobj_.InvokeTypes(-4,LCID,2,(13, 10),()),'{C7C3F5A0-88A3-11D0-ABCB-00A0C90FFFC0}') def __getitem__(self, index): "Allow this class to be accessed as a collection" - if not self.__dict__.has_key('_enum_'): + if '_enum' not self.__dict__: self.__dict__['_enum_'] = self._NewEnum() return self._enum_.__getitem__(index) #This class has Count() property - allow len(ob) to provide this @@ -270,7 +270,7 @@ return win32com.client.util.WrapEnum(self._oleobj_.InvokeTypes(-4,LCID,2,(13, 10),()),'{C7C3F5A4-88A3-11D0-ABCB-00A0C90FFFC0}') def __getitem__(self, index): "Allow this class to be accessed as a collection" - if not self.__dict__.has_key('_enum_'): + if '_enum' not in self.__dict__: self.__dict__['_enum_'] = self._NewEnum() return self._enum_.__getitem__(index) #This class has Count() property - allow len(ob) to provide this @@ -693,7 +693,7 @@ return win32com.client.util.WrapEnum(self._oleobj_.InvokeTypes(-4,LCID,2,(13, 10),()),'{C7C3F5A2-88A3-11D0-ABCB-00A0C90FFFC0}') def __getitem__(self, index): "Allow this class to be accessed as a collection" - if not self.__dict__.has_key('_enum_'): + if '_enum' not self.__dict__: self.__dict__['_enum_'] = self._NewEnum() return self._enum_.__getitem__(index) #This class has Count() property - allow len(ob) to provide this @@ -792,7 +792,7 @@ return win32com.client.util.WrapEnum(self._oleobj_.InvokeTypes(-4,LCID,1,(13, 10),()),None) def __getitem__(self, index): "Allow this class to be accessed as a collection" - if not self.__dict__.has_key('_enum_'): + if '_enum_' not in self.__dict__: self.__dict__['_enum_'] = self._NewEnum() return self._enum_.__getitem__(index) #This class has Count() method - allow len(ob) to provide this @@ -856,7 +856,7 @@ return win32com.client.util.WrapEnum(self._oleobj_.InvokeTypes(-4,LCID,1,(13, 10),()),None) def __getitem__(self, index): "Allow this class to be accessed as a collection" - if not self.__dict__.has_key('_enum_'): + if '_enum_' not in self.__dict__: self.__dict__['_enum_'] = self._NewEnum() return self._enum_.__getitem__(index) #This class has Count() method - allow len(ob) to provide this Modified: trunk/py2exe/sandbox/test/hello.py =================================================================== --- trunk/py2exe/sandbox/test/hello.py 2012-02-04 07:08:51 UTC (rev 691) +++ trunk/py2exe/sandbox/test/hello.py 2012-02-04 07:21:46 UTC (rev 692) @@ -1,4 +1,5 @@ from __future__ import division +# -*- coding: latin-1 -*- import sys This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2013-05-24 19:59:46
|
Revision: 723 http://py2exe.svn.sourceforge.net/py2exe/?rev=723&view=rev Author: theller Date: 2013-05-24 19:59:36 +0000 (Fri, 24 May 2013) Log Message: ----------- Add a fix that my college Oliver Freyd implemented: properly implemented the activation context handling like it works in the python dll itself: We store the actctx, and wrap calls to MemoryLoadLibrary with _My_ActivateActCtx() and _My_DeactivateActCtx(). Modified Paths: -------------- trunk/py2exe/setup.py trunk/py2exe/source/Python-dynload.c trunk/py2exe/source/_memimporter.c trunk/py2exe/source/run_ctypes_dll.c Added Paths: ----------- trunk/py2exe/source/actctx.c Modified: trunk/py2exe/setup.py =================================================================== --- trunk/py2exe/setup.py 2013-02-04 08:00:26 UTC (rev 722) +++ trunk/py2exe/setup.py 2013-05-24 19:59:36 UTC (rev 723) @@ -376,7 +376,8 @@ _memimporter = Extension("_memimporter", ["source/MemoryModule.c", - "source/_memimporter_module.c"], + "source/_memimporter_module.c", + "source/actctx.c"], depends=depends + ["source/_memimporter.c"], define_macros=macros, ) @@ -386,6 +387,7 @@ "source/Python-dynload.c", "source/MemoryModule.c", "source/_memimporter.c", + "source/actctx.c", ], depends=depends, define_macros=macros, @@ -396,6 +398,7 @@ "source/Python-dynload.c", "source/MemoryModule.c", "source/_memimporter.c", + "source/actctx.c", ], libraries=["user32"], depends=depends, @@ -407,6 +410,7 @@ "source/Python-dynload.c", "source/MemoryModule.c", "source/_memimporter.c", + "source/actctx.c", ], libraries=["user32"], export_symbols=["DllCanUnloadNow,PRIVATE", @@ -424,6 +428,7 @@ "source/Python-dynload.c", "source/MemoryModule.c", "source/_memimporter.c", + "source/actctx.c", ], libraries=["user32"], export_symbols=["DllCanUnloadNow,PRIVATE", @@ -441,6 +446,7 @@ "source/Python-dynload.c", "source/MemoryModule.c", "source/_memimporter.c", + "source/actctx.c", "source/icon.rc"], libraries=["user32", "advapi32"], export_symbols=["HttpExtensionProc", Modified: trunk/py2exe/source/Python-dynload.c =================================================================== --- trunk/py2exe/source/Python-dynload.c 2013-02-04 08:00:26 UTC (rev 722) +++ trunk/py2exe/source/Python-dynload.c 2013-05-24 19:59:36 UTC (rev 723) @@ -1,6 +1,7 @@ /* **************** Python-dynload.c **************** */ #include "Python-dynload.h" #include "MemoryModule.h" +#include "actctx.h" #include <stdio.h> struct IMPORT imports[] = { @@ -64,11 +65,13 @@ int i; struct IMPORT *p = imports; HMODULE hmod; - + ULONG_PTR cookie = 0; if (!bytes) return _load_python_FromFile(dllname); - + + cookie = _My_ActivateActCtx();//try some windows manifest magic... hmod = MemoryLoadLibrary(dllname, bytes); + _My_DeactivateActCtx(cookie); if (hmod == NULL) { return 0; } Modified: trunk/py2exe/source/_memimporter.c =================================================================== --- trunk/py2exe/source/_memimporter.c 2013-02-04 08:00:26 UTC (rev 722) +++ trunk/py2exe/source/_memimporter.c 2013-05-24 19:59:36 UTC (rev 723) @@ -16,6 +16,7 @@ "Importer which can load extension modules from memory"; #include "MemoryModule.h" +#include "actctx.h" static void *memdup(void *ptr, Py_ssize_t size) { @@ -77,13 +78,16 @@ FARPROC do_init; char *oldcontext; - + ULONG_PTR cookie = 0; /* code, initfuncname, fqmodulename, path */ if (!PyArg_ParseTuple(args, "s#sss:import_module", &data, &size, &initfuncname, &modname, &pathname)) return NULL; + + cookie = _My_ActivateActCtx();//try some windows manifest magic... hmem = MemoryLoadLibrary(pathname, data); + _My_DeactivateActCtx(cookie); if (!hmem) { PyErr_Format(PyExc_ImportError, "MemoryLoadLibrary failed loading %s", pathname); Added: trunk/py2exe/source/actctx.c =================================================================== --- trunk/py2exe/source/actctx.c (rev 0) +++ trunk/py2exe/source/actctx.c 2013-05-24 19:59:36 UTC (rev 723) @@ -0,0 +1,40 @@ +#include "actctx.h" + +HANDLE PyWin_DLLhActivationContext=NULL; +PFN_GETCURRENTACTCTX pfnGetCurrentActCtx=NULL; +PFN_ACTIVATEACTCTX pfnActivateActCtx=NULL; +PFN_DEACTIVATEACTCTX pfnDeactivateActCtx=NULL; +PFN_ADDREFACTCTX pfnAddRefActCtx=NULL; +PFN_RELEASEACTCTX pfnReleaseActCtx=NULL; + +void _MyLoadActCtxPointers() +{ + HINSTANCE hKernel32 = GetModuleHandleW(L"kernel32.dll"); + if (hKernel32) + pfnGetCurrentActCtx = (PFN_GETCURRENTACTCTX) GetProcAddress(hKernel32, "GetCurrentActCtx"); + // If we can't load GetCurrentActCtx (ie, pre XP) , don't bother with the rest. + if (pfnGetCurrentActCtx) { + pfnActivateActCtx = (PFN_ACTIVATEACTCTX) GetProcAddress(hKernel32, "ActivateActCtx"); + pfnDeactivateActCtx = (PFN_DEACTIVATEACTCTX) GetProcAddress(hKernel32, "DeactivateActCtx"); + pfnAddRefActCtx = (PFN_ADDREFACTCTX) GetProcAddress(hKernel32, "AddRefActCtx"); + pfnReleaseActCtx = (PFN_RELEASEACTCTX) GetProcAddress(hKernel32, "ReleaseActCtx"); + } +} + +ULONG_PTR _My_ActivateActCtx() +{ + ULONG_PTR ret = 0; + if (PyWin_DLLhActivationContext && pfnActivateActCtx) + if (!(*pfnActivateActCtx)(PyWin_DLLhActivationContext, &ret)) { + OutputDebugString("py2exe failed to activate the activation context before loading a DLL\n"); + ret = 0; // no promise the failing function didn't change it! + } + return ret; +} + +void _My_DeactivateActCtx(ULONG_PTR cookie) +{ + if (cookie && pfnDeactivateActCtx) + if (!(*pfnDeactivateActCtx)(0, cookie)) + OutputDebugString("py2exe failed to de-activate the activation context\n"); +} Modified: trunk/py2exe/source/run_ctypes_dll.c =================================================================== --- trunk/py2exe/source/run_ctypes_dll.c 2013-02-04 08:00:26 UTC (rev 722) +++ trunk/py2exe/source/run_ctypes_dll.c 2013-05-24 19:59:36 UTC (rev 723) @@ -29,6 +29,7 @@ #include <assert.h> #include "Python-dynload.h" #include "MemoryModule.h" +#include "actctx.h" // Function pointers we load from _ctypes.pyd typedef int (__stdcall *__PROC__DllCanUnloadNow) (void); @@ -39,6 +40,9 @@ __PROC__DllCanUnloadNow Pyc_DllCanUnloadNow = NULL; __PROC__DllGetClassObject Pyc_DllGetClassObject = NULL; +extern BOOL _LoadPythonDLL(HMODULE hmod); +extern BOOL _LocateScript(HMODULE hmod); + extern void init_memimporter(void); void SystemError(int error, char *msg) @@ -81,11 +85,13 @@ // shouldn't do this twice assert(g_ctypes == NULL); + #ifdef _DEBUG strcpy(dll_path, "_ctypes_d.pyd"); #else strcpy(dll_path, "_ctypes.pyd"); #endif + g_ctypes = MyGetModuleHandle(dll_path); /* if (g_ctypes == NULL) { @@ -113,9 +119,11 @@ // give up in disgust return -1; } - + Pyc_DllCanUnloadNow = (__PROC__DllCanUnloadNow)MyGetProcAddress(g_ctypes, "DllCanUnloadNow"); Pyc_DllGetClassObject = (__PROC__DllGetClassObject)MyGetProcAddress(g_ctypes, "DllGetClassObject"); + assert(Pyc_DllGetClassObject); + return 0; } @@ -132,6 +140,17 @@ call in. */ PyGILState_STATE restore_state = PyGILState_UNLOCKED; + if (!Py_IsInitialized) { + // Python function pointers are yet to be loaded + // - force that now. See above for why we *must* + // know about the initialized state of Python so + // we can setup the thread-state correctly + // before calling init_with_instance(); This is + // wasteful, but fixing it would involve a + // restructure of init_with_instance() + _LocateScript(gInstance); + _LoadPythonDLL(gInstance); + } if (Py_IsInitialized && Py_IsInitialized()) { restore_state = PyGILState_Ensure(); } @@ -166,10 +185,17 @@ if ( dwReason == DLL_PROCESS_ATTACH) { gInstance = hInstance; InitializeCriticalSection(&csInit); + _MyLoadActCtxPointers(); + if (pfnGetCurrentActCtx && pfnAddRefActCtx) + if ((*pfnGetCurrentActCtx)(&PyWin_DLLhActivationContext)) + if (!(*pfnAddRefActCtx)(PyWin_DLLhActivationContext)) + OutputDebugString("Python failed to load the default activation context\n"); } else if ( dwReason == DLL_PROCESS_DETACH ) { gInstance = 0; DeleteCriticalSection(&csInit); + if (pfnReleaseActCtx) + (*pfnReleaseActCtx)(PyWin_DLLhActivationContext); // not much else safe to do here } return TRUE; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2013-06-05 18:42:16
|
Revision: 726 http://sourceforge.net/p/py2exe/svn/726 Author: theller Date: 2013-06-05 18:42:13 +0000 (Wed, 05 Jun 2013) Log Message: ----------- Work in progress: Using the latest MemoryModule from Joachim Bauch which works on 64-bit builds. Still missing: Using binary search in MemoryGetProcAddress. Modified Paths: -------------- trunk/py2exe/py2exe/build_exe.py trunk/py2exe/setup.py trunk/py2exe/source/MemoryModule.c trunk/py2exe/source/MemoryModule.h trunk/py2exe/source/Python-dynload.c trunk/py2exe/source/_memimporter.c trunk/py2exe/source/run_ctypes_dll.c trunk/py2exe/source/run_dll.c trunk/py2exe/source/start.c trunk/py2exe/zipextimporter.py Added Paths: ----------- trunk/py2exe/source/MyLoadLibrary.c trunk/py2exe/source/MyLoadLibrary.h trunk/py2exe/source/actctx.h Removed Paths: ------------- trunk/py2exe/source/_memimporter_module.c Modified: trunk/py2exe/py2exe/build_exe.py =================================================================== --- trunk/py2exe/py2exe/build_exe.py 2013-05-31 18:50:41 UTC (rev 725) +++ trunk/py2exe/py2exe/build_exe.py 2013-06-05 18:42:13 UTC (rev 726) @@ -215,8 +215,6 @@ self.bundle_files = int(self.bundle_files) if self.bundle_files < 1 or self.bundle_files > 3: raise DistutilsOptionError("bundle-files must be 1, 2, or 3, not %s" % self.bundle_files) - if is_win64 and self.bundle_files < 3: - raise DistutilsOptionError("bundle-files %d not yet supported on win64" % self.bundle_files) if self.skip_archive: if self.compressed: raise DistutilsOptionError("can't compress when skipping archive") @@ -1094,7 +1092,7 @@ tcl_src_dir = tcl_dst_dir = None if "Tkinter" in mf.modules.keys(): - import tkinter + import Tkinter import _tkinter tk = _tkinter.create() tcl_dir = tk.call("info", "library") Modified: trunk/py2exe/setup.py =================================================================== --- trunk/py2exe/setup.py 2013-05-31 18:50:41 UTC (rev 725) +++ trunk/py2exe/setup.py 2013-06-05 18:42:13 UTC (rev 726) @@ -376,16 +376,18 @@ _memimporter = Extension("_memimporter", ["source/MemoryModule.c", - "source/_memimporter_module.c", + "source/MyLoadLibrary.c", + "source/_memimporter.c", "source/actctx.c"], - depends=depends + ["source/_memimporter.c"], - define_macros=macros, + depends=depends, + define_macros=macros + [("STANDALONE", "1")], ) run = Interpreter("py2exe.run", ["source/run.c", "source/start.c", "source/icon.rc", "source/Python-dynload.c", "source/MemoryModule.c", + "source/MyLoadLibrary.c", "source/_memimporter.c", "source/actctx.c", ], @@ -397,6 +399,7 @@ ["source/run_w.c", "source/start.c", "source/icon.rc", "source/Python-dynload.c", "source/MemoryModule.c", + "source/MyLoadLibrary.c", "source/_memimporter.c", "source/actctx.c", ], @@ -409,6 +412,7 @@ ["source/run_dll.c", "source/start.c", "source/icon.rc", "source/Python-dynload.c", "source/MemoryModule.c", + "source/MyLoadLibrary.c", "source/_memimporter.c", "source/actctx.c", ], @@ -427,6 +431,7 @@ ["source/run_ctypes_dll.c", "source/start.c", "source/icon.rc", "source/Python-dynload.c", "source/MemoryModule.c", + "source/MyLoadLibrary.c", "source/_memimporter.c", "source/actctx.c", ], @@ -445,6 +450,7 @@ ["source/run_isapi.c", "source/start.c", "source/Python-dynload.c", "source/MemoryModule.c", + "source/MyLoadLibrary.c", "source/_memimporter.c", "source/actctx.c", "source/icon.rc"], Modified: trunk/py2exe/source/MemoryModule.c =================================================================== --- trunk/py2exe/source/MemoryModule.c 2013-05-31 18:50:41 UTC (rev 725) +++ trunk/py2exe/source/MemoryModule.c 2013-06-05 18:42:13 UTC (rev 726) @@ -1,12 +1,12 @@ /* * Memory DLL loading code - * Version 0.0.2 with additions from Thomas Heller + * Version 0.0.3 * - * Copyright (c) 2004-2005 by Joachim Bauch / ma...@jo... + * Copyright (c) 2004-2013 by Joachim Bauch / ma...@jo... * http://www.joachim-bauch.de * * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with + * 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * @@ -19,671 +19,715 @@ * * The Initial Developer of the Original Code is Joachim Bauch. * - * Portions created by Joachim Bauch are Copyright (C) 2004-2005 + * Portions created by Joachim Bauch are Copyright (C) 2004-2013 * Joachim Bauch. All Rights Reserved. * - * Portions Copyright (C) 2005 Thomas Heller. - * */ +#ifndef __GNUC__ // disable warnings about pointer <-> DWORD conversions #pragma warning( disable : 4311 4312 ) +#endif -#include <Windows.h> +#ifdef _WIN64 +#define POINTER_TYPE ULONGLONG +#else +#define POINTER_TYPE DWORD +#endif + +#include <windows.h> #include <winnt.h> -#if DEBUG_OUTPUT +#include <tchar.h> +#ifdef DEBUG_OUTPUT #include <stdio.h> #endif #ifndef IMAGE_SIZEOF_BASE_RELOCATION // Vista SDKs no longer define IMAGE_SIZEOF_BASE_RELOCATION!? -# define IMAGE_SIZEOF_BASE_RELOCATION (sizeof(IMAGE_BASE_RELOCATION)) +#define IMAGE_SIZEOF_BASE_RELOCATION (sizeof(IMAGE_BASE_RELOCATION)) #endif + #include "MemoryModule.h" -/* - XXX We need to protect at least walking the 'loaded' linked list with a lock! -*/ - -/******************************************************************/ -FINDPROC findproc; -void *findproc_data; - -struct NAME_TABLE { - char *name; - DWORD ordinal; -}; - -typedef struct tagMEMORYMODULE { - PIMAGE_NT_HEADERS headers; - unsigned char *codeBase; - HMODULE *modules; - int numModules; - int initialized; - - struct NAME_TABLE *name_table; - - char *name; - int refcount; - struct tagMEMORYMODULE *next, *prev; +typedef struct { + PIMAGE_NT_HEADERS headers; + unsigned char *codeBase; + HCUSTOMMODULE *modules; + int numModules; + int initialized; + CustomLoadLibraryFunc loadLibrary; + CustomGetProcAddressFunc getProcAddress; + CustomFreeLibraryFunc freeLibrary; + void *userdata; } MEMORYMODULE, *PMEMORYMODULE; typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved); #define GET_HEADER_DICTIONARY(module, idx) &(module)->headers->OptionalHeader.DataDirectory[idx] -MEMORYMODULE *loaded; /* linked list of loaded memory modules */ - -/* private - insert a loaded library in a linked list */ -static void _Register(char *name, MEMORYMODULE *module) -{ - module->next = loaded; - if (loaded) - loaded->prev = module; - module->prev = NULL; - loaded = module; -} - -/* private - remove a loaded library from a linked list */ -static void _Unregister(MEMORYMODULE *module) -{ - free(module->name); - if (module->prev) - module->prev->next = module->next; - if (module->next) - module->next->prev = module->prev; - if (module == loaded) - loaded = module->next; -} - -/* public - replacement for GetModuleHandle() */ -HMODULE MyGetModuleHandle(LPCTSTR lpModuleName) -{ - MEMORYMODULE *p = loaded; - while (p) { - // If already loaded, only increment the reference count - if (0 == _stricmp(lpModuleName, p->name)) { - return (HMODULE)p; - } - p = p->next; - } - return GetModuleHandle(lpModuleName); -} - -/* public - replacement for LoadLibrary, but searches FIRST for memory - libraries, then for normal libraries. So, it will load libraries AS memory - module if they are found by findproc(). -*/ -HMODULE MyLoadLibrary(char *lpFileName) -{ - MEMORYMODULE *p = loaded; - HMODULE hMod; - - while (p) { - // If already loaded, only increment the reference count - if (0 == _stricmp(lpFileName, p->name)) { - p->refcount++; - return (HMODULE)p; - } - p = p->next; - } - if (findproc) { - void *pdata = findproc(lpFileName, findproc_data); - if (pdata) { - hMod = MemoryLoadLibrary(lpFileName, pdata); - free(p); - return hMod; - } - } - hMod = LoadLibrary(lpFileName); - return hMod; -} - -/* public - replacement for GetProcAddress() */ -FARPROC MyGetProcAddress(HMODULE hModule, LPCSTR lpProcName) -{ - MEMORYMODULE *p = loaded; - while (p) { - if ((HMODULE)p == hModule) - return MemoryGetProcAddress(p, lpProcName); - p = p->next; - } - return GetProcAddress(hModule, lpProcName); -} - -/* public - replacement for FreeLibrary() */ -BOOL MyFreeLibrary(HMODULE hModule) -{ - MEMORYMODULE *p = loaded; - while (p) { - if ((HMODULE)p == hModule) { - if (--p->refcount == 0) { - _Unregister(p); - MemoryFreeLibrary(p); - } - return TRUE; - } - p = p->next; - } - return FreeLibrary(hModule); -} - -#if DEBUG_OUTPUT +#ifdef DEBUG_OUTPUT static void OutputLastError(const char *msg) { - LPVOID tmp; - char *tmpmsg; - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&tmp, 0, NULL); - tmpmsg = (char *)LocalAlloc(LPTR, strlen(msg) + strlen(tmp) + 3); - sprintf(tmpmsg, "%s: %s", msg, tmp); - OutputDebugString(tmpmsg); - LocalFree(tmpmsg); - LocalFree(tmp); + LPVOID tmp; + char *tmpmsg; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&tmp, 0, NULL); + tmpmsg = (char *)LocalAlloc(LPTR, strlen(msg) + strlen(tmp) + 3); + sprintf(tmpmsg, "%s: %s", msg, tmp); + OutputDebugString(tmpmsg); + LocalFree(tmpmsg); + LocalFree(tmp); } #endif -/* -static int dprintf(char *fmt, ...) -{ - char Buffer[4096]; - va_list marker; - int result; - - va_start(marker, fmt); - result = vsprintf(Buffer, fmt, marker); - OutputDebugString(Buffer); - return result; -} -*/ - static void CopySections(const unsigned char *data, PIMAGE_NT_HEADERS old_headers, PMEMORYMODULE module) { - int i, size; - unsigned char *codeBase = module->codeBase; - unsigned char *dest; - PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers); - for (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++) - { - if (section->SizeOfRawData == 0) - { - // section doesn't contain data in the dll itself, but may define - // uninitialized data - size = old_headers->OptionalHeader.SectionAlignment; - if (size > 0) - { - dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress, - size, - MEM_COMMIT, - PAGE_READWRITE); + int i, size; + unsigned char *codeBase = module->codeBase; + unsigned char *dest; + PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers); + for (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++) { + if (section->SizeOfRawData == 0) { + // section doesn't contain data in the dll itself, but may define + // uninitialized data + size = old_headers->OptionalHeader.SectionAlignment; + if (size > 0) { + dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress, + size, + MEM_COMMIT, + PAGE_READWRITE); - section->Misc.PhysicalAddress = (DWORD)dest; - memset(dest, 0, size); - } + section->Misc.PhysicalAddress = (DWORD) (POINTER_TYPE) dest; + memset(dest, 0, size); + } - // section is empty - continue; - } + // section is empty + continue; + } - // commit memory block and copy data from dll - dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress, - section->SizeOfRawData, - MEM_COMMIT, - PAGE_READWRITE); - memcpy(dest, data + section->PointerToRawData, section->SizeOfRawData); - section->Misc.PhysicalAddress = (DWORD)dest; - } + // commit memory block and copy data from dll + dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress, + section->SizeOfRawData, + MEM_COMMIT, + PAGE_READWRITE); + memcpy(dest, data + section->PointerToRawData, section->SizeOfRawData); + section->Misc.PhysicalAddress = (DWORD) (POINTER_TYPE) dest; + } } // Protection flags for memory pages (Executable, Readable, Writeable) static int ProtectionFlags[2][2][2] = { - { - // not executable - {PAGE_NOACCESS, PAGE_WRITECOPY}, - {PAGE_READONLY, PAGE_READWRITE}, - }, { - // executable - {PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY}, - {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE}, - }, + { + // not executable + {PAGE_NOACCESS, PAGE_WRITECOPY}, + {PAGE_READONLY, PAGE_READWRITE}, + }, { + // executable + {PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY}, + {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE}, + }, }; static void FinalizeSections(PMEMORYMODULE module) { - int i; - PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers); - - // loop through all sections and change access flags - for (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++) - { - DWORD protect, oldProtect, size; - int executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0; - int readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0; - int writeable = (section->Characteristics & IMAGE_SCN_MEM_WRITE) != 0; + int i; + PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers); +#ifdef _WIN64 + POINTER_TYPE imageOffset = (module->headers->OptionalHeader.ImageBase & 0xffffffff00000000); +#else + #define imageOffset 0 +#endif + + // loop through all sections and change access flags + for (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++) { + DWORD protect, oldProtect, size; + int executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0; + int readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0; + int writeable = (section->Characteristics & IMAGE_SCN_MEM_WRITE) != 0; - if (section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) - { - // section is not needed any more and can safely be freed - VirtualFree((LPVOID)section->Misc.PhysicalAddress, section->SizeOfRawData, MEM_DECOMMIT); - continue; - } + if (section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) { + // section is not needed any more and can safely be freed + VirtualFree((LPVOID)((POINTER_TYPE)section->Misc.PhysicalAddress | imageOffset), section->SizeOfRawData, MEM_DECOMMIT); + continue; + } - // determine protection flags based on characteristics - protect = ProtectionFlags[executable][readable][writeable]; - if (section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED) - protect |= PAGE_NOCACHE; + // determine protection flags based on characteristics + protect = ProtectionFlags[executable][readable][writeable]; + if (section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED) { + protect |= PAGE_NOCACHE; + } - // determine size of region - size = section->SizeOfRawData; - if (size == 0) - { - if (section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) - size = module->headers->OptionalHeader.SizeOfInitializedData; - else if (section->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) - size = module->headers->OptionalHeader.SizeOfUninitializedData; - } + // determine size of region + size = section->SizeOfRawData; + if (size == 0) { + if (section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) { + size = module->headers->OptionalHeader.SizeOfInitializedData; + } else if (section->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) { + size = module->headers->OptionalHeader.SizeOfUninitializedData; + } + } - if (size > 0) - { - // change memory access flags - if (VirtualProtect((LPVOID)section->Misc.PhysicalAddress, section->SizeOfRawData, protect, &oldProtect) == 0) -#if DEBUG_OUTPUT - OutputLastError("Error protecting memory page") + if (size > 0) { + // change memory access flags + if (VirtualProtect((LPVOID)((POINTER_TYPE)section->Misc.PhysicalAddress | imageOffset), size, protect, &oldProtect) == 0) +#ifdef DEBUG_OUTPUT + OutputLastError("Error protecting memory page") #endif - ; - } - } + ; + } + } +#ifndef _WIN64 +#undef imageOffset +#endif } static void -PerformBaseRelocation(PMEMORYMODULE module, DWORD delta) +PerformBaseRelocation(PMEMORYMODULE module, SIZE_T delta) { - DWORD i; - unsigned char *codeBase = module->codeBase; + DWORD i; + unsigned char *codeBase = module->codeBase; - PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_BASERELOC); - if (directory->Size > 0) - { - PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION)(codeBase + directory->VirtualAddress); - for (; relocation->VirtualAddress > 0; ) - { - unsigned char *dest = (unsigned char *)(codeBase + relocation->VirtualAddress); - unsigned short *relInfo = (unsigned short *)((unsigned char *)relocation + IMAGE_SIZEOF_BASE_RELOCATION); - for (i=0; i<((relocation->SizeOfBlock-IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relInfo++) - { - DWORD *patchAddrHL; - int type, offset; + PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_BASERELOC); + if (directory->Size > 0) { + PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION) (codeBase + directory->VirtualAddress); + for (; relocation->VirtualAddress > 0; ) { + unsigned char *dest = codeBase + relocation->VirtualAddress; + unsigned short *relInfo = (unsigned short *)((unsigned char *)relocation + IMAGE_SIZEOF_BASE_RELOCATION); + for (i=0; i<((relocation->SizeOfBlock-IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relInfo++) { + DWORD *patchAddrHL; +#ifdef _WIN64 + ULONGLONG *patchAddr64; +#endif + int type, offset; - // the upper 4 bits define the type of relocation - type = *relInfo >> 12; - // the lower 12 bits define the offset - offset = *relInfo & 0xfff; - - switch (type) - { - case IMAGE_REL_BASED_ABSOLUTE: - // skip relocation - break; + // the upper 4 bits define the type of relocation + type = *relInfo >> 12; + // the lower 12 bits define the offset + offset = *relInfo & 0xfff; + + switch (type) + { + case IMAGE_REL_BASED_ABSOLUTE: + // skip relocation + break; - case IMAGE_REL_BASED_HIGHLOW: - // change complete 32 bit address - patchAddrHL = (DWORD *)(dest + offset); - *patchAddrHL += delta; - break; + case IMAGE_REL_BASED_HIGHLOW: + // change complete 32 bit address + patchAddrHL = (DWORD *) (dest + offset); + *patchAddrHL += (DWORD) delta; + break; + +#ifdef _WIN64 + case IMAGE_REL_BASED_DIR64: + patchAddr64 = (ULONGLONG *) (dest + offset); + *patchAddr64 += (ULONGLONG) delta; + break; +#endif - default: - //printf("Unknown relocation: %d\n", type); - break; - } - } + default: + //printf("Unknown relocation: %d\n", type); + break; + } + } - // advance to next relocation block - relocation = (PIMAGE_BASE_RELOCATION)(((DWORD)relocation) + relocation->SizeOfBlock); - } - } + // advance to next relocation block + relocation = (PIMAGE_BASE_RELOCATION) (((char *) relocation) + relocation->SizeOfBlock); + } + } } static int BuildImportTable(PMEMORYMODULE module) { - int result=1; - unsigned char *codeBase = module->codeBase; + int result=1; + unsigned char *codeBase = module->codeBase; + HCUSTOMMODULE *tmp; - PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_IMPORT); - if (directory->Size > 0) - { - PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR)(codeBase + directory->VirtualAddress); - for (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++) - { - DWORD *thunkRef, *funcRef; - HMODULE handle; + PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_IMPORT); + if (directory->Size > 0) { + PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR) (codeBase + directory->VirtualAddress); + for (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++) { + POINTER_TYPE *thunkRef; + FARPROC *funcRef; + HCUSTOMMODULE handle = module->loadLibrary((LPCSTR) (codeBase + importDesc->Name), module->userdata); + if (handle == NULL) { + SetLastError(ERROR_MOD_NOT_FOUND); + result = 0; + break; + } - handle = MyLoadLibrary(codeBase + importDesc->Name); - if (handle == INVALID_HANDLE_VALUE) - { - //LastError should already be set -#if DEBUG_OUTPUT - OutputLastError("Can't load library"); -#endif - result = 0; - break; - } + tmp = (HCUSTOMMODULE *) realloc(module->modules, (module->numModules+1)*(sizeof(HCUSTOMMODULE))); + if (tmp == NULL) { + module->freeLibrary(handle, module->userdata); + SetLastError(ERROR_OUTOFMEMORY); + result = 0; + break; + } + module->modules = tmp; - module->modules = (HMODULE *)realloc(module->modules, (module->numModules+1)*(sizeof(HMODULE))); - if (module->modules == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - result = 0; - break; - } + module->modules[module->numModules++] = handle; + if (importDesc->OriginalFirstThunk) { + thunkRef = (POINTER_TYPE *) (codeBase + importDesc->OriginalFirstThunk); + funcRef = (FARPROC *) (codeBase + importDesc->FirstThunk); + } else { + // no hint table + thunkRef = (POINTER_TYPE *) (codeBase + importDesc->FirstThunk); + funcRef = (FARPROC *) (codeBase + importDesc->FirstThunk); + } + for (; *thunkRef; thunkRef++, funcRef++) { + if (IMAGE_SNAP_BY_ORDINAL(*thunkRef)) { + *funcRef = module->getProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef), module->userdata); + } else { + PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME) (codeBase + (*thunkRef)); + *funcRef = module->getProcAddress(handle, (LPCSTR)&thunkData->Name, module->userdata); + } + if (*funcRef == 0) { + result = 0; + break; + } + } - module->modules[module->numModules++] = handle; - if (importDesc->OriginalFirstThunk) - { - thunkRef = (DWORD *)(codeBase + importDesc->OriginalFirstThunk); - funcRef = (DWORD *)(codeBase + importDesc->FirstThunk); - } else { - // no hint table - thunkRef = (DWORD *)(codeBase + importDesc->FirstThunk); - funcRef = (DWORD *)(codeBase + importDesc->FirstThunk); - } - for (; *thunkRef; thunkRef++, funcRef++) - { - if IMAGE_SNAP_BY_ORDINAL(*thunkRef) { - *funcRef = (DWORD)MyGetProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef)); - } else { - PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME)(codeBase + *thunkRef); - *funcRef = (DWORD)MyGetProcAddress(handle, (LPCSTR)&thunkData->Name); - } - if (*funcRef == 0) - { - SetLastError(ERROR_PROC_NOT_FOUND); - result = 0; - break; - } - } + if (!result) { + module->freeLibrary(handle, module->userdata); + SetLastError(ERROR_PROC_NOT_FOUND); + break; + } + } + } - if (!result) - break; - } - } + return result; +} - return result; +static HCUSTOMMODULE _LoadLibrary(LPCSTR filename, void *userdata) +{ + HMODULE result = LoadLibraryA(filename); + if (result == NULL) { + return NULL; + } + + return (HCUSTOMMODULE) result; } -/* - MemoryLoadLibrary - load a library AS MEMORY MODULE, or return - existing MEMORY MODULE with increased refcount. +static FARPROC _GetProcAddress(HCUSTOMMODULE module, LPCSTR name, void *userdata) +{ + return (FARPROC) GetProcAddress((HMODULE) module, name); +} - This allows to load a library AGAIN as memory module which is - already loaded as HMODULE! +static void _FreeLibrary(HCUSTOMMODULE module, void *userdata) +{ + FreeLibrary((HMODULE) module); +} -*/ -HMEMORYMODULE MemoryLoadLibrary(char *name, const void *data) +HMEMORYMODULE MemoryLoadLibrary(const void *data) { - PMEMORYMODULE result; - PIMAGE_DOS_HEADER dos_header; - PIMAGE_NT_HEADERS old_header; - unsigned char *code, *headers; - DWORD locationDelta; - DllEntryProc DllEntry; - BOOL successfull; - MEMORYMODULE *p = loaded; + return MemoryLoadLibraryEx(data, _LoadLibrary, _GetProcAddress, _FreeLibrary, NULL); +} - while (p) { - // If already loaded, only increment the reference count - if (0 == _stricmp(name, p->name)) { - p->refcount++; - return (HMODULE)p; - } - p = p->next; - } +HMEMORYMODULE MemoryLoadLibraryEx(const void *data, + CustomLoadLibraryFunc loadLibrary, + CustomGetProcAddressFunc getProcAddress, + CustomFreeLibraryFunc freeLibrary, + void *userdata) +{ + PMEMORYMODULE result; + PIMAGE_DOS_HEADER dos_header; + PIMAGE_NT_HEADERS old_header; + unsigned char *code, *headers; + SIZE_T locationDelta; + DllEntryProc DllEntry; + BOOL successfull; - /* Do NOT check for GetModuleHandle here! */ + dos_header = (PIMAGE_DOS_HEADER)data; + if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) { + SetLastError(ERROR_BAD_EXE_FORMAT); + return NULL; + } - dos_header = (PIMAGE_DOS_HEADER)data; - if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) - { - SetLastError(ERROR_BAD_FORMAT); -#if DEBUG_OUTPUT - OutputDebugString("Not a valid executable file.\n"); -#endif - return NULL; - } + old_header = (PIMAGE_NT_HEADERS)&((const unsigned char *)(data))[dos_header->e_lfanew]; + if (old_header->Signature != IMAGE_NT_SIGNATURE) { + SetLastError(ERROR_BAD_EXE_FORMAT); + return NULL; + } - old_header = (PIMAGE_NT_HEADERS)&((const unsigned char *)(data))[dos_header->e_lfanew]; - if (old_header->Signature != IMAGE_NT_SIGNATURE) - { - SetLastError(ERROR_BAD_FORMAT); -#if DEBUG_OUTPUT - OutputDebugString("No PE header found.\n"); -#endif - return NULL; - } + // reserve memory for image of library + // XXX: is it correct to commit the complete memory region at once? + // calling DllEntry raises an exception if we don't... + code = (unsigned char *)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase), + old_header->OptionalHeader.SizeOfImage, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE); - // reserve memory for image of library - code = (unsigned char *)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase), - old_header->OptionalHeader.SizeOfImage, - MEM_RESERVE, - PAGE_READWRITE); - - if (code == NULL) + if (code == NULL) { // try to allocate memory at arbitrary position code = (unsigned char *)VirtualAlloc(NULL, old_header->OptionalHeader.SizeOfImage, - MEM_RESERVE, + MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + if (code == NULL) { + SetLastError(ERROR_OUTOFMEMORY); + return NULL; + } + } - if (code == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); -#if DEBUG_OUTPUT - OutputLastError("Can't reserve memory"); -#endif - return NULL; - } + result = (PMEMORYMODULE)HeapAlloc(GetProcessHeap(), 0, sizeof(MEMORYMODULE)); + if (result == NULL) { + SetLastError(ERROR_OUTOFMEMORY); + VirtualFree(code, 0, MEM_RELEASE); + return NULL; + } - result = (PMEMORYMODULE)HeapAlloc(GetProcessHeap(), 0, sizeof(MEMORYMODULE)); - result->codeBase = code; - result->numModules = 0; - result->modules = NULL; - result->initialized = 0; - result->next = result->prev = NULL; - result->refcount = 1; - result->name = _strdup(name); - result->name_table = NULL; + result->codeBase = code; + result->numModules = 0; + result->modules = NULL; + result->initialized = 0; + result->loadLibrary = loadLibrary; + result->getProcAddress = getProcAddress; + result->freeLibrary = freeLibrary; + result->userdata = userdata; - // XXX: is it correct to commit the complete memory region at once? - // calling DllEntry raises an exception if we don't... - VirtualAlloc(code, - old_header->OptionalHeader.SizeOfImage, - MEM_COMMIT, - PAGE_READWRITE); + // commit memory for headers + headers = (unsigned char *)VirtualAlloc(code, + old_header->OptionalHeader.SizeOfHeaders, + MEM_COMMIT, + PAGE_READWRITE); + + // copy PE header to code + memcpy(headers, dos_header, dos_header->e_lfanew + old_header->OptionalHeader.SizeOfHeaders); + result->headers = (PIMAGE_NT_HEADERS)&((const unsigned char *)(headers))[dos_header->e_lfanew]; - // commit memory for headers - headers = (unsigned char *)VirtualAlloc(code, - old_header->OptionalHeader.SizeOfHeaders, - MEM_COMMIT, - PAGE_READWRITE); - - // copy PE header to code - memcpy(headers, dos_header, dos_header->e_lfanew + old_header->OptionalHeader.SizeOfHeaders); - result->headers = (PIMAGE_NT_HEADERS)&((const unsigned char *)(headers))[dos_header->e_lfanew]; + // update position + result->headers->OptionalHeader.ImageBase = (POINTER_TYPE)code; - // update position - result->headers->OptionalHeader.ImageBase = (DWORD)code; + // copy sections from DLL file block to new memory location + CopySections(data, old_header, result); - // copy sections from DLL file block to new memory location - CopySections(data, old_header, result); + // adjust base address of imported data + locationDelta = (SIZE_T)(code - old_header->OptionalHeader.ImageBase); + if (locationDelta != 0) { + PerformBaseRelocation(result, locationDelta); + } - // adjust base address of imported data - locationDelta = (DWORD)(code - old_header->OptionalHeader.ImageBase); - if (locationDelta != 0) - PerformBaseRelocation(result, locationDelta); + // load required dlls and adjust function table of imports + if (!BuildImportTable(result)) { + goto error; + } - // load required dlls and adjust function table of imports - if (!BuildImportTable(result)) - goto error; + // mark memory pages depending on section headers and release + // sections that are marked as "discardable" + FinalizeSections(result); - // mark memory pages depending on section headers and release - // sections that are marked as "discardable" - FinalizeSections(result); + // get entry point of loaded library + if (result->headers->OptionalHeader.AddressOfEntryPoint != 0) { + DllEntry = (DllEntryProc) (code + result->headers->OptionalHeader.AddressOfEntryPoint); + // notify library about attaching to process + successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0); + if (!successfull) { + SetLastError(ERROR_DLL_INIT_FAILED); + goto error; + } + result->initialized = 1; + } - // get entry point of loaded library - if (result->headers->OptionalHeader.AddressOfEntryPoint != 0) - { - DllEntry = (DllEntryProc)(code + result->headers->OptionalHeader.AddressOfEntryPoint); - if (DllEntry == 0) - { - SetLastError(ERROR_BAD_FORMAT); /* XXX ? */ -#if DEBUG_OUTPUT - OutputDebugString("Library has no entry point.\n"); -#endif - goto error; - } + return (HMEMORYMODULE)result; - // notify library about attaching to process - successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0); - if (!successfull) - { -#if DEBUG_OUTPUT - OutputDebugString("Can't attach library.\n"); -#endif - goto error; - } - result->initialized = 1; - } - - _Register(name, result); - - return (HMEMORYMODULE)result; - error: - // cleanup - free(result->name); - MemoryFreeLibrary(result); - return NULL; + // cleanup + MemoryFreeLibrary(result); + return NULL; } -int _compare(const struct NAME_TABLE *p1, const struct NAME_TABLE *p2) +FARPROC MemoryGetProcAddress(HMEMORYMODULE module, LPCSTR name) { - return _stricmp(p1->name, p2->name); -} + unsigned char *codeBase = ((PMEMORYMODULE)module)->codeBase; + int idx=-1; + DWORD i, *nameRef; + WORD *ordinal; + PIMAGE_EXPORT_DIRECTORY exports; + PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE)module, IMAGE_DIRECTORY_ENTRY_EXPORT); + if (directory->Size == 0) { + // no export table found + SetLastError(ERROR_PROC_NOT_FOUND); + return NULL; + } -int _find(const char **name, const struct NAME_TABLE *p) -{ - return _stricmp(*name, p->name); -} + exports = (PIMAGE_EXPORT_DIRECTORY) (codeBase + directory->VirtualAddress); + if (exports->NumberOfNames == 0 || exports->NumberOfFunctions == 0) { + // DLL doesn't export anything + SetLastError(ERROR_PROC_NOT_FOUND); + return NULL; + } -struct NAME_TABLE *GetNameTable(PMEMORYMODULE module) -{ - unsigned char *codeBase; - PIMAGE_EXPORT_DIRECTORY exports; - PIMAGE_DATA_DIRECTORY directory; - DWORD i, *nameRef; - WORD *ordinal; - struct NAME_TABLE *p, *ptab; + // search function name in list of exported names + nameRef = (DWORD *) (codeBase + exports->AddressOfNames); + ordinal = (WORD *) (codeBase + exports->AddressOfNameOrdinals); + for (i=0; i<exports->NumberOfNames; i++, nameRef++, ordinal++) { + if (_stricmp(name, (const char *) (codeBase + (*nameRef))) == 0) { + idx = *ordinal; + break; + } + } - if (module->name_table) - return module->name_table; + if (idx == -1) { + // exported symbol not found + SetLastError(ERROR_PROC_NOT_FOUND); + return NULL; + } - codeBase = module->codeBase; - directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_EXPORT); - exports = (PIMAGE_EXPORT_DIRECTORY)(codeBase + directory->VirtualAddress); + if ((DWORD)idx > exports->NumberOfFunctions) { + // name <-> ordinal number don't match + SetLastError(ERROR_PROC_NOT_FOUND); + return NULL; + } - nameRef = (DWORD *)(codeBase + exports->AddressOfNames); - ordinal = (WORD *)(codeBase + exports->AddressOfNameOrdinals); - - p = ((PMEMORYMODULE)module)->name_table = (struct NAME_TABLE *)malloc(sizeof(struct NAME_TABLE) - * exports->NumberOfNames); - if (p == NULL) - return NULL; - ptab = p; - for (i=0; i<exports->NumberOfNames; ++i) { - p->name = (char *)(codeBase + *nameRef++); - p->ordinal = *ordinal++; - ++p; - } - qsort(ptab, exports->NumberOfNames, sizeof(struct NAME_TABLE), _compare); - return ptab; + // AddressOfFunctions contains the RVAs to the "real" functions + return (FARPROC) (codeBase + (*(DWORD *) (codeBase + exports->AddressOfFunctions + (idx*4)))); } -FARPROC MemoryGetProcAddress(HMEMORYMODULE module, const char *name) +void MemoryFreeLibrary(HMEMORYMODULE mod) { - unsigned char *codeBase = ((PMEMORYMODULE)module)->codeBase; - int idx=-1; - PIMAGE_EXPORT_DIRECTORY exports; - PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE)module, IMAGE_DIRECTORY_ENTRY_EXPORT); + int i; + PMEMORYMODULE module = (PMEMORYMODULE)mod; - if (directory->Size == 0) - // no export table found - return NULL; + if (module != NULL) { + if (module->initialized != 0) { + // notify library about detaching from process + DllEntryProc DllEntry = (DllEntryProc) (module->codeBase + module->headers->OptionalHeader.AddressOfEntryPoint); + (*DllEntry)((HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0); + module->initialized = 0; + } - exports = (PIMAGE_EXPORT_DIRECTORY)(codeBase + directory->VirtualAddress); - if (exports->NumberOfNames == 0 || exports->NumberOfFunctions == 0) - // DLL doesn't export anything - return NULL; + if (module->modules != NULL) { + // free previously opened libraries + for (i=0; i<module->numModules; i++) { + if (module->modules[i] != NULL) { + module->freeLibrary(module->modules[i], module->userdata); + } + } - if (HIWORD(name)) { - struct NAME_TABLE *ptab; - struct NAME_TABLE *found; - ptab = GetNameTable((PMEMORYMODULE)module); - if (ptab == NULL) - // some failure - return NULL; - found = bsearch(&name, ptab, exports->NumberOfNames, sizeof(struct NAME_TABLE), _find); - if (found == NULL) - // exported symbol not found - return NULL; - - idx = found->ordinal; - } - else - idx = LOWORD(name) - exports->Base; + free(module->modules); + } - if ((DWORD)idx > exports->NumberOfFunctions) - // name <-> ordinal number don't match - return NULL; - - // AddressOfFunctions contains the RVAs to the "real" functions - return (FARPROC)(codeBase + *(DWORD *)(codeBase + exports->AddressOfFunctions + (idx*4))); + if (module->codeBase != NULL) { + // release memory of library + VirtualFree(module->codeBase, 0, MEM_RELEASE); + } + + HeapFree(GetProcessHeap(), 0, module); + } } -void MemoryFreeLibrary(HMEMORYMODULE mod) +#define DEFAULT_LANGUAGE MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) + +HMEMORYRSRC MemoryFindResource(HMEMORYMODULE module, LPCTSTR name, LPCTSTR type) { - int i; - PMEMORYMODULE module = (PMEMORYMODULE)mod; + return MemoryFindResourceEx(module, name, type, DEFAULT_LANGUAGE); +} - if (module != NULL) - { - if (module->initialized != 0) - { - // notify library about detaching from process - DllEntryProc DllEntry = (DllEntryProc)(module->codeBase + module->headers->OptionalHeader.AddressOfEntryPoint); - (*DllEntry)((HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0); - module->initialized = 0; - } +static PIMAGE_RESOURCE_DIRECTORY_ENTRY _MemorySearchResourceEntry( + void *root, + PIMAGE_RESOURCE_DIRECTORY resources, + LPCTSTR key) +{ + PIMAGE_RESOURCE_DIRECTORY_ENTRY entries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (resources + 1); + PIMAGE_RESOURCE_DIRECTORY_ENTRY result = NULL; + DWORD start; + DWORD end; + DWORD middle; + + if (!IS_INTRESOURCE(key) && key[0] == TEXT('#')) { + // special case: resource id given as string + TCHAR *endpos = NULL; +#if defined(UNICODE) + long int tmpkey = (WORD) wcstol((TCHAR *) &key[1], &endpos, 10); +#else + long int tmpkey = (WORD) strtol((TCHAR *) &key[1], &endpos, 10); +#endif + if (tmpkey <= 0xffff && lstrlen(endpos) == 0) { + key = MAKEINTRESOURCE(tmpkey); + } + } + + // entries are stored as ordered list of named entries, + // followed by an ordered list of id entries - we can do + // a binary search to find faster... + if (IS_INTRESOURCE(key)) { + WORD check = (WORD) (POINTER_TYPE) key; + start = resources->NumberOfNamedEntries; + end = start + resources->NumberOfIdEntries; + + while (end > start) { + WORD entryName; + middle = (start + end) >> 1; + entryName = (WORD) entries[middle].Name; + if (check < entryName) { + end = (end != middle ? middle : middle-1); + } else if (check > entryName) { + start = (start != middle ? middle : middle+1); + } else { + result = &entries[middle]; + break; + } + } + } else { +#if !defined(UNICODE) + char *searchKey = NULL; + int searchKeyLength = 0; +#endif + start = 0; + end = resources->NumberOfIdEntries; + while (end > start) { + // resource names are always stored using 16bit characters + int cmp; + PIMAGE_RESOURCE_DIR_STRING_U resourceString; + middle = (start + end) >> 1; + resourceString = (PIMAGE_RESOURCE_DIR_STRING_U) (((char *) root) + (entries[middle].Name & 0x7FFFFFFF)); +#if !defined(UNICODE) + if (searchKey == NULL || searchKeyLength < resourceString->Length) { + void *tmp = realloc(searchKey, resourceString->Length); + if (tmp == NULL) { + break; + } + + searchKey = (char *) tmp; + } + wcstombs(searchKey, resourceString->NameString, resourceString->Length); + cmp = strncmp(key, searchKey, resourceString->Length); +#else + cmp = wcsncmp(key, resourceString->NameString, resourceString->Length); +#endif + if (cmp < 0) { + end = (middle != end ? middle : middle-1); + } else if (cmp > 0) { + start = (middle != start ? middle : middle+1); + } else { + result = &entries[middle]; + break; + } + } +#if !defined(UNICODE) + free(searchKey); +#endif + } + + + return result; +} - if (module->modules != NULL) - { - // free previously opened libraries - for (i=0; i<module->numModules; i++) - if (module->modules[i] != INVALID_HANDLE_VALUE) - MyFreeLibrary(module->modules[i]); +HMEMORYRSRC MemoryFindResourceEx(HMEMORYMODULE module, LPCTSTR name, LPCTSTR type, WORD language) +{ + unsigned char *codeBase = ((PMEMORYMODULE) module)->codeBase; + PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE) module, IMAGE_DIRECTORY_ENTRY_RESOURCE); + PIMAGE_RESOURCE_DIRECTORY rootResources; + PIMAGE_RESOURCE_DIRECTORY nameResources; + PIMAGE_RESOURCE_DIRECTORY typeResources; + PIMAGE_RESOURCE_DIRECTORY_ENTRY foundType; + PIMAGE_RESOURCE_DIRECTORY_ENTRY foundName; + PIMAGE_RESOURCE_DIRECTORY_ENTRY foundLanguage; + if (directory->Size == 0) { + // no resource table found + SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND); + return NULL; + } + + if (language == DEFAULT_LANGUAGE) { + // use language from current thread + language = LANGIDFROMLCID(GetThreadLocale()); + } - free(module->modules); - } + // resources are stored as three-level tree + // - first node is the type + // - second node is the name + // - third node is the language + rootResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress); + foundType = _MemorySearchResourceEntry(rootResources, rootResources, type); + if (foundType == NULL) { + SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND); + return NULL; + } + + typeResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress + (foundType->OffsetToData & 0x7fffffff)); + foundName = _MemorySearchResourceEntry(rootResources, typeResources, name); + if (foundName == NULL) { + SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND); + return NULL; + } + + nameResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress + (foundName->OffsetToData & 0x7fffffff)); + foundLanguage = _MemorySearchResourceEntry(rootResources, nameResources, (LPCTSTR) (POINTER_TYPE) language); + if (foundLanguage == NULL) { + // requested language not found, use first available + if (nameResources->NumberOfIdEntries == 0) { + SetLastError(ERROR_RESOURCE_LANG_NOT_FOUND); + return NULL; + } + + foundLanguage = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (nameResources + 1); + } + + return (codeBase + directory->VirtualAddress + (foundLanguage->OffsetToData & 0x7fffffff)); +} - if (module->codeBase != NULL) - // release memory of library - VirtualFree(module->codeBase, 0, MEM_RELEASE); +DWORD MemorySizeofResource(HMEMORYMODULE module, HMEMORYRSRC resource) +{ + PIMAGE_RESOURCE_DATA_ENTRY entry = (PIMAGE_RESOURCE_DATA_ENTRY) resource; + + return entry->Size; +} - if (module->name_table != NULL) - free(module->name_table); +LPVOID MemoryLoadResource(HMEMORYMODULE module, HMEMORYRSRC resource) +{ + unsigned char *codeBase = ((PMEMORYMODULE) module)->codeBase; + PIMAGE_RESOURCE_DATA_ENTRY entry = (PIMAGE_RESOURCE_DATA_ENTRY) resource; + + return codeBase + entry->OffsetToData; +} - HeapFree(GetProcessHeap(), 0, module); - } +int +MemoryLoadString(HMEMORYMODULE module, UINT id, LPTSTR buffer, int maxsize) +{ + return MemoryLoadStringEx(module, id, buffer, maxsize, DEFAULT_LANGUAGE); } + +int +MemoryLoadStringEx(HMEMORYMODULE module, UINT id, LPTSTR buffer, int maxsize, WORD language) +{ + HMEMORYRSRC resource; + PIMAGE_RESOURCE_DIR_STRING_U data; + DWORD size; + if (maxsize == 0) { + return 0; + } + + resource = MemoryFindResourceEx(module, MAKEINTRESOURCE((id >> 4) + 1), RT_STRING, language); + if (resource == NULL) { + buffer[0] = 0; + return 0; + } + + data = MemoryLoadResource(module, resource); + id = id & 0x0f; + while (id--) { + data = (PIMAGE_RESOURCE_DIR_STRING_U) (((char *) data) + (data->Length + 1) * sizeof(WCHAR)); + } + if (data->Length == 0) { + SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND); + buffer[0] = 0; + return 0; + } + + size = data->Length; + if (size >= (DWORD) maxsize) { + size = maxsize; + } else { + buffer[size] = 0; + } +#if defined(UNICODE) + wcsncpy(buffer, data->NameString, size); +#else + wcstombs(buffer, data->NameString, size); +#endif + return size; +} Modified: trunk/py2exe/source/MemoryModule.h =================================================================== --- trunk/py2exe/source/MemoryModule.h 2013-05-31 18:50:41 UTC (rev 725) +++ trunk/py2exe/source/MemoryModule.h 2013-06-05 18:42:13 UTC (rev 726) @@ -1,12 +1,12 @@ /* * Memory DLL loading code - * Version 0.0.2 + * Version 0.0.3 * - * Copyright (c) 2004-2005 by Joachim Bauch / ma...@jo... + * Copyright (c) 2004-2013 by Joachim Bauch / ma...@jo... * http://www.joachim-bauch.de * * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with + * 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * @@ -19,7 +19,7 @@ * * The Initial Developer of the Original Code is Joachim Bauch. * - * Portions created by Joachim Bauch are Copyright (C) 2004-2005 + * Portions created by Joachim Bauch are Copyright (C) 2004-2013 * Joachim Bauch. All Rights Reserved. * */ @@ -27,30 +27,81 @@ #ifndef __MEMORY_MODULE_HEADER #define __MEMORY_MODULE_HEADER -#include <Windows.h> +#include <windows.h> typedef void *HMEMORYMODULE; +typedef void *HMEMORYRSRC; + +typedef void *HCUSTOMMODULE; + #ifdef __cplusplus extern "C" { #endif -typedef void *(*FINDPROC)(); +typedef HCUSTOMMODULE (*CustomLoadLibraryFunc)(LPCSTR, void *); +typedef FARPROC (*CustomGetProcAddressFunc)(HCUSTOMMODULE, LPCSTR, void *); +typedef void (*CustomFreeLibraryFunc)(HCUSTOMMODULE, void *); -extern FINDPROC findproc; -extern void *findproc_data; +/** + * Load DLL from memory location. + * + * All dependencies are resolved using default LoadLibrary/GetProcAddress + * calls through the Windows API. + */ +HMEMORYMODULE MemoryLoadLibrary(const void *); -HMEMORYMODULE MemoryLoadLibrary(char *, const void *); +/** + * Load DLL from memory location using custom dependency resolvers. + * + * Dependencies will be resolved using passed callback methods. + */ +HMEMORYMODULE MemoryLoadLibraryEx(const void *, + CustomLoadLibraryFunc, + CustomGetProcAddressFunc, + CustomFreeLibraryFunc, + void *); -FARPROC MemoryGetProcAddress(HMEMORYMODULE, const char *); +/** + * Get address of exported method. + */ +FARPROC MemoryGetProcAddress(HMEMORYMODULE, LPCSTR); +/** + * Free previously loaded DLL. + */ void MemoryFreeLibrary(HMEMORYMODULE); -BOOL MyFreeLibrary(HMODULE hModule); -HMODULE MyLoadLibrary(char *lpFileName); -FARPROC MyGetProcAddress(HMODULE hModule, LPCSTR lpProcName); -HMODULE MyGetModuleHandle(LPCTSTR lpModuleName); +/** + * Find the location of a resource with the specified type and name. + */ +HMEMORYRSRC MemoryFindResource(HMEMORYMODULE, LPCTSTR, LPCTSTR); +/** + * Find the location of a resource with the specified type, name and language. + */ +HMEMORYRSRC MemoryFindResourceEx(HMEMORYMODULE, LPCTSTR, LPCTSTR, WORD); + +/** + * Get the size of the resource in bytes. + */ +DWORD MemorySizeofResource(HMEMORYMODULE, HMEMORYRSRC); + +/** + * Get a pointer to the contents of the resource. + */ +LPVOID MemoryLoadResource(HMEMORYMODULE, HMEMORYRSRC); + +/** + * Load a string resource. + */ +int MemoryLoadString(HMEMORYMODULE, UINT, LPTSTR, int); + +/** + * Load a string resource with a given language. + */ +int MemoryLoadStringEx(HMEMORYMODULE, UINT, LPTSTR, int, WORD); + #ifdef __cplusplus } #endif Added: trunk/py2exe/source/MyLoadLibrary.c =================================================================== --- trunk/py2exe/source/MyLoadLibrary.c (rev 0) +++ trunk/py2exe/source/MyLoadLibrary.c 2013-06-05 18:42:13 UTC (rev 726) @@ -0,0 +1,207 @@ +#ifdef STANDALONE +# include <Python.h> +# include "Python-version.h" +#else +# include "Python-dynload.h" +# include <stdio.h> +#endif +#include <windows.h> + +#include "MemoryModule.h" +#include "MyLoadLibrary.h" + +/* + +Windows API: +============ + +HMODULE LoadLibraryA(LPCSTR) +HMODULE GetModuleHandleA(LPCSTR) +BOOL FreeLibrary(HMODULE) +FARPROC GetProcAddress(HMODULE, LPCSTR) + + +MemoryModule API: +================= + +HMEMORYMODULE MemoryLoadLibrary(void *) +void MemoryFreeLibrary(HMEMORYMODULE) +FARPROC MemoryGetProcAddress(HMEMORYMODULE, LPCSTR) + +HMEMORYMODULE MemoryLoadLibrayEx(void *, + load_func, getproc_func, free_func, userdata) + +(there are also some resource functions which are not used here...) + +General API in this file: +========================= + +HMODULE MyLoadLibrary(LPCSTR, void *, userdata) +HMODULE MyGetModuleHandle(LPCSTR) +BOOL MyFreeLibrary(HMODULE) +FARPROC MyGetProcAddress(HMODULE, LPCSTR) + + */ + +/**************************************************************** + * A linked list of loaded MemoryModules. + */ +typedef struct tagLIST { + HCUSTOMMODULE module; + LPCSTR name; + struct tagLIST *next; + struct tagLIST *prev; + int refcount; +} LIST; + +static LIST *libraries; + +/**************************************************************** + * Search for a loaded MemoryModule in the linked list, either by name + * or by module handle. + */ +static LIST *_FindMemoryModule(LPCSTR name, HMODULE module) +{ + LIST *lib = libraries; + while (lib) { + if (name && 0 == stricmp(name, lib->name)) { +// printf("_FindMemoryModule(%s, %p) -> %s\n", name, module, lib->name); + return lib; + } else if (module == lib->module) { +// printf("_FindMemoryModule(%s, %p) -> %s\n", name, module, lib->name); + return lib; + } else { + lib = lib->next; + } + } +// printf("_FindMemoryModule(%s, %p) -> NULL\n", name, module); + return NULL; +} + +/**************************************************************** + * Insert a MemoryModule into the linked list of loaded modules + */ +static LIST *_AddMemoryModule(LPCSTR name, HCUSTOMMODULE module) +{ + LIST *entry = (LIST *)malloc(sizeof(LIST)); + entry->name = strdup(name); + entry->module = module; + entry->next = libraries; + entry->prev = NULL; + entry->refcount = 1; + libraries = entry; +// printf("_AddMemoryModule(%s, %p) -> %p\n", name, module, entry); + return entry; +} + +/**************************************************************** + * Helper functions for MemoryLoadLibraryEx + */ +static FARPROC _GetProcAddress(HCUSTOMMODULE module, LPCSTR name, void *userdata) +{ + FARPROC res; + res = (FARPROC)GetProcAddress((HMODULE)module, name); + if (res == NULL) { + SetLastError(0); + return MemoryGetProcAddress(module, name); + } else + return res; +} + +static void _FreeLibrary(HCUSTOMMODULE module, void *userdata) +{ + LIST *lib = _FindMemoryModule(NULL, module); + if (lib && --lib->refcount == 0) + MemoryFreeLibrary(module); + else + FreeLibrary((HMODULE) module); +} + +static HCUSTOMMODULE _LoadLibrary(LPCSTR filename, void *userdata) +{ + HCUSTOMMODULE result; + LIST *lib = _FindMemoryModule(filename, NULL); + if (lib) { + lib->refcount += 1; + return lib->module; + } + if (userdata) { + PyObject *findproc = (PyObject *)userdata; + PyObject *res = PyObject_CallFunction(findproc, "s", filename); + if (res && PyString_AsString(res)) { + result = MemoryLoadLibraryEx(PyString_AsString(res), + _LoadLibrary, _GetProcAddress, _FreeLibrary, + userdata); + Py_DECREF(res); + lib = _AddMemoryModule(filename, result); + return lib->module; + } else { + PyErr_Clear(); + } + PyErr_Clear(); + } + return (HCUSTOMMODULE)LoadLibraryA(filename); +} + +/**************************************************************** + * Public functions + */ +HMODULE MyGetModuleHandle(LPCSTR name) +{ + LIST *lib; + lib = _FindMemoryModule(name, NULL); + if (lib) + return lib->module; + return GetModuleHandle(name); +} + +HMODULE MyLoadLibrary(LPCSTR name, void *data, void *userdata) +{ + LIST *lib; +// printf("MyLoadLibrary(%s, %p, %p)\n", name, data, userdata); + lib = _FindMemoryModule(name, NULL); + if (lib) { + ++lib->refcount; + return lib->module; + } + if (userdata) { + HCUSTOMMODULE mod = _LoadLibrary(name, userdata); + if (mod) { + LIST *lib = _AddMemoryModule(name, mod); + return lib->module; + } + } else if (data) { + HCUSTOMMODULE mod = MemoryLoadLibraryEx(data, + _LoadLibrary, + _GetProcAddress, + _FreeLibrary, + userdata); + if (mod) { + LIST *lib = _AddMemoryModule(name, mod); + return lib->module; + } + } + return LoadLibrary(name); +} + +BOOL MyFreeLibrary(HMODULE module) +{ + LIST *lib = _FindMemoryModule(NULL, module); + if (lib) { + if (--lib->refcount == 0) { + MemoryFreeLibrary(module); + /* remove lib entry from linked list */ + } + return TRUE; + } else + return FreeLibrary(module); +} + +FARPROC MyGetProcAddress(HMODULE module, LPCSTR procname) +{ + LIST *lib = _FindMemoryModule(NULL, module); + if (lib) + return MemoryGetProcAddress(lib->module, procname); + else + return GetProcAddress(module, procname); +} Added: trunk/py2exe/source/MyLoadLibrary.h =================================================================== --- trunk/py2exe/source/MyLoadLibrary.h (rev 0) +++ trunk/py2exe/source/MyLoadLibrary.h 2013-06-05 18:42:13 UTC (rev 726) @@ -0,0 +1,13 @@ +#ifndef GENERALLOADLIBRARY_H +#define GENERALLOADLIBRARY_H + +HMODULE MyLoadLibrary(LPCSTR, void *, void *); + +HMODULE MyGetModuleHandle(LPCSTR); + +BOOL MyFreeLibrary(HMODULE); + +FARPROC MyGetProcAddress(HMODULE, LPCSTR); + + +#endif Modified: trunk/py2exe/source/Python-dynload.c =================================================================== --- trunk/py2exe/source/Python-dynload.c 2013-05-31 18:50:41 UTC (rev 725) +++ trunk/py2exe/source/Python-dynload.c 2013-06-05 18:42:13 UTC (rev 726) @@ -1,6 +1,7 @@ /* **************** Python-dynload.c **************** */ #include "Python-dynload.h" -#include "MemoryModule.h" +#include <windows.h> +#include "MyLoadLibrary.h" #include "actctx.h" #include <stdio.h> @@ -70,13 +71,13 @@ return _load_python_FromFile(dllname); cookie = _My_ActivateActCtx();//try some windows manifest magic... - hmod = MemoryLoadLibrary(dllname, bytes); + hmod = MyLoadLibrary(dllname, bytes, NULL); _My_DeactivateActCtx(cookie); if (hmod == NULL) { return 0; } for (i = 0; p->name; ++i, ++p) { - p->proc = (void (*)())MemoryGetProcAddress(hmod, p->name); + p->proc = (void (*)())MyGetProcAddress(hmod, p->name); if (p->proc == NULL) { OutputDebugString("undef symbol"); fprintf(stderr, "undefined symbol %s -> exit(-1)\n", p->name); Modified: trunk/py2exe/source/_memimporter.c =================================================================== --- trunk/py2exe/source/_memimporter.c 2013-05-31 18:50:41 UTC (rev 725) +++ trunk/py2exe/source/_memimporter.c 2013-06-05 18:42:13 UTC (rev 726) @@ -15,87 +15,40 @@ static char module_doc[] = "Importer which can load extension modules from memory"; -#include "MemoryModule.h" +#include "MyLoadLibrary.h" #include "actctx.h" -static void *memdup(void *ptr, Py_ssize_t size) -{ - void *p = malloc(size); - if (p == NULL) - return NULL; - memcpy(p, ptr, size); - return p; -} - -/* - Be sure to detect errors in FindLibrary - undetected errors lead to - very strange bahaviour. -*/ -static void* FindLibrary(char *name, PyObject *callback) -{ - PyObject *result; - char *p; - Py_ssize_t size; - - if (callback == NULL) - return NULL; - result = PyObject_CallFunction(callback, "s", name); - if (result == NULL) { - PyErr_Clear(); - return NULL; - } - if (-1 == PyString_AsStringAndSize(result, &p, &size)) { - PyErr_Clear(); - Py_DECREF(result); - return NULL; - } - p = memdup(p, size); - Py_DECREF(result); - return p; -} - -static PyObject *set_find_proc(PyObject *self, PyObject *args) -{ - PyObject *callback = NULL; - if (!PyArg_ParseTuple(args, "|O:set_find_proc", &callback)) - return NULL; - Py_XDECREF((PyObject *)findproc_data); - Py_XINCREF(callback); - findproc_data = (void *)callback; - Py_INCREF(Py_None); - return Py_None; -} - static PyObject * import_module(PyObject *self, PyObject *args) { - char *data; - int size; char *initfuncname; char *modname; char *pathname; - HMEMORYMODULE hmem; + HMODULE hmem; FARPROC do_init; char *oldcontext; ULONG_PTR cookie = 0; + PyObject *findproc; /* code, initfuncname, fqmodulename, path */ - if (!PyArg_ParseTuple(args, "s#sss:import_module", - &data, &size, - &initfuncname, &modname, &pathname)) + if (!PyArg_ParseTuple(args, "sssO:import_module", + &modname, &pathname, + &initfuncname, + &findproc)) return NULL; cookie = _My_ActivateActCtx();//try some windows manifest magic... - hmem = MemoryLoadLibrary(pathname, data); + hmem = MyLoadLibrary(pathname, NULL, findproc); _My_DeactivateActCtx(cookie); + if (!hmem) { PyErr_Format(PyExc_ImportError, "MemoryLoadLibrary failed loading %s", pathname); return NULL; } - do_init = MemoryGetProcAddress(hmem, initfuncname); + do_init = MyGetProcAddress(hmem, initfuncname); if (!do_init) { ... [truncated message content] |
From: <th...@us...> - 2013-06-23 19:30:00
|
Revision: 731 http://sourceforge.net/p/py2exe/svn/731 Author: theller Date: 2013-06-23 19:29:56 +0000 (Sun, 23 Jun 2013) Log Message: ----------- Implement binary search in MemoryGetProcAddress(). Modified Paths: -------------- trunk/py2exe/setup.py trunk/py2exe/source/MemoryModule.c Modified: trunk/py2exe/setup.py =================================================================== --- trunk/py2exe/setup.py 2013-06-23 19:19:39 UTC (rev 730) +++ trunk/py2exe/setup.py 2013-06-23 19:29:56 UTC (rev 731) @@ -371,6 +371,8 @@ if 'zlib' in sys.builtin_module_names: macros.append(("PYZLIB_BUILTIN", None)) +macros.append(("USE_BINARY_SEARCH", '1')) + ##macros.append(("AS_PY2EXE_BUILTIN", "1")) # for runtime linking python.dll in _memimporter.c depends = ["source/import-tab.c", "source/import-tab.h"] Modified: trunk/py2exe/source/MemoryModule.c =================================================================== --- trunk/py2exe/source/MemoryModule.c 2013-06-23 19:19:39 UTC (rev 730) +++ trunk/py2exe/source/MemoryModule.c 2013-06-23 19:29:56 UTC (rev 731) @@ -22,6 +22,12 @@ * Portions created by Joachim Bauch are Copyright (C) 2004-2013 * Joachim Bauch. All Rights Reserved. * + * + * THeller: Added binary search in MemoryGetProcAddress function + * (#define USE_BINARY_SEARCH to enable it). This gives a very large + * speedup for libraries that exports lots of functions. + * + * These portions are Copyright (C) 2013 Thomas Heller. */ #ifndef __GNUC__ @@ -49,6 +55,15 @@ #include "MemoryModule.h" +#ifdef USE_BINARY_SEARCH + +struct NAME_TABLE { + LPCSTR name; + WORD idx; +}; + +#endif + typedef struct { PIMAGE_NT_HEADERS headers; unsigned char *codeBase; @@ -58,6 +73,10 @@ CustomLoadLibraryFunc loadLibrary; CustomGetProcAddressFunc getProcAddress; CustomFreeLibraryFunc freeLibrary; +#ifdef USE_BINARY_SEARCH + struct NAME_TABLE *name_table; + int numEntries; +#endif void *userdata; } MEMORYMODULE, *PMEMORYMODULE; @@ -387,6 +406,9 @@ result->getProcAddress = getProcAddress; result->freeLibrary = freeLibrary; result->userdata = userdata; +#ifdef USE_BINARY_SEARCH + result->name_table = NULL; +#endif // commit memory for headers headers = (unsigned char *)VirtualAlloc(code, @@ -439,6 +461,18 @@ return NULL; } +#ifdef USE_BINARY_SEARCH +int _compare(const struct NAME_TABLE *p1, const struct NAME_TABLE *p2) +{ + return _stricmp(p1->name, p2->name); +} + +int _find(LPCSTR *name, const struct NAME_TABLE *p) +{ + return _stricmp(*name, p->name); +} +#endif + FARPROC MemoryGetProcAddress(HMEMORYMODULE module, LPCSTR name) { unsigned char *codeBase = ((PMEMORYMODULE)module)->codeBase; @@ -460,6 +494,42 @@ return NULL; } +#ifdef USE_BINARY_SEARCH + + // build name table and sort it by names + if (((PMEMORYMODULE)module)->name_table == NULL) { + struct NAME_TABLE *entry = (struct NAME_TABLE*)malloc(exports->NumberOfNames + * sizeof(struct NAME_TABLE)); + ((PMEMORYMODULE)module)->name_table = entry; + if (entry == NULL) { + ((PMEMORYMODULE)module)->numEntries = 0; + SetLastError(ERROR_OUTOFMEMORY); + return NULL; + } + ((PMEMORYMODULE)module)->numEntries = exports->NumberOfNames; + + nameRef = (DWORD *) (codeBase + exports->AddressOfNames); + ordinal = (WORD *) (codeBase + exports->AddressOfNameOrdinals); + for (i=0; i<exports->NumberOfNames; i++, nameRef++, ordinal++) { + entry->name = (const char *) (codeBase + (*nameRef)); + entry->idx = *ordinal; + entry++; + } + entry = ((PMEMORYMODULE)module)->name_table; + qsort(entry, exports->NumberOfNames, sizeof(struct NAME_TABLE), _compare); + } + + // search function name in list of exported names with binary search + if (((PMEMORYMODULE)module)->name_table) { + struct NAME_TABLE *found; + found = bsearch(&name, + ((PMEMORYMODULE)module)->name_table, + exports->NumberOfNames, + sizeof(struct NAME_TABLE), _find); + if (found) + idx = found->idx; + } +#else // search function name in list of exported names nameRef = (DWORD *) (codeBase + exports->AddressOfNames); ordinal = (WORD *) (codeBase + exports->AddressOfNameOrdinals); @@ -469,6 +539,7 @@ break; } } +#endif if (idx == -1) { // exported symbol not found @@ -499,6 +570,12 @@ module->initialized = 0; } +#ifdef USE_BINARY_SEARCH + if (module->name_table != NULL) { + free(module->name_table); + } +#endif + if (module->modules != NULL) { // free previously opened libraries for (i=0; i<module->numModules; i++) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2013-06-23 19:33:37
|
Revision: 732 http://sourceforge.net/p/py2exe/svn/732 Author: theller Date: 2013-06-23 19:33:35 +0000 (Sun, 23 Jun 2013) Log Message: ----------- Add some print statements for easier debugging. Fix some bugs. Modified Paths: -------------- trunk/py2exe/ChangeLog trunk/py2exe/source/MyLoadLibrary.c Modified: trunk/py2exe/ChangeLog =================================================================== --- trunk/py2exe/ChangeLog 2013-06-23 19:29:56 UTC (rev 731) +++ trunk/py2exe/ChangeLog 2013-06-23 19:33:35 UTC (rev 732) @@ -1,3 +1,8 @@ +2013-06-23 Thomas Heller <th...@ct...> + + * Updated the code with the current MemoryLoadLibrary module which + will also work on 64-bit windows. + 2013-05-24 Thomas Heller <th...@ct...> * properly implemented the activation context handling like it Modified: trunk/py2exe/source/MyLoadLibrary.c =================================================================== --- trunk/py2exe/source/MyLoadLibrary.c 2013-06-23 19:29:56 UTC (rev 731) +++ trunk/py2exe/source/MyLoadLibrary.c 2013-06-23 19:33:35 UTC (rev 732) @@ -10,6 +10,8 @@ #include "MemoryModule.h" #include "MyLoadLibrary.h" +/* #define VERBOSE /* enable to print debug output */ + /* Windows API: @@ -56,6 +58,28 @@ static LIST *libraries; +int level; + +static int dprintf(char *fmt, ...) +{ +#ifdef VERBOSE + va_list marker; + int i; + + va_start(marker, fmt); + for (i = 0; i < level; ++i) { + putchar(' '); + putchar(' '); + } + return vprintf(fmt, marker) + 2*level; +#else + return 0; +#endif +} + +#define PUSH() level++ +#define POP() level-- + /**************************************************************** * Search for a loaded MemoryModule in the linked list, either by name * or by module handle. @@ -65,16 +89,15 @@ LIST *lib = libraries; while (lib) { if (name && 0 == _stricmp(name, lib->name)) { -// printf("_FindMemoryModule(%s, %p) -> %s\n", name, module, lib->name); + dprintf("_FindMemoryModule(%s, %p) -> %s[%d]\n", name, module, lib->name, lib->refcount); return lib; } else if (module == lib->module) { -// printf("_FindMemoryModule(%s, %p) -> %s\n", name, module, lib->name); + dprintf("_FindMemoryModule(%s, %p) -> %s[%d]\n", name, module, lib->name, lib->refcount); return lib; } else { lib = lib->next; } } -// printf("_FindMemoryModule(%s, %p) -> NULL\n", name, module); return NULL; } @@ -90,7 +113,8 @@ entry->prev = NULL; entry->refcount = 1; libraries = entry; -// printf("_AddMemoryModule(%s, %p) -> %p\n", name, module, entry); + dprintf("_AddMemoryModule(%s, %p) -> %p[%d]\n", + name, module, entry, entry->refcount); return entry; } @@ -99,30 +123,26 @@ */ static FARPROC _GetProcAddress(HCUSTOMMODULE module, LPCSTR name, void *userdata) { - FARPROC res; - res = (FARPROC)GetProcAddress((HMODULE)module, name); - if (res == NULL) { - SetLastError(0); - return MemoryGetProcAddress(module, name); - } else - return res; + return MyGetProcAddress(module, name); } static void _FreeLibrary(HCUSTOMMODULE module, void *userdata) { - LIST *lib = _FindMemoryModule(NULL, module); - if (lib && --lib->refcount == 0) - MemoryFreeLibrary(module); - else - FreeLibrary((HMODULE) module); + MyFreeLibrary(module); } static HCUSTOMMODULE _LoadLibrary(LPCSTR filename, void *userdata) { HCUSTOMMODULE result; - LIST *lib = _FindMemoryModule(filename, NULL); + LIST *lib; + dprintf("_LoadLibrary(%s, %p)\n", filename, userdata); + PUSH(); + lib = _FindMemoryModule(filename, NULL); if (lib) { lib->refcount += 1; + POP(); + dprintf("_LoadLibrary(%s, %p) -> %s[%d]\n\n", + filename, userdata, lib->name, lib->refcount); return lib->module; } if (userdata) { @@ -133,14 +153,24 @@ _LoadLibrary, _GetProcAddress, _FreeLibrary, userdata); Py_DECREF(res); - lib = _AddMemoryModule(filename, result); - return lib->module; + if (result) { + lib = _AddMemoryModule(filename, result); + POP(); + dprintf("_LoadLibrary(%s, %p) -> %s[%d]\n\n", + filename, userdata, lib->name, lib->refcount); + return lib->module; + } else { + dprintf("_LoadLibrary(%s, %p) failed with error %d\n", + filename, userdata, GetLastError()); + } } else { PyErr_Clear(); } - PyErr_Clear(); } - return (HCUSTOMMODULE)LoadLibraryA(filename); + result = (HCUSTOMMODULE)LoadLibraryA(filename); + POP(); + dprintf("LoadLibraryA(%s) -> %p\n\n", filename, result); + return result; } /**************************************************************** @@ -155,23 +185,14 @@ return GetModuleHandle(name); } -HMODULE MyLoadLibrary(LPCSTR name, void *data, void *userdata) +HMODULE MyLoadLibrary(LPCSTR name, void *bytes, void *userdata) { - LIST *lib; -// printf("MyLoadLibrary(%s, %p, %p)\n", name, data, userdata); - lib = _FindMemoryModule(name, NULL); - if (lib) { - ++lib->refcount; - return lib->module; - } if (userdata) { HCUSTOMMODULE mod = _LoadLibrary(name, userdata); - if (mod) { - LIST *lib = _AddMemoryModule(name, mod); - return lib->module; - } - } else if (data) { - HCUSTOMMODULE mod = MemoryLoadLibraryEx(data, + if (mod) + return mod; + } else if (bytes) { + HCUSTOMMODULE mod = MemoryLoadLibraryEx(bytes, _LoadLibrary, _GetProcAddress, _FreeLibrary, @@ -188,10 +209,8 @@ { LIST *lib = _FindMemoryModule(NULL, module); if (lib) { - if (--lib->refcount == 0) { + if (--lib->refcount == 0) MemoryFreeLibrary(module); - /* remove lib entry from linked list */ - } return TRUE; } else return FreeLibrary(module); @@ -199,9 +218,15 @@ FARPROC MyGetProcAddress(HMODULE module, LPCSTR procname) { + FARPROC proc; LIST *lib = _FindMemoryModule(NULL, module); - if (lib) - return MemoryGetProcAddress(lib->module, procname); - else + if (lib) { +// dprintf("MyGetProcAddress(%p, %s)\n", module, procname); +// PUSH(); + proc = MemoryGetProcAddress(lib->module, procname); +// POP(); +// dprintf("MyGetProcAddress(%p, %s) -> %p\n", module, procname, proc); + return proc; + } else return GetProcAddress(module, procname); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2013-07-02 05:53:59
|
Revision: 736 http://sourceforge.net/p/py2exe/svn/736 Author: theller Date: 2013-07-02 05:53:55 +0000 (Tue, 02 Jul 2013) Log Message: ----------- Remove postinstall script (doesn't make much sense, and doesn't work with 64-bit bdist_wininst). 2to3 changes. Modified Paths: -------------- trunk/py2exe/setup.py trunk/py2exe/zipextimporter.py Removed Paths: ------------- trunk/py2exe/py2exe_postinstall.py Deleted: trunk/py2exe/py2exe_postinstall.py =================================================================== --- trunk/py2exe/py2exe_postinstall.py 2013-06-30 18:03:08 UTC (rev 735) +++ trunk/py2exe/py2exe_postinstall.py 2013-07-02 05:53:55 UTC (rev 736) @@ -1,8 +0,0 @@ -"""py2exe is now installed on your machine. - -There are some samples in the 'samples' subdirectory.""" - -import sys - -if len(sys.argv) == 2 and sys.argv[1] == "-install": - print __doc__ Modified: trunk/py2exe/setup.py =================================================================== --- trunk/py2exe/setup.py 2013-06-30 18:03:08 UTC (rev 735) +++ trunk/py2exe/setup.py 2013-07-02 05:53:55 UTC (rev 736) @@ -41,7 +41,7 @@ from distutils.errors import * if sys.version_info < (2, 3): - raise DistutilsError, "This package requires Python 2.3 or later" + raise DistutilsError("This package requires Python 2.3 or later") # Some nasty hacks to ensure all our targets are built with a manifest that # references the CRT manifest (which the msvc9compiler implementation @@ -77,7 +77,7 @@ def __init__(self, *args, **kw): # Add a custom 'target_desc' option, which matches CCompiler # (is there a better way? - if kw.has_key("target_desc"): + if "target_desc" in kw: self.target_desc = kw['target_desc'] del kw['target_desc'] else: @@ -111,10 +111,9 @@ for inter in self.interpreters: sources = inter.sources if sources is None or type(sources) not in (type([]), type(())): - raise DistutilsSetupError, \ - ("in 'interpreters' option ('%s'), " + + raise DistutilsSetupError(("in 'interpreters' option ('%s'), " + "'sources' must be present and must be " + - "a list of source filenames") % inter.name + "a list of source filenames") % inter.name) sources = list(sources) fullname = self.get_exe_fullname(inter.name) @@ -202,8 +201,8 @@ def get_exe_filename (self, inter_name): ext_path = string.split(inter_name, '.') if self.debug: - return apply(os.path.join, ext_path) + '_d' - return apply(os.path.join, ext_path) + return os.path.join(*ext_path) + '_d' + return os.path.join(*ext_path) def setup_compiler(self): # This method *should* be available separately in build_ext! @@ -302,7 +301,7 @@ if not self.dry_run: try: os.remove(name) - except OSError, details: + except OSError as details: self.warn("Could not remove file: %s" % details) if os.path.splitext(name)[1] == '.py': # Try to remove .pyc and -pyo files also @@ -319,7 +318,7 @@ if not self.dry_run: try: os.rmdir(name) - except OSError, details: + except OSError as details: self.warn("Are there additional user files?\n"\ " Could not remove directory: %s" % details) else: @@ -515,7 +514,6 @@ libraries=["imagehlp"]), ], py_modules = ["zipextimporter"], - scripts = ["py2exe_postinstall.py"], interpreters = interpreters, packages=['py2exe', 'py2exe.resources', Modified: trunk/py2exe/zipextimporter.py =================================================================== --- trunk/py2exe/zipextimporter.py 2013-06-30 18:03:08 UTC (rev 735) +++ trunk/py2exe/zipextimporter.py 2013-07-02 05:53:55 UTC (rev 736) @@ -65,7 +65,7 @@ def load_module(self, fullname): verbose = _memimporter.get_verbose_flag() - if sys.modules.has_key(fullname): + if fullname in sys.modules: mod = sys.modules[fullname] if verbose: sys.stderr.write("import %s # previously loaded from zipfile %s\n" % (fullname, self.archive)) @@ -92,7 +92,7 @@ if verbose: sys.stderr.write("import %s # loaded from zipfile %s\n" % (fullname, mod.__file__)) return mod - raise zipimport.ZipImportError, "can't find module %s" % fullname + raise zipimport.ZipImportError("can't find module %s" % fullname) def __repr__(self): return "<%s object %r>" % (self.__class__.__name__, self.archive) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2013-09-07 10:11:50
|
Revision: 738 http://sourceforge.net/p/py2exe/svn/738 Author: theller Date: 2013-09-07 10:11:45 +0000 (Sat, 07 Sep 2013) Log Message: ----------- Change version to 0.6.10.a1. Update Copyright statements. Modified Paths: -------------- trunk/py2exe/py2exe/__init__.py trunk/py2exe/py2exe/resources/StringTables.py trunk/py2exe/py2exe/resources/VersionInfo.py trunk/py2exe/setup.py trunk/py2exe/source/py2exe_util.c trunk/py2exe/source/run.c trunk/py2exe/source/run_ctypes_dll.c trunk/py2exe/source/run_dll.c trunk/py2exe/source/run_isapi.c trunk/py2exe/source/run_w.c trunk/py2exe/source/start.c Modified: trunk/py2exe/py2exe/__init__.py =================================================================== --- trunk/py2exe/py2exe/__init__.py 2013-07-10 20:16:39 UTC (rev 737) +++ trunk/py2exe/py2exe/__init__.py 2013-09-07 10:11:45 UTC (rev 738) @@ -62,7 +62,7 @@ # special one contained in this module. # -__version__ = "0.6.10dev" +__version__ = "0.6.10.a1" import distutils.dist, distutils.core, distutils.command, build_exe, sys Modified: trunk/py2exe/py2exe/resources/StringTables.py =================================================================== --- trunk/py2exe/py2exe/resources/StringTables.py 2013-07-10 20:16:39 UTC (rev 737) +++ trunk/py2exe/py2exe/resources/StringTables.py 2013-09-07 10:11:45 UTC (rev 738) @@ -1,5 +1,5 @@ ## -## Copyright (c) 2000, 2001, 2002 Thomas Heller +## Copyright (c) 2000-2013 Thomas Heller ## ## Permission is hereby granted, free of charge, to any person obtaining ## a copy of this software and associated documentation files (the Modified: trunk/py2exe/py2exe/resources/VersionInfo.py =================================================================== --- trunk/py2exe/py2exe/resources/VersionInfo.py 2013-07-10 20:16:39 UTC (rev 737) +++ trunk/py2exe/py2exe/resources/VersionInfo.py 2013-09-07 10:11:45 UTC (rev 738) @@ -1,6 +1,6 @@ # -*- coding: latin-1 -*- ## -## Copyright (c) 2000, 2001, 2002, 2003 Thomas Heller +## Copyright (c) 2000-2013 Thomas Heller ## ## Permission is hereby granted, free of charge, to any person obtaining ## a copy of this software and associated documentation files (the Modified: trunk/py2exe/setup.py =================================================================== --- trunk/py2exe/setup.py 2013-07-10 20:16:39 UTC (rev 737) +++ trunk/py2exe/setup.py 2013-09-07 10:11:45 UTC (rev 738) @@ -1,6 +1,6 @@ #!/usr/bin/python ## -## Copyright (c) 2000-2008 Thomas Heller, Jimmy Retzlaff +## Copyright (c) 2000-2013 Thomas Heller, Jimmy Retzlaff ## ## Permission is hereby granted, free of charge, to any person obtaining ## a copy of this software and associated documentation files (the @@ -376,9 +376,10 @@ extra_link_args = [] if 0: - # enable this to debug a release build + # enable this to include debug info into a release build extra_compile_args.append("/Z7") extra_link_args.append("/DEBUG") + macros.append(("VERBOSE", "1")) ##macros.append(("AS_PY2EXE_BUILTIN", "1")) # for runtime linking python.dll in _memimporter.c depends = ["source/import-tab.c", "source/import-tab.h"] Modified: trunk/py2exe/source/py2exe_util.c =================================================================== --- trunk/py2exe/source/py2exe_util.c 2013-07-10 20:16:39 UTC (rev 737) +++ trunk/py2exe/source/py2exe_util.c 2013-09-07 10:11:45 UTC (rev 738) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2001, 2002, 2003 Thomas Heller + * Copyright (c) 2000-2013 Thomas Heller * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the Modified: trunk/py2exe/source/run.c =================================================================== --- trunk/py2exe/source/run.c 2013-07-10 20:16:39 UTC (rev 737) +++ trunk/py2exe/source/run.c 2013-09-07 10:11:45 UTC (rev 738) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2001 Thomas Heller + * Copyright (c) 2000-2013 Thomas Heller * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the Modified: trunk/py2exe/source/run_ctypes_dll.c =================================================================== --- trunk/py2exe/source/run_ctypes_dll.c 2013-07-10 20:16:39 UTC (rev 737) +++ trunk/py2exe/source/run_ctypes_dll.c 2013-09-07 10:11:45 UTC (rev 738) @@ -1,6 +1,5 @@ /* - * Copyright (c) 2000, 2001 Thomas Heller - * Copyright (c) 2003 Mark Hammond + * Copyright (c) 2000-2013 Thomas Heller, Mark Hammond * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the Modified: trunk/py2exe/source/run_dll.c =================================================================== --- trunk/py2exe/source/run_dll.c 2013-07-10 20:16:39 UTC (rev 737) +++ trunk/py2exe/source/run_dll.c 2013-09-07 10:11:45 UTC (rev 738) @@ -1,6 +1,5 @@ /* - * Copyright (c) 2000, 2001 Thomas Heller - * Copyright (c) 2003 Mark Hammond + * Copyright (c) 2000-2013 Thomas Heller, Mark Hammond * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the Modified: trunk/py2exe/source/run_isapi.c =================================================================== --- trunk/py2exe/source/run_isapi.c 2013-07-10 20:16:39 UTC (rev 737) +++ trunk/py2exe/source/run_isapi.c 2013-09-07 10:11:45 UTC (rev 738) @@ -1,6 +1,5 @@ /* - * Copyright (c) 2000, 2001 Thomas Heller - * Copyright (c) 2003 Mark Hammond + * Copyright (c) 2000, 2001 Thomas Heller, Mark Hammond * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the Modified: trunk/py2exe/source/run_w.c =================================================================== --- trunk/py2exe/source/run_w.c 2013-07-10 20:16:39 UTC (rev 737) +++ trunk/py2exe/source/run_w.c 2013-09-07 10:11:45 UTC (rev 738) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2001 Thomas Heller + * Copyright (c) 2000-2013 Thomas Heller, Mark Hammond * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the Modified: trunk/py2exe/source/start.c =================================================================== --- trunk/py2exe/source/start.c 2013-07-10 20:16:39 UTC (rev 737) +++ trunk/py2exe/source/start.c 2013-09-07 10:11:45 UTC (rev 738) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2001 Thomas Heller + * Copyright (c) 2000-2013 Thomas Heller, Mark Hammond * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |