<s> """<STR_LIT>""" <EOL> from __future__ import with_statement <EOL> import os <EOL> import sys <EOL> import tempfile <EOL> import ctypes <EOL> import ctypes . wintypes <EOL> from ctypes import windll , c_char , c_void_p , POINTER , byref , sizeof <EOL> from ctypes . wintypes import HMODULE , DWORD <EOL> if sys . platform != "<STR_LIT:win32>" : <EOL> raise ImportError ( "<STR_LIT>" ) <EOL> from esky . util import pairwise , files_differ <EOL> LOAD_LIBRARY_AS_DATAFILE = <NUM_LIT> <EOL> RT_ICON = <NUM_LIT:3> <EOL> RT_GROUP_ICON = <NUM_LIT> <EOL> RT_VERSION = <NUM_LIT:16> <EOL> RT_MANIFEST = <NUM_LIT> <EOL> k32 = windll . kernel32 <EOL> k32 . GetModuleFileNameA . argtypes = [ HMODULE , c_void_p , DWORD ] <EOL> _DEFAULT_RESLANG = <NUM_LIT> <EOL> try : <EOL> EnumProcessModules = k32 . EnumProcessModules <EOL> except AttributeError : <EOL> EnumProcessModules = windll . psapi . EnumProcessModules <EOL> def get_loaded_modules ( ) : <EOL> """<STR_LIT>""" <EOL> sz = - <NUM_LIT:1> <EOL> msz = sizeof ( ctypes . wintypes . HMODULE ) <EOL> needed = ctypes . c_int ( <NUM_LIT:0> ) <EOL> proc = k32 . GetCurrentProcess ( ) <EOL> try : <EOL> while needed . value > sz : <EOL> sz = needed . value + <NUM_LIT:32> <EOL> buf = ( ctypes . wintypes . HMODULE * sz ) ( ) <EOL> if not EnumProcessModules ( proc , byref ( buf ) , sz * msz , byref ( needed ) ) : <EOL> raise ctypes . WinError ( ) <EOL> nmbuf = ctypes . create_unicode_buffer ( <NUM_LIT> ) <EOL> i = <NUM_LIT:0> <EOL> while i < needed . value / msz : <EOL> hmod = buf [ i ] <EOL> i += <NUM_LIT:1> <EOL> if not k32 . GetModuleFileNameW ( hmod , byref ( nmbuf ) , <NUM_LIT> ) : <EOL> raise ctypes . WinError ( ) <EOL> yield nmbuf . value <EOL> finally : <EOL> k32 . CloseHandle ( proc ) <EOL> def find_resource ( filename_or_handle , res_type , res_id , res_lang = None ) : <EOL> """<STR_LIT>""" <EOL> tdir = None <EOL> free_library = False <EOL> try : <EOL> if res_lang is None : <EOL> res_lang = _DEFAULT_RESLANG <EOL> if isinstance ( filename_or_handle , basestring ) : <EOL> filename = filename_or_handle <EOL> if not isinstance ( filename , unicode ) : <EOL> filename = filename . decode ( sys . getfilesystemencoding ( ) ) <EOL> for nm in get_loaded_modules ( ) : <EOL> if os . path . abspath ( filename ) == nm : <EOL> ext = filename [ filename . rfind ( "<STR_LIT:.>" ) : ] <EOL> tdir = tempfile . mkdtemp ( ) <EOL> with open ( filename , "<STR_LIT:rb>" ) as inF : <EOL> filename = os . path . join ( tdir , "<STR_LIT>" + ext ) <EOL> with open ( filename , "<STR_LIT:wb>" ) as outF : <EOL> outF . write ( inF . read ( ) ) <EOL> break <EOL> l_handle = k32 . LoadLibraryExW ( filename , None , LOAD_LIBRARY_AS_DATAFILE ) <EOL> if not l_handle : <EOL> raise ctypes . WinError ( ) <EOL> free_library = True <EOL> else : <EOL> l_handle = filename_or_handle <EOL> r_handle = k32 . FindResourceExW ( l_handle , res_type , res_id , res_lang ) <EOL> if not r_handle : <EOL> raise ctypes . WinError ( ) <EOL> r_size = k32 . SizeofResource ( l_handle , r_handle ) <EOL> if not r_size : <EOL> raise ctypes . WinError ( ) <EOL> r_info = k32 . LoadResource ( l_handle , r_handle ) <EOL> if not r_info : <EOL> raise ctypes . WinError ( ) <EOL> r_ptr = k32 . LockResource ( r_info ) <EOL> if not r_ptr : <EOL> raise ctypes . WinError ( ) <EOL> return ( r_ptr - l_handle + <NUM_LIT:1> , r_ptr - l_handle + r_size + <NUM_LIT:1> ) <EOL> finally : <EOL> if free_library : <EOL> k32 . FreeLibrary ( l_handle ) <EOL> if tdir is not None : <EOL> for nm in os . listdir ( tdir ) : <EOL> os . unlink ( os . path . join ( tdir , nm ) ) <EOL> os . rmdir ( tdir ) <EOL> def load_resource ( filename_or_handle , res_type , res_id , res_lang = _DEFAULT_RESLANG ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( filename_or_handle , basestring ) : <EOL> filename = filename_or_handle <EOL> if not isinstance ( filename , unicode ) : <EOL> filename = filename . decode ( sys . getfilesystemencoding ( ) ) <EOL> l_handle = k32 . LoadLibraryExW ( filename , None , LOAD_LIBRARY_AS_DATAFILE ) <EOL> if not l_handle : <EOL> raise ctypes . WinError ( ) <EOL> free_library = True <EOL> else : <EOL> l_handle = filename_or_handle <EOL> free_library = False <EOL> try : <EOL> r_handle = k32 . FindResourceExW ( l_handle , res_type , res_id , res_lang ) <EOL> if not r_handle : <EOL> raise ctypes . WinError ( ) <EOL> r_size = k32 . SizeofResource ( l_handle , r_handle ) <EOL> if not r_size : <EOL> raise ctypes . WinError ( ) <EOL> r_info = k32 . LoadResource ( l_handle , r_handle ) <EOL> if not r_info : <EOL> raise ctypes . WinError ( ) <EOL> r_ptr = k32 . LockResource ( r_info ) <EOL> if not r_ptr : <EOL> raise ctypes . WinError ( ) <EOL> resource = ctypes . cast ( r_ptr , POINTER ( c_char ) ) [ <NUM_LIT:0> : r_size ] <EOL> return resource <EOL> finally : <EOL> if free_library : <EOL> k32 . FreeLibrary ( l_handle ) <EOL> def add_resource ( filename , resource , res_type , res_id , res_lang = _DEFAULT_RESLANG ) : <EOL> """<STR_LIT>""" <EOL> if not isinstance ( filename , unicode ) : <EOL> filename = filename . decode ( sys . getfilesystemencoding ( ) ) <EOL> l_handle = k32 . BeginUpdateResourceW ( filename , <NUM_LIT:0> ) <EOL> if not l_handle : <EOL> raise ctypes . WinError ( ) <EOL> res_info = ( resource , len ( resource ) ) <EOL> if not k32 . UpdateResourceW ( l_handle , res_type , res_id , res_lang , * res_info ) : <EOL> raise ctypes . WinError ( ) <EOL> if not k32 . EndUpdateResourceW ( l_handle , <NUM_LIT:0> ) : <EOL> raise ctypes . WinError ( ) <EOL> def get_app_manifest ( filename_or_handle = None ) : <EOL> """<STR_LIT>""" <EOL> return load_resource ( filename_or_handle , RT_MANIFEST , <NUM_LIT:1> ) <EOL> COMMON_SAFE_RESOURCES = ( ( RT_VERSION , <NUM_LIT:1> , <NUM_LIT:0> ) , ( RT_ICON , <NUM_LIT:0> , <NUM_LIT:0> ) , ( RT_ICON , <NUM_LIT:1> , <NUM_LIT:0> ) , <EOL> ( RT_ICON , <NUM_LIT:2> , <NUM_LIT:0> ) , ( RT_GROUP_ICON , <NUM_LIT:1> , <NUM_LIT:0> ) , ) <EOL> def copy_safe_resources ( source , target ) : <EOL> """<STR_LIT>""" <EOL> for ( rtype , rid , rlang ) in COMMON_SAFE_RESOURCES : <EOL> try : <EOL> res = load_resource ( source , rtype , rid , rlang ) <EOL> except WindowsError : <EOL> pass <EOL> else : <EOL> add_resource ( target , res , rtype , rid , rlang ) <EOL> def is_safe_to_overwrite ( source , target ) : <EOL> """<STR_LIT>""" <EOL> if not source . endswith ( "<STR_LIT>" ) or not target . endswith ( "<STR_LIT>" ) : <EOL> return False <EOL> s_sz = os . stat ( source ) . st_size <EOL> t_sz = os . stat ( target ) . st_size <EOL> if s_sz != t_sz : <EOL> return False <EOL> locs = [ ] <EOL> for ( rtype , rid , rlang ) in COMMON_SAFE_RESOURCES : <EOL> try : <EOL> s_loc = find_resource ( source , rtype , rid , rlang ) <EOL> except WindowsError : <EOL> s_loc = None <EOL> try : <EOL> t_loc = find_resource ( target , rtype , rid , rlang ) <EOL> except WindowsError : <EOL> t_loc = None <EOL> if s_loc != t_loc : <EOL> return False <EOL> if s_loc is not None : <EOL> locs . append ( s_loc ) <EOL> if locs : <EOL> locs . extend ( ( ( <NUM_LIT:0> , <NUM_LIT:0> ) , ( s_sz , s_sz ) ) ) <EOL> locs . sort ( ) <EOL> for ( _ , start ) , ( stop , _ ) in pairwise ( locs ) : <EOL> if files_differ ( source , target , start , stop ) : <EOL> return False <EOL> return True </s>
