pywin32-checkins Mailing List for Python for Windows Extensions (Page 128)
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
You can subscribe to this list here.
| 2003 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
(1) |
Jun
(6) |
Jul
(50) |
Aug
(11) |
Sep
(24) |
Oct
(184) |
Nov
(118) |
Dec
(22) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2004 |
Jan
(31) |
Feb
(25) |
Mar
(34) |
Apr
(105) |
May
(49) |
Jun
(38) |
Jul
(39) |
Aug
(7) |
Sep
(98) |
Oct
(79) |
Nov
(20) |
Dec
(17) |
| 2005 |
Jan
(66) |
Feb
(32) |
Mar
(43) |
Apr
(30) |
May
(58) |
Jun
(30) |
Jul
(16) |
Aug
(4) |
Sep
(21) |
Oct
(42) |
Nov
(11) |
Dec
(14) |
| 2006 |
Jan
(42) |
Feb
(30) |
Mar
(22) |
Apr
(1) |
May
(9) |
Jun
(15) |
Jul
(20) |
Aug
(9) |
Sep
(8) |
Oct
(1) |
Nov
(9) |
Dec
(43) |
| 2007 |
Jan
(52) |
Feb
(45) |
Mar
(20) |
Apr
(12) |
May
(59) |
Jun
(39) |
Jul
(35) |
Aug
(31) |
Sep
(17) |
Oct
(20) |
Nov
(4) |
Dec
(4) |
| 2008 |
Jan
(28) |
Feb
(111) |
Mar
(4) |
Apr
(27) |
May
(40) |
Jun
(27) |
Jul
(32) |
Aug
(94) |
Sep
(87) |
Oct
(153) |
Nov
(336) |
Dec
(331) |
| 2009 |
Jan
(298) |
Feb
(127) |
Mar
(20) |
Apr
(8) |
May
|
Jun
(10) |
Jul
(6) |
Aug
|
Sep
(2) |
Oct
(2) |
Nov
|
Dec
(1) |
| 2010 |
Jan
(7) |
Feb
(1) |
Mar
|
Apr
|
May
(15) |
Jun
(4) |
Jul
(3) |
Aug
(28) |
Sep
(1) |
Oct
(19) |
Nov
(16) |
Dec
(6) |
| 2011 |
Jan
(2) |
Feb
(18) |
Mar
(17) |
Apr
(12) |
May
(5) |
Jun
(11) |
Jul
(7) |
Aug
(2) |
Sep
(2) |
Oct
(4) |
Nov
(4) |
Dec
|
| 2012 |
Jan
(6) |
Feb
(2) |
Mar
|
Apr
(8) |
May
(4) |
Jun
(3) |
Jul
(13) |
Aug
(27) |
Sep
(8) |
Oct
(9) |
Nov
(3) |
Dec
(2) |
| 2013 |
Jan
|
Feb
(1) |
Mar
(5) |
Apr
(10) |
May
|
Jun
(2) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
(9) |
| 2014 |
Jan
(2) |
Feb
(4) |
Mar
(4) |
Apr
(1) |
May
(4) |
Jun
(2) |
Jul
|
Aug
|
Sep
|
Oct
(2) |
Nov
|
Dec
(1) |
| 2015 |
Jan
(1) |
Feb
|
Mar
|
Apr
(6) |
May
(2) |
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
| 2016 |
Jan
(3) |
Feb
(2) |
Mar
|
Apr
(3) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2017 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
|
From: Mark H. <mha...@us...> - 2004-09-07 02:16:50
|
Update of /cvsroot/pywin32/pywin32/com/win32com/server In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9688 Modified Files: dispatcher.py Log Message: * Support writing exception to a logging module object instead of stdout. * Support for GetTypeInfo and GetTypeInfoCount * "deprecate" the pywin.debugger dispatcher - no one uses it and it just upsets py2exe Index: dispatcher.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32com/server/dispatcher.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** dispatcher.py 8 Nov 2003 00:38:44 -0000 1.4 --- dispatcher.py 7 Sep 2004 02:16:40 -0000 1.5 *************** *** 9,12 **** --- 9,13 ---- from win32com.server.exception import IsCOMServerException from win32com.util import IIDToInterfaceName + import win32com class DispatcherBase: *************** *** 22,25 **** --- 23,29 ---- def __init__(self, policyClass, object): self.policy = policyClass(object) + # The logger we should dump to. If None, we should send to the + # default location (typically 'print') + self.logger = getattr(win32com, "logger", None) def _CreateInstance_(self, clsid, reqIID): *************** *** 48,51 **** --- 52,67 ---- self._HandleException_() + def _GetTypeInfo_(self, index, lcid): + try: + return self.policy._GetTypeInfo_(index, lcid) + except: + self._HandleException_() + + def _GetTypeInfoCount_(self): + try: + return self.policy._GetTypeInfoCount_() + except: + self._HandleException_() + def _GetDispID_(self, name, fdex): try: *************** *** 103,115 **** # If not a COM exception, print it for the developer. if not IsCOMServerException(): ! traceback.print_exc() # But still raise it for the framework. reraise() def _trace_(self, *args): ! for arg in args[:-1]: ! print arg, ! print args[-1] ! class DispatcherTrace(DispatcherBase): """A dispatcher, which causes a 'print' line for each COM function called. --- 119,138 ---- # If not a COM exception, print it for the developer. if not IsCOMServerException(): ! if self.logger is not None: ! self.logger.exception("pythoncom server error") ! else: ! traceback.print_exc() # But still raise it for the framework. reraise() def _trace_(self, *args): ! if self.logger is not None: ! record = " ".join(map(str, args)) ! self.logger.debug(record) ! else: ! for arg in args[:-1]: ! print arg, ! print args[-1] ! class DispatcherTrace(DispatcherBase): """A dispatcher, which causes a 'print' line for each COM function called. *************** *** 125,128 **** --- 148,159 ---- return DispatcherBase._GetIDsOfNames_(self, names, lcid) + def _GetTypeInfo_(self, index, lcid): + self._trace_("in _GetTypeInfo_ with index=%d, lcid=%d\n" % (index, lcid)) + return DispatcherBase._GetTypeInfo_(self, index, lcid) + + def _GetTypeInfoCount_(self): + self._trace_("in _GetTypeInfoCount_\n") + return DispatcherBase._GetTypeInfoCount_(self) + def _Invoke_(self, dispid, lcid, wFlags, args): self._trace_("in _Invoke_ with", dispid, lcid, wFlags, args) *************** *** 168,173 **** def __init__(self, policyClass, object): DispatcherTrace.__init__(self, policyClass, object) ! import win32traceutil # Sets up everything. ! print "Object with win32trace dispatcher created (object=%s)" % `object` --- 199,206 ---- def __init__(self, policyClass, object): DispatcherTrace.__init__(self, policyClass, object) ! if self.logger is None: ! # If we have no logger, setup our output. ! import win32traceutil # Sets up everything. ! self._trace_("Object with win32trace dispatcher created (object=%s)" % `object`) *************** *** 191,196 **** """ def __init__(self, policyClass, ob): ! import pywin.debugger pywin.debugger.brk() # DEBUGGER Note - You can either: # * Hit Run and wait for a (non Exception class) exception to occur! --- 224,234 ---- """ def __init__(self, policyClass, ob): ! # No one uses this, and it just causes py2exe to drag all of ! # pythonwin in. ! #import pywin.debugger pywin.debugger.brk() + print "The DispatcherWin32dbg dispatcher is deprecated!" + print "Please let me know if this is a problem." + print "Uncomment the relevant lines in dispatcher.py to re-enable" # DEBUGGER Note - You can either: # * Hit Run and wait for a (non Exception class) exception to occur! *************** *** 203,207 **** # Save details away. typ, val, tb = exc_info() ! import pywin.debugger, pywin.debugger.dbgcon debug = 0 try: --- 241,245 ---- # Save details away. typ, val, tb = exc_info() ! #import pywin.debugger, pywin.debugger.dbgcon debug = 0 try: |
|
From: Mark H. <mha...@us...> - 2004-09-07 02:15:27
|
Update of /cvsroot/pywin32/pywin32/com/win32com/server In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9321 Modified Files: policy.py Log Message: Implement GetTypeInfo and GetTypeInfoCount in the default policy. This will provide type info referenced via _typelib_guid_. See the pippo sample Index: policy.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32com/server/policy.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** policy.py 12 Mar 2004 08:46:18 -0000 1.17 --- policy.py 7 Sep 2004 02:15:07 -0000 1.18 *************** *** 522,525 **** --- 522,556 ---- self._dispid_to_func_[dispid] = name dispid = self._allocnextdispid(dispid) + self._typeinfos_ = None # load these on demand. + + def _build_typeinfos_(self): + # Can only ever be one for now. + tlb_guid = getattr(self._obj_, '_typelib_guid_', None) + if tlb_guid is None: + return [] + tlb_major, tlb_minor = getattr(self._obj_, '_typelib_version_', (1,0)) + tlb = pythoncom.LoadRegTypeLib(tlb_guid, tlb_major, tlb_minor, lcid) + typecomp = tlb.GetTypeComp() + # Not 100% sure what semantics we should use for the default interface. + # Look for the first name in _com_interfaces_ that exists in the typelib. + for iname in self._obj_._com_interfaces_: + try: + type_info, type_comp = typecomp.BindType(iname) + return [type_info] + except pythoncom.com_error: + pass + return [] + + def _GetTypeInfoCount_(self): + if self._typeinfos_ is None: + self._typeinfos_ = self._build_typeinfos_() + return len(self._typeinfos_) + + def _GetTypeInfo_(self, index, lcid): + if self._typeinfos_ is None: + self._typeinfos_ = self._build_typeinfos_() + if index < 0 or index >= len(self._typeinfos_): + raise COMException(scode=winerror.DISP_E_BADINDEX) + return 0, self._typeinfos_[index] def _allocnextdispid(self, last_dispid): |
|
From: Mark H. <mha...@us...> - 2004-09-07 02:12:33
|
Update of /cvsroot/pywin32/pywin32/com/win32com/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9129 Modified Files: PyIDispatch.cpp Log Message: Allow GetTypeInfo to specify the index rather than hard-coding zero. Index: PyIDispatch.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32com/src/PyIDispatch.cpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** PyIDispatch.cpp 20 Apr 2004 22:55:48 -0000 1.8 --- PyIDispatch.cpp 7 Sep 2004 02:12:22 -0000 1.9 *************** *** 462,467 **** { LCID locale = LOCALE_USER_DEFAULT; // @pyparm int|locale|LOCALE_USER_DEFAULT|The locale to use. ! if (!PyArg_ParseTuple(args, "|i:GetTypeInfo", &locale)) return NULL; --- 462,470 ---- { LCID locale = LOCALE_USER_DEFAULT; + int index = 0; // @pyparm int|locale|LOCALE_USER_DEFAULT|The locale to use. ! // @pyparm int|index|0|The index of the typelibrary to fetch. ! // Note that these params are reversed from the win32 call. ! if (!PyArg_ParseTuple(args, "|ii:GetTypeInfo", &locale, &index)) return NULL; *************** *** 470,474 **** ITypeInfo *pti = NULL; PY_INTERFACE_PRECALL; ! SCODE sc = pMyDispatch->GetTypeInfo(0, locale, &pti); PY_INTERFACE_POSTCALL; if (sc!=S_OK) // S_OK is only acceptable result. --- 473,477 ---- ITypeInfo *pti = NULL; PY_INTERFACE_PRECALL; ! SCODE sc = pMyDispatch->GetTypeInfo(index, locale, &pti); PY_INTERFACE_POSTCALL; if (sc!=S_OK) // S_OK is only acceptable result. |
|
From: Mark H. <mha...@us...> - 2004-09-07 02:11:00
|
Update of /cvsroot/pywin32/pywin32/com/win32com/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8985 Modified Files: errorSemantics.py Log Message: Test the new ability to send output to a logging module object. Index: errorSemantics.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32com/test/errorSemantics.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** errorSemantics.py 10 Nov 2003 00:49:29 -0000 1.5 --- errorSemantics.py 7 Sep 2004 02:10:49 -0000 1.6 *************** *** 96,101 **** --- 96,147 ---- raise error("Could not find a traceback in stderr: %r" % (cap.get_captured(),)) + try: + import logging + except ImportError: + logging = None + if logging is not None: + import win32com + class TestLogHandler(logging.Handler): + def __init__(self): + self.num_emits = 0 + logging.Handler.__init__(self) + def emit(self, record): + self.num_emits += 1 + return + print "--- record start" + print self.format(record) + print "--- record end" + + def testLogger(): + assert not hasattr(win32com, "logger") + handler = TestLogHandler() + formatter = logging.Formatter('%(message)s') + handler.setFormatter(formatter) + log = logging.getLogger("win32com_test") + log.addHandler(handler) + win32com.logger = log + # Now throw some exceptions! + # Native interfaces + com_server = wrap(TestServer(), pythoncom.IID_IStream) + try: + com_server.Commit(0) + raise RuntimeError, "should have failed" + except pythoncom.error: + pass + assert handler.num_emits == 1, handler.num_emits + handler.num_emits = 0 # reset + + com_server = Dispatch(wrap(TestServer())) + try: + com_server.Commit(0) + raise RuntimeError, "should have failed" + except pythoncom.error: + pass + assert handler.num_emits == 1, handler.num_emits + if __name__=='__main__': test() + if logging is not None: + testLogger() from util import CheckClean CheckClean() |
|
From: Mark H. <mha...@us...> - 2004-09-07 02:10:21
|
Update of /cvsroot/pywin32/pywin32/com/win32com/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8851 Modified Files: testPippo.py Log Message: Test pippo correctly exposes its type info at runtime. Index: testPippo.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32com/test/testPippo.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** testPippo.py 22 Apr 2004 08:24:00 -0000 1.1 --- testPippo.py 7 Sep 2004 02:10:13 -0000 1.2 *************** *** 3,6 **** --- 3,7 ---- import pythoncom from win32com.client import Dispatch + from win32com.client.gencache import EnsureDispatch class PippoTester(unittest.TestCase): *************** *** 19,23 **** except AttributeError: print "Please run this with python_d for leak tests" ! return # note creating self.object() should have consumed our "one time" leaks self.object.Method1() --- 20,24 ---- except AttributeError: print "Please run this with python_d for leak tests" ! gtrc = lambda: 0 # note creating self.object() should have consumed our "one time" leaks self.object.Method1() *************** *** 30,33 **** --- 31,52 ---- if end-start > 5: self.fail("We lost %d references!" % (end-start,)) + + def testLeaksGencache(self): + try: + gtrc = sys.gettotalrefcount + except AttributeError: + print "Please run this with python_d for leak tests" + gtrc = lambda: 0 + # note creating self.object() should have consumed our "one time" leaks + object = EnsureDispatch("Python.Test.Pippo") + start = gtrc() + for i in range(1000): + object = EnsureDispatch("Python.Test.Pippo") + object.Method1() + object = None + end = gtrc() + if end-start > 10: + self.fail("We lost %d references!" % (end-start,)) + if __name__=='__main__': unittest.main() |
|
From: Mark H. <mha...@us...> - 2004-09-07 02:09:29
|
Update of /cvsroot/pywin32/pywin32/com/win32com/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8757 Modified Files: testvb.py Log Message: Make sure empty arrays work with VB Index: testvb.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32com/test/testvb.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** testvb.py 4 May 2004 06:59:53 -0000 1.18 --- testvb.py 7 Sep 2004 02:09:20 -0000 1.19 *************** *** 247,250 **** --- 247,255 ---- # (NOTE Python will convert incoming arrays to tuples, so we pass a tuple, even tho # a list works fine - just makes it easier for us to compare the result! + # Empty array + _DoTestArray(vbtest, ()) + # Empty child array + _DoTestArray(vbtest, ((), ())) + # ints _DoTestArray(vbtest, tuple(range(1,100))) # Floats |
|
From: Mark H. <mha...@us...> - 2004-09-07 02:08:20
|
Update of /cvsroot/pywin32/pywin32/com/win32comext/axscript/client In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8578 Modified Files: error.py Log Message: Don't check specifically for SyntaxError, check for any sub-class, so IndentationError is handled too. Index: error.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/axscript/client/error.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** error.py 2 Jul 2004 04:06:40 -0000 1.5 --- error.py 7 Sep 2004 02:08:02 -0000 1.6 *************** *** 83,87 **** linecache.clearcache() try: ! if type is SyntaxError: self._BuildFromSyntaxError(site, value, tb) else: --- 83,87 ---- linecache.clearcache() try: ! if issubclass(type, SyntaxError): self._BuildFromSyntaxError(site, value, tb) else: |
|
From: Mark H. <mha...@us...> - 2004-09-07 02:05:46
|
Update of /cvsroot/pywin32/pywin32/win32/Demos In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8353 Modified Files: win32gui_menu.py Log Message: Fix the demo to correctly work with checkbox items, radio-button items, and demonstrate using an icon in a menu. Index: win32gui_menu.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/Demos/win32gui_menu.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** win32gui_menu.py 16 Oct 2003 05:37:23 -0000 1.1 --- win32gui_menu.py 7 Sep 2004 02:05:36 -0000 1.2 *************** *** 10,14 **** # Based on Andy McKay's demo code. from win32api import * ! from win32gui import * from win32gui_struct import * import win32con --- 10,18 ---- # Based on Andy McKay's demo code. from win32api import * ! # Try and use XP features, so we get alpha-blending etc. ! try: ! from winxpgui import * ! except ImportError: ! from win32gui import * from win32gui_struct import * import win32con *************** *** 46,52 **** --- 50,60 ---- hicon = LoadImage(hinst, iconPathName, win32con.IMAGE_ICON, 0, 0, icon_flags) else: + iconPathName = None print "Can't find a Python icon file - using default" hicon = LoadIcon(0, win32con.IDI_APPLICATION) + self.iconPathName = iconPathName + self.createMenu() + flags = NIF_ICON | NIF_MESSAGE | NIF_TIP nid = (self.hwnd, 0, flags, win32con.WM_USER+20, hicon, "Python Demo") *************** *** 54,57 **** --- 62,153 ---- print "Please right-click on the Python icon in the taskbar" + def createMenu(self): + self.hmenu = menu = CreatePopupMenu() + # Create our 'Exit' item with the standard, ugly 'close' icon. + item, extras = PackMENUITEMINFO(text = "Exit", + hbmpItem=win32con.HBMMENU_MBAR_CLOSE, + wID=1000) + InsertMenuItem(menu, 0, 1, item) + # Create a 'text only' menu via InsertMenuItem rather then + # AppendMenu, just to prove we can! + item, extras = PackMENUITEMINFO(text = "Text only item", + wID=1001) + InsertMenuItem(menu, 0, 1, item) + + load_bmp_flags=win32con.LR_LOADFROMFILE | \ + win32con.LR_LOADTRANSPARENT + # These images are "over sized", so we load them scaled. + hbmp = LoadImage(0, os.path.join(this_dir, "images/smiley.bmp"), + win32con.IMAGE_BITMAP, 20, 20, load_bmp_flags) + + # Create a top-level menu with a bitmap + item, extras = PackMENUITEMINFO(text="Menu with bitmap", + hbmpItem=hbmp, + wID=1002) + InsertMenuItem(menu, 0, 1, item) + + # Create one with an icon - this is a fair bit more work, as we need + # to convert the icon to a bitmap. + # First load the icon. + ico_x = GetSystemMetrics(win32con.SM_CXSMICON) + ico_y = GetSystemMetrics(win32con.SM_CYSMICON) + if self.iconPathName: + hicon = LoadImage(0, self.iconPathName, win32con.IMAGE_ICON, ico_x, ico_y, win32con.LR_LOADFROMFILE) + else: + shell_dll = os.path.join(GetSystemDirectory(), "shell32.dll") + large, small = win32gui.ExtractIconEx(shell_dll, 4, 1) + hicon = small[0] + DestroyIcon(large[0]) + + hdcBitmap = CreateCompatibleDC(0) + hdcScreen = GetDC(0) + hbm = CreateCompatibleBitmap(hdcScreen, ico_x, ico_y) + hbmOld = SelectObject(hdcBitmap, hbm) + # Fill the background. + brush = GetSysColorBrush(win32con.COLOR_MENU) + FillRect(hdcBitmap, (0, 0, 16, 16), brush) + # unclear if brush needs to be feed. Best clue I can find is: + # "GetSysColorBrush returns a cached brush instead of allocating a new + # one." - implies no DeleteObject + # draw the icon + DrawIconEx(hdcBitmap, 0, 0, hicon, ico_x, ico_y, 0, 0, win32con.DI_NORMAL) + SelectObject(hdcBitmap, hbmOld) + DeleteDC(hdcBitmap) + + item, extras = PackMENUITEMINFO(text="Menu with icon", + hbmpItem=hbm, + wID=1009) + InsertMenuItem(menu, 0, 1, item) + + # Create a sub-menu, and put a few funky ones there. + self.sub_menu = sub_menu = CreatePopupMenu() + # A 'checkbox' menu. + item, extras = PackMENUITEMINFO(fState=win32con.MFS_CHECKED, + text="Checkbox menu", + hbmpItem=hbmp, + wID=1003) + InsertMenuItem(sub_menu, 0, 1, item) + # A 'radio' menu. + InsertMenu(sub_menu, 0, win32con.MF_BYPOSITION, win32con.MF_SEPARATOR, None) + item, extras = PackMENUITEMINFO(fType=win32con.MFT_RADIOCHECK, + fState=win32con.MFS_CHECKED, + text="Checkbox menu - bullet 1", + hbmpItem=hbmp, + wID=1004) + InsertMenuItem(sub_menu, 0, 1, item) + item, extras = PackMENUITEMINFO(fType=win32con.MFT_RADIOCHECK, + fState=win32con.MFS_UNCHECKED, + text="Checkbox menu - bullet 2", + hbmpItem=hbmp, + wID=1005) + InsertMenuItem(sub_menu, 0, 1, item) + # And add the sub-menu to the top-level menu. + item, extras = PackMENUITEMINFO(text="Sub-Menu", + hSubMenu=sub_menu) + InsertMenuItem(menu, 0, 1, item) + + # Set 'Exit' as the default option. + SetMenuDefaultItem(menu, 1000, 0) + def OnDestroy(self, hwnd, msg, wparam, lparam): nid = (self.hwnd, 0) *************** *** 62,125 **** if lparam==win32con.WM_RBUTTONUP: print "You right clicked me." ! menu = CreatePopupMenu() ! # Create our 'Exit' item with the standard, ugly 'close' icon. ! item, extras = PackMENUITEMINFO(text = "Exit", ! hbmpItem=win32con.HBMMENU_MBAR_CLOSE, ! wID=1000) ! InsertMenuItem(menu, 0, 1, item) ! # Create a 'text only' menu via InsertMenuItem rather then ! # AppendMenu, just to prove we can! ! item, extras = PackMENUITEMINFO(text = "Text only item", ! wID=1001) ! InsertMenuItem(menu, 0, 1, item) ! ! load_bmp_flags=win32con.LR_LOADFROMFILE | \ ! win32con.LR_LOADTRANSPARENT ! # These images are "over sized", so we load them scaled. ! hbmp = LoadImage(0, os.path.join(this_dir, "images/smiley.bmp"), ! win32con.IMAGE_BITMAP, 20, 20, load_bmp_flags) ! ! # Create a top-level menu with a bitmap ! item, extras = PackMENUITEMINFO(text="Menu with icon", ! hbmpItem=hbmp, ! wID=1002) ! InsertMenuItem(menu, 0, 1, item) ! ! # Create a sub-menu, and put a few funky ones there. ! self.sub_menu = sub_menu = CreatePopupMenu() ! # A 'checkbox' menu. ! item, extras = PackMENUITEMINFO(fState=win32con.MFS_CHECKED, ! text="Checkbox menu", ! hbmpItem=hbmp, ! wID=1003) ! InsertMenuItem(sub_menu, 0, 1, item) ! # A 'radio' menu. ! InsertMenu(sub_menu, 0, win32con.MF_BYPOSITION, win32con.MF_SEPARATOR, None) ! item, extras = PackMENUITEMINFO(fType=win32con.MFT_RADIOCHECK, ! fState=win32con.MFS_CHECKED, ! text="Checkbox menu - bullet 1", ! hbmpItem=hbmp, ! wID=1004) ! InsertMenuItem(sub_menu, 0, 1, item) ! item, extras = PackMENUITEMINFO(fType=win32con.MFT_RADIOCHECK, ! fState=win32con.MFS_UNCHECKED, ! text="Checkbox menu - bullet 2", ! hbmpItem=hbmp, ! wID=1005) ! InsertMenuItem(sub_menu, 0, 1, item) ! # And add the sub-menu to the top-level menu. ! item, extras = PackMENUITEMINFO(text="Sub-Menu", ! hSubMenu=sub_menu) ! InsertMenuItem(menu, 0, 1, item) ! ! # Set 'Exit' as the default option. ! SetMenuDefaultItem(menu, 1000, 0) ! ! # And display the menu at the cursor pos. pos = GetCursorPos() SetForegroundWindow(self.hwnd) ! TrackPopupMenu(menu, win32con.TPM_LEFTALIGN, pos[0], pos[1], 0, self.hwnd, None) PostMessage(self.hwnd, win32con.WM_NULL, 0, 0) ! self.hmenu = menu return 1 --- 158,174 ---- if lparam==win32con.WM_RBUTTONUP: print "You right clicked me." ! # display the menu at the cursor pos. pos = GetCursorPos() SetForegroundWindow(self.hwnd) ! TrackPopupMenu(self.hmenu, win32con.TPM_LEFTALIGN, pos[0], pos[1], 0, self.hwnd, None) PostMessage(self.hwnd, win32con.WM_NULL, 0, 0) ! elif lparam==win32con.WM_LBUTTONDBLCLK: ! print "You double-clicked me" ! # find the default menu item and fire it. ! cmd = GetMenuDefaultItem(self.hmenu, False, 0) ! if cmd == -1: ! print "Can't find a default!" ! # and just pretend it came from the menu ! self.OnCommand(hwnd, win32con.WM_COMMAND, cmd, 0) return 1 *************** *** 132,137 **** print "Goodbye" DestroyWindow(self.hwnd) ! elif id==1003: ! # Our 'checkbox' item state = GetMenuState(self.sub_menu, id, win32con.MF_BYCOMMAND) if state==-1: --- 181,186 ---- print "Goodbye" DestroyWindow(self.hwnd) ! elif id in (1003, 1004, 1005): ! # Our 'checkbox' and 'radio' items state = GetMenuState(self.sub_menu, id, win32con.MF_BYCOMMAND) if state==-1: *************** *** 140,159 **** check_flags = win32con.MF_UNCHECKED print "Menu was checked - unchecking" ! elif state & win32con.MF_UNCHECKED: check_flags = win32con.MF_CHECKED print "Menu was unchecked - checking" - else: - raise RuntimeError, "Menu is neither checked nor unchecked!" ! CheckMenuItem(self.sub_menu, id, win32con.MF_BYCOMMAND & check_flags) ! if GetMenuState(self.sub_menu, id, win32con.MF_BYCOMMAND) & win32con.MF_CHECKED != check_flags: ! raise RuntimeError, "The new item didn't get the new checked state!" ! elif id==1004 or id==1005: ! # Our 'checkbox' item ! state = GetMenuState(self.sub_menu, id, win32con.MF_BYCOMMAND) ! if state==-1: ! raise RuntimeError, "No item found" ! CheckMenuItem(self.sub_menu, id, win32con.MF_BYCOMMAND & win32con.MF_CHECKED) ! if GetMenuState(self.sub_menu, id, win32con.MF_BYCOMMAND) & win32con.MF_CHECKED == 0: raise RuntimeError, "The new item didn't get the new checked state!" else: --- 189,207 ---- check_flags = win32con.MF_UNCHECKED print "Menu was checked - unchecking" ! else: check_flags = win32con.MF_CHECKED print "Menu was unchecked - checking" ! if id == 1003: ! # simple checkbox ! rc = CheckMenuItem(self.sub_menu, id, ! win32con.MF_BYCOMMAND | check_flags) ! else: ! # radio button - must pass the first and last IDs in the ! # "group", and the ID in the group that is to be selected. ! rc = CheckMenuRadioItem(self.sub_menu, 1004, 1005, id, ! win32con.MF_BYCOMMAND) ! new_state = GetMenuState(self.sub_menu, id, win32con.MF_BYCOMMAND) ! if new_state & win32con.MF_CHECKED != check_flags: raise RuntimeError, "The new item didn't get the new checked state!" else: |
|
From: Mark H. <mha...@us...> - 2004-09-07 02:04:39
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8081 Modified Files: win32gui.i Log Message: Add GetIconInfo, CreateBitmap and GetMenuDefaultItem Index: win32gui.i =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/win32gui.i,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -d -r1.46 -r1.47 *** win32gui.i 15 Aug 2004 07:35:37 -0000 1.46 --- win32gui.i 7 Sep 2004 02:04:28 -0000 1.47 *************** *** 288,291 **** --- 288,317 ---- %typemap(python,argout) POINT *BOTH = POINT *OUTPUT; + %typemap(python,argout) ICONINFO *OUTPUT { + PyObject *o; + o = Py_BuildValue("lllll", $source->fIcon, $source->xHotspot, + $source->yHotspot, $source->hbmMask, $source->hbmColor); + if (!$target) { + $target = o; + } else if ($target == Py_None) { + Py_DECREF(Py_None); + $target = o; + } else { + if (!PyList_Check($target)) { + PyObject *o2 = $target; + $target = PyList_New(0); + PyList_Append($target,o2); + Py_XDECREF(o2); + } + PyList_Append($target,o); + Py_XDECREF(o); + } + } + + %typemap(python,ignore) ICONINFO *OUTPUT(ICONINFO temp) + { + $target = &temp; + } + %typemap(python,except) LRESULT { Py_BEGIN_ALLOW_THREADS *************** *** 1945,1948 **** --- 1971,1983 ---- ); + // @pyswig HBITMAP|CreateBitmap|Creates a bitmap + HBITMAP CreateBitmap( + int nWidth, // @pyparm int|width||bitmap width, in pixels + int nHeight, // @pyparm int|height||bitmap height, in pixels + UINT cPlanes, // @pyparm int|cPlanes||number of color planes + UINT cBitsPerPel, // @pyparm int|cBitsPerPixel||number of bits to identify color + NULL_ONLY null // @pyparm None|bitmap bits||Must be None + ); + // @pyswig HGDIOBJ|SelectObject|Selects an object into the specified device context (DC). The new object replaces the previous object of the same type. HGDIOBJ SelectObject( *************** *** 2468,2471 **** --- 2503,2511 ---- BOOLAPI DestroyIcon( HICON hicon); + // @pyswig tuple|GetIconInfo| + // @pyparm int|hicon||The icon to query + // @rdesc The result is a tuple of (fIcon, xHotspot, yHotspot, hbmMask, hbmColor) + // The hbmMask and hbmColor items are bitmaps created for the caller, so must be freed. + BOOLAPI GetIconInfo( HICON hicon, ICONINFO *OUTPUT); // @pyswig |ScreenToClient|Convert screen coordinates to client coords *************** *** 2528,2531 **** --- 2568,2574 ---- BOOLAPI SetMenuDefaultItem(HMENU hMenu, UINT flags, UINT fByPos); + // @pyswig |GetMenuDefaultItem| + int GetMenuDefaultItem(HMENU hMenu, UINT fByPos, UINT flags); + // @pyswig |AppendMenu| BOOLAPI AppendMenu(HMENU hMenu, UINT uFlags, UINT uIDNewItem, TCHAR *lpNewItem); |
|
From: Mark H. <mha...@us...> - 2004-09-06 23:52:52
|
Update of /cvsroot/pywin32/pywin32/win32/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18414 Modified Files: win32con.py Log Message: As found by Thomas Heller, "PY_0U" should be zero. This affects the CDN_ constants. Index: win32con.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/Lib/win32con.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** win32con.py 24 Apr 2004 00:54:19 -0000 1.5 --- win32con.py 6 Sep 2004 23:52:42 -0000 1.6 *************** *** 2,6 **** WINVER = 1280 WM_USER = 1024 ! PY_0U = 5177344 OFN_READONLY = 1 OFN_OVERWRITEPROMPT = 2 --- 2,6 ---- WINVER = 1280 WM_USER = 1024 ! PY_0U = 0 OFN_READONLY = 1 OFN_OVERWRITEPROMPT = 2 |
|
From: Mark H. <mha...@us...> - 2004-09-06 23:51:13
|
Update of /cvsroot/pywin32/pywin32/win32/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18282 Modified Files: win32rcparser.py Log Message: Dont imply WS_VISIBLE for dialogs - we don't for anything else, and it it directly exposed by the MSVC UI. Index: win32rcparser.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/Lib/win32rcparser.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** win32rcparser.py 26 May 2004 08:26:39 -0000 1.3 --- win32rcparser.py 6 Sep 2004 23:51:03 -0000 1.4 *************** *** 9,13 **** """ __author__="Adam Walker" ! __version__="0.10" import sys, os, shlex, stat --- 9,13 ---- """ __author__="Adam Walker" ! __version__="0.11" import sys, os, shlex, stat *************** *** 364,368 **** def dialogStyle(self, dlg): ! dlg.style, dlg.styles = self.styles( [], win32con.WS_VISIBLE | win32con.DS_SETFONT) def dialogExStyle(self, dlg): self.getToken() --- 364,368 ---- def dialogStyle(self, dlg): ! dlg.style, dlg.styles = self.styles( [], win32con.DS_SETFONT) def dialogExStyle(self, dlg): self.getToken() |
|
From: Mark H. <mha...@us...> - 2004-09-06 23:49:34
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17872 Modified Files: win32file.i Log Message: CreateIoCompletionPort returns a handle object so it gets automatically closed (and a .Close() method). Autoduck clarifications. Index: win32file.i =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/win32file.i,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** win32file.i 1 Sep 2004 05:09:38 -0000 1.43 --- win32file.i 6 Sep 2004 23:49:18 -0000 1.44 *************** *** 227,231 **** #ifndef MS_WINCE // @pyswig <o PyHANDLE>|CreateIoCompletionPort|Can associate an instance of an opened file with a newly created or an existing input/output (I/O) completion port; or it can create an I/O completion port without associating it with a file. ! HANDLE CreateIoCompletionPort ( HANDLE FileHandle, // @pyparm <o PyHANDLE>|handle||file handle to associate with the I/O completion port HANDLE INPUT_NULLOK, // @pyparm <o PyHANDLE>|existing||handle to the I/O completion port --- 227,231 ---- #ifndef MS_WINCE // @pyswig <o PyHANDLE>|CreateIoCompletionPort|Can associate an instance of an opened file with a newly created or an existing input/output (I/O) completion port; or it can create an I/O completion port without associating it with a file. ! PyHANDLE CreateIoCompletionPort ( HANDLE FileHandle, // @pyparm <o PyHANDLE>|handle||file handle to associate with the I/O completion port HANDLE INPUT_NULLOK, // @pyparm <o PyHANDLE>|existing||handle to the I/O completion port *************** *** 1536,1539 **** --- 1536,1545 ---- } ret = PyObject_FromFILE_NOTIFY_INFORMATION(buffer, bytes_returned); + // @rdesc The result is a list of (action, filename) + // @comm The FILE_NOTIFY_INFORMATION structure used by this function + // is variable length, depending on the length of the filename. + // The size of the buffer must be at least 6 bytes long + the length + // of the filenames returned. The number of notifications that can be + // returned for a given buffer size depends on the filename lengths. done: free(buffer); |
|
From: Roger U. <ru...@us...> - 2004-09-06 19:25:23
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32229/win32/src Modified Files: win32service.i Log Message: Add Set/QueryServiceObjectSecurity, QueryServiceStatusEx, and interfaces to the Desktop and Windowstation functions Index: win32service.i =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/win32service.i,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** win32service.i 8 Nov 2003 12:34:45 -0000 1.4 --- win32service.i 6 Sep 2004 19:25:08 -0000 1.5 *************** *** 3,17 **** --- 3,662 ---- %module win32service // An interface to the Windows NT Service API + %include "typemaps.i" %include "pywin32.i" + %{ + #undef PyHANDLE + #include "PyWinObjects.h" + static BOOL (WINAPI *fpQueryServiceStatusEx)(SC_HANDLE,SC_STATUS_TYPE,LPBYTE,DWORD,LPDWORD) = NULL; + %} + %init %{ // All errors raised by this module are of this type. Py_INCREF(PyWinExc_ApiError); PyDict_SetItemString(d, "error", PyWinExc_ApiError); + PyDict_SetItemString(d, "HWINSTAType", (PyObject *)&PyHWINSTAType); + PyDict_SetItemString(d, "HDESKType", (PyObject *)&PyHDESKType); + HMODULE hmod; + FARPROC fp; + hmod=GetModuleHandle(_T("Advapi32")); + if (hmod==NULL) + hmod=LoadLibrary(_T("Advapi32")); + if (hmod!=NULL){ + fp=GetProcAddress(hmod,"QueryServiceStatusEx"); + if (fp!=NULL) + fpQueryServiceStatusEx=(BOOL (WINAPI *)(SC_HANDLE,SC_STATUS_TYPE,LPBYTE,DWORD,LPDWORD))fp; + } + %} + + %{ + #include "structmember.h" + // @object PyHWINSTA|Wrapper for a handle to a window station - returned by CreateWindowStation, OpenWindowStation, or GetProcessWindowStation + class PyHWINSTA : public PyHANDLE + { + public: + PyHWINSTA(HWINSTA hwinsta); + ~PyHWINSTA(void); + static void deallocFunc(PyObject *ob); + static PyObject *EnumDesktops(PyObject *self, PyObject *args); + static PyObject *SetProcessWindowStation(PyObject *self, PyObject *args); + static PyObject *CloseWindowStation(PyObject *self, PyObject *args); + static struct PyMemberDef members[]; + static struct PyMethodDef methods[]; + static PyObject *PyHWINSTA_new(PyTypeObject *tp, PyObject *args, PyObject *kwargs); + }; + + struct PyMethodDef PyHWINSTA::methods[] = { + {"EnumDesktops", PyHWINSTA::EnumDesktops, METH_VARARGS, "List desktop names within the window station"}, // @pymeth EnumDesktops|List desktop names within the window station + {"SetProcessWindowStation", PyHWINSTA::SetProcessWindowStation, METH_VARARGS, "Associates the calling process with the window station"}, // @pymeth SetProcessWindowStation|Associates the calling process with the window station + {"CloseWindowStation", PyHWINSTA::CloseWindowStation, METH_VARARGS, "Closes the window station handle"}, // @pymeth CloseWindowStation|Closes the window station handle + {"Detach", PyHANDLE::Detach, METH_VARARGS, "Releases reference to handle without closing it"}, //@pymeth Detach|Releases reference to handle without closing it + {NULL} + }; + + struct PyMemberDef PyHWINSTA::members[] = { + // ??? offsetof not working correctly ??? + // {"handle", T_LONG, offsetof(PyHWINSTA,m_handle), READONLY, "For use where an integer handle is required"}, + {NULL} + }; + + PyObject *PyHWINSTA::PyHWINSTA_new(PyTypeObject *tp, PyObject *args, PyObject *kwargs) + { + static char *keywords[]={"handle",0}; + HWINSTA hwinsta; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "l", keywords, &hwinsta)) + return NULL; + return new PyHWINSTA(hwinsta); + } + + PyTypeObject PyHWINSTAType = + { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "PyHWINSTA", + sizeof(PyHWINSTA), + 0, + PyHWINSTA::deallocFunc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + PyHANDLEType.tp_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + PyHWINSTA::methods, + PyHWINSTA::members, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + PyHWINSTA::PyHWINSTA_new + }; + + #define PyHWINSTA_Check(ob) ((ob)->ob_type == &PyHWINSTAType) + + PyHWINSTA::PyHWINSTA(HWINSTA hwinsta) : PyHANDLE((HANDLE)hwinsta) + { + ob_type = &PyHWINSTAType; + } + PyHWINSTA::~PyHWINSTA(void) + { + ::CloseWindowStation((HWINSTA)m_handle); + } + + void PyHWINSTA::deallocFunc(PyObject *ob) + { + delete (PyHWINSTA *)ob; + } + + + // @object PyHDESK|Object representing a handle to a desktop, created by CreateDesktop, GetThreadDesktop, and OpenDesktop. + + class PyHDESK : public PyHANDLE + { + public: + PyHDESK(HDESK hdesk); + ~PyHDESK(void); + static void deallocFunc(PyObject *ob); + static PyObject *SetThreadDesktop(PyObject *self, PyObject *args); + static PyObject *EnumDesktopWindows(PyObject *self, PyObject *args); + static PyObject *SwitchDesktop(PyObject *self, PyObject *args); + static PyObject *CloseDesktop(PyObject *self, PyObject *args); + static struct PyMemberDef members[]; + static struct PyMethodDef methods[]; + static PyObject *PyHDESK_new(PyTypeObject *tp, PyObject *args, PyObject *kwargs); + }; + + struct PyMethodDef PyHDESK::methods[] = { + {"SetThreadDesktop", PyHDESK::SetThreadDesktop, METH_VARARGS, "Assigns desktop to calling thread"}, // @pymeth SetThreadDesktop|Assigns desktop to calling thread + {"EnumDesktopWindows", PyHDESK::EnumDesktopWindows, METH_VARARGS, "Lists all top-level windows on the desktop"}, // @pymeth EnumDesktopWindows|Lists all top-level windows on the desktop + {"SwitchDesktop", PyHDESK::SwitchDesktop, METH_VARARGS, "Activates the desktop"}, // @pymeth SwitchDesktop|Activates the desktop + {"CloseDesktop", PyHDESK::CloseDesktop, METH_VARARGS, "Closes the handle"}, //@pymeth CloseDesktop|Closes the desktop handle + {"Detach", PyHANDLE::Detach, METH_VARARGS, "Releases reference to handle without closing it"}, //@pymeth Detach|Releases reference to handle without closing it + {NULL} + }; + + struct PyMemberDef PyHDESK::members[] = { + // {"handle", T_LONG, offsetof(PyHDESK,m_handle), READONLY, "For use where an integer handle is required"}, + {NULL} + }; + + PyObject *PyHDESK::PyHDESK_new(PyTypeObject *tp, PyObject *args, PyObject *kwargs) + { + static char *keywords[]={"handle",0}; + HDESK hdesk; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "l", keywords, &hdesk)) + return NULL; + return new PyHDESK(hdesk); + } + + PyTypeObject PyHDESKType = + { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "PyHDESK", + sizeof(PyHDESK), + 0, + PyHDESK::deallocFunc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + PyHANDLEType.tp_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + PyHDESK::methods, + PyHDESK::members, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + PyHDESK::PyHDESK_new + }; + + #define PyHDESK_Check(ob) ((ob)->ob_type == &PyHDESKType) + + PyHDESK::PyHDESK(HDESK hdesk) : PyHANDLE((HANDLE)hdesk) + { + ob_type = &PyHDESKType; + } + + PyHDESK::~PyHDESK(void) + { + ::CloseDesktop((HDESK)m_handle); + } + + void PyHDESK::deallocFunc(PyObject *ob) + { + delete (PyHDESK *)ob; + } + + BOOL CALLBACK EnumWindowStationProc(LPWSTR winstaname, LPARAM ret) + { + PyObject *obwinstaname=PyWinObject_FromWCHAR(winstaname); + if (obwinstaname==NULL) + return FALSE; + PyList_Append((PyObject *)ret,obwinstaname); + Py_DECREF(obwinstaname); + return TRUE; + } + + BOOL CALLBACK EnumDesktopsProc(LPWSTR desktopname, LPARAM ret) + { + PyObject *obdesktopname=PyWinObject_FromWCHAR(desktopname); + if (obdesktopname==NULL) + return FALSE; + PyList_Append((PyObject *)ret,obdesktopname); + Py_DECREF(obdesktopname); + return TRUE; + } + + BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM ret) + { + PyObject *obhandle=PyWinObject_FromHANDLE(hwnd); + if (obhandle==NULL) + return FALSE; + PyList_Append((PyObject *)ret,obhandle); + Py_DECREF(obhandle); + return TRUE; + } + + // @pymethod (PyUNICODE,...)|PyHWINSTA|EnumDesktops|Lists names of desktops in the window station + PyObject *PyHWINSTA::EnumDesktops(PyObject *self, PyObject *args) + { + if (!PyArg_ParseTuple(args, ":EnumDesktops")) + return NULL; + PyObject *ret=PyList_New(0); + if (ret==NULL) + return NULL; + if (!::EnumDesktopsW((HWINSTA)((PyHWINSTA *)self)->m_handle, EnumDesktopsProc, (LPARAM)ret)){ + Py_DECREF(ret); + ret=NULL; + if (!PyErr_Occurred()) + PyWin_SetAPIError("EnumDesktops",GetLastError()); + } + return ret; + } + + // @pymethod |PyHWINSTA|SetProcessWindowStation|Associates the calling process with the window station + PyObject *PyHWINSTA::SetProcessWindowStation(PyObject *self, PyObject *args) + { + if (!PyArg_ParseTuple(args, ":SetProcessWindowStation")) + return NULL; + if (!::SetProcessWindowStation((HWINSTA)((PyHWINSTA *)self)->m_handle)) + return PyWin_SetAPIError("SetProcessWindowStation",GetLastError()); + Py_INCREF(Py_None); + return Py_None; + } + + // @pymethod |PyHWINSTA|CloseWindowStation|Closes the window station handle + // @comm This function cannot close the handle to current process's window station + PyObject *PyHWINSTA::CloseWindowStation(PyObject *self, PyObject *args) + { + if (!PyArg_ParseTuple(args, ":CloseWindowStation")) + return NULL; + if (!::CloseWindowStation((HWINSTA)((PyHWINSTA *)self)->m_handle)) + return PyWin_SetAPIError("CloseWindowStation",GetLastError()); + Py_INCREF(Py_None); + return Py_None; + } + + // @pymethod |PyHDESK|SetThreadDesktop|Assigns this desktop to the calling thread + PyObject *PyHDESK::SetThreadDesktop(PyObject *self, PyObject *args) + { + if (!PyArg_ParseTuple(args, ":SetThreadDesktop")) + return NULL; + if (!::SetThreadDesktop((HDESK)((PyHDESK *)self)->m_handle)) + return PyWin_SetAPIError("SetThreadDesktop",GetLastError()); + Py_INCREF(Py_None); + return Py_None; + } + + // @pymethod |PyHDESK|SwitchDesktop|Activates the desktop + PyObject *PyHDESK::SwitchDesktop(PyObject *self, PyObject *args) + { + if (!PyArg_ParseTuple(args, ":SwitchDesktop")) + return NULL; + if (!::SwitchDesktop((HDESK)((PyHDESK *)self)->m_handle)) + return PyWin_SetAPIError("SwitchDesktop",GetLastError()); + Py_INCREF(Py_None); + return Py_None; + } + + // @pymethod |PyHDESK|CloseDesktop|Closes the desktop handle + PyObject *PyHDESK::CloseDesktop(PyObject *self, PyObject *args) + { + if (!PyArg_ParseTuple(args, ":CloseDesktop")) + return NULL; + if (!::CloseDesktop((HDESK)((PyHDESK *)self)->m_handle)) + return PyWin_SetAPIError("CloseDesktop",GetLastError()); + Py_INCREF(Py_None); + return Py_None; + } + + // @pymethod (<o PyHANDLE>,...)|PyHDESK|EnumDesktopWindows|Returns a list of handles to all top-level windows on desktop + PyObject *PyHDESK::EnumDesktopWindows(PyObject *self, PyObject *args) + { + if (!PyArg_ParseTuple(args, ":EnumDesktopWindows")) + return NULL; + PyObject *ret=PyList_New(0); + if (ret==NULL) + return NULL; + if (!::EnumDesktopWindows((HDESK)((PyHDESK *)self)->m_handle, EnumWindowsProc, (LPARAM)ret)){ + Py_DECREF(ret); + ret=NULL; + if (!PyErr_Occurred()) + PyWin_SetAPIError("EnumDesktopWindows",GetLastError()); + } + return ret; + } %} + // @pyswig <o PyHDESK>|GetThreadDesktop|Retrieves a handle to the desktop for a thread + %native(GetThreadDesktop) PyGetThreadDesktop; %{ + PyObject *PyGetThreadDesktop(PyObject *self, PyObject *args) + { + DWORD tid; + HDESK hdesk; + // @pyparm int|ThreadId||Id of thread + if (!PyArg_ParseTuple(args, "l:GetThreadDesktop", &tid)) + return NULL; + hdesk=GetThreadDesktop(tid); + if (hdesk==NULL) + return PyWin_SetAPIError("GetThreadDesktop",GetLastError()); + return new PyHDESK(hdesk); + } + %} + + // @pyswig (PyUNICODE,...)|EnumWindowStations|Lists names of window stations + // @comm Only window stations for which you have WINSTA_ENUMERATE access will be returned + %native(EnumWindowStations) PyEnumWindowStations; + %{ + PyObject *PyEnumWindowStations(PyObject *self, PyObject *args) + { + if (!PyArg_ParseTuple(args, ":EnumWindowStations")) + return NULL; + PyObject *ret=PyList_New(0); + if (ret==NULL) + return NULL; + if (!EnumWindowStationsW(EnumWindowStationProc, (LPARAM)ret)){ + Py_DECREF(ret); + ret=NULL; + if (!PyErr_Occurred()) + PyWin_SetAPIError("EnumWindowStations",GetLastError()); + } + return ret; + } + %} + // @pyswig |GetUserObjectInformation|Returns specified type of info about a window station or desktop + // @comm Return type is dependent on UOI_* constant passed in + %native(GetUserObjectInformation) PyGetUserObjectInformation; + %{ + PyObject *PyGetUserObjectInformation(PyObject *self, PyObject *args) + { + HANDLE handle; + DWORD origbuflen=128, reqdbuflen=0, err; + #ifdef Py_DEBUG + origbuflen=3; + #endif + void *buf=NULL; + PyObject *obhandle, *ret=NULL; + BOOL bsuccess; + int info_type; + // @pyparm <o PyHANDLE>|Handle||Handle to window station or desktop + // @pyparm int|type||Type of info to return, one of UOI_FLAGS,UOI_NAME, UOI_TYPE, or UOI_USER_SID + if (!PyArg_ParseTuple(args, "Ol:GetUserObjectInformation", &obhandle, &info_type)) + return NULL; + if (!PyWinObject_AsHANDLE(obhandle, &handle)) + return NULL; + buf=malloc(origbuflen); + if (buf==NULL) + return PyErr_Format(PyExc_MemoryError, "GetUserObjectInformation unable to allocate %d bytes", origbuflen); + bsuccess=GetUserObjectInformationW(handle, info_type, buf, origbuflen, &reqdbuflen); + if (!bsuccess){ + err=GetLastError(); + if (err==ERROR_INSUFFICIENT_BUFFER){ + free(buf); + buf=malloc(reqdbuflen); + if (buf==NULL) + return PyErr_Format(PyExc_MemoryError, "GetUserObjectInformation unable to allocate %d bytes", reqdbuflen); + bsuccess=GetUserObjectInformationW(handle, info_type, buf, reqdbuflen, &reqdbuflen); + if (!bsuccess) + err=GetLastError(); + } + } + if (!bsuccess) + PyWin_SetAPIError("GetUserObjectInformation",err); + else + switch(info_type){ + case UOI_NAME: + case UOI_TYPE:{ + ret=PyWinObject_FromWCHAR((WCHAR *)buf); + break; + } + case UOI_USER_SID:{ + if (reqdbuflen==0){ + Py_INCREF(Py_None); + ret=Py_None; + } + else + ret=PyWinObject_FromSID((PSID)buf); + break; + } + case UOI_FLAGS:{ + ret=Py_BuildValue("{s:N,s:N,s:l}", + "Inherit", PyBool_FromLong(((USEROBJECTFLAGS *)buf)->fInherit), + "Reserved", PyBool_FromLong(((USEROBJECTFLAGS *)buf)->fReserved), + "Flags", ((USEROBJECTFLAGS *)buf)->dwFlags); + break; + } + default: + PyErr_SetString(PyExc_NotImplementedError,"Type of information is not supported yet"); + break; + } + if (buf) + free (buf); + return ret; + } + %} + + // @pyswig |SetUserObjectInformation|Set specified type of info for a window station or desktop object + // @comm Currently only UOI_FLAGS supported + %native(SetUserObjectInformation) PySetUserObjectInformation; + %{ + PyObject *PySetUserObjectInformation(PyObject *self, PyObject *args) + { + HANDLE handle; + USEROBJECTFLAGS uof; + DWORD buflen=sizeof(USEROBJECTFLAGS); + int info_type=UOI_FLAGS; + PyObject *obhandle, *obinfo; + static char *uof_members[]={"Inherit", "Reserved", "Flags", 0}; + static char *uof_format="Object must be a dictionary containing {'Inherit':bool, 'Reserved':bool, 'Flags':int}"; + // @pyparm <o PyHANDLE>|Handle||Handle to window station or desktop + // @pyparm object|info||Information to set for handle, currently only a dictionary representing USEROBJECTFLAGS struct + // @pyparm int|type|UOI_FLAGS|Type of info to set, currently only accepts UOI_FLAGS + if (!PyArg_ParseTuple(args,"OO|l:SetUserObjectInformation", &obhandle, &obinfo, &info_type)) + return NULL; + if (!PyWinObject_AsHANDLE(obhandle, &handle)) + return NULL; + if (info_type!=UOI_FLAGS){ + PyErr_SetString(PyExc_TypeError,"Only UOI_FLAGS currently supported"); + return NULL; + } + if (!PyDict_Check(obinfo)){ + PyErr_SetString(PyExc_TypeError,uof_format); + return NULL; + } + PyObject *dummy_tuple=PyTuple_New(0); + if (!PyArg_ParseTupleAndKeywords(dummy_tuple, obinfo, "lll", uof_members, &uof.fInherit, &uof.fReserved, &uof.dwFlags)){ + PyErr_SetString(PyExc_TypeError,uof_format); + return NULL; + } + if (!SetUserObjectInformationW(handle, info_type, (void *)&uof, buflen)) + return PyWin_SetAPIError("SetUserObjectInformation",GetLastError()); + Py_INCREF(Py_None); + return Py_None; + } + %} + + + // @pyswig <o PyHWINSTA>|OpenWindowStation|Returns a handle to the specified window station + %native(OpenWindowStation) PyOpenWindowStation; + %{ + PyObject *PyOpenWindowStation(PyObject *self, PyObject *args) + { + WCHAR *winsta_name=NULL; + BOOL Inherit; + ACCESS_MASK DesiredAccess; + PyObject *obwinsta_name, *ret=NULL; + HWINSTA hwinsta; + // @pyparm str/PyUNICODE|szWinSta||Name of window station + // @pyparm Bool|Inherit||Allow handle to be inherited by subprocesses + // @pyparm int|DesiredAccess||Bitmask of access types + if (!PyArg_ParseTuple(args,"Oll:OpenWindowStation",&obwinsta_name, &Inherit, &DesiredAccess)) + return NULL; + if (!PyWinObject_AsWCHAR(obwinsta_name,&winsta_name,FALSE)) + return NULL; + hwinsta=OpenWindowStationW(winsta_name,Inherit,DesiredAccess); + if (hwinsta==NULL) + PyWin_SetAPIError("OpenWindowStation",GetLastError()); + else + ret= new PyHWINSTA(hwinsta); + PyWinObject_FreeWCHAR(winsta_name); + return ret; + } + %} + + // @pyswig <o PyHDESK>|OpenDesktop|Opens a handle to a desktop + %native(OpenDesktop) PyOpenDesktop; + %{ + PyObject *PyOpenDesktop(PyObject *self, PyObject *args) + { + WCHAR *desktop_name=NULL; + BOOL Inherit; + ACCESS_MASK DesiredAccess; + DWORD Flags; + PyObject *obdesktop_name, *ret=NULL; + HDESK hdesk; + // @pyparm str/unicode|szDesktop||Name of desktop to open + // @pyparm int|Flags||DF_ALLOWOTHERACCOUNTHOOK or 0 + // @pyparm bool|Inherit||Allow handle to be inherited + // @pyparm int|DesiredAccess||ACCESS_MASK specifying level of access for handle + if (!PyArg_ParseTuple(args,"Olll:OpenWindowStation",&obdesktop_name, &Flags, &Inherit, &DesiredAccess)) + return NULL; + if (!PyWinObject_AsWCHAR(obdesktop_name,&desktop_name,FALSE)) + return NULL; + hdesk=OpenDesktopW(desktop_name, Flags, Inherit,DesiredAccess); + if (hdesk==NULL) + PyWin_SetAPIError("OpenDesktop",GetLastError()); + else + ret= new PyHDESK(hdesk); + PyWinObject_FreeWCHAR(desktop_name); + return ret; + } + %} + + // @pyswig <o PyHDESK>|CreateDesktop|Creates a new desktop in calling process's current window station + %native(CreateDesktop) PyCreateDesktop; + %{ + PyObject *PyCreateDesktop(PyObject *self, PyObject *args) + { + PyObject *obDesktop, *obSA=NULL, *ret=NULL; + WCHAR *Desktop=NULL; + DWORD Flags; + ACCESS_MASK DesiredAccess; + PSECURITY_ATTRIBUTES pSA; + HDESK hdesk; + // @pyparm str/unicode|Desktop||Name of desktop to create + // @pyparm int|Flags||DF_ALLOWOTHERACCOUNTHOOK or 0 + // @pyparm int|DesiredAccess||An ACCESS_MASK determining level of access available thru returned handle + // @pyparm <o PySECURITY_ATTRIBUTES>|SecurityAttributes||Specifies inheritance and controls access to desktop + if (!PyArg_ParseTuple(args,"OllO:CreateDesktop", &obDesktop, &Flags, &DesiredAccess, &obSA)) + return NULL; + if (!PyWinObject_AsSECURITY_ATTRIBUTES(obSA, &pSA, TRUE)) + return NULL; + if (!PyWinObject_AsWCHAR(obDesktop, &Desktop, FALSE)) + return NULL; + + hdesk=CreateDesktopW(Desktop,NULL,NULL,Flags,DesiredAccess, pSA); + if (hdesk==NULL) + PyWin_SetAPIError("CreateDesktop",GetLastError()); + else + ret= new PyHDESK(hdesk); + + PyWinObject_FreeWCHAR(Desktop); + return ret; + } + %} + + // @pyswig <o PyHDESK>|OpenInputDesktop|Returns a handle to desktop for logged-in user + %native(OpenInputDesktop) PyOpenInputDesktop; + %{ + PyObject *PyOpenInputDesktop(PyObject *self, PyObject *args) + { + DWORD Flags; + BOOL Inherit; + ACCESS_MASK DesiredAccess; + HDESK hdesk; + // @pyparm int|Flags||DF_ALLOWOTHERACCOUNTHOOK or 0 + // @pyparm bool|Inherit||Specifies if handle will be inheritable + // @pyparm int|DesiredAccess||ACCESS_MASK specifying access available to returned handle + if (!PyArg_ParseTuple(args,"lll:OpenInputDesktop",&Flags,&Inherit,&DesiredAccess)) + return NULL; + hdesk=OpenInputDesktop(Flags,Inherit,DesiredAccess); + if (hdesk==NULL) + return PyWin_SetAPIError("OpenInputDesktop",GetLastError()); + return new PyHDESK(hdesk); + } + %} + + // @pyswig <o PyHWINSTA>|GetProcessWindowStation|Returns a handle to calling process's current window station + %native(GetProcessWindowStation) PyGetProcessWindowStation; + %{ + PyObject *PyGetProcessWindowStation(PyObject *self, PyObject *args) + { + HWINSTA hwinsta; + if (!PyArg_ParseTuple(args,":GetProcessWindowStation")) + return NULL; + hwinsta=::GetProcessWindowStation(); + if (hwinsta==NULL) + return PyWin_SetAPIError("GetProcessWindowStation",GetLastError()); + return new PyHWINSTA(hwinsta); + } + %} + + // @pyswig <o PyHWINSTA>|CreateWindowStation|Creates a new window station + // @comm If name is None or empty string, name is formatteded from logon id + %native(CreateWindowStation) PyCreateWindowStation; + %{ + PyObject *PyCreateWindowStation(PyObject *self, PyObject *args) + { + HWINSTA hwinsta; + WCHAR *winsta_name; + DWORD Flags; + ACCESS_MASK DesiredAccess; + PSECURITY_ATTRIBUTES pSA; + PyObject *obwinsta_name, *obSA; + // @pyparm str/unicode|WindowStation||Name of window station to create, or None + // @pyparm int|Flags||CWF_CREATE_ONLY or 0 + // @pyparm int|DesiredAccess||Bitmask of access types available to returned handle + // @pyparm <o PySECURITY_ATTRIBUTES>|SecurityAttributes||Specifies security for window station, and whether handle is inheritable + if (!PyArg_ParseTuple(args,"OllO:CreateWindowStation", &obwinsta_name, &Flags, &DesiredAccess, &obSA)) + return NULL; + if (!PyWinObject_AsSECURITY_ATTRIBUTES(obSA, &pSA, TRUE)) + return NULL; + if (!PyWinObject_AsWCHAR(obwinsta_name, &winsta_name, TRUE)) + return NULL; + hwinsta=CreateWindowStationW(winsta_name, Flags, DesiredAccess, pSA); + PyWinObject_FreeWCHAR(winsta_name); + if (hwinsta==NULL) + return PyWin_SetAPIError("CreateWindowStation",GetLastError()); + return new PyHWINSTA(hwinsta); + } + %} + + %{ BOOL BuildDeps(PyObject *obDeps, TCHAR **ppDeps) { *************** *** 448,451 **** --- 1093,1194 ---- // @pyparm int|scHandle||Handle to query + // @pyswig <o SERVICE_STATUS>|QueryServiceStatusEx|Queries a service status + %native (QueryServiceStatusEx) MyQueryServiceStatusEx; + %{ + PyObject *MyQueryServiceStatusEx(PyObject *self, PyObject *args) + { + if (fpQueryServiceStatusEx==NULL){ + PyErr_SetString(PyExc_NotImplementedError,"QueryServiceStatusEx does not exist on this platform"); + return NULL; + } + SC_HANDLE hService; + SC_STATUS_TYPE InfoLevel=SC_STATUS_PROCESS_INFO; // only existing info level + SERVICE_STATUS_PROCESS info; + DWORD bufsize=sizeof(SERVICE_STATUS_PROCESS); + DWORD reqdbufsize; + // @pyparm int|scHandle||Handle to query + if (!PyArg_ParseTuple(args,"l:QueryServiceStatusEx",&hService)) + return NULL; + if (!(*fpQueryServiceStatusEx)(hService,InfoLevel,(BYTE *)&info,bufsize,&reqdbufsize)) + return PyWin_SetAPIError("QueryServiceStatusEx", GetLastError()); + return Py_BuildValue("{s:l,s:l,s:l,s:l,s:l,s:l,s:l,s:l,s:l}", + "ServiceType", info.dwServiceType, + "CurrentState", info.dwCurrentState, + "ControlsAccepted", info.dwControlsAccepted, + "Win32ExitCode", info.dwWin32ExitCode, + "ServiceSpecificExitCode",info.dwServiceSpecificExitCode, + "CheckPoint", info.dwCheckPoint, + "WaitHint", info.dwWaitHint, + "ProcessId", info.dwProcessId, + "ServiceFlags", info.dwServiceFlags); + } + %} + + // @pyswig |SetServiceObjectSecurity|Set the security descriptor for a service + %native (SetServiceObjectSecurity) MySetServiceObjectSecurity; + %{ + PyObject *MySetServiceObjectSecurity(PyObject *self, PyObject *args) + { + PyObject *obSD; + PSECURITY_DESCRIPTOR pSD; + SECURITY_INFORMATION info; + SC_HANDLE hsvc; + // @pyparm int|Handle||Service handle + // @pyparm int|SecurityInformation||Type of infomation to set, combination of values from SECURITY_INFORMATION enum + // @pyparm <o PySECURITY_DESCRIPTOR>|SecurityDescriptor||PySECURITY_DESCRIPTOR containing infomation to set + if (!PyArg_ParseTuple(args,"llO:SetServiceObjectSecurity",&hsvc, &info, &obSD)) + return NULL; + if (!PyWinObject_AsSECURITY_DESCRIPTOR(obSD,&pSD,FALSE)) + return NULL; + if (!SetServiceObjectSecurity(hsvc,info,pSD)) + return PyWin_SetAPIError("SetServiceObjectSecurity",GetLastError()); + Py_INCREF(Py_None); + return Py_None; + } + %} + + // @pyswig <o PySECURITY_DESCRIPTOR>|QueryServiceObjectSecurity|Retrieves information from the security descriptor for a service + %native (QueryServiceObjectSecurity) MyQueryServiceObjectSecurity; + %{ + PyObject *MyQueryServiceObjectSecurity(PyObject *self, PyObject *args) + { + PyObject *ret=NULL; + PSECURITY_DESCRIPTOR pSD=NULL; + SECURITY_INFORMATION info; + DWORD err, origbufsize=SECURITY_DESCRIPTOR_MIN_LENGTH, reqdbufsize=0; + SC_HANDLE hsvc; + // @pyparm int|Handle||Service handle + // @pyparm int|SecurityInformation||Type of infomation to retrieve, combination of values from SECURITY_INFORMATION enum + if (!PyArg_ParseTuple(args,"ll:QueryServiceObjectSecurity",&hsvc, &info)) + return NULL; + pSD=(PSECURITY_DESCRIPTOR)malloc(origbufsize); + if (pSD==NULL){ + PyErr_Format(PyExc_MemoryError, "QueryServiceObjectSecurity: unable to allocate %d bytes", origbufsize); + return NULL; + } + if (!QueryServiceObjectSecurity(hsvc,info,pSD,origbufsize,&reqdbufsize)){ + err=GetLastError(); + if (err==ERROR_INSUFFICIENT_BUFFER){ + free(pSD); + pSD=(PSECURITY_DESCRIPTOR)malloc(reqdbufsize); + if (pSD==NULL) + PyErr_Format(PyExc_MemoryError,"QueryServiceObjectSecurity: unable to reallocatate %d bytes",reqdbufsize); + else + if (!QueryServiceObjectSecurity(hsvc,info,pSD,reqdbufsize,&reqdbufsize)) + PyWin_SetAPIError("QueryServiceObjectSecurity",GetLastError()); + else + ret=PyWinObject_FromSECURITY_DESCRIPTOR(pSD); + } + else + PyWin_SetAPIError("QueryServiceObjectSecurity",err); + } + else + ret=PyWinObject_FromSECURITY_DESCRIPTOR(pSD); + if (pSD!=NULL) + free(pSD); + return ret; + } + %} + // @pyswig <o SERVICE_STATUS>|SetServiceStatus|Sets a service status BOOLAPI SetServiceStatus( *************** *** 668,669 **** --- 1411,1420 ---- #define SERVICE_SPECIFIC_ERROR ERROR_SERVICE_SPECIFIC_ERROR // A service specific error has occurred. + + #define UOI_FLAGS UOI_FLAGS + #define UOI_NAME UOI_NAME + #define UOI_TYPE UOI_TYPE + #define UOI_USER_SID UOI_USER_SID + #define WSF_VISIBLE WSF_VISIBLE + #define DF_ALLOWOTHERACCOUNTHOOK DF_ALLOWOTHERACCOUNTHOOK + // #define CWF_CREATE_ONLY CWF_CREATE_ONLY |
|
From: Roger U. <ru...@us...> - 2004-09-05 15:43:27
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10742/win32/src Modified Files: PyHANDLE.cpp Log Message: Let PyWinObject_AsHANDLE accept any object that can be converted to an int - for subclasses of PyHANDLE that don't use PyHANDLEType Index: PyHANDLE.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/PyHANDLE.cpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** PyHANDLE.cpp 7 Nov 2003 03:58:17 -0000 1.8 --- PyHANDLE.cpp 5 Sep 2004 15:43:17 -0000 1.9 *************** *** 26,34 **** PyHANDLE *pH = (PyHANDLE *)ob; *pHANDLE = (HANDLE)(*pH); ! } else if (PyInt_Check(ob)) { // Support integer objects for b/w compat. *pHANDLE = (HANDLE)PyInt_AsLong(ob); ! } else { ! PyErr_SetString(PyExc_TypeError, "The object is not a PyHANDLE object"); ! return FALSE; } return TRUE; --- 26,35 ---- PyHANDLE *pH = (PyHANDLE *)ob; *pHANDLE = (HANDLE)(*pH); ! } else{ // Support integer objects for b/w compat. *pHANDLE = (HANDLE)PyInt_AsLong(ob); ! if ((*pHANDLE==(HANDLE)-1)&&PyErr_Occurred()){ ! PyErr_SetString(PyExc_TypeError, "The object is not a PyHANDLE object"); ! return FALSE; ! } } return TRUE; *************** *** 42,57 **** BOOL PyWinObject_CloseHANDLE(PyObject *obHandle) { ! BOOL ok; if (PyHANDLE_Check(obHandle)) ! // Python error already set. ! ok = ((PyHANDLE *)obHandle)->Close(); ! else if PyInt_Check(obHandle) { ! ok = ::CloseHandle((HANDLE)PyInt_AsLong(obHandle)); ! if (!ok) ! PyWin_SetAPIError("CloseHandle"); ! } else { ! PyErr_Format(PyExc_TypeError, "A handle must be a HANDLE object or an integer (got %s)", obHandle->ob_type->tp_name); return FALSE; ! } return ok; } --- 43,57 ---- BOOL PyWinObject_CloseHANDLE(PyObject *obHandle) { ! // PyWinObject_AsHANDLE checks this also, but need to make sure an override Close method is called if (PyHANDLE_Check(obHandle)) ! return ((PyHANDLE *)obHandle)->Close(); // Python error already set. ! ! HANDLE h; ! BOOL ok; ! if (!PyWinObject_AsHANDLE(obHandle, &h, FALSE)) return FALSE; ! ok=::CloseHandle(h); // This can still trigger an Invalid Handle exception in debug mode ! if (!ok) ! PyWin_SetAPIError("CloseHandle"); return ok; } *************** *** 242,247 **** --- 242,249 ---- { long result = ((PyHANDLE *)ob)->asLong(); + /* PyHANDLE::asLong sets no errors if ( result == -1 ) return NULL; + */ return PyInt_FromLong(result); } |
|
From: Mark H. <mha...@us...> - 2004-09-05 08:14:03
|
Update of /cvsroot/pywin32/pywin32/pyisapi/isapi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29859 Modified Files: install.py Log Message: Some installation changes, from Patrik Simons (and then played with by me) Index: install.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/pyisapi/isapi/install.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** install.py 4 Sep 2004 09:40:33 -0000 1.2 --- install.py 5 Sep 2004 08:13:52 -0000 1.3 *************** *** 10,15 **** import traceback ! _APP_INPROC = 0; ! _APP_OUTPROC = 1; _APP_POOLED = 2 _IIS_OBJECT = "IIS://LocalHost/W3SVC" --- 10,15 ---- import traceback ! _APP_INPROC = 0 ! _APP_OUTPROC = 1 _APP_POOLED = 2 _IIS_OBJECT = "IIS://LocalHost/W3SVC" *************** *** 35,40 **** is_debug_build = False ! for ext, _, _ in imp.get_suffixes(): ! if ext == "_d.pyd": is_debug_build = True break --- 35,40 ---- is_debug_build = False ! for imp_ext, _, _ in imp.get_suffixes(): ! if imp_ext == "_d.pyd": is_debug_build = True break *************** *** 46,49 **** --- 46,50 ---- Description = None Path = None + Server = None def __init__(self, **kw): self.__dict__.update(kw) *************** *** 53,57 **** Description = None # defaults to Name AppProtection = _DEFAULT_PROTECTION ! Headers = _DEFAULT_HEADERS; Path = None # defaults to WWW root. AccessExecute = _DEFAULT_ACCESS_EXECUTE --- 54,58 ---- Description = None # defaults to Name AppProtection = _DEFAULT_PROTECTION ! Headers = _DEFAULT_HEADERS Path = None # defaults to WWW root. AccessExecute = _DEFAULT_ACCESS_EXECUTE *************** *** 64,67 **** --- 65,69 ---- ScriptMaps = [] ScriptMapUpdate = "end" # can be 'start', 'end', 'replace' + Server = None def __init__(self, **kw): self.__dict__.update(kw) *************** *** 74,80 **** def __init__(self, **kw): self.__dict__.update(kw) ! class ISAPIParameters: ! ServerName = _DEFAULT_SERVER_NAME; # Description = None Filters = [] --- 76,82 ---- def __init__(self, **kw): self.__dict__.update(kw) ! class ISAPIParameters: ! ServerName = _DEFAULT_SERVER_NAME # Description = None Filters = [] *************** *** 102,146 **** class ConfigurationError(InstallationError): pass ! def FindWebServiceObject(class_name = None, obj_name = None): ! #webService = adsi.ADsGetObject(_IIS_OBJECT, adsi.IID_IADsContainer) ! webService = GetObject(_IIS_OBJECT) ! if class_name is None and obj_name is None: ! return webService ! raise ItemNotFound, "WebService %s.%s" % (class_name, obj_name) ! def FindWebServer(server_desc): ! webService = GetObject(_IIS_OBJECT) ! for ob in webService: ! if ob.Class == _IIS_SERVER and ob.ServerComment == server_desc: ! return ob ! raise ItemNotFound, "WebServer %s" % (server_desc,) ! ! def FindADSIObject(adsiObject, clsName, objName): ! # IIS6 seems to have different case for the same objects compared to IIS5. ! # So do all ADSI searches case-insensitive. ! clsName = clsName.lower() ! objName = objName.lower() ! for child in adsiObject: ! # print "Checking", child.Class, child.Name ! if child.Class.lower() == clsName and child.Name.lower() == objName: ! return child ! raise ItemNotFound, "ADSI object %s.%s" % (clsName, objName) ! def CreateVirtualDir(webRootDir, params, options): if not params.Name: raise ConfigurationError, "No Name param" _CallHook(params, "PreInstall", options) try: ! newDir = webRootDir.Create(_IIS_WEBVIRTUALDIR, params.Name) except pythoncom.com_error, details: rc = _GetWin32ErrorCode(details) if rc != winerror.ERROR_ALREADY_EXISTS: raise ! # I don't understand this "WEBDIR" vs "WEBVIRTUALDIR" ! try: ! newDir = FindADSIObject(webRootDir, _IIS_WEBVIRTUALDIR, params.Name) ! except ItemNotFound: ! newDir = FindADSIObject(webRootDir, _IIS_WEBDIR, params.Name) ! log(2, "Updating existing directory '%s'..." % (params.Name,)); else: log(2, "Creating new directory '%s'..." % (params.Name,)) --- 104,161 ---- class ConfigurationError(InstallationError): pass ! def FindPath(options, server, name): ! if name.lower().startswith("iis://"): ! return name ! else: ! if name and name[0] != "/": ! name = "/"+name ! return FindWebServer(options, server)+"/ROOT"+name ! def FindWebServer(options, server_desc): ! # command-line options get first go. ! if options.server: ! server = options.server ! # If the config passed by the caller doesn't specify one, use the default ! elif server_desc is None: ! server = _IIS_OBJECT+"/1" ! else: ! server = server_desc ! # Check it is good. ! try: ! GetObject(server) ! except pythoncom.com_error, details: ! hr, msg, exc, arg_err = details ! if exc and exc[2]: ! msg = exc[2] ! raise ItemNotFound, \ ! "WebServer %s: %s" % (server, msg) ! return server ! def CreateDirectory(params, options): if not params.Name: raise ConfigurationError, "No Name param" + slash = params.Name.rfind("/") + if slash >= 0: + parent = params.Name[:slash] + name = params.Name[slash+1:] + else: + parent = "" + name = params.Name + webDir = GetObject(FindPath(options, params.Server, parent)) + if parent: + # Note that the directory won't be visible in the IIS UI + # unless the directory exists on the filesystem. + keyType = _IIS_WEBDIR + else: + keyType = _IIS_WEBVIRTUALDIR _CallHook(params, "PreInstall", options) try: ! newDir = webDir.Create(keyType, name) except pythoncom.com_error, details: rc = _GetWin32ErrorCode(details) if rc != winerror.ERROR_ALREADY_EXISTS: raise ! newDir = GetObject(FindPath(options, params.Server, params.Name)) ! log(2, "Updating existing directory '%s'..." % (params.Name,)) else: log(2, "Creating new directory '%s'..." % (params.Name,)) *************** *** 148,157 **** friendly = params.Description or params.Name newDir.AppFriendlyName = friendly ! path = params.Path or webRootDir.Path ! newDir.Path = path newDir.AppCreate2(params.AppProtection) newDir.HttpCustomHeaders = params.Headers ! ! log(2, "Setting directory options..."); newDir.AccessExecute = params.AccessExecute newDir.AccessRead = params.AccessRead --- 163,175 ---- friendly = params.Description or params.Name newDir.AppFriendlyName = friendly ! try: ! path = params.Path or webDir.Path ! newDir.Path = path ! except AttributeError: ! pass newDir.AppCreate2(params.AppProtection) newDir.HttpCustomHeaders = params.Headers ! ! log(2, "Setting directory options...") newDir.AccessExecute = params.AccessExecute newDir.AccessRead = params.AccessRead *************** *** 187,193 **** return newDir ! def CreateISAPIFilter(webServer, filterParams, options): _CallHook(filterParams, "PreInstall", options) ! filters = FindADSIObject(webServer, _IIS_FILTERS, "Filters") try: newFilter = filters.Create(_IIS_FILTER, filterParams.Name) --- 205,212 ---- return newDir ! def CreateISAPIFilter(filterParams, options): ! server = FindWebServer(options, filterParams.Server) _CallHook(filterParams, "PreInstall", options) ! filters = GetObject(server+"/Filters") try: newFilter = filters.Create(_IIS_FILTER, filterParams.Name) *************** *** 197,201 **** raise log(2, "Updating existing filter '%s'..." % (filterParams.Name,)) ! newFilter = FindADSIObject(filters, _IIS_FILTER, filterParams.Name) assert os.path.isfile(filterParams.Path) newFilter.FilterPath = filterParams.Path --- 216,220 ---- raise log(2, "Updating existing filter '%s'..." % (filterParams.Name,)) ! newFilter = GetObject(server+"/Filters/"+filterParams.Name) assert os.path.isfile(filterParams.Path) newFilter.FilterPath = filterParams.Path *************** *** 211,219 **** return newFilter ! def DeleteISAPIFilter(webServer, filterParams, options): _CallHook(filterParams, "PreRemove", options) ! filters = FindADSIObject(webServer, _IIS_FILTERS, "Filters") try: ! newFilter = filters.Delete(_IIS_FILTER, filterParams.Name) log(2, "Deleted ISAPI filter '%s'" % (filterParams.Name,)) except pythoncom.com_error, details: --- 230,239 ---- return newFilter ! def DeleteISAPIFilter(filterParams, options): _CallHook(filterParams, "PreRemove", options) ! server = FindWebServer(options, filterParams.Server) ! filters = GetObject(server+"/Filters") try: ! filters.Delete(_IIS_FILTER, filterParams.Name) log(2, "Deleted ISAPI filter '%s'" % (filterParams.Name,)) except pythoncom.com_error, details: *************** *** 237,243 **** "PyISAPI_loader" + suffix + ".dll") if not os.path.isfile(template): ! raise isapi.install.ConfigurationError, \ ! "Template loader '%s' does not exist" ! # We can't do a simple "is newer" check, as the DLL is specific to the # Python version. So we check the date-time and size are identical, # and skip the copy in that case. --- 257,263 ---- "PyISAPI_loader" + suffix + ".dll") if not os.path.isfile(template): ! raise ConfigurationError, \ ! "Template loader '%s' does not exist" % (template,) ! # We can't do a simple "is newer" check, as the DLL is specific to the # Python version. So we check the date-time and size are identical, # and skip the copy in that case. *************** *** 264,300 **** def Install(params, options): - server_name = _DEFAULT_SERVER_NAME _CallHook(params, "PreInstall", options) - web_service = FindWebServiceObject() - server = FindWebServer(server_name) - root = FindADSIObject(server, _IIS_WEBVIRTUALDIR, "Root") for vd in params.VirtualDirs: ! CreateVirtualDir(root, vd, options) for filter_def in params.Filters: ! f = CreateISAPIFilter(server, filter_def, options) _CallHook(params, "PostInstall", options) def Uninstall(params, options): _CallHook(params, "PreRemove", options) - server_name = _DEFAULT_SERVER_NAME - web_service = FindWebServiceObject() - server = FindWebServer(server_name) - root = FindADSIObject(server, _IIS_WEBVIRTUALDIR, "Root") for vd in params.VirtualDirs: _CallHook(vd, "PreRemove", options) - # Find the virtual dir, and unload it. This should stop the app - # immediately, rather than needing to restart IIS. try: ! d = FindADSIObject(root, _IIS_WEBVIRTUALDIR, vd.Name) ! except ItemNotFound: ! # This can happen when the VD has not yet been loaded ! pass ! else: ! d.AppUnload() ! log (2, "Unloaded Virtual Directory: %s" % (vd.Name,)) ! # Now actually delete the directory. ! try: ! newDir = root.Delete(_IIS_WEBVIRTUALDIR, vd.Name) except pythoncom.com_error, details: rc = _GetWin32ErrorCode(details) --- 284,304 ---- def Install(params, options): _CallHook(params, "PreInstall", options) for vd in params.VirtualDirs: ! CreateDirectory(vd, options) for filter_def in params.Filters: ! CreateISAPIFilter(filter_def, options) _CallHook(params, "PostInstall", options) def Uninstall(params, options): _CallHook(params, "PreRemove", options) for vd in params.VirtualDirs: _CallHook(vd, "PreRemove", options) try: ! directory = GetObject(FindPath(options, vd.Server, vd.Name)) ! directory.AppUnload() ! parent = GetObject(directory.Parent) ! parent.Delete(directory.Class, directory.Name) except pythoncom.com_error, details: rc = _GetWin32ErrorCode(details) *************** *** 305,309 **** for filter_def in params.Filters: ! DeleteISAPIFilter(server, filter_def, options) _CallHook(params, "PostRemove", options) --- 309,313 ---- for filter_def in params.Filters: ! DeleteISAPIFilter(filter_def, options) _CallHook(params, "PostRemove", options) *************** *** 314,318 **** if not os.path.isfile(dll_name): raise ConfigurationError, "%s does not exist" % (dll_name,) ! # Patch up all references to the DLL. for f in params.Filters: --- 318,322 ---- if not os.path.isfile(dll_name): raise ConfigurationError, "%s does not exist" % (dll_name,) ! # Patch up all references to the DLL. for f in params.Filters: *************** *** 367,374 **** } - # Later we will probably need arguments that allow us to change the - # name of the default server, etc - ie, at the moment, we only work - # when the WWW server is named _DEFAULT_SERVER_NAME ("Default Web Site") - # # We support 2 ways of extending our command-line/install support. # * Many of the installation items allow you to specify "PreInstall", --- 371,374 ---- *************** *** 390,394 **** argv = argv or sys.argv conf_module_name = conf_module_name or sys.argv[0] - if opt_parser is None: # Build our own parser. --- 390,393 ---- *************** *** 416,420 **** parser.add_option("-v", "--verbosity", action="count", dest="verbose", default=1, ! help="set the verbosity of status messages") (options, args) = parser.parse_args(argv[1:]) --- 415,422 ---- parser.add_option("-v", "--verbosity", action="count", dest="verbose", default=1, ! help="increase the verbosity of status messages") ! parser.add_option("", "--server", action="store", ! help="Specifies the IIS server to install/uninstall on." \ ! " Default is '%s/1'" % (_IIS_OBJECT,)) (options, args) = parser.parse_args(argv[1:]) *************** *** 435,439 **** parser.error("Invalid arg '%s'" % (arg,)) handler(options, log, arg) ! except InstallationError, details: if options.verbose > 1: traceback.print_exc() --- 437,441 ---- parser.error("Invalid arg '%s'" % (arg,)) handler(options, log, arg) ! except (ItemNotFound, InstallationError), details: if options.verbose > 1: traceback.print_exc() |
|
From: Mark H. <mha...@us...> - 2004-09-04 09:56:56
|
Update of /cvsroot/pywin32/pywin32/pyisapi/samples In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9685 Added Files: advanced.py Log Message: New sample demonstrating module reload and custom command-line handling. --- NEW FILE: advanced.py --- # This extension demonstrates some advanced features of the Python ISAPI # framework. # We demonstrate: # * Reloading your Python module without shutting down IIS (eg, when your # .py implementation file changes.) # * Custom command-line handling - both additional options and commands. from isapi import isapicon from isapi.simple import SimpleExtension import sys, os, stat if hasattr(sys, "isapidllhandle"): import win32traceutil # Notes on reloading # If your HttpFilterProc or HttpExtensionProc functions raises # 'isapi.InternalReloadException', the framework will not treat it # as an error but instead will terminate your extension, reload your # extension module, re-initialize the instance, and re-issue the request. # The Initialize functions are called with None as their param. The # return code from the terminate function is ignored. # # This is all the framework does to help you. It is up to your code # when you raise this exception. This sample uses a Win32 "find # notification". Whenever windows tells us one of the files in the # directory has changed, we check if the time of our source-file has # changed, and set a flag. Next imcoming request, we check the flag and # raise the special exception if set. # # The end result is that the module is automatically reloaded whenever # the source-file changes - you need take no further action to see your # changes reflected in the running server. # The framework only reloads your module - if you have libraries you # depend on and also want reloaded, you must arrange for this yourself. # One way of doing this would be to special case the import of these # modules. Eg: # -- # try: # my_module = reload(my_module) # module already imported - reload it # except NameError: # import my_module # first time around - import it. # -- # When your module is imported for the first time, the NameError will # be raised, and the module imported. When the ISAPI framework reloads # your module, the existing module will avoid the NameError, and allow # you to reload that module. from isapi import InternalReloadException import win32event, win32file, winerror, win32con, threading try: reload_counter += 1 except NameError: reload_counter = 0 # A watcher thread that checks for __file__ changing. # When it detects it, it simply sets "change_detected" to true. class ReloadWatcherThread(threading.Thread): def __init__(self): self.change_detected = False self.filename = __file__ if self.filename.endswith("c") or self.filename.endswith("o"): self.filename = self.filename[:-1] self.handle = win32file.FindFirstChangeNotification( os.path.dirname(self.filename), False, # watch tree? win32con.FILE_NOTIFY_CHANGE_LAST_WRITE) threading.Thread.__init__(self) def run(self): last_time = os.stat(self.filename)[stat.ST_MTIME] while 1: try: rc = win32event.WaitForSingleObject(self.handle, win32event.INFINITE) win32file.FindNextChangeNotification(self.handle) except win32event.error, details: # handle closed - thread should terminate. if details[0] != winerror.ERROR_INVALID_HANDLE: raise break this_time = os.stat(self.filename)[stat.ST_MTIME] if this_time != last_time: print "Detected file change - flagging for reload." self.change_detected = True last_time = this_time def stop(self): win32file.FindCloseChangeNotification(self.handle) # The ISAPI extension - handles requests in our virtual dir, and sends the # response to the client. class Extension(SimpleExtension): "Python advanced sample Extension" def __init__(self): self.reload_watcher = ReloadWatcherThread() self.reload_watcher.start() def HttpExtensionProc(self, ecb): # NOTE: If you use a ThreadPoolExtension, you must still perform # this check in HttpExtensionProc - raising the exception from # The "Dispatch" method will just cause the exception to be # rendered to the browser. if self.reload_watcher.change_detected: print "Doing reload" raise InternalReloadException ecb.SendResponseHeaders("200 OK", "Content-Type: text/html\r\n\r\n", 0) print >> ecb, "<HTML><BODY>" print >> ecb, "This module has been imported" print >> ecb, "%d times" % (reload_counter,) print >> ecb, "</BODY></HTML>" ecb.close() return isapicon.HSE_STATUS_SUCCESS def TerminateExtension(self, status): self.reload_watcher.stop() # The entry points for the ISAPI extension. def __ExtensionFactory__(): return Extension() # Our special command line customization. # Pre-install hook for our virtual directory. def PreInstallDirectory(params, options): # If the user used our special '--description' option, # then we override our default. if options.description: params.Description = options.description # Post install hook for our entire script def PostInstall(params, options): print print "The sample has been installed." print "Point your browser to /AdvancedPythonSample" print "If you modify the source file and reload the page," print "you should see the reload counter increment" # Handler for our custom 'status' argument. def status_handler(options, log, arg): "Query the status of something" print "Everything seems to be fine!" custom_arg_handlers = {"status": status_handler} if __name__=='__main__': # If run from the command-line, install ourselves. from isapi.install import * params = ISAPIParameters(PostInstall = PostInstall) # Setup the virtual directories - this is a list of directories our # extension uses - in this case only 1. # Each extension has a "script map" - this is the mapping of ISAPI # extensions. sm = [ ScriptMapParams(Extension="*", Flags=0) ] vd = VirtualDirParameters(Name="AdvancedPythonSample", Description = Extension.__doc__, ScriptMaps = sm, ScriptMapUpdate = "replace", # specify the pre-install hook. PreInstall = PreInstallDirectory ) params.VirtualDirs = [vd] # Setup our custom option parser. from optparse import OptionParser parser = OptionParser('') # black usage, so isapi sets it. parser.add_option("", "--description", action="store", help="custom description to use for the virtual directory") HandleCommandLine(params, opt_parser=parser, custom_arg_handlers = custom_arg_handlers) |
|
From: Mark H. <mha...@us...> - 2004-09-04 09:40:48
|
Update of /cvsroot/pywin32/pywin32/pyisapi/isapi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7477 Modified Files: install.py Log Message: Make the command-line handling much more flexible. Callers can provide their own optparse parser, handlers for their own commands, and specify 'hooks' called during install and remove. Index: install.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/pyisapi/isapi/install.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** install.py 1 Sep 2004 03:07:11 -0000 1.1 --- install.py 4 Sep 2004 09:40:33 -0000 1.2 *************** *** 8,11 **** --- 8,12 ---- import pythoncom import winerror + import traceback _APP_INPROC = 0; *************** *** 79,82 **** --- 80,85 ---- Filters = [] VirtualDirs = [] + def __init__(self, **kw): + self.__dict__.update(kw) verbose = 1 # The level - 0 is quiet. *************** *** 95,100 **** return winerror.SCODE_CODE(hr) ! class ItemNotFound(Exception): pass ! class ConfigurationError(Exception): pass def FindWebServiceObject(class_name = None, obj_name = None): --- 98,104 ---- return winerror.SCODE_CODE(hr) ! class InstallationError(Exception): pass ! class ItemNotFound(InstallationError): pass ! class ConfigurationError(InstallationError): pass def FindWebServiceObject(class_name = None, obj_name = None): *************** *** 123,129 **** raise ItemNotFound, "ADSI object %s.%s" % (clsName, objName) ! def CreateVirtualDir(webRootDir, params): if not params.Name: raise ConfigurationError, "No Name param" try: newDir = webRootDir.Create(_IIS_WEBVIRTUALDIR, params.Name) --- 127,134 ---- raise ItemNotFound, "ADSI object %s.%s" % (clsName, objName) ! def CreateVirtualDir(webRootDir, params, options): if not params.Name: raise ConfigurationError, "No Name param" + _CallHook(params, "PreInstall", options) try: newDir = webRootDir.Create(_IIS_WEBVIRTUALDIR, params.Name) *************** *** 140,143 **** --- 145,149 ---- else: log(2, "Creating new directory '%s'..." % (params.Name,)) + friendly = params.Description or params.Name newDir.AppFriendlyName = friendly *************** *** 177,184 **** "Unknown ScriptMapUpdate option '%s'" % (params.ScriptMapUpdate,) newDir.SetInfo() log(1, "Configured Virtual Directory: %s" % (params.Name,)) return newDir ! def CreateISAPIFilter(webServer, filterParams): filters = FindADSIObject(webServer, _IIS_FILTERS, "Filters") try: --- 183,192 ---- "Unknown ScriptMapUpdate option '%s'" % (params.ScriptMapUpdate,) newDir.SetInfo() + _CallHook(params, "PostInstall", options, newDir) log(1, "Configured Virtual Directory: %s" % (params.Name,)) return newDir ! def CreateISAPIFilter(webServer, filterParams, options): ! _CallHook(filterParams, "PreInstall", options) filters = FindADSIObject(webServer, _IIS_FILTERS, "Filters") try: *************** *** 199,206 **** filters.FilterLoadOrder = ",".join(load_order) filters.SetInfo() log (1, "Configured Filter: %s" % (filterParams.Name,)) return newFilter ! def DeleteISAPIFilter(webServer, filterParams): filters = FindADSIObject(webServer, _IIS_FILTERS, "Filters") try: --- 207,216 ---- filters.FilterLoadOrder = ",".join(load_order) filters.SetInfo() + _CallHook(filterParams, "PostInstall", options, newFilter) log (1, "Configured Filter: %s" % (filterParams.Name,)) return newFilter ! def DeleteISAPIFilter(webServer, filterParams, options): ! _CallHook(filterParams, "PreRemove", options) filters = FindADSIObject(webServer, _IIS_FILTERS, "Filters") try: *************** *** 218,221 **** --- 228,232 ---- filters.FilterLoadOrder = ",".join(load_order) filters.SetInfo() + _CallHook(filterParams, "PostRemove", options) log (1, "Deleted Filter: %s" % (filterParams.Name,)) *************** *** 246,260 **** log(2, "%s is up to date." % (dll_name,)) ! def Install(params): server_name = _DEFAULT_SERVER_NAME web_service = FindWebServiceObject() server = FindWebServer(server_name) root = FindADSIObject(server, _IIS_WEBVIRTUALDIR, "Root") for vd in params.VirtualDirs: ! CreateVirtualDir(root, vd) for filter_def in params.Filters: ! f = CreateISAPIFilter(server, filter_def) ! def Uninstall(params): server_name = _DEFAULT_SERVER_NAME web_service = FindWebServiceObject() --- 257,281 ---- log(2, "%s is up to date." % (dll_name,)) ! def _CallHook(ob, hook_name, options, *extra_args): ! func = getattr(ob, hook_name, None) ! if func is not None: ! args = (ob,options) + extra_args ! func(*args) ! ! def Install(params, options): server_name = _DEFAULT_SERVER_NAME + _CallHook(params, "PreInstall", options) web_service = FindWebServiceObject() server = FindWebServer(server_name) root = FindADSIObject(server, _IIS_WEBVIRTUALDIR, "Root") for vd in params.VirtualDirs: ! CreateVirtualDir(root, vd, options) ! for filter_def in params.Filters: ! f = CreateISAPIFilter(server, filter_def, options) ! _CallHook(params, "PostInstall", options) ! def Uninstall(params, options): ! _CallHook(params, "PreRemove", options) server_name = _DEFAULT_SERVER_NAME web_service = FindWebServiceObject() *************** *** 262,265 **** --- 283,298 ---- root = FindADSIObject(server, _IIS_WEBVIRTUALDIR, "Root") for vd in params.VirtualDirs: + _CallHook(vd, "PreRemove", options) + # Find the virtual dir, and unload it. This should stop the app + # immediately, rather than needing to restart IIS. + try: + d = FindADSIObject(root, _IIS_WEBVIRTUALDIR, vd.Name) + except ItemNotFound: + # This can happen when the VD has not yet been loaded + pass + else: + d.AppUnload() + log (2, "Unloaded Virtual Directory: %s" % (vd.Name,)) + # Now actually delete the directory. try: newDir = root.Delete(_IIS_WEBVIRTUALDIR, vd.Name) *************** *** 268,276 **** if rc != winerror.ERROR_PATH_NOT_FOUND: raise log (1, "Deleted Virtual Directory: %s" % (vd.Name,)) - for filter_def in params.Filters: ! DeleteISAPIFilter(server, filter_def) # Patch up any missing module names in the params, replacing them with --- 301,310 ---- if rc != winerror.ERROR_PATH_NOT_FOUND: raise + _CallHook(vd, "PostRemove", options) log (1, "Deleted Virtual Directory: %s" % (vd.Name,)) for filter_def in params.Filters: ! DeleteISAPIFilter(server, filter_def, options) ! _CallHook(params, "PostRemove", options) # Patch up any missing module names in the params, replacing them with *************** *** 313,317 **** return dll_name ! def InstallModule(conf_module_name, params): if not hasattr(sys, "frozen"): conf_module_name = os.path.abspath(conf_module_name) --- 347,351 ---- return dll_name ! def InstallModule(conf_module_name, params, options): if not hasattr(sys, "frozen"): conf_module_name = os.path.abspath(conf_module_name) *************** *** 321,335 **** loader_dll = GetLoaderModuleName(conf_module_name) _PatchParamsModule(params, loader_dll) ! Install(params) ! def UninstallModule(conf_module_name, params): loader_dll = GetLoaderModuleName(conf_module_name) _PatchParamsModule(params, loader_dll, False) ! Uninstall(params) # Later we will probably need arguments that allow us to change the # name of the default server, etc - ie, at the moment, we only work # when the WWW server is named _DEFAULT_SERVER_NAME ("Default Web Site") ! def HandleCommandLine(params, argv=None, conf_module_name = None): global verbose from optparse import OptionParser --- 355,388 ---- loader_dll = GetLoaderModuleName(conf_module_name) _PatchParamsModule(params, loader_dll) ! Install(params, options) ! def UninstallModule(conf_module_name, params, options): loader_dll = GetLoaderModuleName(conf_module_name) _PatchParamsModule(params, loader_dll, False) ! Uninstall(params, options) ! ! standard_arguments = { ! "install" : "Install the extension", ! "remove" : "Remove the extension" ! } # Later we will probably need arguments that allow us to change the # name of the default server, etc - ie, at the moment, we only work # when the WWW server is named _DEFAULT_SERVER_NAME ("Default Web Site") ! # ! # We support 2 ways of extending our command-line/install support. ! # * Many of the installation items allow you to specify "PreInstall", ! # "PostInstall", "PreRemove" and "PostRemove" hooks ! # All hooks are called with the 'params' object being operated on, and ! # the 'optparser' options for this session (ie, the command-line options) ! # PostInstall for VirtualDirectories and Filters both have an additional ! # param - the ADSI object just created. ! # * You can pass your own option parser for us to use, and/or define a map ! # with your own custom arg handlers. It is a map of 'arg'->function. ! # The function is called with (options, log_fn, arg). The function's ! # docstring is used in the usage output. ! def HandleCommandLine(params, argv=None, conf_module_name = None, ! default_arg = "install", ! opt_parser = None, custom_arg_handlers = {}): global verbose from optparse import OptionParser *************** *** 338,346 **** conf_module_name = conf_module_name or sys.argv[0] ! parser = OptionParser(usage="%prog [options] [install|remove]") parser.add_option("-q", "--quiet", action="store_false", dest="verbose", default=True, help="don't print status messages to stdout") ! parser.add_option("-v", "--verbosity", dest="verbose", default=1, help="set the verbosity of status messages") --- 391,418 ---- conf_module_name = conf_module_name or sys.argv[0] ! if opt_parser is None: ! # Build our own parser. ! parser = OptionParser(usage='') ! else: ! # The caller is providing their own filter, presumably with their ! # own options all setup. ! parser = opt_parser ! ! # build a usage string if we don't have one. ! if not parser.get_usage(): ! all_args = standard_arguments.copy() ! for arg, handler in custom_arg_handlers.items(): ! all_args[arg] = handler.__doc__ ! arg_names = "|".join(all_args.keys()) ! usage_string = "%prog [options] [" + arg_names + "]\n" ! usage_string += "commands:\n" ! for arg, desc in all_args.items(): ! usage_string += " %-10s: %s" % (arg, desc) + "\n" ! parser.set_usage(usage_string[:-1]) ! parser.add_option("-q", "--quiet", action="store_false", dest="verbose", default=True, help="don't print status messages to stdout") ! parser.add_option("-v", "--verbosity", action="count", dest="verbose", default=1, help="set the verbosity of status messages") *************** *** 349,360 **** verbose = options.verbose if not args: ! args = ["install"] ! for arg in args: ! if arg == "install": ! InstallModule(conf_module_name, params) ! log(1, "Installation complete.") ! elif arg in ["remove", "uninstall"]: ! UninstallModule(conf_module_name, params) ! log(1, "Uninstallation complete.") ! else: ! parser.error("Invalid arg '%s'" % (arg,)) --- 421,440 ---- verbose = options.verbose if not args: ! args = [default_arg] ! try: ! for arg in args: ! if arg == "install": ! InstallModule(conf_module_name, params, options) ! log(1, "Installation complete.") ! elif arg in ["remove", "uninstall"]: ! UninstallModule(conf_module_name, params, options) ! log(1, "Uninstallation complete.") ! else: ! handler = custom_arg_handlers.get(arg, None) ! if handler is None: ! parser.error("Invalid arg '%s'" % (arg,)) ! handler(options, log, arg) ! except InstallationError, details: ! if options.verbose > 1: ! traceback.print_exc() ! print "%s: %s" % (details.__class__.__name__, details) |
|
From: Mark H. <mha...@us...> - 2004-09-04 09:38:23
|
Update of /cvsroot/pywin32/pywin32/pyisapi/samples In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7197 Modified Files: redirector.py Log Message: Correct comment, and use 'isapidllhandle' instead of GetConsoleTitle Index: redirector.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/pyisapi/samples/redirector.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** redirector.py 1 Sep 2004 03:07:12 -0000 1.1 --- redirector.py 4 Sep 2004 09:38:11 -0000 1.2 *************** *** 4,8 **** # Please see README.txt in this directory, and specifically the # information about the "loader" DLL - installing this sample will create ! # "redirector.dll" in the current directory. The readme explains this. # Executing this script (or any server config script) will install the extension --- 4,8 ---- # Please see README.txt in this directory, and specifically the # information about the "loader" DLL - installing this sample will create ! # "_redirector.dll" in the current directory. The readme explains this. # Executing this script (or any server config script) will install the extension *************** *** 30,43 **** from isapi import isapicon, threaded_extension from isapi.simple import SimpleFilter import traceback import urllib ! # If we have no console (eg, am running from inside IIS), redirect output ! # somewhere useful - in this case, the standard win32 trace collector. ! import win32api ! try: ! win32api.GetConsoleTitle() ! except win32api.error: ! # No console - redirect import win32traceutil --- 30,40 ---- from isapi import isapicon, threaded_extension from isapi.simple import SimpleFilter + import sys import traceback import urllib ! # sys.isapidllhandle will exist when we are loaded by the IIS framework. ! # In this case we redirect our output to the win32traceutil collector. ! if hasattr(sys, "isapidllhandle"): import win32traceutil |
|
From: Mark H. <mha...@us...> - 2004-09-04 09:37:19
|
Update of /cvsroot/pywin32/pywin32/pyisapi/isapi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7119 Modified Files: __init__.py Log Message: Add InternalReloadException. Index: __init__.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/pyisapi/isapi/__init__.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** __init__.py 1 Sep 2004 03:07:11 -0000 1.1 --- __init__.py 4 Sep 2004 09:37:09 -0000 1.2 *************** *** 24,26 **** class ExtensionError(ISAPIError): pass ! \ No newline at end of file --- 24,33 ---- class ExtensionError(ISAPIError): pass ! ! # A little development aid - a filter or extension callback function can ! # raise one of these exceptions, and the handler module will be reloaded. ! # This means you can change your code without restarting IIS. ! # After a reload, your filter/extension will have the GetFilterVersion/ ! # GetExtensionVersion function called, but with None as the first arg. ! class InternalReloadException(Exception): ! pass |
|
From: Mark H. <mha...@us...> - 2004-09-04 09:36:58
|
Update of /cvsroot/pywin32/pywin32/pyisapi/isapi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7051 Modified Files: threaded_extension.py Log Message: Close the completion port handle on terminate. Delegate to base-class to setup the flags/description. Index: threaded_extension.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/pyisapi/isapi/threaded_extension.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** threaded_extension.py 1 Sep 2004 03:07:11 -0000 1.1 --- threaded_extension.py 4 Sep 2004 09:36:49 -0000 1.2 *************** *** 2,6 **** import isapi.simple from win32file import GetQueuedCompletionStatus, CreateIoCompletionPort, \ ! PostQueuedCompletionStatus from win32security import SetThreadToken from win32event import INFINITE --- 2,6 ---- import isapi.simple from win32file import GetQueuedCompletionStatus, CreateIoCompletionPort, \ ! PostQueuedCompletionStatus, CloseHandle from win32security import SetThreadToken from win32event import INFINITE *************** *** 58,62 **** def GetExtensionVersion(self, vi): ! vi.ExtensionDesc = self.__doc__ # As per Q192800, the CompletionPort should be created with the number # of processors, even if the number of worker threads is much larger. --- 58,62 ---- def GetExtensionVersion(self, vi): ! isapi.simple.SimpleExtension.GetExtensionVersion(self, vi) # As per Q192800, the CompletionPort should be created with the number # of processors, even if the number of worker threads is much larger. *************** *** 84,87 **** --- 84,88 ---- worker.join(self.worker_shutdown_wait) self.dispatch_map = {} # break circles + CloseHandle(self.io_req_port) # This is the one operation the base class supports - a simple |
|
From: Mark H. <mha...@us...> - 2004-09-04 09:36:22
|
Update of /cvsroot/pywin32/pywin32/pyisapi/isapi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6918 Modified Files: simple.py Log Message: * Add base-class constructors, incase we add something later, and Init functions handle reload Index: simple.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/pyisapi/isapi/simple.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** simple.py 1 Sep 2004 03:07:11 -0000 1.1 --- simple.py 4 Sep 2004 09:36:12 -0000 1.2 *************** *** 3,8 **** class SimpleExtension: "Base class for a a simple ISAPI extension" def GetExtensionVersion(self, vi): ! vi.ExtensionDesc = self.__doc__ def HttpExtensionProc(self, control_block): --- 3,13 ---- class SimpleExtension: "Base class for a a simple ISAPI extension" + def __init__(self): + pass + def GetExtensionVersion(self, vi): ! # nod to our reload capability - vi is None when we are reloaded. ! if vi is not None: ! vi.ExtensionDesc = self.__doc__ def HttpExtensionProc(self, control_block): *************** *** 15,23 **** "Base class for a a simple ISAPI filter" filter_flags = None def GetFilterVersion(self, fv): if self.filter_flags is None: raise RuntimeError, "You must specify the filter flags" ! fv.Flags = self.filter_flags ! fv.FilterDesc = self.__doc__ def HttpFilterProc(self, fc): --- 20,33 ---- "Base class for a a simple ISAPI filter" filter_flags = None + def __init__(self): + pass + def GetFilterVersion(self, fv): if self.filter_flags is None: raise RuntimeError, "You must specify the filter flags" ! # nod to our reload capability - fv is None when we are reloaded. ! if fv is not None: ! fv.Flags = self.filter_flags ! fv.FilterDesc = self.__doc__ def HttpFilterProc(self, fc): |
|
From: Mark H. <mha...@us...> - 2004-09-04 09:29:02
|
Update of /cvsroot/pywin32/pywin32/pyisapi/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5536 Modified Files: PythonEng.cpp PythonEng.h pyISAPI.cpp Log Message: Reorganize the C++ code so that we can support 'reloading' the extension or filter. By raising a special exception, the Python code can force the framework to reload the main module, and re-instantiate the handlers. Index: pyISAPI.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/pyisapi/src/pyISAPI.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pyISAPI.cpp 1 Sep 2004 03:07:12 -0000 1.1 --- pyISAPI.cpp 4 Sep 2004 09:28:50 -0000 1.2 *************** *** 32,37 **** #include "pyFilterObjects.h" static CPythonEngine pyEngine; ! static CPythonEngine pyFilterEngine; bool g_IsFrozen = false; --- 32,49 ---- #include "pyFilterObjects.h" + static const char *name_ext_factory = "__ExtensionFactory__"; + static const char *name_ext_init = "GetExtensionVersion"; + static const char *name_ext_do = "HttpExtensionProc"; + static const char *name_ext_term = "TerminateExtension"; + + static const char *name_filter_factory = "__FilterFactory__"; + static const char *name_filter_init = "GetFilterVersion"; + static const char *name_filter_do = "HttpFilterProc"; + static const char *name_filter_term = "TerminateFilter"; + static CPythonEngine pyEngine; ! static CPythonHandler filterHandler; ! static CPythonHandler extensionHandler; ! bool g_IsFrozen = false; *************** *** 52,69 **** { pVer->dwExtensionVersion = MAKELONG( HSE_VERSION_MINOR, HSE_VERSION_MAJOR ); ! ! // stage 1: ensure Python ready to go ! if (!pyEngine.InitMainInterp()){ ! TRACE("Unable to initialse python interpreter"); ! return false; ! } ! if (!pyEngine.LoadHandler("__ExtensionFactory__")) { ! // LoadHandler has reported any errors to Python. TRACE("Unable to load Python handler"); return false; } - if (!pyEngine.SetCallback("GetExtensionVersion")) - return FALSE; - PyObject *resultobject = NULL; bool bRetStatus = true; --- 64,74 ---- { pVer->dwExtensionVersion = MAKELONG( HSE_VERSION_MINOR, HSE_VERSION_MAJOR ); ! // ensure our handler ready to go ! if (!extensionHandler.Init(&pyEngine, name_ext_factory, ! name_ext_init, name_ext_do, name_ext_term)) { ! // already have reported any errors to Python. TRACE("Unable to load Python handler"); return false; } PyObject *resultobject = NULL; bool bRetStatus = true; *************** *** 72,76 **** // create the Python object PyVERSION_INFO *pyVO = new PyVERSION_INFO(pVer); ! resultobject = pyEngine.Callback("N", pyVO); if (! resultobject) { ExtensionError(NULL, "Extension version function failed!"); --- 77,81 ---- // create the Python object PyVERSION_INFO *pyVO = new PyVERSION_INFO(pVer); ! resultobject = extensionHandler.Callback(HANDLER_INIT, "N", pyVO); if (! resultobject) { ExtensionError(NULL, "Extension version function failed!"); *************** *** 88,93 **** Py_XDECREF(resultobject); PyGILState_Release(state); - if (bRetStatus) - bRetStatus = pyEngine.SetCallback("HttpExtensionProc"); return bRetStatus; } --- 93,96 ---- *************** *** 99,103 **** CControlBlock * pcb = new CControlBlock(pECB); PyECB *pyECB = new PyECB(pcb); ! PyObject *resultobject = pyEngine.Callback("N", pyECB); if (! resultobject) { ExtensionError(pcb, "HttpExtensionProc function failed!"); --- 102,106 ---- CControlBlock * pcb = new CControlBlock(pECB); PyECB *pyECB = new PyECB(pcb); ! PyObject *resultobject = extensionHandler.Callback(HANDLER_DO, "N", pyECB); if (! resultobject) { ExtensionError(pcb, "HttpExtensionProc function failed!"); *************** *** 119,142 **** { // extension is being terminated ! BOOL bRetStatus = pyEngine.SetCallback("TerminateExtension"); ! if (bRetStatus) { ! PyGILState_STATE state = PyGILState_Ensure(); ! PyObject *resultobject = pyEngine.Callback("i", dwFlags); ! if (! resultobject) { ! FilterError(NULL, "Extension term function failed!"); ! bRetStatus = false; ! } else { ! if (resultobject == Py_None) ! bRetStatus = TRUE; ! else if (PyInt_Check(resultobject)) ! bRetStatus = PyInt_AsLong(resultobject) ? true : false; ! else { ! FilterError(NULL, "Extension term should return an int, or None"); ! bRetStatus = FALSE; ! } } - Py_XDECREF(resultobject); - PyGILState_Release(state); } return bRetStatus; } --- 122,144 ---- { // extension is being terminated ! BOOL bRetStatus; ! PyGILState_STATE state = PyGILState_Ensure(); ! PyObject *resultobject = extensionHandler.Callback(HANDLER_TERM, "i", dwFlags); ! if (! resultobject) { ! ExtensionError(NULL, "Extension term function failed!"); ! bRetStatus = false; ! } else { ! if (resultobject == Py_None) ! bRetStatus = TRUE; ! else if (PyInt_Check(resultobject)) ! bRetStatus = PyInt_AsLong(resultobject) ? true : false; ! else { ! ExtensionError(NULL, "Extension term should return an int, or None"); ! bRetStatus = FALSE; } } + Py_XDECREF(resultobject); + PyGILState_Release(state); + extensionHandler.Term(); return bRetStatus; } *************** *** 145,157 **** { pVer->dwFilterVersion = HTTP_FILTER_REVISION; ! if (!pyFilterEngine.InitMainInterp() || ! !pyFilterEngine.LoadHandler("__FilterFactory__")) ! return FALSE; ! if (!pyFilterEngine.SetCallback("GetFilterVersion")) return FALSE; PyGILState_STATE state = PyGILState_Ensure(); PyFILTER_VERSION *pyFV = new PyFILTER_VERSION(pVer); ! PyObject *resultobject = pyFilterEngine.Callback("N", pyFV); BOOL bRetStatus; if (! resultobject) { --- 147,159 ---- { pVer->dwFilterVersion = HTTP_FILTER_REVISION; ! // ensure our handler ready to go ! if (!filterHandler.Init(&pyEngine, name_filter_factory, ! name_filter_init, name_filter_do, name_filter_term)) ! // error already imported. return FALSE; PyGILState_STATE state = PyGILState_Ensure(); PyFILTER_VERSION *pyFV = new PyFILTER_VERSION(pVer); ! PyObject *resultobject = filterHandler.Callback(HANDLER_INIT, "N", pyFV); BOOL bRetStatus; if (! resultobject) { *************** *** 170,183 **** Py_XDECREF(resultobject); PyGILState_Release(state); - if (bRetStatus) - // All future callbacks are the filter proc! - bRetStatus = pyFilterEngine.SetCallback("HttpFilterProc"); - return bRetStatus; - /* Specify the types and order of notification */ - // Need to call Python so it can set all this. - // pVer->dwFlags = (SF_NOTIFY_PREPROC_HEADERS | SF_NOTIFY_NONSECURE_PORT | SF_NOTIFY_URL_MAP | SF_NOTIFY_SEND_RAW_DATA | SF_NOTIFY_ORDER_DEFAULT); - // strcpy(pVer->lpszFilterDesc, "Python sample filter"); - // return true; } --- 172,176 ---- *************** *** 186,190 **** DWORD action; PyGILState_STATE state = PyGILState_Ensure(); ! PyObject *resultobject = NULL; --- 179,183 ---- DWORD action; PyGILState_STATE state = PyGILState_Ensure(); ! PyObject *resultobject = NULL; *************** *** 192,196 **** CFilterContext fc(phfc, NotificationType, pvData); PyHFC *pyHFC = new PyHFC(&fc); ! resultobject = pyFilterEngine.Callback("O", pyHFC); if (! resultobject) { FilterError(&fc, "Filter function failed!"); --- 185,189 ---- CFilterContext fc(phfc, NotificationType, pvData); PyHFC *pyHFC = new PyHFC(&fc); ! resultobject = filterHandler.Callback(HANDLER_DO, "O", pyHFC); if (! resultobject) { FilterError(&fc, "Filter function failed!"); *************** *** 216,224 **** BOOL WINAPI TerminateFilter(DWORD status) { - if (!pyFilterEngine.SetCallback("TerminateFilter")) - return FALSE; BOOL bRetStatus; PyGILState_STATE state = PyGILState_Ensure(); ! PyObject *resultobject = pyFilterEngine.Callback("i", status); if (! resultobject) { FilterError(NULL, "Filter version function failed!"); --- 209,215 ---- BOOL WINAPI TerminateFilter(DWORD status) { BOOL bRetStatus; PyGILState_STATE state = PyGILState_Ensure(); ! PyObject *resultobject = filterHandler.Callback(HANDLER_TERM, "i", status); if (! resultobject) { FilterError(NULL, "Filter version function failed!"); *************** *** 237,241 **** PyGILState_Release(state); // filter is being terminated ! pyFilterEngine.ShutdownInterp(); return bRetStatus; } --- 228,232 ---- PyGILState_Release(state); // filter is being terminated ! filterHandler.Term(); return bRetStatus; } Index: PythonEng.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/pyisapi/src/PythonEng.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PythonEng.cpp 1 Sep 2004 03:07:12 -0000 1.1 --- PythonEng.cpp 4 Sep 2004 09:28:50 -0000 1.2 *************** *** 43,48 **** CRITICAL_SECTION CPythonEngine::m_initLock; bool CPythonEngine::m_haveInit = false; ! CPythonEngine::CPythonEngine() : m_handler(0), m_callback(0) { InitializeCriticalSection(&m_initLock); --- 43,49 ---- CRITICAL_SECTION CPythonEngine::m_initLock; bool CPythonEngine::m_haveInit = false; + PyObject * CPythonEngine::m_reload_exception = NULL; ! CPythonEngine::CPythonEngine() { InitializeCriticalSection(&m_initLock); *************** *** 80,85 **** PySys_SetObject("isapidllhandle", obh); Py_XDECREF(obh); ! PyGILState_Release(old_state); m_haveInit = true; } --- 81,92 ---- PySys_SetObject("isapidllhandle", obh); Py_XDECREF(obh); ! // Locate the special exception we use to trigger a reload. ! PyObject *isapi_package = PyImport_ImportModule("isapi"); ! if (isapi_package) ! m_reload_exception = PyObject_GetAttrString(isapi_package, ! "InternalReloadException"); ! Py_XDECREF(isapi_package); PyGILState_Release(old_state); + FindModuleName(); m_haveInit = true; } *************** *** 87,99 **** } ! bool CPythonEngine::LoadHandler(char *factory_name) { - PyObject *m; TCHAR szFilePath[_MAX_PATH]; TCHAR szBase[_MAX_FNAME]; - TCHAR szErrBuf[1024]; TCHAR *module_name; - - assert(m_handler==NULL); // should only be called once. // If a name for the module has been magically setup (eg, via a frozen --- 94,102 ---- } ! void CPythonEngine::FindModuleName() { TCHAR szFilePath[_MAX_PATH]; TCHAR szBase[_MAX_FNAME]; TCHAR *module_name; // If a name for the module has been magically setup (eg, via a frozen *************** *** 115,128 **** } } PyGILState_STATE old_state = PyGILState_Ensure(); ! if (!(m = PyImport_ImportModule(module_name))) { _snprintf(szErrBuf, sizeof(szErrBuf)/sizeof(szErrBuf[0]), ! "Failed to import callback module '%s'", module_name); ExtensionError(NULL, szErrBuf); } if (m) { ! if (!((m_handler = PyObject_CallMethod(m, factory_name, NULL)))) { _snprintf(szErrBuf, sizeof(szErrBuf)/sizeof(szErrBuf[0]), ! "Factory function '%s' failed", factory_name); ExtensionError(NULL, szErrBuf); } --- 118,205 ---- } } + strncpy(m_module_name, module_name, sizeof(m_module_name)/sizeof(m_module_name[0])); + } + + bool CPythonEngine::AddToPythonPath(LPCTSTR pPathName) + { + PyObject *obPathList = PySys_GetObject(_T("path")); + if (obPathList==NULL) { + return false; + } + + PyObject *obNew = PyString_FromString(pPathName); + if (obNew==NULL) { + return false; + } + + bool bFnd=false; + for (int i=0; i<PyList_Size(obPathList); i++){ + PyObject * obItem = PyList_GetItem(obPathList, i); + if(PyObject_Compare(obNew, obItem) == 0){ + bFnd = true; + break; + } + } + + if (!bFnd) + PyList_Insert(obPathList, 0, obNew); + + Py_XDECREF(obNew); + return true; + } + + /////////////////////////////////////////////////////////////////////// + // + // The callback manager + // + CPythonHandler::CPythonHandler() : + m_namefactory(0), + m_nameinit(0), + m_namedo(0), + m_nameterm(0), + m_callback_init(0), + m_callback_do(0), + m_callback_term(0), + m_handler(0) + { + return; + } + + bool CPythonHandler::Init( + CPythonEngine *engine, + const char *factory, const char *nameinit, const char *namedo, + const char *nameterm) + { + if (!engine->InitMainInterp()) + return false; + m_nameinit = nameinit; + m_namedo = namedo; + m_nameterm = nameterm; + m_namefactory = factory; + m_engine = engine; + return LoadHandler(false); + } + + bool CPythonHandler::LoadHandler(bool reload) + { + char szErrBuf[1024]; + PyObject *m; PyGILState_STATE old_state = PyGILState_Ensure(); ! m = PyImport_ImportModule(m_engine->m_module_name); ! if (m && reload) { ! PyObject *m_orig = m; ! m = PyImport_ReloadModule(m); ! Py_DECREF(m_orig); ! } ! if (!m) { _snprintf(szErrBuf, sizeof(szErrBuf)/sizeof(szErrBuf[0]), ! "Failed to import callback module '%s'", m_engine->m_module_name); ExtensionError(NULL, szErrBuf); } if (m) { ! Py_XDECREF(m_handler); ! if (!((m_handler = PyObject_CallMethod(m, (char *)m_namefactory, NULL)))) { _snprintf(szErrBuf, sizeof(szErrBuf)/sizeof(szErrBuf[0]), ! "Factory function '%s' failed", m_namefactory); ExtensionError(NULL, szErrBuf); } *************** *** 133,167 **** } ! // Set the current 'callback' - all future callbacks will be made to ! // the fetched method. ! bool CPythonEngine::SetCallback(const char *cbname) { ! assert(m_handler); ! if (!m_handler) ! return NULL; PyGILState_STATE old_state = PyGILState_Ensure(); ! ! Py_XDECREF(m_callback); ! m_callback = PyObject_GetAttrString(m_handler, (char *)cbname); ! if (!m_callback) ExtensionError(NULL, "Failed to locate the callback"); PyGILState_Release(old_state); ! return m_callback != NULL; } // NOTE: Caller must setup and release thread-state - as we return a PyObject, // the caller must at least Py_DECREF it, so must hold the lock. ! PyObject *CPythonEngine::Callback( ! const char *format /* = NULL */, ! ... ) { ! assert(m_callback); ! if (!m_callback) return NULL; va_list va; ! PyObject *args, *retval; if (format && *format) { --- 210,268 ---- } ! ! bool CPythonHandler::CheckCallback(const char *cbname, PyObject **cb) { ! if (*cb!=NULL) ! return true; // already have the callback. PyGILState_STATE old_state = PyGILState_Ensure(); ! if (!m_handler) { ! PyErr_SetString(PyExc_RuntimeError, "The handler failed to load"); ! return false; ! } ! *cb = PyObject_GetAttrString(m_handler, (char *)cbname); ! if (!*cb) ExtensionError(NULL, "Failed to locate the callback"); PyGILState_Release(old_state); ! return (*cb) != NULL; } // NOTE: Caller must setup and release thread-state - as we return a PyObject, // the caller must at least Py_DECREF it, so must hold the lock. ! PyObject *CPythonHandler::DoCallback( ! HANDLER_TYPE typ, ! PyObject *args ) { ! PyObject **ppcb; ! const char *cb_name; ! switch(typ) { ! case HANDLER_INIT: ! ppcb = &m_callback_init; ! cb_name = m_nameinit; ! break; ! case HANDLER_TERM: ! ppcb = &m_callback_term; ! cb_name = m_nameterm; ! break; ! default: ! ppcb = &m_callback_do; ! cb_name = m_namedo; ! break; ! } ! if (!CheckCallback(cb_name, ppcb)) return NULL; + return PyObject_Call(*ppcb, args, NULL); + } + + PyObject *CPythonHandler::Callback( + HANDLER_TYPE typ, + const char *format /* = NULL */, + ... + ) + { va_list va; ! PyObject *args; if (format && *format) { *************** *** 186,227 **** args = a; } ! retval = PyObject_Call(m_callback, args, NULL); Py_DECREF(args); ! return retval; } ! void CPythonEngine::ShutdownInterp(void) { // never shut down - Python leaks badly and has other // side effects if you repeatedly Init then Term ! } ! ! bool CPythonEngine::AddToPythonPath(LPCTSTR pPathName) ! { ! PyObject *obPathList = PySys_GetObject(_T("path")); ! if (obPathList==NULL) { ! return false; ! } ! ! PyObject *obNew = PyString_FromString(pPathName); ! if (obNew==NULL) { ! return false; ! } ! ! bool bFnd=false; ! for (int i=0; i<PyList_Size(obPathList); i++){ ! PyObject * obItem = PyList_GetItem(obPathList, i); ! if(PyObject_Compare(obNew, obItem) == 0){ ! bFnd = true; ! break; ! } ! } ! ! if (!bFnd) ! PyList_Insert(obPathList, 0, obNew); ! ! Py_XDECREF(obNew); ! return true; } --- 287,339 ---- args = a; } ! ! PyObject *ret = DoCallback(typ, args); ! if (!ret) { ! if (m_engine->m_reload_exception && ! PyErr_ExceptionMatches(m_engine->m_reload_exception)) { ! PyErr_Clear(); ! // Need to call term first ! PyObject *temp_args = Py_BuildValue("(i)", 0); ! ret = DoCallback(HANDLER_TERM, temp_args); ! Py_XDECREF(temp_args); ! if (!ret) { ! ExtensionError(NULL, "Terminating for reload failed"); ! PyErr_Clear(); ! } ! Py_XDECREF(ret); ! // Now force the reload and refresh of all callbacks. ! if (!LoadHandler(true)) ! return NULL; ! Py_XDECREF(m_callback_init); ! m_callback_init = NULL; ! Py_XDECREF(m_callback_do); ! m_callback_do = NULL; ! Py_XDECREF(m_callback_term); ! m_callback_term = NULL; ! // call init again ! temp_args = Py_BuildValue("(z)", NULL); ! ret = DoCallback(HANDLER_INIT, temp_args); ! Py_XDECREF(temp_args); ! if (!ret) { ! ExtensionError(NULL, "Reinitializing after import failed"); ! PyErr_Clear(); ! } ! Py_XDECREF(ret); ! // And make the original call again. ! ret = DoCallback(typ, args); ! } ! } Py_DECREF(args); ! return ret; } ! void CPythonHandler::Term(void) { // never shut down - Python leaks badly and has other // side effects if you repeatedly Init then Term ! Py_XDECREF(m_callback_init); ! Py_XDECREF(m_callback_do); ! Py_XDECREF(m_callback_term); } Index: PythonEng.h =================================================================== RCS file: /cvsroot/pywin32/pywin32/pyisapi/src/PythonEng.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PythonEng.h 1 Sep 2004 03:07:12 -0000 1.1 --- PythonEng.h 4 Sep 2004 09:28:50 -0000 1.2 *************** *** 49,66 **** ~CPythonEngine(); bool InitMainInterp(void); ! void ShutdownInterp(void); ! bool LoadHandler(char *factory_name); ! PyObject *GetHandler() {return m_handler;} ! bool SetCallback(const char *callbackName); ! PyObject *Callback(const char *szFormat, ...); protected: bool AddToPythonPath(LPCTSTR pPathName); ! PyObject *m_handler; // couple of vars used to ensure that we intialis exactly once static CRITICAL_SECTION m_initLock; static bool m_haveInit; - PyObject * m_callback; }; // general error handler --- 49,93 ---- ~CPythonEngine(); bool InitMainInterp(void); ! char m_module_name[_MAX_FNAME]; ! static PyObject * m_reload_exception; protected: + bool AddToPythonPath(LPCTSTR pPathName); ! void FindModuleName(); // couple of vars used to ensure that we intialis exactly once static CRITICAL_SECTION m_initLock; static bool m_haveInit; }; + typedef enum { + HANDLER_INIT, + HANDLER_DO, + HANDLER_TERM, + } HANDLER_TYPE; + + class CPythonHandler + { + public: + CPythonHandler(); + bool Init(CPythonEngine *engine, + const char *factory, const char *nameinit, const char *namedo, + const char *nameterm); + void Term(); + PyObject *Callback(HANDLER_TYPE typ, const char *szFormat, ...); + protected: + PyObject *DoCallback(HANDLER_TYPE typ, PyObject *args); + + bool LoadHandler(bool reload); + bool CPythonHandler::CheckCallback(const char *cbname, PyObject **cb); + const char *m_namefactory; + const char *m_nameinit; + const char *m_namedo; + const char *m_nameterm; + PyObject *m_callback_init; // reference to instance methods.87 + PyObject *m_callback_do; + PyObject *m_callback_term; + PyObject *m_handler; // reference to the class instance. + CPythonEngine *m_engine; + }; // general error handler |
|
From: Mark H. <mha...@us...> - 2004-09-04 09:26:02
|
Update of /cvsroot/pywin32/pywin32/pyisapi/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5065 Modified Files: PyExtensionObjects.cpp PyFilterObjects.cpp Log Message: Add 'write' to the FilterControlBlock, and 'close' to both Index: PyExtensionObjects.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/pyisapi/src/PyExtensionObjects.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyExtensionObjects.cpp 1 Sep 2004 03:07:12 -0000 1.1 --- PyExtensionObjects.cpp 4 Sep 2004 09:25:49 -0000 1.2 *************** *** 143,147 **** {"ReadClient", PyECB::ReadClient, 1}, // @pymeth ReadClient| {"SendResponseHeaders", PyECB::SendResponseHeaders, 1}, ! {"DoneWithSession", PyECB::DoneWithSession, 1}, {"IsSessionActive", PyECB::IsSessionActive,1}, {"Redirect", PyECB::Redirect,1}, --- 143,148 ---- {"ReadClient", PyECB::ReadClient, 1}, // @pymeth ReadClient| {"SendResponseHeaders", PyECB::SendResponseHeaders, 1}, ! {"DoneWithSession", PyECB::DoneWithSession, 1}, ! {"close", PyECB::DoneWithSession, 1}, // @pymeth close|A synonym for DoneWithSession. {"IsSessionActive", PyECB::IsSessionActive,1}, {"Redirect", PyECB::Redirect,1}, Index: PyFilterObjects.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/pyisapi/src/PyFilterObjects.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyFilterObjects.cpp 1 Sep 2004 03:07:12 -0000 1.1 --- PyFilterObjects.cpp 4 Sep 2004 09:25:49 -0000 1.2 *************** *** 230,233 **** --- 230,234 ---- {"GetServerVariable", PyHFC::GetServerVariable, 1}, // @pymeth | {"WriteClient", PyHFC::WriteClient, 1}, // @pymeth | + {"write", PyHFC::WriteClient, 1}, // @pymeth write|A synonym for WriteClient, this allows you to 'print >> fc' {"SendResponseHeader", PyHFC::SendResponseHeader, 1}, // @pymeth | {NULL} |
|
From: Mark H. <mha...@us...> - 2004-09-04 03:06:38
|
Update of /cvsroot/pywin32/pywin32 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22965 Modified Files: setup_win32all.py Log Message: * Fix SDK lib dir handling. * Work around problem in distutils where the build order of dependents can't be defined - we need our .mc files processed before .cpp; the .mc generation process creates a .h Index: setup_win32all.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/setup_win32all.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** setup_win32all.py 15 Aug 2004 04:25:37 -0000 1.27 --- setup_win32all.py 4 Sep 2004 03:06:29 -0000 1.28 *************** *** 275,279 **** if extra not in self.include_dirs and os.path.isdir(extra): self.include_dirs.insert(0, extra) ! extra = os.path.join(sys.exec_prefix, 'lib') if extra not in self.library_dirs and os.path.isdir(extra): self.library_dirs.insert(0, extra) --- 275,279 ---- if extra not in self.include_dirs and os.path.isdir(extra): self.include_dirs.insert(0, extra) ! extra = os.path.join(sdk_dir, 'lib') if extra not in self.library_dirs and os.path.isdir(extra): self.library_dirs.insert(0, extra) *************** *** 717,733 **** macros, objects, extra, pp_opts, build = \ msvccompiler.MSVCCompiler._setup_compile(self, *args) ! build_order = ".i .mc .rc .cpp".split() ! decorated = [(build_order.index(ext.lower()), obj, (src, ext)) ! for obj, (src, ext) in build.items()] ! decorated.sort() ! items = [item[1:] for item in decorated] ! # The compiler itself only calls ".items" - leverage that, so that ! # when it does, the list is in the correct order. ! class OnlyItems: ! def __init__(self, items): ! self._items = items ! def items(self): ! return self._items ! build = OnlyItems(items) return macros, objects, extra, pp_opts, build --- 717,734 ---- macros, objects, extra, pp_opts, build = \ msvccompiler.MSVCCompiler._setup_compile(self, *args) ! if sys.hexversion < 0x02040000: ! build_order = ".i .mc .rc .cpp".split() ! decorated = [(build_order.index(ext.lower()), obj, (src, ext)) ! for obj, (src, ext) in build.items()] ! decorated.sort() ! items = [item[1:] for item in decorated] ! # The compiler itself only calls ".items" - leverage that, so that ! # when it does, the list is in the correct order. ! class OnlyItems: ! def __init__(self, items): ! self._items = items ! def items(self): ! return self._items ! build = OnlyItems(items) return macros, objects, extra, pp_opts, build *************** *** 1078,1081 **** --- 1079,1083 ---- 'com/win32comext/axscript/test/*', 'com/win32comext/axscript/Demos/*', + 'com/win32comext/mapi/demos/*.py', 'com/win32comext/shell/test/*.py', 'com/win32comext/shell/demos/servers/*.py', |
|
From: Mark H. <mha...@us...> - 2004-09-01 05:09:49
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30177 Modified Files: win32file.i Log Message: When passing overlapped structures via IOCompletionPorts, we temporarily bump the reference on the PyOVERLAPPED, so we get the exact same object back out of the completion port. This is to prevent the object's .object attribute from dieing while queued the port. Index: win32file.i =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/win32file.i,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** win32file.i 22 Jul 2004 08:36:31 -0000 1.42 --- win32file.i 1 Sep 2004 05:09:38 -0000 1.43 *************** *** 17,20 **** --- 17,21 ---- #include "winbase.h" #include "assert.h" + #include <stddef.h> #endif *************** *** 1180,1183 **** --- 1181,1221 ---- #ifndef MS_WINCE %{ + + // See Q192800 for an interesting discussion on overlapped and IOCP. + + PyObject *PyWinObject_FromQueuedOVERLAPPED(OVERLAPPED *p) + { + if (p==NULL || p==(OVERLAPPED *)-1) { + Py_INCREF(Py_None); + return Py_None; + } + + // We know this is a pointer to an OVERLAPPED inside a PyObject + // extract it back out. + size_t off = offsetof(PyOVERLAPPED, m_overlapped); + PyOVERLAPPED *po = (PyOVERLAPPED *)(((LPBYTE)p) - off); + // consume reference added when it was posted. + return po; + } + + BOOL PyWinObject_AsQueuedOVERLAPPED(PyObject *ob, OVERLAPPED **ppOverlapped, BOOL bNoneOK = TRUE) + { + PyOVERLAPPED *po = NULL; + if (!PyWinObject_AsPyOVERLAPPED(ob, &po, bNoneOK)) + return FALSE; + if (bNoneOK && po==NULL) { + *ppOverlapped = NULL; + return TRUE; + } + assert(po); + if (!po) + return FALSE; + PyOVERLAPPED::sMyOverlapped *pMyOverlapped = (PyOVERLAPPED::sMyOverlapped *)po; + // Add a fake reference so the object lives while in the queue. + Py_INCREF(ob); + *ppOverlapped = po->GetOverlapped(); + return TRUE; + } + // @pyswig (int, int, int, <o PyOVERLAPPED>)|GetQueuedCompletionStatus|Attempts to dequeue an I/O completion packet from a specified input/output completion port. // @comm This method never throws an API error. *************** *** 1198,1213 **** OVERLAPPED *pOverlapped = NULL; UINT errCode; ! Py_BEGIN_ALLOW_THREADS BOOL ok = GetQueuedCompletionStatus(handle, &bytes, &key, &pOverlapped, timeout); ! errCode = ok ? ok : GetLastError(); ! Py_END_ALLOW_THREADS ! PyObject *obOverlapped = PyWinObject_FromOVERLAPPED(pOverlapped); PyObject *rc = Py_BuildValue("illO", errCode, bytes, key, obOverlapped); Py_XDECREF(obOverlapped); return rc; } %} %native (GetQueuedCompletionStatus) myGetQueuedCompletionStatus; #endif // MS_WINCE --- 1236,1284 ---- OVERLAPPED *pOverlapped = NULL; UINT errCode; ! Py_BEGIN_ALLOW_THREADS BOOL ok = GetQueuedCompletionStatus(handle, &bytes, &key, &pOverlapped, timeout); ! errCode = ok ? 0 : GetLastError(); ! Py_END_ALLOW_THREADS ! PyObject *obOverlapped = PyWinObject_FromQueuedOVERLAPPED(pOverlapped); PyObject *rc = Py_BuildValue("illO", errCode, bytes, key, obOverlapped); Py_XDECREF(obOverlapped); return rc; } + + // @pyswig None|PostQueuedCompletionStatus|lets you post an I/O completion packet to an I/O completion port. The I/O completion packet will satisfy an outstanding call to the GetQueuedCompletionStatus function. + PyObject *myPostQueuedCompletionStatus(PyObject *self, PyObject *args) + { + PyObject *obHandle, *obOverlapped = NULL; + DWORD bytesTransfered = 0, key = 0; + // @pyparm <o PyHANDLE>|handle||handle to an I/O completion port + // @pyparm int|numberOfbytes|0|value to return via GetQueuedCompletionStatus' first result + // @pyparm int|completionKey|0|value to return via GetQueuedCompletionStatus' second result + // @pyparm <o PyOVERLAPPED>|overlapped|None|value to return via GetQueuedCompletionStatus' third result + if (!PyArg_ParseTuple(args, "O|iiO", &obHandle, &bytesTransfered, &key, &obOverlapped)) + return NULL; + HANDLE handle; + if (!PyWinObject_AsHANDLE(obHandle, &handle, FALSE)) + return NULL; + OVERLAPPED *pOverlapped; + if (!PyWinObject_AsQueuedOVERLAPPED(obOverlapped, &pOverlapped, TRUE)) + return NULL; + BOOL ok; + Py_BEGIN_ALLOW_THREADS + ok = ::PostQueuedCompletionStatus(handle, bytesTransfered, key, pOverlapped); + Py_END_ALLOW_THREADS + if (!ok) + return PyWin_SetAPIError("PostQueuedCompletionStatus"); + Py_INCREF(Py_None); + return Py_None; + // @comm Note that if you post overlapped objects, but your post is closed + // before all pending requests are processed, the overlapped objects + // (including its 'handle' and 'object' members) will leak. + // See MS KB article Q192800 for a summary of this. + } + %} %native (GetQueuedCompletionStatus) myGetQueuedCompletionStatus; + %native (PostQueuedCompletionStatus) myPostQueuedCompletionStatus; #endif // MS_WINCE *************** *** 1386,1399 **** #endif // MS_WINCE - #ifndef MS_WINCE - // @pyswig <o PyOVERLAPPED>|PostQueuedCompletionStatus|lets you post an I/O completion packet to an I/O completion port. The I/O completion packet will satisfy an outstanding call to the GetQueuedCompletionStatus function. - BOOLAPI PostQueuedCompletionStatus( - PyHANDLE CompletionPort, // @pyparm <o PyHANDLE>|handle||handle to an I/O completion port - DWORD dwNumberOfBytesTransferred, // @pyparm int|numberOfbytes||value to return via GetQueuedCompletionStatus' first result - DWORD dwCompletionKey, // // @pyparm int|completionKey||value to return via GetQueuedCompletionStatus' second result - OVERLAPPED *lpOverlapped // @pyparm <o PyOVERLAPPED>|overlapped||value to return via GetQueuedCompletionStatus' third result - ); - #endif // MS_WINCE - // QueryDosDevice --- 1457,1460 ---- |