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

Support basic library and resource loading #1

Merged
merged 9 commits into from
Feb 12, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
68 changes: 68 additions & 0 deletions mini_pywin32/_win32api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from __future__ import absolute_import

import ctypes
from ctypes.wintypes import (
BOOL, DWORD, HANDLE, HMODULE, LONG, LPCWSTR, WCHAR, WORD, HRSRC,
HGLOBAL, LPVOID)

from .util import check_null, check_zero, function_factory, LONG_PTR

kernel32 = ctypes.windll.kernel32

ENUMRESTYPEPROC = ctypes.WINFUNCTYPE(BOOL, HMODULE, LONG, LONG_PTR)
ENUMRESNAMEPROC = ctypes.WINFUNCTYPE(BOOL, HMODULE, LONG, LONG, LONG_PTR)
ENUMRESLANGPROC = ctypes.WINFUNCTYPE(
BOOL, HMODULE, WCHAR, WCHAR, WORD, LONG_PTR)

_LoadLibraryEx = function_factory(
kernel32.LoadLibraryExW,
[LPCWSTR, HANDLE, DWORD],
HMODULE, check_null)

_FreeLibrary = function_factory(
kernel32.FreeLibrary,
[HMODULE],
BOOL,
check_zero)

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

_EnumResourceNames = function_factory(
kernel32.EnumResourceNamesW,
[HMODULE, DWORD, ENUMRESNAMEPROC, LONG_PTR],
BOOL,
check_zero)

_EnumResourceLanguages = function_factory(
kernel32.EnumResourceLanguagesW,
[HMODULE, LPCWSTR, LPCWSTR, ENUMRESLANGPROC, LONG_PTR],
BOOL,
check_zero)

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

_LockResource = function_factory(
kernel32.LockResource,
[HGLOBAL],
LPVOID,
check_null)

_FindResourceEx = function_factory(
kernel32.FindResourceExW,
[HMODULE, DWORD, DWORD, WORD],
HRSRC,
check_null)

_SizeofResource = function_factory(
kernel32.SizeofResource,
[HMODULE, HRSRC],
DWORD,
check_zero)
26 changes: 13 additions & 13 deletions mini_pywin32/_win32cred.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ def _encode_password(password):
return unicode_str(password).encode("utf-16")

class CREDENTIAL(Structure):
_fields_ = [("Flags", DWORD),
("Type", DWORD),
("TargetName", c_wchar_p),
("Comment", c_wchar_p),
("LastWritten", FILETIME),
("CredentialBlobSize", DWORD),
("CredentialBlob", LPBYTE),
("Persist", DWORD),
("_DO_NOT_USE_AttributeCount", DWORD),
("__DO_NOT_USE_Attribute", c_void_p),
("TargetAlias", c_wchar_p),
("UserName", c_wchar_p),
]
_fields_ = [
("Flags", DWORD),
("Type", DWORD),
("TargetName", c_wchar_p),
("Comment", c_wchar_p),
("LastWritten", FILETIME),
("CredentialBlobSize", DWORD),
("CredentialBlob", LPBYTE),
("Persist", DWORD),
("_DO_NOT_USE_AttributeCount", DWORD),
("__DO_NOT_USE_Attribute", c_void_p),
("TargetAlias", c_wchar_p),
("UserName", c_wchar_p)]

PCREDENTIAL = POINTER(CREDENTIAL)

Expand Down
107 changes: 107 additions & 0 deletions mini_pywin32/tests/test_win32api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import sys
import unittest

import mini_pywin32.win32api
import win32api


class TestWin32API(unittest.TestCase):

def setUp(self):
self.handle = None

def tearDown(self):
if self.handle is not None:
self._free_library(win32api, self.handle)

def test_load_library_ex(self):
self.handle = self._load_library(win32api)
mini = self._load_library(mini_pywin32.win32api)
self.assertEqual(mini, self.handle)

with self.assertRaises(WindowsError):
mini_pywin32.win32api.LoadLibraryEx('ttt.dll', 0, 0x2)

def test_free_library(self):
self.handle = self._load_library(win32api)
self.assertIsNone(self._free_library(win32api, self.handle))
self.assertNotEqual(
self._free_library(mini_pywin32.win32api, self.handle), 0)

with self.assertRaises(WindowsError):
self._free_library(mini_pywin32.win32api, -3)

def test_enum_resource_types(self):
self.handle = self._load_library(win32api)
original = self._enum_resource_types(win32api, self.handle)
mini = self._enum_resource_types(mini_pywin32.win32api, self.handle)
self.assertEqual(mini, original)

