Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Resource functions issues #58

Merged
merged 44 commits into from
May 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
192e842
fix typo
itziakos May 8, 2017
6a9b911
update signatures to follow the pywin32 package
itziakos May 10, 2017
c8e010a
update docstrings
itziakos May 10, 2017
a154415
add tests for the BeginUpdate, Update and EndUpdate resource functions
itziakos May 11, 2017
84cb106
LoadResource returns a pointer, use check_null to check the return value
virtuald May 12, 2017
41e7450
add missing changes
itziakos May 12, 2017
c4754c5
update windows directory tests
itziakos May 12, 2017
efdb98a
fix expected variable
itziakos May 12, 2017
bec8edb
it should be indentical to what win32api returns
itziakos May 12, 2017
a886982
minor cleanup
itziakos May 12, 2017
2f83aac
make sure that we check the return value of the functions
itziakos May 12, 2017
5d14476
add a check_false return value function
itziakos May 12, 2017
cce3878
do not use `addCleanup` for compatibility with 2.6
itziakos May 15, 2017
2cfa2e0
augment the test on begin and end update
itziakos May 15, 2017
4c66fb1
try to coerce to boolean
itziakos May 15, 2017
3a3ee8d
more places where we need to check for false
itziakos May 15, 2017
6eb7465
flake8 fixes
itziakos May 15, 2017
205c1ce
more places that need to use check_false
itziakos May 15, 2017
6314835
we need to special can the behaviour on wine
itziakos May 15, 2017
5dafcd2
fix check_false function
itziakos May 15, 2017
731bfff
fix bad check
itziakos May 15, 2017
9a8f06f
update ErrorWhen to workaround issues with wine
itziakos May 15, 2017
2ec14ec
set the function_name attribute so that errors have the correct infor…
itziakos May 15, 2017
8085ac8
minor cleanup
itziakos May 15, 2017
df5a6e8
api-fix: pywin32 functions do not return a value
itziakos May 16, 2017
9640f36
test: check raise conditions of start and end resource update
itziakos May 16, 2017
9ca0bdd
add UpdateResource check with unicode string
itziakos May 16, 2017
1fd801a
fix: no need to return value on functions that use check_false
itziakos May 16, 2017
d023f08
fix UpdateResource to comply with pywin32 behaviour
itziakos May 16, 2017
151abb2
fix: cffi BeginUpdateResource should return HMODULE
itziakos May 16, 2017
0da95a6
flake8 fixes
itziakos May 16, 2017
932d1b0
more cleanup
itziakos May 16, 2017
d9bdbf1
Comply to the python 3 pipywin23 behaviour.
itziakos May 16, 2017
789c3f9
use the right module
itziakos May 16, 2017
fc4aae1
fix cffi wrapping for UpdateResource
itziakos May 16, 2017
080f119
skip failing tests on wine instead of adding workarounds
itziakos May 16, 2017
12bca16
skip failing wine tests on travis
itziakos May 16, 2017
713a3be
assert the errorcode is not success
itziakos May 16, 2017
1d7a1ad
fix comptibility code for python 2.6
itziakos May 16, 2017
015362f
skip failing test on wine
itziakos May 16, 2017
974abc2
fix check for errno == 0
itziakos May 16, 2017
d0ed52f
do not skip tests for this build
itziakos May 16, 2017
9d849a7
fix tests
itziakos May 16, 2017
3839894
skip another test that fails in wine
itziakos May 16, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ python:

env:
- BITS=32
SKIP_WINE_KNOWN_FAILURES=1

# The pywin32-219 installers for python 2.6 64bit are missing files.
# 64-bit for 2.7, 3.3 and 3.4 are tested with appveyor.
# 64-bit for 2.7, 3.5 and 3.6 are tested with appveyor.

before_install:
- sudo add-apt-repository ppa:ubuntu-wine/ppa -y
Expand Down
12 changes: 6 additions & 6 deletions win32ctypes/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
#
from __future__ import absolute_import

__all__ = ['_kernel32', '_advapi32', '_winerrors', '_common']

