You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(15) |
Oct
(31) |
Nov
(38) |
Dec
(21) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(46) |
Feb
(2) |
Mar
(10) |
Apr
(13) |
May
(2) |
Jun
(14) |
Jul
(28) |
Aug
(3) |
Sep
(7) |
Oct
(8) |
Nov
(8) |
Dec
(11) |
2005 |
Jan
|
Feb
|
Mar
|
Apr
(42) |
May
(1) |
Jun
(8) |
Jul
(4) |
Aug
(18) |
Sep
(38) |
Oct
(10) |
Nov
|
Dec
(7) |
2006 |
Jan
|
Feb
(8) |
Mar
(9) |
Apr
|
May
|
Jun
(6) |
Jul
(6) |
Aug
|
Sep
|
Oct
|
Nov
(12) |
Dec
(8) |
2007 |
Jan
(3) |
Feb
|
Mar
(9) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(5) |
Oct
|
Nov
|
Dec
|
2008 |
Jan
|
Feb
(4) |
Mar
(2) |
Apr
(17) |
May
(16) |
Jun
(2) |
Jul
|
Aug
(3) |
Sep
(1) |
Oct
|
Nov
(11) |
Dec
(1) |
2009 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
2010 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
2012 |
Jan
(1) |
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(2) |
2013 |
Jan
(14) |
Feb
(14) |
Mar
|
Apr
|
May
(3) |
Jun
(10) |
Jul
(2) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(10) |
Jun
|
Jul
|
Aug
|
Sep
(9) |
Oct
(8) |
Nov
|
Dec
|
2017 |
Jan
(3) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(4) |
Sep
|
Oct
|
Nov
|
Dec
|
From: <th...@us...> - 2014-05-12 12:33:45
|
Revision: 747 http://sourceforge.net/p/py2exe/svn/747 Author: theller Date: 2014-05-12 12:33:42 +0000 (Mon, 12 May 2014) Log Message: ----------- Bump version number to 0.9.2.1. Modified Paths: -------------- trunk/py2exe-3/py2exe/__init__.py Modified: trunk/py2exe-3/py2exe/__init__.py =================================================================== --- trunk/py2exe-3/py2exe/__init__.py 2014-05-12 12:33:17 UTC (rev 746) +++ trunk/py2exe-3/py2exe/__init__.py 2014-05-12 12:33:42 UTC (rev 747) @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """py2exe package """ -__version__ = "0.9.2.0" +__version__ = "0.9.2.1" from .patch_distutils import patch_distutils This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-05-12 12:33:20
|
Revision: 746 http://sourceforge.net/p/py2exe/svn/746 Author: theller Date: 2014-05-12 12:33:17 +0000 (Mon, 12 May 2014) Log Message: ----------- Wrap some long lines. Modified Paths: -------------- trunk/py2exe-3/py2exe/mf3.py Modified: trunk/py2exe-3/py2exe/mf3.py =================================================================== --- trunk/py2exe-3/py2exe/mf3.py 2014-05-12 12:32:54 UTC (rev 745) +++ trunk/py2exe-3/py2exe/mf3.py 2014-05-12 12:33:17 UTC (rev 746) @@ -153,13 +153,16 @@ if level == 0: if fromlist: - text = "%sfrom %s import %s" % (self._indent, name, ", ".join(fromlist)) + caller_info + text = "%sfrom %s import %s" % (self._indent, name, + ", ".join(fromlist)) + caller_info else: text = "%simport %s" % (self._indent, name) + caller_info elif name: - text = "%sfrom %s import %s" % (self._indent, "."*level + name, ", ".join(fromlist)) + caller_info + text = "%sfrom %s import %s" % (self._indent, "."*level + name, + ", ".join(fromlist)) + caller_info else: - text = "%sfrom %s import %s" % (self._indent, "."*level, ", ".join(fromlist)) + caller_info + text = "%sfrom %s import %s" % (self._indent, "."*level, + ", ".join(fromlist)) + caller_info print(text) @@ -242,8 +245,8 @@ def _gcd_import(self, name, package=None, level=0): - """Import and return the module based on its name, the package the call is - being made from, and the level adjustment. + """Import and return the module based on its name, the package + the call is being made from, and the level adjustment. """ # __main__ is always the current main module; do never import that. @@ -253,7 +256,8 @@ self._sanity_check(name, package, level) if level > 0: name = self._resolve_name(name, package, level) - # 'name' is now the fully qualified, absolute name of the module we want to import. + # 'name' is now the fully qualified, absolute name of the + # module we want to import. caller = self.__last_caller.__name__ if self.__last_caller else "-" @@ -477,7 +481,8 @@ print("P", end=" ") else: print("m", end=" ") - print("%-35s" % name, getattr(m, "__file__", "(built-in, frozen, or namespace)")) + print("%-35s" % name, getattr(m, "__file__", + "(built-in, frozen, or namespace)")) deps = sorted(self._depgraph[name]) text = "\n".join(textwrap.wrap(", ".join(deps))) print(" imported from:\n%s" % textwrap.indent(text, " ")) @@ -501,7 +506,8 @@ print() print(" %-35s" % ("%d submodules that appear to be missing, but" - " could also be global names in the parent package" % len(maybe))) + " could also be global names" + " in the parent package" % len(maybe))) print(" %-35s" % "-----------------------------------------" "----------------------------------------------------") @@ -586,7 +592,8 @@ source = self.__source__ if source is not None: # XXX??? for py3exe: - __file__ = self.__file__ if hasattr(self, "__file__") else "<string>" + __file__ = self.__file__ \ + if hasattr(self, "__file__") else "<string>" try: self.__code_object__ = compile(source, __file__, "exec", optimize=self.__optimize__) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-05-12 12:32:56
|
Revision: 745 http://sourceforge.net/p/py2exe/svn/745 Author: theller Date: 2014-05-12 12:32:54 +0000 (Mon, 12 May 2014) Log Message: ----------- Add missing _My_DeactivateActCtx call which caused a lot a trouble. Modified Paths: -------------- trunk/py2exe-3/source/_memimporter.c Modified: trunk/py2exe-3/source/_memimporter.c =================================================================== --- trunk/py2exe-3/source/_memimporter.c 2014-05-09 17:56:11 UTC (rev 744) +++ trunk/py2exe-3/source/_memimporter.c 2014-05-12 12:32:54 UTC (rev 745) @@ -174,6 +174,7 @@ hmem = MyLoadLibrary(pathname, NULL, findproc); if (res) SetDllDirectory(NULL); // restore the default dll directory search path + _My_DeactivateActCtx(cookie); if (!hmem) { char *msg; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-05-09 17:56:13
|
Revision: 744 http://sourceforge.net/p/py2exe/svn/744 Author: theller Date: 2014-05-09 17:56:11 +0000 (Fri, 09 May 2014) Log Message: ----------- Complete a sentence. Modified Paths: -------------- trunk/py2exe-3/README.rst Modified: trunk/py2exe-3/README.rst =================================================================== --- trunk/py2exe-3/README.rst 2014-05-09 17:44:17 UTC (rev 743) +++ trunk/py2exe-3/README.rst 2014-05-09 17:56:11 UTC (rev 744) @@ -243,4 +243,4 @@ Building isapi extensions is not supported: I don't use them so I will not implement this. -The modulefinder does not yet +The modulefinder does not yet support PEP420 implicit namespace packages. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-05-09 17:44:20
|
Revision: 743 http://sourceforge.net/p/py2exe/svn/743 Author: theller Date: 2014-05-09 17:44:17 +0000 (Fri, 09 May 2014) Log Message: ----------- Ready for release. Version 0.9.2.0. Modified Paths: -------------- trunk/py2exe-3/README.rst trunk/py2exe-3/py2exe/__init__.py Added Paths: ----------- trunk/py2exe-3/ChangeLog Added: trunk/py2exe-3/ChangeLog =================================================================== --- trunk/py2exe-3/ChangeLog (rev 0) +++ trunk/py2exe-3/ChangeLog 2014-05-09 17:44:17 UTC (rev 743) @@ -0,0 +1,3 @@ +2014-05-09 <th...@ct...> + + * Releasing py2exe for Python 3, version 0.9.2.0. Modified: trunk/py2exe-3/README.rst =================================================================== --- trunk/py2exe-3/README.rst 2014-05-09 17:25:07 UTC (rev 742) +++ trunk/py2exe-3/README.rst 2014-05-09 17:44:17 UTC (rev 743) @@ -3,9 +3,8 @@ `py2exe` is a distutils extension which allows to build standalone Windows executable programs (32-bit and 64-bit) from Python scripts; -Python 3.3 and Python 3.4 are supported. It can build console -executables, windows (GUI) executables, windows services, and DLL/EXE -COM servers. +Python 3.3 and later are supported. It can build console executables, +windows (GUI) executables, windows services, and DLL/EXE COM servers. py2exe for Python 2 is still available at http://sourceforge.net/project/showfiles.php?group_id=15583. @@ -16,10 +15,24 @@ News ---- +The C-runtime library for Python 3 does NOT need a windows manifest +any longer to load correctly (this is a feature of Python, not of +py2exe). -Create an exe-file with a simple command -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +`py2exe` now contains a hooks module which contains information about +some standard packages. The goal is to fine-tune the build process so +that no (at least less) warnings are emitted from modulefinder. +Thanks to a brand new modulefinder (based on Python's importlib) +py2exe can now find and extract modules even from packages you have +installed as zipped eggs. + +py2exe now longer uses a `build` directory for temporary files. + +It is planned to achive full compatibility with the setup-scripts for +Python 2; however this is probably not yet the case. + + In addition to your beloved setup.py scripts :-), there is now also a command-line utility which allows to build the exe without any effort. @@ -27,7 +40,7 @@ :: - py -3.3 -m py2exe.build_exe myscript.py + py -3.4 -m py2exe.build_exe myscript.py or (if you have the Python ``Scripts`` directory on your PATH): @@ -44,39 +57,17 @@ :: - py -3.3 -m py2exe myscript.py -W mysetup.py + py -3.4 -m py2exe myscript.py -W mysetup.py ... edit myssetup.py - py -3.3 mysetup.py py2exe + py -3.4 mysetup.py py2exe -Hooks -~~~~~ -`py2exe` now contains a hooks module which allows to customize the -build-process. The goal is to fine-tune the build process so that no -warnings are emitted from modulefinder. - -The hooks module is the `py2exe\\hooks.py` file in your installation; -it currently contains hooks for quite some libraries. Patches for -more libraries will gratefully be accepted. - -Windows C-runtime library -~~~~~~~~~~~~~~~~~~~~~~~~~ - -The C-runtime library for Python 3 does NOT need a windows manifest -any longer, unless you have special requirements. - -Compatibility with py2exe for Python 2 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -It is planned to achive full compatibility with the setup-scripts for -Python 2; however this is probably not yet the case. - Installation ------------ :: - py -3.3 -m pip install py2exe + py -3.4 -m pip install py2exe or @@ -251,3 +242,5 @@ Building isapi extensions is not supported: I don't use them so I will not implement this. + +The modulefinder does not yet Modified: trunk/py2exe-3/py2exe/__init__.py =================================================================== --- trunk/py2exe-3/py2exe/__init__.py 2014-05-09 17:25:07 UTC (rev 742) +++ trunk/py2exe-3/py2exe/__init__.py 2014-05-09 17:44:17 UTC (rev 743) @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """py2exe package """ -__version__ = "0.9.1.8" +__version__ = "0.9.2.0" from .patch_distutils import patch_distutils This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-05-09 17:25:10
|
Revision: 742 http://sourceforge.net/p/py2exe/svn/742 Author: theller Date: 2014-05-09 17:25:07 +0000 (Fri, 09 May 2014) Log Message: ----------- Allow and document 'bundle-files == 0' in the setup-script version. Modified Paths: -------------- trunk/py2exe-3/py2exe/distutils_buildexe.py trunk/py2exe-3/py2exe/setup_template.py Modified: trunk/py2exe-3/py2exe/distutils_buildexe.py =================================================================== --- trunk/py2exe-3/py2exe/distutils_buildexe.py 2014-05-08 19:55:04 UTC (rev 741) +++ trunk/py2exe-3/py2exe/distutils_buildexe.py 2014-05-09 17:25:07 UTC (rev 742) @@ -157,8 +157,8 @@ self.includes = fancy_split(self.includes) self.ignores = fancy_split(self.ignores) self.bundle_files = int(self.bundle_files) - if self.bundle_files < 1 or self.bundle_files > 3: - raise ValueError("bundle-files must be 1, 2, or 3, not %s" + if self.bundle_files < 0 or self.bundle_files > 3: + raise ValueError("bundle-files must be 0, 1, 2, or 3, not %s" % self.bundle_files) if self.ascii: warnings.warn("The 'ascii' option is no longer supported, ignored.") Modified: trunk/py2exe-3/py2exe/setup_template.py =================================================================== --- trunk/py2exe-3/py2exe/setup_template.py 2014-05-08 19:55:04 UTC (rev 741) +++ trunk/py2exe-3/py2exe/setup_template.py 2014-05-09 17:25:07 UTC (rev 742) @@ -138,6 +138,12 @@ # and loaded in the normal way. # # bundle_files == 1: +# Extension modules and the Python dll are put into the zipfile or +# the exe/dll files, and everything is loaded without unpacking to +# the file system. This does not work for some dlls, so use with +# caution. +# +# bundle_files == 0: # Extension modules, the Python dll, and other needed dlls are put # into the zipfile or the exe/dll files, and everything is loaded # without unpacking to the file system. This does not work for This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-05-08 19:55:07
|
Revision: 741 http://sourceforge.net/p/py2exe/svn/741 Author: theller Date: 2014-05-08 19:55:04 +0000 (Thu, 08 May 2014) Log Message: ----------- README.rst updates. Modified Paths: -------------- trunk/py2exe-3/README.rst Added Paths: ----------- trunk/py2exe-3/publish/ Property Changed: ---------------- trunk/py2exe-3/ trunk/py2exe-3/py2exe/ Index: trunk/py2exe-3 =================================================================== --- trunk/py2exe-3 2014-05-08 18:40:18 UTC (rev 740) +++ trunk/py2exe-3 2014-05-08 19:55:04 UTC (rev 741) Property changes on: trunk/py2exe-3 ___________________________________________________________________ Added: svn:ignore ## -0,0 +1,2 ## +dist +build Modified: trunk/py2exe-3/README.rst =================================================================== --- trunk/py2exe-3/README.rst 2014-05-08 18:40:18 UTC (rev 740) +++ trunk/py2exe-3/README.rst 2014-05-08 19:55:04 UTC (rev 741) @@ -2,10 +2,13 @@ =================== `py2exe` is a distutils extension which allows to build standalone -Windows executable programs from Python scripts; Python 3.3 and Python -3.4 are supported. +Windows executable programs (32-bit and 64-bit) from Python scripts; +Python 3.3 and Python 3.4 are supported. It can build console +executables, windows (GUI) executables, windows services, and DLL/EXE +COM servers. -`py2exe` for ``Python 2`` is available at http://sourceforge.net/project/showfiles.php?group_id=15583 +py2exe for Python 2 is still available at +http://sourceforge.net/project/showfiles.php?group_id=15583. .. contents:: @@ -13,12 +16,15 @@ News ---- + Create an exe-file with a simple command ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In addition to you beloved setup.py scripts, there is now a -command-line utility which allows to build the exe without any effort: +In addition to your beloved setup.py scripts :-), there is now also a +command-line utility which allows to build the exe without any effort. +Running + :: py -3.3 -m py2exe.build_exe myscript.py @@ -32,9 +38,9 @@ will create an executable `myscript.exe` in the `dist` subdirectory. -If you add the ``-W <setup-script.py>`` switch to the command line it -will write a *commented* ``setup.py`` script for you, which can be -customized further: +If you add the ``-W <setup-script.py>`` switch to the above command +line a *commented* ``setup.py`` script will be generated which can be +used to further customize the exe: :: @@ -119,19 +125,20 @@ relative pathname of the python archive -b option, --bundle-files option - How to bundle the files. 3 - create an .exe, a zip- - archive, and .pyd files in the file system. 2 - create - .exe and a zip-archive that contains the pyd files. + How to bundle the files: + 3 - create script.exe, python.dll, extensions.pyd, others.dll. + 2 - create script.exe, python.dll, others.dll. + 1 - create script.exe, others.dll. + 0 - create script.exe. -W setup_path, --write-setup-script setup_path Do not build the executables; instead write a setup script that allows further customizations of the build process. - --service modname + -svc svnmodule, --service svcmodule The name of a module that contains a service - Using a setup-script -------------------- @@ -140,6 +147,105 @@ switches are the same as before; but they are *NOT* compatible with the command-line switches for the builder mentioned above. +Documentation about the setup-script and other usage tips are in the +wiki pages at http://www.py2exe.org. + + +The bundle-files option explained +--------------------------------- + +The applications that py2exe creates will always need the following +parts: + +1. The exe-file(s) itself. py2exe can build several executables at the + same time; this is especially useful if these are related to each + other since some parts can be shared. +2. The python-dll. +3. The pure python modules needed to run the app. The byte-code for these + modules is always packed into a zip-archive. +4. Compiled python-extension modules. +5. Supporting dlls, if any. + +The bundle-files option determines how these files are packed together +for your application. This is explained with a script ``test_sqlite.py`` +that simply contains this code: + +:: + + import sqlite3 + print(sqlite3) + +The command to build the exe-file is: + +:: + + py2exe.build_exe test_sqlite.py -c --bundle-files <option> + +The ``-c`` option specifies to create a compressed zip-archive. + +``--bundle-files 3`` is the simplest way. These files will be +created in a ``dist`` subdirectory, about 8 MB total size: + +:: + + test_sqlite.exe + _bz2.pyd + _ctypes.pyd + _hashlib.pyd + _lzma.pyd + _socket.pyd + _sqlite3.pyd + _ssl.pyd + _win32sysloader.pyd + pyexpat.pyd + python34.dll + pywintypes34.dll + select.pyd + sqlite3.dll + unicodedata.pyd + win32api.pyd + win32evtlog.pyd + +The zip-archive is appended to the test_sqlite.exe file itself, which +has a size of 1.5 MB in this case. + +``--bundle-files 2`` will include all the Python extensions into the +appended zip-archive; they are loaded via special code at runtime +*without* being unpacked to the file-system. The files in the +``dist`` directory now are these: + +:: + + test_sqlite.exe + python34.dll + sqlite3.dll + +``--bundle-files 1`` will additionally pack the python-dll into the +zip-archive: + +:: + + test_sqlite.exe + sqlite3.dll + +``--bundle-files 0`` now finally creates a real single-file executable +of 6 MB: + +:: + + test_sqlite.exe + +If you are building several related executables that you plan to +distribute together, it may make sense to specify a zip-archive shared +by all the exes with the ``--library libname`` option. The +executables will then become quite small (about 25 kB), since nearly +all code will be in the separate shared archive. + +*Note that not all applications will work with ``bundle-files`` set to +0 or 1*. Be sure to test them. + + + Bugs ---- Index: trunk/py2exe-3/publish =================================================================== --- trunk/py2exe-3/publish 2014-05-08 18:40:18 UTC (rev 740) +++ trunk/py2exe-3/publish 2014-05-08 19:55:04 UTC (rev 741) Property changes on: trunk/py2exe-3/publish ___________________________________________________________________ Added: svn:ignore ## -0,0 +1,2 ## +dist +__pycache__ Index: trunk/py2exe-3/py2exe =================================================================== --- trunk/py2exe-3/py2exe 2014-05-08 18:40:18 UTC (rev 740) +++ trunk/py2exe-3/py2exe 2014-05-08 19:55:04 UTC (rev 741) Property changes on: trunk/py2exe-3/py2exe ___________________________________________________________________ Added: svn:ignore ## -0,0 +1 ## +__pycache__ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-05-08 18:40:22
|
Revision: 740 http://sourceforge.net/p/py2exe/svn/740 Author: theller Date: 2014-05-08 18:40:18 +0000 (Thu, 08 May 2014) Log Message: ----------- py2exe for Python 3. Copied from the repository at https://ctypes-stuff.googlecode.com/svn/trunk/mf where it was developed. Actually it was grown out of some modulefinder experiments with Python 3. Added Paths: ----------- trunk/py2exe-3/ trunk/py2exe-3/LICENSE.txt trunk/py2exe-3/MANIFEST.in trunk/py2exe-3/MIT-License.txt trunk/py2exe-3/MPL2-License.txt trunk/py2exe-3/README.rst trunk/py2exe-3/TODO.txt trunk/py2exe-3/build_exe.py trunk/py2exe-3/py2exe/ trunk/py2exe-3/py2exe/__init__.py trunk/py2exe-3/py2exe/__main__.py trunk/py2exe-3/py2exe/_wapi.py trunk/py2exe-3/py2exe/boot_common.py trunk/py2exe-3/py2exe/boot_ctypes_com_server.py trunk/py2exe-3/py2exe/boot_service.py trunk/py2exe-3/py2exe/build_exe.py trunk/py2exe-3/py2exe/distutils_buildexe.py trunk/py2exe-3/py2exe/dllfinder.py trunk/py2exe-3/py2exe/hooks.py trunk/py2exe-3/py2exe/icons.py trunk/py2exe-3/py2exe/mf3.py trunk/py2exe-3/py2exe/patch_distutils.py trunk/py2exe-3/py2exe/py2exe_distutils.py trunk/py2exe-3/py2exe/resources.py trunk/py2exe-3/py2exe/runtime.py trunk/py2exe-3/py2exe/setup_template.py trunk/py2exe-3/py2exe/versioninfo.py trunk/py2exe-3/py2exe.ods trunk/py2exe-3/setup.py trunk/py2exe-3/source/ trunk/py2exe-3/source/MemoryModule.c trunk/py2exe-3/source/MemoryModule.h trunk/py2exe-3/source/MyLoadLibrary.c trunk/py2exe-3/source/MyLoadLibrary.h trunk/py2exe-3/source/Python-dynload.h trunk/py2exe-3/source/_memimporter.c trunk/py2exe-3/source/actctx.c trunk/py2exe-3/source/actctx.h trunk/py2exe-3/source/dll.c trunk/py2exe-3/source/icon.rc trunk/py2exe-3/source/icon1.ico trunk/py2exe-3/source/python-dynload.c trunk/py2exe-3/source/resource.h trunk/py2exe-3/source/run.c trunk/py2exe-3/source/run_ctypes_dll.c trunk/py2exe-3/source/run_w.c trunk/py2exe-3/source/start.c trunk/py2exe-3/tests/ trunk/py2exe-3/tests/maketest.py trunk/py2exe-3/tests/test_mf.py trunk/py2exe-3/tests/test_modulefinder.py trunk/py2exe-3/zipextimporter.py Added: trunk/py2exe-3/LICENSE.txt =================================================================== --- trunk/py2exe-3/LICENSE.txt (rev 0) +++ trunk/py2exe-3/LICENSE.txt 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,6 @@ +The files source/MemoryModule.c and source/MemoryModule.h are licensed +under the Mozilla Public License Version 2.0, see +MPL2-License.txt. + +All other files are licensed under the MIT/X11 License, +see MIT-License.txt. Added: trunk/py2exe-3/MANIFEST.in =================================================================== --- trunk/py2exe-3/MANIFEST.in (rev 0) +++ trunk/py2exe-3/MANIFEST.in 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,5 @@ +include source/*.c +include source/*.h +include source/*.rc +include source/*.ico +include LICENSE.txt MIT-License.txt MPL2-License.txt \ No newline at end of file Added: trunk/py2exe-3/MIT-License.txt =================================================================== --- trunk/py2exe-3/MIT-License.txt (rev 0) +++ trunk/py2exe-3/MIT-License.txt 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,20 @@ +Copyright (c) 2000-2014 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 +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Added: trunk/py2exe-3/MPL2-License.txt =================================================================== --- trunk/py2exe-3/MPL2-License.txt (rev 0) +++ trunk/py2exe-3/MPL2-License.txt 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. Added: trunk/py2exe-3/README.rst =================================================================== --- trunk/py2exe-3/README.rst (rev 0) +++ trunk/py2exe-3/README.rst 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,147 @@ +py2exe for Python 3 +=================== + +`py2exe` is a distutils extension which allows to build standalone +Windows executable programs from Python scripts; Python 3.3 and Python +3.4 are supported. + +`py2exe` for ``Python 2`` is available at http://sourceforge.net/project/showfiles.php?group_id=15583 + +.. contents:: + + +News +---- + +Create an exe-file with a simple command +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In addition to you beloved setup.py scripts, there is now a +command-line utility which allows to build the exe without any effort: + +:: + + py -3.3 -m py2exe.build_exe myscript.py + +or (if you have the Python ``Scripts`` directory on your PATH): + +:: + + build_exe myscript.py + + +will create an executable `myscript.exe` in the `dist` subdirectory. + +If you add the ``-W <setup-script.py>`` switch to the command line it +will write a *commented* ``setup.py`` script for you, which can be +customized further: + +:: + + py -3.3 -m py2exe myscript.py -W mysetup.py + ... edit myssetup.py + py -3.3 mysetup.py py2exe + +Hooks +~~~~~ + +`py2exe` now contains a hooks module which allows to customize the +build-process. The goal is to fine-tune the build process so that no +warnings are emitted from modulefinder. + +The hooks module is the `py2exe\\hooks.py` file in your installation; +it currently contains hooks for quite some libraries. Patches for +more libraries will gratefully be accepted. + +Windows C-runtime library +~~~~~~~~~~~~~~~~~~~~~~~~~ + +The C-runtime library for Python 3 does NOT need a windows manifest +any longer, unless you have special requirements. + +Compatibility with py2exe for Python 2 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +It is planned to achive full compatibility with the setup-scripts for +Python 2; however this is probably not yet the case. + +Installation +------------ + +:: + + py -3.3 -m pip install py2exe + +or + +:: + + pip install py2exe + + +Using the builder +----------------- + +Build runtime archive for a script: + +:: + + build_exe [-h] [-i modname] [-x modname] [-p package_name] [-O] [-s] + [-r] [-f modname] [-v] [-c] [-d DESTDIR] [-l LIBNAME] + [-b {0,1,2,3}] [-W setup_path] + [-svc service] + [script [script ...]] + + +positional arguments: + script + +optional arguments: + -h, --help show this help message and exit + -i modname, --include modname + module to include + -x modname, --exclude modname + module to exclude + -p package_name, --package package_name + module to exclude + -O, --optimize use optimized bytecode + -s, --summary print a single line listing how many modules were + found and how many modules are missing + -r, --report print a detailed report listing all found modules, the + missing modules, and which module imported them. + -f modname, --from modname + print where the module <modname> is imported. + -v verbose output + -c, --compress create a compressed library + -d DESTDIR, --dest DESTDIR + destination directory + -l LIBNAME, --library LIBNAME + relative pathname of the python archive + + -b option, --bundle-files option + How to bundle the files. 3 - create an .exe, a zip- + archive, and .pyd files in the file system. 2 - create + .exe and a zip-archive that contains the pyd files. + + -W setup_path, --write-setup-script setup_path + Do not build the executables; instead write a setup + script that allows further customizations of the build + process. + + --service modname + The name of a module that contains a service + + +Using a setup-script +-------------------- + +Creating an executable (or more than one at the same time) with a +setup-script works in the same way as for Python 2. The command-line +switches are the same as before; but they are *NOT* compatible with +the command-line switches for the builder mentioned above. + +Bugs +---- + +Building isapi extensions is not supported: I don't use them so I will +not implement this. Added: trunk/py2exe-3/TODO.txt =================================================================== --- trunk/py2exe-3/TODO.txt (rev 0) +++ trunk/py2exe-3/TODO.txt 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,51 @@ +Bugs: + +- debug the 'verbose' argument to py2exe. It defaults to 1, using + '-q' sets it to 0, '-v' doesn't change it, '-vv' sets it to 2. + Strange. + +- Is this true any longer ???: + ctypes com servers (inproc) do not work with bundle_files 2 or 3 + when the same Python version is used in the client. Did this work + at all with py2exe 0.6? + +- distutils catches errors different from DistutilsError (or so) + +- distutils_buildexe needs to import DistutilsOptionError (or so) + +- Does probably not work with extensions built against the limited API + (python3.dll)??? + +- py2exe for Python2 used an 'uac_info' string (exec_level) or tuple + (exec_level, ui_access) attribute on the Target to include or patch + a default manifest. + +- custom_boot_script ? + +- typelib ? + +Ideas: + +- clean up console output when building. + +- add some scripts to inspect executables, like: +- dump_manifest.py +- dump_versioninfo.py +- or even a general resource dumper? + +TODO: + +- services cmdline_style not yet implemented + +Fixed bugs: + + rev 380: - ctypes DLL COM servers can now load dlls (like sqlite3.dll) correctly. + rev 343: - DLL com servers are now implemented + rev 336: - py2exe\dll.dll is not installed. + rev 342: - when installed as egg, py2exe/boot_common.py is not a file and so not found. + rev 342: - number of icons (or icon images) is limited for whatever reason. + rev 342: - extensions are in the wrong directory when library is in a subdirectory + rev 342: - (String) Versioninfo not build? (Needs 'self.version = "6.5"' attribute in Target???) + Must include this into setup_template.py! + rev 342: - services not yet implemented + Added: trunk/py2exe-3/build_exe.py =================================================================== --- trunk/py2exe-3/build_exe.py (rev 0) +++ trunk/py2exe-3/build_exe.py 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,8 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +"""build_exe script.""" + +from py2exe.build_exe import main + +if __name__ == "__main__": + main() Added: trunk/py2exe-3/py2exe/__init__.py =================================================================== --- trunk/py2exe-3/py2exe/__init__.py (rev 0) +++ trunk/py2exe-3/py2exe/__init__.py 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,9 @@ +#!/usr/bin/python3,3 +# -*- coding: utf-8 -*- +"""py2exe package +""" +__version__ = "0.9.1.8" + +from .patch_distutils import patch_distutils + +patch_distutils() Added: trunk/py2exe-3/py2exe/__main__.py =================================================================== --- trunk/py2exe-3/py2exe/__main__.py (rev 0) +++ trunk/py2exe-3/py2exe/__main__.py 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,8 @@ +#!/usr/bin/python3.3 +# -*- coding: utf-8 -*- +"""py2exe.__main__ +""" + +if __name__ == "__main__": + from . import build_exe + build_exe.main() Added: trunk/py2exe-3/py2exe/_wapi.py =================================================================== --- trunk/py2exe-3/py2exe/_wapi.py (rev 0) +++ trunk/py2exe-3/py2exe/_wapi.py 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,126 @@ +"""Some Windows api functions, data types, and constants.""" +from ctypes import * + +_kernel32 = WinDLL("kernel32") +_imagehlp = WinDLL("imagehlp") + +def BOOL_errcheck(result, func, args): + if result: + return result + raise WinError() + +## if __debug__: +## from ctypeslib.dynamic_module import include +## # 0x0502: Windows XP SP2 +## # 0x0600: (Internet Explorer 6) shell32.dll version 6 +## include("""\ +## #define UNICODE +## #define NO_STRICT +## #define WINVER 0x0502 +## #define _WIN32_WINNT 0x0502 +## #define _WIN32_IE 0x0600 +## #include <windows.h> +## #include <imagehlp.h> +## """, +## persist=True) + +WSTRING = c_wchar_p +STRING = c_char_p +UINT = c_uint +WCHAR = c_wchar +LPWSTR = WSTRING +GetWindowsDirectoryW = _kernel32.GetWindowsDirectoryW +GetWindowsDirectoryW.restype = UINT +GetWindowsDirectoryW.argtypes = [LPWSTR, UINT] +GetSystemDirectoryW = _kernel32.GetSystemDirectoryW +GetSystemDirectoryW.restype = UINT +GetSystemDirectoryW.argtypes = [LPWSTR, UINT] +DWORD = c_ulong +PVOID = c_void_p +HANDLE = PVOID +HINSTANCE = HANDLE +HMODULE = HINSTANCE +GetModuleFileNameW = _kernel32.GetModuleFileNameW +GetModuleFileNameW.restype = DWORD +GetModuleFileNameW.argtypes = [HMODULE, LPWSTR, DWORD] +BOOL = c_int + +# values for enumeration '_IMAGEHLP_STATUS_REASON' +BindOutOfMemory = 0 +BindRvaToVaFailed = 1 +BindNoRoomInImage = 2 +BindImportModuleFailed = 3 +BindImportProcedureFailed = 4 +BindImportModule = 5 +BindImportProcedure = 6 +BindForwarder = 7 +BindForwarderNOT = 8 +BindImageModified = 9 +BindExpandFileHeaders = 10 +BindImageComplete = 11 +BindMismatchedSymbols = 12 +BindSymbolsNotUpdated = 13 +BindImportProcedure32 = 14 +BindImportProcedure64 = 15 +BindForwarder32 = 16 +BindForwarder64 = 17 +BindForwarderNOT32 = 18 +BindForwarderNOT64 = 19 +_IMAGEHLP_STATUS_REASON = c_int # enum +CHAR = c_char +PIMAGEHLP_STATUS_ROUTINE = WINFUNCTYPE(BOOL, _IMAGEHLP_STATUS_REASON, STRING, STRING, c_ulong, c_ulong) +PSTR = STRING +BindImageEx = _imagehlp.BindImageEx +BindImageEx.restype = BOOL +BindImageEx.argtypes = [DWORD, PSTR, PSTR, PSTR, PIMAGEHLP_STATUS_ROUTINE] +BindImageEx.errcheck = BOOL_errcheck +BIND_ALL_IMAGES = 4 # Variable c_int +BIND_CACHE_IMPORT_DLLS = 8 # Variable c_int +BIND_NO_UPDATE = 2 # Variable c_int +LPCWSTR = WSTRING +SearchPathW = _kernel32.SearchPathW +SearchPathW.restype = DWORD +SearchPathW.argtypes = [LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPWSTR, POINTER(LPWSTR)] +BeginUpdateResourceW = _kernel32.BeginUpdateResourceW +BeginUpdateResourceW.restype = HANDLE +BeginUpdateResourceW.argtypes = [LPCWSTR, BOOL] +WORD = c_ushort +LPVOID = c_void_p +UpdateResourceW = _kernel32.UpdateResourceW +UpdateResourceW.restype = BOOL +UpdateResourceW.argtypes = [HANDLE, LPCWSTR, LPCWSTR, WORD, LPVOID, DWORD] +UpdateResourceW.errcheck = BOOL_errcheck +EndUpdateResourceW = _kernel32.EndUpdateResourceW +EndUpdateResourceW.restype = BOOL +EndUpdateResourceW.argtypes = [HANDLE, BOOL] +EndUpdateResourceW.errcheck = BOOL_errcheck +LPCSTR = STRING +UpdateResourceA = _kernel32.UpdateResourceA +UpdateResourceA.restype = BOOL +UpdateResourceA.argtypes = [HANDLE, LPCSTR, LPCSTR, WORD, LPVOID, DWORD] +UpdateResourceA.errcheck = BOOL_errcheck +RT_STRING = 6 # Variable WSTRING +RT_VERSION = 16 # Variable WSTRING +class tagVS_FIXEDFILEINFO(Structure): + pass +VS_FIXEDFILEINFO = tagVS_FIXEDFILEINFO +tagVS_FIXEDFILEINFO._fields_ = [ + ('dwSignature', DWORD), + ('dwStrucVersion', DWORD), + ('dwFileVersionMS', DWORD), + ('dwFileVersionLS', DWORD), + ('dwProductVersionMS', DWORD), + ('dwProductVersionLS', DWORD), + ('dwFileFlagsMask', DWORD), + ('dwFileFlags', DWORD), + ('dwFileOS', DWORD), + ('dwFileType', DWORD), + ('dwFileSubtype', DWORD), + ('dwFileDateMS', DWORD), + ('dwFileDateLS', DWORD), +] +VFT_APP = 1 # Variable c_long +VOS_NT_WINDOWS32 = 262148 # Variable c_long +BYTE = c_ubyte +RT_ICON = 3 # Variable WSTRING +RT_GROUP_ICON = 14 # Variable WSTRING Added: trunk/py2exe-3/py2exe/boot_common.py =================================================================== --- trunk/py2exe-3/py2exe/boot_common.py (rev 0) +++ trunk/py2exe-3/py2exe/boot_common.py 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,104 @@ +# Common py2exe boot script - executed for all target types. + +# When we are a windows_exe we have no console, and writing to +# sys.stderr or sys.stdout will sooner or later raise an exception, +# and tracebacks will be lost anyway (see explanation below). +# +# We assume that output to sys.stdout can go to the bitsink, but we +# *want* to see tracebacks. So we redirect sys.stdout into an object +# with a write method doing nothing, and sys.stderr into a logfile +# having the same name as the executable, with '.log' appended. +# +# We only open the logfile if something is written to sys.stderr. +# +# If the logfile cannot be opened for *any* reason, we have no choice +# but silently ignore the error. +# +# It remains to be seen if the 'a' flag for opening the logfile is a +# good choice, or 'w' would be better. +# +# More elaborate explanation on why this is needed: +# +# The sys.stdout and sys.stderr that GUI programs get (from Windows) are +# more than useless. This is not a py2exe problem, pythonw.exe behaves +# in the same way. +# +# To demonstrate, run this program with pythonw.exe: +# +# import sys +# sys.stderr = open("out.log", "w") +# for i in range(10000): +# print i +# +# and open the 'out.log' file. It contains this: +# +# Traceback (most recent call last): +# File "out.py", line 6, in ? +# print i +# IOError: [Errno 9] Bad file descriptor +# +# In other words, after printing a certain number of bytes to the +# system-supplied sys.stdout (or sys.stderr) an exception will be raised. +# + +import sys +import os +import ctypes + +##print("this is boot_common") +##print("PATH", repr(sys.path[0]), "thats it.") + +if sys.frozen == "windows_exe": + class Stderr(object): + _file = None + _error = None + def write(self, text, alert=ctypes.windll.user32.MessageBoxW, + fname=os.path.splitext(sys.executable)[0] + '.log'): + if self._file is None and self._error is None: + import atexit, os, sys + try: + self._file = open(fname, 'a') + except Exception as details: + self._error = details + atexit.register(alert, 0, + "The logfile '%s' could not be opened:\n %s" % \ + (fname, details), + "Errors in %r" % os.path.basename(sys.executable), + 0) + else: + atexit.register(alert, 0, + "See the logfile '%s' for details" % fname, + "Errors in %r" % os.path.basename(sys.executable), + 0) + if self._file is not None: + self._file.write(text) + self._file.flush() + def flush(self): + if self._file is not None: + self._file.flush() + sys.stderr = Stderr() + del Stderr + + class Blackhole(object): + softspace = 0 + def write(self, text): + pass + def flush(self): + pass + sys.stdout = Blackhole() + del Blackhole +del sys, ctypes + +## # Disable linecache.getline() which is called by +## # traceback.extract_stack() when an exception occurs to try and read +## # the filenames embedded in the packaged python code. This is really +## # annoying on windows when the d: or e: on our build box refers to +## # someone elses removable or network drive so the getline() call +## # causes it to ask them to insert a disk in that drive. +## import linecache +## def fake_getline(filename, lineno, module_globals=None): +## return '' +## linecache.orig_getline = linecache.getline +## linecache.getline = fake_getline +## +##del linecache, fake_getline Added: trunk/py2exe-3/py2exe/boot_ctypes_com_server.py =================================================================== --- trunk/py2exe-3/py2exe/boot_ctypes_com_server.py (rev 0) +++ trunk/py2exe-3/py2exe/boot_ctypes_com_server.py 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,89 @@ +# This support script is executed as the entry point for ctypes com servers. +# XXX Currently, this is always run as part of a dll. + +import sys +import _ctypes + +if 1: + ################################################################ + # XXX Remove later! + import ctypes + class LOGGER: + def __init__(self): + self.softspace = None + def write(self, text): + if isinstance(text, str): + ctypes.windll.kernel32.OutputDebugStringW(text) + else: + ctypes.windll.kernel32.OutputDebugStringA(text) + sys.stderr = sys.stdout = LOGGER() +## sys.stderr.write("PATH is %s\n" % sys.path) + +################################################################ +# tell the win32 COM registering/unregistering code that we're inside +# of an EXE/DLL + +if not hasattr(sys, "frozen"): + # standard exes have none. + sys.frozen = _ctypes.frozen = 1 +else: + # com DLLs already have sys.frozen set to 'dll' + _ctypes.frozen = sys.frozen + +# Add some extra imports here, just to avoid putting them as "hidden imports" +# anywhere else - this script has the best idea about what it needs. +# (and hidden imports are currently disabled :) +#... + +# We assume that py2exe has magically set com_module_names +# to the module names that expose the COM objects we host. +# Note that here all the COM modules for the app are imported - hence any +# environment changes (such as sys.stderr redirection) will happen now. +try: + com_module_names +except NameError: + print("This script is designed to be run from inside py2exe % s" % str(details)) + sys.exit(1) + +com_modules = [] +for name in com_module_names: + __import__(name) + com_modules.append(sys.modules[name]) + +def get_classes(module): + return [ob + for ob in module.__dict__.values() + if hasattr(ob, "_reg_progid_") + ] + +def build_class_map(): + # Set _clsid_to_class in comtypes.server.inprocserver. + # + # This avoids the need to have registry entries pointing to the + # COM server class. + classmap = {} + for mod in com_modules: + # dump each class + for cls in get_classes(mod): + classmap[cls._reg_clsid_] = cls + import comtypes.server.inprocserver + comtypes.server.inprocserver._clsid_to_class = classmap +build_class_map() +del build_class_map + +def DllRegisterServer(): + # Enumerate each module implementing an object + from comtypes.server.register import register + for mod in com_modules: + # register each class + for cls in get_classes(mod): + register(cls) + + +def DllUnregisterServer(): + # Enumerate each module implementing an object + from comtypes.server.register import unregister + for mod in com_modules: + # unregister each class + for cls in get_classes(mod): + unregister(cls) Added: trunk/py2exe-3/py2exe/boot_service.py =================================================================== --- trunk/py2exe-3/py2exe/boot_service.py (rev 0) +++ trunk/py2exe-3/py2exe/boot_service.py 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,200 @@ +# boot_service.py +import sys +import os +import servicemanager +import win32service +import win32serviceutil +import winerror +# We assume that py2exe has magically set service_module_names +# to the module names that expose the services we host. +service_klasses = [] +try: + service_module_names +except NameError: + print("This script is designed to be run from inside py2exe") + sys.exit(1) + +for name in service_module_names: + # Use the documented fact that when a fromlist is present, + # __import__ returns the innermost module in 'name'. + # 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(): + if hasattr(ob, "_svc_name_"): + service_klasses.append(ob) + +if not service_klasses: + raise RuntimeError("No service classes found") + +# Event source records come from servicemanager +evtsrc_dll = os.path.abspath(servicemanager.__file__) + +# Tell the Python servicemanager what classes we host. +if len(service_klasses)==1: + k = service_klasses[0] + # One service - make the event name the same as the service. + servicemanager.Initialize(k._svc_name_, evtsrc_dll) + # And the class that hosts it. + servicemanager.PrepareToHostSingle(k) +else: + # Multiple services (NOTE - this hasn't been tested!) + # Use the base name of the exe as the event source + servicemanager.Initialize(os.path.basename(sys.executable), evtsrc_dll) + for k in service_klasses: + servicemanager.PrepareToHostMultiple(k._svc_name_, k) + +################################################################ + +if cmdline_style == "py2exe": + # Simulate the old py2exe service command line handling (to some extent) + # This could do with some re-thought + + class GetoptError(Exception): + pass + + def w_getopt(args, options): + """A getopt for Windows style command lines. + + Options may start with either '-' or '/', the option names may + have more than one letter (examples are /tlb or -RegServer), and + option names are case insensitive. + + Returns two elements, just as getopt.getopt. The first is a list + of (option, value) pairs in the same way getopt.getopt does, but + there is no '-' or '/' prefix to the option name, and the option + name is always lower case. The second is the list of arguments + which do not belong to any option. + + Different from getopt.getopt, a single argument not belonging to an option + does not terminate parsing. + """ + opts = [] + arguments = [] + while args: + if args[0][:1] in "/-": + arg = args[0][1:] # strip the '-' or '/' + arg = arg.lower() + if arg + ':' in options: + try: + opts.append((arg, args[1])) + except IndexError: + 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]) + args = args[1:] + else: + arguments.append(args[0]) + args = args[1:] + + return opts, arguments + + options = "help install remove auto disabled interactive user: password:".split() + + def usage(): + print("Services are supposed to be run by the system after they have been installed.") + print("These command line options are available for (de)installation:") + for opt in options: + if opt.endswith(":"): + print("\t-%s <arg>" % opt) + else: + print("\t-%s" % opt) + print() + + try: + opts, args = w_getopt(sys.argv[1:], options) + except GetoptError as detail: + print(detail) + usage() + sys.exit(1) + + if opts: + startType = None + bRunInteractive = 0 + serviceDeps = None + userName = None + password = None + + do_install = False + do_remove = False + + done = False + + for o, a in opts: + if o == "help": + usage() + done = True + elif o == "install": + do_install = True + elif o == "remove": + do_remove = True + elif o == "auto": + startType = win32service.SERVICE_AUTO_START + elif o == "disabled": + startType = win32service.SERVICE_DISABLED + elif o == "user": + userName = a + elif o == "password": + password = a + elif o == "interactive": + bRunInteractive = True + + if do_install: + for k in service_klasses: + svc_display_name = getattr(k, "_svc_display_name_", k._svc_name_) + svc_deps = getattr(k, "_svc_deps_", None) + win32serviceutil.InstallService(None, + k._svc_name_, + svc_display_name, + exeName = sys.executable, + userName = userName, + password = password, + startType = startType, + bRunInteractive = bRunInteractive, + serviceDeps = svc_deps, + description = getattr(k, "_svc_description_", None), + ) + done = True + + if do_remove: + for k in service_klasses: + win32serviceutil.RemoveService(k._svc_name_) + done = True + + if done: + sys.exit(0) + else: + usage() + + print("Connecting to the Service Control Manager") + servicemanager.StartServiceCtrlDispatcher() + +elif cmdline_style == "pywin32": + assert len(service_klasses) == 1, "Can only handle 1 service!" + k = service_klasses[0] + if len(sys.argv) == 1: + try: + servicemanager.StartServiceCtrlDispatcher() + except win32service.error as details: + if details[0] == winerror.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: + win32serviceutil.usage() + else: + win32serviceutil.HandleCommandLine(k) + +elif cmdline_style == "custom": + assert len(service_module_names) == 1, "Can only handle 1 service!" + # Unlike services implemented in .py files, when a py2exe service exe is + # executed without args, it may mean the service is being started. + if len(sys.argv) == 1: + try: + servicemanager.StartServiceCtrlDispatcher() + except win32service.error as details: + if details[0] == winerror.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: + win32serviceutil.usage() + else: + # assume/insist that the module provides a HandleCommandLine function. + mod = sys.modules[service_module_names[0]] + mod.HandleCommandLine() Added: trunk/py2exe-3/py2exe/build_exe.py =================================================================== --- trunk/py2exe-3/py2exe/build_exe.py (rev 0) +++ trunk/py2exe-3/py2exe/build_exe.py 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,145 @@ +#!/usr/bin/python3.3 +# -*- coding: utf-8 -*- +import argparse +import logging +import os +import textwrap +from . import runtime + +def main(): + parser = argparse.ArgumentParser(description="Build runtime archive for a script", + formatter_class=argparse.RawTextHelpFormatter) + + # what to include, what to exclude... + parser.add_argument("-i", "--include", + help="module to include", + dest="includes", + metavar="modname", + action="append" + ) + parser.add_argument("-x", "--exclude", + help="module to exclude", + dest="excludes", + metavar="modname", + action="append") + parser.add_argument("-p", "--package", + help="module to exclude", + dest="packages", + metavar="package_name", + action="append") + + # how to compile the code... + parser.add_argument("-O", "--optimize", + help="use optimized bytecode", + dest="optimize", + action="count") + + # reporting options... + parser.add_argument("-s", "--summary", + help="""print a single line listing how many modules were + found and how many modules are missing""", + dest="summary", + action="store_true") + parser.add_argument("-r", "--report", + help="""print a detailed report listing all found modules, + the missing modules, and which module imported them.""", + dest="report", + action="store_true") + parser.add_argument("-f", "--from", + help="""print where the module <modname> is imported.""", + metavar="modname", + dest="show_from", + action="append") + + parser.add_argument("-v", + dest="verbose", + action="store_true") + + parser.add_argument("-c", "--compress", + dest="compress", + action="store_true") + + # what to build + parser.add_argument("-d", "--dest", +## required=True, + default="dist", + help="""destination directory""", + dest="destdir") + + parser.add_argument("-l", "--library", + help="""relative pathname of the python archive""", + dest="libname") + + parser.add_argument("-b", "--bundle-files", + help=textwrap.dedent("""\ + How to bundle the files: + 3 - create script.exe, python.dll, extensions.pyd, others.dll. + 2 - create script.exe, python.dll, others.dll. + 1 - create script.exe, others.dll. + 0 - create script.exe. + """), + choices=[0, 1, 2, 3], + type=int, + default=3) + + parser.add_argument("-W", "--write-setup-script", + help=textwrap.dedent("""\ + Do not build the executables; instead write a setup script that allows + further customizations of the build process. + """), + metavar="setup_path", + dest="setup_path") + + # exe files to build... + parser.add_argument("script", + metavar="script", + nargs="*", + ) + + parser.add_argument("-svc", "--service", + help="""Build a service""", + metavar="service", + action="append", + ) + + + options = parser.parse_args() + if not options.service and not options.script: + parser.error("nothing to build") + + options.service = runtime.fixup_targets(options.service, "modules") + for target in options.service: + target.exe_type = "service" + + options.script = runtime.fixup_targets(options.script, "script") + for target in options.script: + if target.script.endswith(".pyw"): + target.exe_type = "windows_exe" + else: + target.exe_type = "console_exe" + + if options.setup_path: + if os.path.isfile(options.setup_path): + message = "File %r already exists, are you sure you want to overwrite it? [yN]: " + answer = input(message % options.setup_path) + if answer not in "yY": + print("Canceled.") + return + from .setup_template import write_setup + write_setup(options) + # no further action + return + + options.data_files = None + options.com_servers = [] + options.unbuffered = False + + level = logging.INFO if options.verbose else logging.WARNING + logging.basicConfig(level=level) + + builder = runtime.Runtime(options) + builder.analyze() + builder.build() + +if __name__ == "__main__": + main() Added: trunk/py2exe-3/py2exe/distutils_buildexe.py =================================================================== --- trunk/py2exe-3/py2exe/distutils_buildexe.py (rev 0) +++ trunk/py2exe-3/py2exe/distutils_buildexe.py 2014-05-08 18:40:18 UTC (rev 740) @@ -0,0 +1,1742 @@ +import sys +import warnings + +from distutils.core import Command + +## from distutils.spawn import spawn +## from distutils.errors import * +## import sys, os, imp, types, stat +## import marshal +## import zipfile +## try: +## set +## except NameError: +## from sets import Set as set +## import tempfile +## import struct +## import re +## import fnmatch + +## is_win64 = struct.calcsize("P") == 8 + +## def _is_debug_build(): +## for ext, _, _ in imp.get_suffixes(): +## if ext == "_d.pyd": +## return True +## return False + +## is_debug_build = _is_debug_build() + +## if is_debug_build: +## python_dll = "python%d%d_d.dll" % sys.version_info[:2] +## else: +## python_dll = "python%d%d.dll" % sys.version_info[:2] + +## # 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'] +## _c_suffixes = [_triple[0] for _triple in imp.get_suffixes() +## if _triple[2] == imp.C_EXTENSION] + +## def imp_find_module(name): +## # same as imp.find_module, but handles dotted names +## names = name.split('.') +## path = None +## for name in names: +## result = imp.find_module(name, path) +## path = [result[1]] +## return result + +def fancy_split(str, sep=","): + # a split which also strips whitespace from the items + # passing a list or tuple will return it unchanged + if str is None: + return [] + if hasattr(str, "split"): + return [item.strip() for item in str.split(sep)] + return str + +## def ensure_unicode(text): +## if isinstance(text, unicode): +## return text +## return text.decode("mbcs") + +## # This loader locates extension modules relative to the library.zip +## # file when an archive is used (i.e., skip_archive is not used), otherwise +## # it locates extension modules relative to sys.prefix. +## LOADER = """ +## def __load(): +## import imp, os, sys +## try: +## dirname = os.path.dirname(__loader__.archive) +## except NameError: +## dirname = sys.prefix +## path = os.path.join(dirname, '%s') +## #print "py2exe extension module", __name__, "->", path +## mod = imp.load_dynamic(__name__, path) +## ## mod.frozen = 1 +## __load() +## del __load +## """ + + +from . import runtime + + +class py2exe(Command): + description = "" + # List of option tuples: long name, short name (None if no short + # name), and help string. + user_options = [ + ('optimize=', 'O', + "optimization level: -O1 for \"python -O\", " + "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), + ('dist-dir=', 'd', + "directory to put final built distributions in (default is dist)"), + + ("excludes=", 'e', + "comma-separated list of modules to exclude"), + ("dll-excludes=", None, + "comma-separated list of DLLs to exclude"), + ("ignores=", None, + "comma-separated list of modules to ignore if they are not found"), + ("includes=", 'i', + "comma-separated list of modules to include"), + ("packages=", 'p', + "comma-separated list of packages to include"), + + ("compressed", 'c', + "create a compressed zipfile"), + + ("xref", 'x', + "create and show a module cross reference"), + + ("bundle-files=", 'b', + "bundle dlls in the zipfile or the exe. Valid levels are 1, 2, or 3 (default)"), + + ("skip-archive", None, + "do not place Python bytecode files in an archive, put them directly in the file system"), + + ("ascii", 'a', + "do not automatically include encodings and codecs"), + + ('custom-boot-script=', None, + "Python file that will be run when setting up the runtime environment"), + ] + + boolean_options = ["compressed", "xref", "ascii", "skip-archive"] + + def initialize_options (self): + self.xref =0 + self.compressed = 0 + self.unbuffered = 0 + self.optimize = 0 + self.includes = None + self.excludes = None + self.ignores = None + self.packages = None + self.dist_dir = None + self.dll_excludes = None + self.typelibs = None + self.bundle_files = 3 + self.skip_archive = 0 + self.ascii = 0 + self.custom_boot_script = None + + def finalize_options (self): + self.optimize = int(self.optimize) + self.excludes = fancy_split(self.excludes) + self.includes = fancy_split(self.includes) + self.ignores = fancy_split(self.ignores) + self.bundle_files = int(self.bundle_files) + if self.bundle_files < 1 or self.bundle_files > 3: + raise ValueError("bundle-files must be 1, 2, or 3, not %s" + % self.bundle_files) + if self.ascii: + warnings.warn("The 'ascii' option is no longer supported, ignored.") + if self.s... [truncated message content] |
From: <th...@us...> - 2014-05-08 18:19:53
|
Revision: 739 http://sourceforge.net/p/py2exe/svn/739 Author: theller Date: 2014-05-08 18:19:51 +0000 (Thu, 08 May 2014) Log Message: ----------- Remove py3exe. Failed attempt. Removed Paths: ------------- trunk/py3exe/ 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. |
From: <th...@us...> - 2013-07-10 20:16:41
|
Revision: 737 http://sourceforge.net/p/py2exe/svn/737 Author: theller Date: 2013-07-10 20:16:39 +0000 (Wed, 10 Jul 2013) Log Message: ----------- Enable full logging, and log to stderr. Modified Paths: -------------- trunk/py2exe/source/MyLoadLibrary.c Modified: trunk/py2exe/source/MyLoadLibrary.c =================================================================== --- trunk/py2exe/source/MyLoadLibrary.c 2013-07-02 05:53:55 UTC (rev 736) +++ trunk/py2exe/source/MyLoadLibrary.c 2013-07-10 20:16:39 UTC (rev 737) @@ -71,7 +71,7 @@ putchar(' '); putchar(' '); } - return vprintf(fmt, marker) + 2*level; + return vfprintf(stderr, fmt, marker) + 2*level; #else return 0; #endif @@ -221,11 +221,11 @@ FARPROC proc; LIST *lib = _FindMemoryModule(NULL, module); if (lib) { -// dprintf("MyGetProcAddress(%p, %p(%s))\n", module, procname, HIWORD(procname) ? procname : ""); -// PUSH(); + dprintf("MyGetProcAddress(%p, %p(%s))\n", module, procname, HIWORD(procname) ? procname : ""); + PUSH(); proc = MemoryGetProcAddress(lib->module, procname); -// POP(); -// dprintf("MyGetProcAddress(%p, %p(%s))\n", module, procname, HIWORD(procname) ? procname : "", proc); + POP(); + dprintf("MyGetProcAddress(%p, %p(%s)) -> %p\n", module, procname, HIWORD(procname) ? 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-06-30 18:03:10
|
Revision: 735 http://sourceforge.net/p/py2exe/svn/735 Author: theller Date: 2013-06-30 18:03:08 +0000 (Sun, 30 Jun 2013) Log Message: ----------- Add options for easier debugging. Modified Paths: -------------- trunk/py2exe/setup.py Modified: trunk/py2exe/setup.py =================================================================== --- trunk/py2exe/setup.py 2013-06-30 18:02:34 UTC (rev 734) +++ trunk/py2exe/setup.py 2013-06-30 18:03:08 UTC (rev 735) @@ -373,6 +373,14 @@ macros.append(("USE_BINARY_SEARCH", '1')) +extra_compile_args = [] +extra_link_args = [] + +if 0: + # enable this to debug a release build + extra_compile_args.append("/Z7") + extra_link_args.append("/DEBUG") + ##macros.append(("AS_PY2EXE_BUILTIN", "1")) # for runtime linking python.dll in _memimporter.c depends = ["source/import-tab.c", "source/import-tab.h"] @@ -383,6 +391,8 @@ "source/actctx.c"], depends=depends, define_macros=macros + [("STANDALONE", "1")], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, ) run = Interpreter("py2exe.run", @@ -395,6 +405,8 @@ ], depends=depends, define_macros=macros, + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, ) run_w = Interpreter("py2exe.run_w", @@ -408,6 +420,8 @@ libraries=["user32"], depends=depends, define_macros=macros, + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, ) run_dll = Interpreter("py2exe.run_dll", @@ -427,6 +441,8 @@ target_desc = "shared_library", depends=depends, define_macros=macros, + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, ) run_ctypes_dll = Interpreter("py2exe.run_ctypes_dll", @@ -446,6 +462,8 @@ target_desc = "shared_library", depends=depends, define_macros=macros, + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, ) run_isapi = Interpreter("py2exe.run_isapi", @@ -465,12 +483,12 @@ target_desc = "shared_library", depends=depends, define_macros=macros, + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, ) interpreters = [run, run_w, run_dll, run_ctypes_dll, run_isapi] -options = {"bdist_wininst": {"install_script": "py2exe_postinstall.py"}} - setup(name="py2exe", version=__version__, description="Build standalone executables for Windows", @@ -502,7 +520,6 @@ packages=['py2exe', 'py2exe.resources', ], - options = options, ) # Local Variables: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2013-06-30 18:02:41
|
Revision: 734 http://sourceforge.net/p/py2exe/svn/734 Author: theller Date: 2013-06-30 18:02:34 +0000 (Sun, 30 Jun 2013) Log Message: ----------- Fix crash in GetProcAddress for functions exported only by ordinal. Modified Paths: -------------- trunk/py2exe/source/MemoryModule.c Modified: trunk/py2exe/source/MemoryModule.c =================================================================== --- trunk/py2exe/source/MemoryModule.c 2013-06-30 18:01:52 UTC (rev 733) +++ trunk/py2exe/source/MemoryModule.c 2013-06-30 18:02:34 UTC (rev 734) @@ -519,26 +519,32 @@ 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; - } + if (!IS_INTRESOURCE(name)) { + // 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 + idx = (int)name; #else - // 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 (!IS_INTRESOURCE(name)) { + // 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; + } + } + } else + idx = (int)name; #endif if (idx == -1) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2013-06-30 18:01:54
|
Revision: 733 http://sourceforge.net/p/py2exe/svn/733 Author: theller Date: 2013-06-30 18:01:52 +0000 (Sun, 30 Jun 2013) Log Message: ----------- Fix debug print. Modified Paths: -------------- trunk/py2exe/source/MyLoadLibrary.c Modified: trunk/py2exe/source/MyLoadLibrary.c =================================================================== --- trunk/py2exe/source/MyLoadLibrary.c 2013-06-23 19:33:35 UTC (rev 732) +++ trunk/py2exe/source/MyLoadLibrary.c 2013-06-30 18:01:52 UTC (rev 733) @@ -221,11 +221,11 @@ FARPROC proc; LIST *lib = _FindMemoryModule(NULL, module); if (lib) { -// dprintf("MyGetProcAddress(%p, %s)\n", module, procname); +// dprintf("MyGetProcAddress(%p, %p(%s))\n", module, procname, HIWORD(procname) ? procname : ""); // PUSH(); proc = MemoryGetProcAddress(lib->module, procname); // POP(); -// dprintf("MyGetProcAddress(%p, %s) -> %p\n", module, procname, proc); +// dprintf("MyGetProcAddress(%p, %p(%s))\n", module, procname, HIWORD(procname) ? 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-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-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:19:42
|
Revision: 730 http://sourceforge.net/p/py2exe/svn/730 Author: theller Date: 2013-06-23 19:19:39 +0000 (Sun, 23 Jun 2013) Log Message: ----------- Add Microsoft.VC90.CRT to the manifest. Add the VC90.CRT assembly to data_files. Modified Paths: -------------- trunk/py2exe/py2exe/samples/advanced/setup.py Modified: trunk/py2exe/py2exe/samples/advanced/setup.py =================================================================== --- trunk/py2exe/py2exe/samples/advanced/setup.py 2013-06-22 14:43:32 UTC (rev 729) +++ trunk/py2exe/py2exe/samples/advanced/setup.py 2013-06-23 19:19:39 UTC (rev 730) @@ -60,6 +60,17 @@ /> </dependentAssembly> </dependency> +<dependency> + <dependentAssembly> + <assemblyIdentity + type="win32" + name="Microsoft.VC90.CRT" + version="9.0.21022.8" + processorArchitecture="*" + publicKeyToken="1fc8b3b9a1e18e3b" + /> + </dependentAssembly> +</dependency> </assembly> ''' @@ -124,6 +135,9 @@ dll_excludes = "MSVCP90.dll mswsock.dll powrprof.dll".split() +from glob import glob +data_files = [("Microsoft.VC90.CRT", glob(r'C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\amd64\Microsoft.VC90.CRT\*.*'))] + setup( options = {"py2exe": {"typelibs": # typelib for WMI @@ -137,6 +151,7 @@ # Can include a subdirectory name. zipfile = "lib/shared.zip", + data_files = data_files, service = [myservice], com_server = [interp], console = [test_wx_console, test_wmi], This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2013-06-22 14:43:36
|
Revision: 729 http://sourceforge.net/p/py2exe/svn/729 Author: theller Date: 2013-06-22 14:43:32 +0000 (Sat, 22 Jun 2013) Log Message: ----------- Use "*" for processorarchitecture in the manifest. Add some dll_excludes. Modified Paths: -------------- trunk/py2exe/py2exe/samples/advanced/setup.py trunk/py2exe/py2exe/samples/singlefile/gui/setup.py Modified: trunk/py2exe/py2exe/samples/advanced/setup.py =================================================================== --- trunk/py2exe/py2exe/samples/advanced/setup.py 2013-06-22 14:42:30 UTC (rev 728) +++ trunk/py2exe/py2exe/samples/advanced/setup.py 2013-06-22 14:43:32 UTC (rev 729) @@ -43,7 +43,7 @@ <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity version="5.0.0.0" - processorArchitecture="x86" + processorArchitecture="*" name="%(prog)s" type="win32" /> @@ -54,7 +54,7 @@ type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" - processorArchitecture="X86" + processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" /> @@ -122,6 +122,8 @@ excludes = ["pywin", "pywin.debugger", "pywin.debugger.dbgcon", "pywin.dialogs", "pywin.dialogs.list"] +dll_excludes = "MSVCP90.dll mswsock.dll powrprof.dll".split() + setup( options = {"py2exe": {"typelibs": # typelib for WMI @@ -129,6 +131,7 @@ # create a compressed zip archive "compressed": 1, "optimize": 2, + "dll_excludes": dll_excludes, "excludes": excludes}}, # The lib directory contains everything except the executables and the python dll. # Can include a subdirectory name. Modified: trunk/py2exe/py2exe/samples/singlefile/gui/setup.py =================================================================== --- trunk/py2exe/py2exe/samples/singlefile/gui/setup.py 2013-06-22 14:42:30 UTC (rev 728) +++ trunk/py2exe/py2exe/samples/singlefile/gui/setup.py 2013-06-22 14:43:32 UTC (rev 729) @@ -35,7 +35,7 @@ <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity version="5.0.0.0" - processorArchitecture="x86" + processorArchitecture="*" name="%(prog)s" type="win32" /> @@ -46,7 +46,7 @@ type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" - processorArchitecture="X86" + processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" /> @@ -73,7 +73,10 @@ options = {"py2exe": {"compressed": 1, "optimize": 2, "ascii": 1, - "bundle_files": 1}}, + "bundle_files": 1, + "dll_excludes": "MSVCP90.dll mswsock.dll powrprof.dll".split(), + }, + }, zipfile = None, windows = [test_wx], ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2013-06-22 14:42:32
|
Revision: 728 http://sourceforge.net/p/py2exe/svn/728 Author: theller Date: 2013-06-22 14:42:30 +0000 (Sat, 22 Jun 2013) Log Message: ----------- Cleanup. Modified Paths: -------------- trunk/py2exe/zipextimporter.py Modified: trunk/py2exe/zipextimporter.py =================================================================== --- trunk/py2exe/zipextimporter.py 2013-06-05 19:32:27 UTC (rev 727) +++ trunk/py2exe/zipextimporter.py 2013-06-22 14:42:30 UTC (rev 728) @@ -64,9 +64,10 @@ return None def load_module(self, fullname): + verbose = _memimporter.get_verbose_flag() if sys.modules.has_key(fullname): mod = sys.modules[fullname] - if _memimporter.get_verbose_flag(): + if verbose: sys.stderr.write("import %s # previously loaded from zipfile %s\n" % (fullname, self.archive)) return mod try: @@ -83,12 +84,12 @@ for s in suffixes: path = filename + s if path in self._files: - if _memimporter.get_verbose_flag(): + if verbose: sys.stderr.write("# found %s in zipfile %s\n" % (path, self.archive)) mod = _memimporter.import_module(fullname, path, initname, self.get_data) mod.__file__ = "%s\\%s" % (self.archive, path) mod.__loader__ = self - if _memimporter.get_verbose_flag(): + 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 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2013-06-05 19:32:30
|
Revision: 727 http://sourceforge.net/p/py2exe/svn/727 Author: theller Date: 2013-06-05 19:32:27 +0000 (Wed, 05 Jun 2013) Log Message: ----------- Fix compiler warnings. Modified Paths: -------------- trunk/py2exe/source/MyLoadLibrary.c Modified: trunk/py2exe/source/MyLoadLibrary.c =================================================================== --- trunk/py2exe/source/MyLoadLibrary.c 2013-06-05 18:42:13 UTC (rev 726) +++ trunk/py2exe/source/MyLoadLibrary.c 2013-06-05 19:32:27 UTC (rev 727) @@ -64,7 +64,7 @@ { LIST *lib = libraries; while (lib) { - if (name && 0 == stricmp(name, lib->name)) { + if (name && 0 == _stricmp(name, lib->name)) { // printf("_FindMemoryModule(%s, %p) -> %s\n", name, module, lib->name); return lib; } else if (module == lib->module) { @@ -84,7 +84,7 @@ static LIST *_AddMemoryModule(LPCSTR name, HCUSTOMMODULE module) { LIST *entry = (LIST *)malloc(sizeof(LIST)); - entry->name = strdup(name); + entry->name = _strdup(name); entry->module = module; entry->next = libraries; entry->prev = NULL; 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-05-31 18:50:43
|
Revision: 725 http://sourceforge.net/p/py2exe/svn/725 Author: theller Date: 2013-05-31 18:50:41 +0000 (Fri, 31 May 2013) Log Message: ----------- Test commit Modified Paths: -------------- trunk/py2exe/build.cmd Modified: trunk/py2exe/build.cmd =================================================================== --- trunk/py2exe/build.cmd 2013-05-24 20:01:00 UTC (rev 724) +++ trunk/py2exe/build.cmd 2013-05-31 18:50:41 UTC (rev 725) @@ -20,3 +20,4 @@ C:\Python25\python.exe setup.py sdist -f rm -rf build + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2013-05-24 20:01:12
|
Revision: 724 http://py2exe.svn.sourceforge.net/py2exe/?rev=724&view=rev Author: theller Date: 2013-05-24 20:01:00 +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/ChangeLog Modified: trunk/py2exe/ChangeLog =================================================================== --- trunk/py2exe/ChangeLog 2013-05-24 19:59:36 UTC (rev 723) +++ trunk/py2exe/ChangeLog 2013-05-24 20:01:00 UTC (rev 724) @@ -1,3 +1,11 @@ +2013-05-24 Thomas Heller <th...@ct...> + + * 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(). + + 2009-08-14 Thomas Heller <th...@py...> * Fix 'DeprecationWarning: the sets module is deprecated' in Python 2.6, 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. |