with self.assertRaises(WindowsError):
mini_pywin32.win32api.EnumResourceTypes(-3)

def test_enum_resource_names(self):
self.handle = self._load_library(win32api)
resource_types = self._enum_resource_types(win32api, self.handle)

for resource_type in resource_types:
original = self._enum_resource_names(
win32api, self.handle, resource_type)
mini = self._enum_resource_names(
mini_pywin32.win32api, self.handle, resource_type)
self.assertEqual(mini, original)

with self.assertRaises(WindowsError):
mini_pywin32.win32api.EnumResourceNames(2, 3)


def test_enum_resource_languages(self):
handle = self._load_library(win32api)
resource_types = self._enum_resource_types(win32api, handle)

for resource_type in resource_types:
resource_names = self._enum_resource_names(
win32api, handle, resource_type)
for resource_name in resource_names:
resource_languages = self._enum_resource_languages(
win32api, handle, resource_type, resource_name)
for resource_language in resource_languages:
original = self._load_resource(
win32api, handle,
resource_type, resource_name,
resource_language)
mini = self._load_resource(
mini_pywin32.win32api, handle,
resource_type, resource_name,
resource_language)
self.assertEqual(mini, original)

with self.assertRaises(WindowsError):
mini_pywin32.win32api.LoadResource(
handle, resource_type, resource_name, 3)

def _load_library(self, module):
# backward shim for win32api module which does not export
# LOAD_LIBRARY_AS_DATAFILE
LOAD_LIBRARY_AS_DATAFILE = getattr(
module, "LOAD_LIBRARY_AS_DATAFILE", 0x2)
return module.LoadLibraryEx(
sys.executable, 0, LOAD_LIBRARY_AS_DATAFILE)

def _free_library(self, module, handle):
return module.FreeLibrary(handle)

def _enum_resource_types(self, module, handle):
return module.EnumResourceTypes(handle)

def _enum_resource_names(self, module, handle, resource_type):
return module.EnumResourceNames(handle, resource_type)

def _enum_resource_languages(self, module, handle, resource_type, name):
return module.EnumResourceLanguages(handle, resource_type, name)

def _load_resource(
self, module, handle, resource_type,
resource_name, resource_language):
return module.LoadResource(
handle, resource_type, resource_name, resource_language)
26 changes: 26 additions & 0 deletions mini_pywin32/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import ctypes
from ctypes import WinError

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


def function_factory(
function, argument_types, return_type=None, error_checking=None):
function.argtypes = argument_types
function.restype = return_type
if error_checking is not None:
function.errcheck = error_checking
return function

def check_null(result, func, arguments, *args):
if result is None:
raise WinError()
return result

def check_zero(result, func, arguments, *args):
if result == 0:
raise WinError()
return result
59 changes: 59 additions & 0 deletions mini_pywin32/win32api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from __future__ import absolute_import

from . import _win32api, _win32cred

LOAD_LIBRARY_AS_DATAFILE = 0x2


def LoadLibraryEx(FileName, handle, flags):
if not handle == 0:
raise ValueError("handle != 0 not supported")
return _win32api._LoadLibraryEx(FileName, 0, flags)


def EnumResourceTypes(hModule):
resource_types = []

def callback(hModule, typeid, param):
resource_types.append(typeid)
return True

_win32api._EnumResourceTypes(
hModule, _win32api.ENUMRESTYPEPROC(callback), 0)
return resource_types


def EnumResourceNames(hModule, type_):
resource_names = []

def callback(hModule, type_, type_name, param):
resource_names.append(type_name)
return True

_win32api._EnumResourceNames(
hModule, type_, _win32api.ENUMRESNAMEPROC(callback), 0)
return resource_names


def EnumResourceLanguages(hModule, type_, name):
resource_languages = []

def callback(hModule, type_name, res_name, language_id, param):
resource_languages.append(language_id)
return True

_win32api._EnumResourceLanguages(
hModule, type_, name, _win32api.ENUMRESLANGPROC(callback), 0)
return resource_languages


def LoadResource(hModule, type_, name, language):
hrsrc = _win32api._FindResourceEx(hModule, type_, name, language)
size = _win32api._SizeofResource(hModule, hrsrc)
hglob = _win32api._LoadResource(hModule, hrsrc)
pointer = _win32api._LockResource(hglob)
return _win32cred._PyString_FromStringAndSize(pointer, size)


def FreeLibrary(hModule):
return _win32api._FreeLibrary(hModule)