from . import _winerrors

try:
import cffi
except ImportError:
from win32ctypes.core.ctypes import _advapi32, _common, _kernel32
from .ctypes import _advapi32, _common, _kernel32
_backend = 'ctypes'
else:
from win32ctypes.core.cffi import _advapi32, _common, _kernel32
from .cffi import _advapi32, _common, _kernel32
del cffi
_backend = 'cffi'

from win32ctypes.core import _winerrors

__all__ = ['_kernel32', '_advapi32', '_winerrors', '_common']
68 changes: 42 additions & 26 deletions win32ctypes/core/cffi/_kernel32.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from __future__ import absolute_import

from ._util import (
ffi, check_null, check_zero, HMODULE, PVOID, RESOURCE, resource)
ffi, check_null, check_zero, check_false, HMODULE, PVOID, RESOURCE, resource)

# TODO: retrieve this value using ffi
MAX_PATH = 260
Expand Down Expand Up @@ -95,67 +95,83 @@ def _GetTickCount():
def _LoadLibraryEx(lpFilename, hFile, dwFlags):
result = check_null(
kernel32.LoadLibraryExW(
unicode(lpFilename), ffi.NULL, dwFlags))
unicode(lpFilename), ffi.NULL, dwFlags),
function_name='LoadLibraryEx')
return HMODULE(result)


def _FreeLibrary(hModule):
check_zero(kernel32.FreeLibrary(PVOID(hModule)))
check_false(
kernel32.FreeLibrary(PVOID(hModule)),
function_name='FreeLibrary')


def _EnumResourceTypes(hModule, lpEnumFunc, lParam):
callback = ffi.callback('ENUMRESTYPEPROC', lpEnumFunc)
check_zero(
kernel32.EnumResourceTypesW(PVOID(hModule), callback, lParam))
check_false(
kernel32.EnumResourceTypesW(PVOID(hModule), callback, lParam),
function_name='EnumResourceTypes')


def _EnumResourceNames(hModule, lpszType, lpEnumFunc, lParam):
callback = ffi.callback('ENUMRESNAMEPROC', lpEnumFunc)
check_zero(
check_false(
kernel32.EnumResourceNamesW(
PVOID(hModule), RESOURCE(lpszType), callback, lParam))
PVOID(hModule), RESOURCE(lpszType), callback, lParam),
function_name='EnumResourceNames')


def _EnumResourceLanguages(hModule, lpType, lpName, lpEnumFunc, lParam):
callback = ffi.callback('ENUMRESLANGPROC', lpEnumFunc)
check_zero(
check_false(
kernel32.EnumResourceLanguagesW(
PVOID(hModule), RESOURCE(lpType),
RESOURCE(lpName), callback, lParam))
RESOURCE(lpName), callback, lParam),
function_name='EnumResourceLanguages')


def _FindResourceEx(hModule, lpType, lpName, wLanguage):
return check_null(
kernel32.FindResourceExW(
PVOID(hModule), RESOURCE(lpType), RESOURCE(lpName), wLanguage))
PVOID(hModule), RESOURCE(lpType), RESOURCE(lpName), wLanguage),
function_name='FindResourceEx')


def _SizeofResource(hModule, hResInfo):
return check_zero(kernel32.SizeofResource(PVOID(hModule), hResInfo))
return check_zero(
kernel32.SizeofResource(PVOID(hModule), hResInfo),
function_name='SizeofResource')


def _LoadResource(hModule, hResInfo):
return check_null(kernel32.LoadResource(PVOID(hModule), hResInfo))
return check_null(
kernel32.LoadResource(PVOID(hModule), hResInfo),
function_name='LoadResource')


def _LockResource(hResData):
return check_null(kernel32.LockResource(hResData))
return check_null(
kernel32.LockResource(hResData),
function_name='LockResource')


def _BeginUpdateResource(pFileName, bDeleteExistingResources):
return check_null(
kernel32.BeginUpdateResourceW(unicode(pFileName),
bDeleteExistingResources))
result = check_null(
kernel32.BeginUpdateResourceW(
unicode(pFileName), bDeleteExistingResources))
return HMODULE(result)


def _EndUpdateResource(hUpdate, fDiscard):
check_zero(kernel32.EndUpdateResourceW(PVOID(hUpdate), fDiscard))


def _UpdateResource(hUpdate, lpType, lpName, wLanguage, lpData, cbData):
return check_null(
kernel32.UpdateResourceW(PVOID(hUpdate), unicode(lpType),
unicode(lpName), wLanguage, PVOID(lpData),
cbData))


check_false(
kernel32.EndUpdateResourceW(PVOID(hUpdate), fDiscard),
function_name='EndUpdateResource')


def _UpdateResource(hUpdate, lpType, lpName, wLanguage, cData, cbData):
lpData = ffi.from_buffer(cData)
check_false(
kernel32.UpdateResourceW(
PVOID(hUpdate), RESOURCE(lpType), RESOURCE(lpName),
wLanguage, PVOID(lpData), cbData),
function_name='UpdateResource')
22 changes: 21 additions & 1 deletion win32ctypes/core/cffi/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,27 @@ def resource(lpRESOURCEID):


class ErrorWhen(object):
""" Callable factory for raising errors when calling cffi functions.

def __init__(self, check):
"""

def __init__(self, check, raise_on_zero=True):
""" Constructor

Parameters
----------
check :
The return value that designates that an error has taken place.

raise_on_zero : bool
When set any error will be raised. When false the winerror
is checked and only non-zero win errors are raised. Currently
this parameters is used to workaround issues with the win32
implementation in ``wine``.

"""
self._check = check
self._raise_on_zero = raise_on_zero

def __call__(self, value, function_name=''):
if value == self._check:
Expand All @@ -72,5 +90,7 @@ def _raise_error(self, function_name=''):
exception.function = function_name
raise exception


check_null = ErrorWhen(ffi.NULL)
check_zero = ErrorWhen(0)
check_false = ErrorWhen(False)
15 changes: 9 additions & 6 deletions win32ctypes/core/ctypes/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@

import ctypes
import sys
from ctypes import pythonapi, POINTER, c_void_p, py_object, c_char_p, cast
from ctypes import (
pythonapi, POINTER, c_void_p, py_object, c_char_p, c_int, c_long, c_int64,
c_longlong)
from ctypes import cast # noqa imported here for convenience
from ctypes.wintypes import BYTE

from win32ctypes.core.compat import PY3
Expand All @@ -18,12 +21,12 @@
PPy_UNICODE = c_void_p
LPBYTE = POINTER(BYTE)
is_64bits = sys.maxsize > 2**32
Py_ssize_t = ctypes.c_int64 if is_64bits else ctypes.c_int
Py_ssize_t = c_int64 if is_64bits else c_int

if ctypes.sizeof(ctypes.c_long) == ctypes.sizeof(ctypes.c_void_p):
LONG_PTR = ctypes.c_long
elif ctypes.sizeof(ctypes.c_longlong) == ctypes.sizeof(ctypes.c_void_p):
LONG_PTR = ctypes.c_longlong
if ctypes.sizeof(c_long) == ctypes.sizeof(c_void_p):
LONG_PTR = c_long
elif ctypes.sizeof(c_longlong) == ctypes.sizeof(c_void_p):
LONG_PTR = c_longlong

if PY3:
_PyBytes_FromStringAndSize = function_factory(
Expand Down
25 changes: 13 additions & 12 deletions win32ctypes/core/ctypes/_kernel32.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
HGLOBAL, LPVOID, UINT, LPWSTR, MAX_PATH)

from ._common import LONG_PTR, IS_INTRESOURCE
from ._util import check_null, check_zero, function_factory
from ._util import check_null, check_zero, check_false, function_factory

_ENUMRESTYPEPROC = ctypes.WINFUNCTYPE(BOOL, HMODULE, LPVOID, LONG_PTR)
_ENUMRESNAMEPROC = ctypes.WINFUNCTYPE(BOOL, HMODULE, LPVOID, LPVOID, LONG_PTR)
Expand Down Expand Up @@ -64,8 +64,10 @@ def wrapped(handle, type_, name, language, param):

return _ENUMRESLANGPROC(wrapped)


_GetACP = function_factory(kernel32.GetACP, None, UINT)


_LoadLibraryEx = function_factory(
kernel32.LoadLibraryExW,
[LPCWSTR, HANDLE, DWORD],
Expand All @@ -75,19 +77,19 @@ def wrapped(handle, type_, name, language, param):
kernel32.FreeLibrary,
[HMODULE],
BOOL,
check_zero)
check_false)

_EnumResourceTypes = function_factory(
kernel32.EnumResourceTypesW,
[HMODULE, _ENUMRESTYPEPROC, LONG_PTR],
BOOL,
check_zero)
check_false)

_LoadResource = function_factory(
kernel32.LoadResource,
[HMODULE, HRSRC],
HGLOBAL,
check_zero)
check_null)

_LockResource = function_factory(
kernel32.LockResource,
Expand All @@ -105,13 +107,13 @@ def wrapped(handle, type_, name, language, param):
kernel32.EnumResourceNamesW,
[HMODULE, LPCWSTR, _ENUMRESNAMEPROC, LONG_PTR],
BOOL,
check_zero)
check_false)

_BaseEnumResourceLanguages = function_factory(
kernel32.EnumResourceLanguagesW,
[HMODULE, LPCWSTR, LPCWSTR, _ENUMRESLANGPROC, LONG_PTR],
BOOL,
check_zero)
check_false)

_BaseFindResourceEx = function_factory(
kernel32.FindResourceExW,
Expand All @@ -134,13 +136,13 @@ def wrapped(handle, type_, name, language, param):
kernel32.EndUpdateResourceW,
[HANDLE, BOOL],
BOOL,
check_zero)
check_false)

_BaseUpdateResource = function_factory(
kernel32.UpdateResourceW,
[HANDLE, LPCWSTR, LPCWSTR, WORD, LPVOID, DWORD],
BOOL,
check_zero)
check_false)

_BaseGetWindowsDirectory = function_factory(
kernel32.GetWindowsDirectoryW,
Expand Down Expand Up @@ -170,19 +172,18 @@ def _GetSystemDirectory():
def _UpdateResource(hUpdate, lpType, lpName, wLanguage, lpData, cbData):
lp_type = LPCWSTR(lpType)
lp_name = LPCWSTR(lpName)
return _BaseUpdateResource(hUpdate, lp_type, lp_name, wLanguage, lpData, cbData)
_BaseUpdateResource(hUpdate, lp_type, lp_name, wLanguage, lpData, cbData)


def _EnumResourceNames(hModule, lpszType, lpEnumFunc, lParam):
resource_type = LPCWSTR(lpszType)
return _BaseEnumResourceNames(
hModule, resource_type, lpEnumFunc, lParam)
_BaseEnumResourceNames(hModule, resource_type, lpEnumFunc, lParam)


def _EnumResourceLanguages(hModule, lpType, lpName, lpEnumFunc, lParam):
resource_type = LPCWSTR(lpType)
resource_name = LPCWSTR(lpName)
return _BaseEnumResourceLanguages(
_BaseEnumResourceLanguages(
hModule, resource_type, resource_name, lpEnumFunc, lParam)


Expand Down
14 changes: 14 additions & 0 deletions win32ctypes/core/ctypes/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def check_null(result, function, arguments, *args):
return result
return check_null


check_null = check_null_factory()


Expand All @@ -53,4 +54,17 @@ def check_zero(result, function, arguments, *args):
return result
return check_zero


check_zero = check_zero_factory()


def check_false_factory(function_name=None):
def check_false(result, function, arguments, *args):
if not bool(result):
raise make_error(function, function_name)
else:
return True
return check_false


check_false = check_false_factory()
Loading