pywin32-checkins Mailing List for Python for Windows Extensions (Page 115)
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...> - 2005-04-11 13:04:49
|
Update of /cvsroot/pywin32/pywin32/com/win32comext/axscript/client In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1781/axscript/client Modified Files: debug.py framework.py pyscript.py scriptdispatch.py Log Message: Patches from Kiriakos Vlahos, as described in [ 1119799 ] Active Debugging bugs. Index: pyscript.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/axscript/client/pyscript.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** pyscript.py 13 Feb 2005 12:26:33 -0000 1.8 --- pyscript.py 11 Apr 2005 13:04:40 -0000 1.9 *************** *** 39,48 **** # return string.join(string.split(text,'\n'),'\r\n') - def RemoveCR(text): - # No longer just "RemoveCR" - should be renamed to - # FixNewlines, or something. Idea is to fix arbitary newlines into - # something Python can compile... - return re.sub('(\r\n)|\r|(\n\r)','\n',text) - class AXScriptCodeBlock(framework.AXScriptCodeBlock): def GetDisplayName(self): --- 39,42 ---- *************** *** 343,347 **** if codeBlock is not None: realCode = "def %s():\n" % funcName ! for line in string.split(RemoveCR(codeBlock.codeText),"\n"): realCode = realCode + '\t' + line + '\n' realCode = realCode + '\n' --- 337,341 ---- if codeBlock is not None: realCode = "def %s():\n" % funcName ! for line in string.split(framework.RemoveCR(codeBlock.codeText),"\n"): realCode = realCode + '\t' + line + '\n' realCode = realCode + '\n' *************** *** 371,375 **** def DoParseScriptText(self, code, sourceContextCookie, startLineNumber, bWantResult, flags): ! code = RemoveCR(code) + "\n" if flags & SCRIPTTEXT_ISEXPRESSION: name = "Script Expression" --- 365,369 ---- def DoParseScriptText(self, code, sourceContextCookie, startLineNumber, bWantResult, flags): ! code = framework.RemoveCR(code) + "\n" if flags & SCRIPTTEXT_ISEXPRESSION: name = "Script Expression" Index: debug.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/axscript/client/debug.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** debug.py 1 Jun 2002 02:25:43 -0000 1.2 --- debug.py 11 Apr 2005 13:04:40 -0000 1.3 *************** *** 190,194 **** def _query_interface_(self, iid): trace("DebuggerQI with", iid) ! return 0 def GetScriptTextAttributes(self, code, delim, flags): --- 190,194 ---- def _query_interface_(self, iid): trace("DebuggerQI with", iid) ! return _wrap(self.debugMgr.scriptEngine, iid) def GetScriptTextAttributes(self, code, delim, flags): Index: framework.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/axscript/client/framework.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** framework.py 1 Feb 2004 22:24:20 -0000 1.20 --- framework.py 11 Apr 2005 13:04:40 -0000 1.21 *************** *** 16,19 **** --- 16,26 ---- import pythoncom import types + import re + + def RemoveCR(text): + # No longer just "RemoveCR" - should be renamed to + # FixNewlines, or something. Idea is to fix arbitary newlines into + # something Python can compile... + return re.sub('(\r\n)|\r|(\n\r)','\n',text) SCRIPTTEXT_FORCEEXECUTION = -2147483648 # 0x80000000 *************** *** 828,833 **** # This stack frame is debugged - therefore we do as little as possible in it. def _ApplyInScriptedSection(self, fn, args): ! if self.debugManager: self.debugManager.OnEnterScript() ! return apply(fn, args) def ApplyInScriptedSection(self, codeBlock, fn, args): --- 835,846 ---- # This stack frame is debugged - therefore we do as little as possible in it. def _ApplyInScriptedSection(self, fn, args): ! if self.debugManager: ! self.debugManager.OnEnterScript() ! if self.debugManager.adb.appDebugger: ! return self.debugManager.adb.runcall(fn, *args) ! else: ! return apply(fn, args) ! else: ! return apply(fn, args) def ApplyInScriptedSection(self, codeBlock, fn, args): *************** *** 859,863 **** try: try: ! codeObject = self._CompileInScriptedSection(code, name, type) codeBlock.codeObject = codeObject return 1 --- 872,876 ---- try: try: ! codeObject = self._CompileInScriptedSection(RemoveCR(code), name, type) codeBlock.codeObject = codeObject return 1 *************** *** 870,875 **** # This stack frame is debugged - therefore we do as little as possible in it. def _ExecInScriptedSection(self, codeObject, globals, locals = None): ! if self.debugManager: self.debugManager.OnEnterScript() ! exec codeObject in globals, locals def ExecInScriptedSection(self, codeBlock, globals, locals = None): --- 883,894 ---- # This stack frame is debugged - therefore we do as little as possible in it. def _ExecInScriptedSection(self, codeObject, globals, locals = None): ! if self.debugManager: ! self.debugManager.OnEnterScript() ! if self.debugManager.adb.appDebugger: ! return self.debugManager.adb.run(codeObject, globals, locals) ! else: ! exec codeObject in globals, locals ! else: ! exec codeObject in globals, locals def ExecInScriptedSection(self, codeBlock, globals, locals = None): *************** *** 888,893 **** def _EvalInScriptedSection(self, codeBlock, globals, locals = None): ! if self.debugManager: self.debugManager.OnEnterScript() ! return eval(codeBlock, globals, locals) def EvalInScriptedSection(self, codeBlock, globals, locals = None): --- 907,918 ---- def _EvalInScriptedSection(self, codeBlock, globals, locals = None): ! if self.debugManager: ! self.debugManager.OnEnterScript() ! if self.debugManager.adb.appDebugger: ! return self.debugManager.adb.runeval(codeBlock, globals, locals) ! else: ! return eval(codeBlock, globals, locals) ! else: ! return eval(codeBlock, globals, locals) def EvalInScriptedSection(self, codeBlock, globals, locals = None): Index: scriptdispatch.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/axscript/client/scriptdispatch.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** scriptdispatch.py 24 Nov 1999 23:42:13 -0000 1.2 --- scriptdispatch.py 11 Apr 2005 13:04:41 -0000 1.3 *************** *** 28,32 **** self.engine = engine self.scriptNamespace = scriptNamespace ! def _dynamic_(self, name, lcid, wFlags, args): if wFlags & pythoncom.INVOKE_FUNC: --- 28,32 ---- self.engine = engine self.scriptNamespace = scriptNamespace ! def _dynamic_(self, name, lcid, wFlags, args): if wFlags & pythoncom.INVOKE_FUNC: *************** *** 68,71 **** --- 68,83 ---- class StrictDynamicPolicy(win32com.server.policy.DynamicPolicy): + def _wrap_(self, object): + win32com.server.policy.DynamicPolicy._wrap_(self, object) + if hasattr(self._obj_, 'scriptNamespace'): + for name in dir(self._obj_.scriptNamespace): + self._dyn_dispid_to_name_[self._getdispid_(name,0)] = name + + def _getmembername_(self, dispid): + try: + return str(self._dyn_dispid_to_name_[dispid]) + except KeyError: + raise COMException(scode=winerror.DISP_E_UNKNOWNNAME, desc="Name not found") + def _getdispid_(self, name, fdex): try: |
From: Mark H. <mha...@us...> - 2005-04-11 00:37:45
|
Update of /cvsroot/pywin32/pywin32/win32/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4129 Modified Files: win32serviceutil.py Log Message: * Set the event-log 'Source' to be the service name. Very early failures will still get the default 'Python Service'. * When removing the service, also remove the eventlog source. * Correct comments Index: win32serviceutil.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/Lib/win32serviceutil.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** win32serviceutil.py 31 Jan 2005 04:12:00 -0000 1.16 --- win32serviceutil.py 11 Apr 2005 00:37:09 -0000 1.17 *************** *** 284,287 **** --- 284,293 ---- win32service.CloseServiceHandle(hscm) + import win32evtlogutil + try: + win32evtlogutil.RemoveSourceFromRegistry(serviceName) + except win32api.error: + pass + def ControlService(serviceName, code, machine = None): hscm = win32service.OpenSCManager(machine,None,win32service.SC_MANAGER_ALL_ACCESS) *************** *** 663,668 **** class ServiceFramework: # Required Attributes: ! # _svc_name = The service name ! # _svc_display_name = The service display name # Optional Attributes: --- 669,674 ---- class ServiceFramework: # Required Attributes: ! # _svc_name_ = The service name ! # _svc_display_name_ = The service display name # Optional Attributes: *************** *** 675,678 **** --- 681,685 ---- import servicemanager self.ssh = servicemanager.RegisterServiceCtrlHandler(args[0], self.ServiceCtrlHandler) + servicemanager.SetEventSourceName(self._svc_name_) self.checkPoint = 0 |
From: Mark H. <mha...@us...> - 2005-04-11 00:34:40
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3218 Modified Files: PythonService.cpp Log Message: Allow the Python program to specify the 'application name' for the event log entries. Very early failures will still get the default 'Python Service'. Index: PythonService.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/PythonService.cpp,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** PythonService.cpp 31 Mar 2005 00:21:01 -0000 1.17 --- PythonService.cpp 11 Apr 2005 00:34:30 -0000 1.18 *************** *** 35,38 **** --- 35,40 ---- TCHAR g_szEventSourceName[MAX_PATH] = _T("Python Service"); + TCHAR g_szEventSourceFileName[MAX_PATH] = _T(""); + BOOL g_bRegisteredEventSource = FALSE; BOOL bServiceDebug = FALSE; BOOL bServiceRunning = FALSE; *************** *** 279,282 **** --- 281,302 ---- } + // @pymethod |servicemanager|SetEventSourceName|Sets the event source name + // for event log entries written by the service. + static PyObject *PySetEventSourceName(PyObject *self, PyObject *args) + { + PyObject *obName; + if (!PyArg_ParseTuple(args, "O:SetEventSourceName", &obName)) + return NULL; + TCHAR *msg; + if (!PyWinObject_AsTCHAR(obName, &msg)) + return NULL; + _tcsncpy(g_szEventSourceName, msg, + sizeof g_szEventSourceName/sizeof TCHAR); + PyWinObject_FreeTCHAR(msg); + g_bRegisteredEventSource = FALSE; // so this name re-registered. + Py_INCREF(Py_None); + return Py_None; + } + // @pymethod int/None|servicemanager|RegisterServiceCtrlHandler|Registers the Python service control handler function. static PyObject *PyRegisterServiceCtrlHandler(PyObject *self, PyObject *args) *************** *** 491,494 **** --- 511,515 ---- {"PrepareToHostMultiple", PyPrepareToHostMultiple, 1}, // @pymeth PrepareToHostMultiple| {"RunningAsService", PyRunningAsService, 1}, // @pymeth RunningAsService|Indicates if the code is running as a service. + {"SetEventSourceName", PySetEventSourceName, 1}, // @pymeth SetEventSourceName|Sets the event source name for event log entries written by the service. {NULL} }; *************** *** 603,608 **** // evtsrc_file - The name of the file registered with the event viewer for this // source. ! // Both params can be NULL, meaning a default source name is used, and this ! // DLL as the file. If either param is non-NULL, both must be non-NULL. // // RETURN VALUE: --- 624,628 ---- // evtsrc_file - The name of the file registered with the event viewer for this // source. ! // Both params can be NULL, meaning defaults are used. // // RETURN VALUE: *************** *** 610,651 **** BOOL PythonService_Initialize( const TCHAR *evtsrc_name, const TCHAR *evtsrc_file) { ! TCHAR evtsrc_file_buf[MAX_PATH+_MAX_FNAME]; ! if (!evtsrc_name && !evtsrc_file) { ! // g_szEventSourceName keeps default of "Python Service" ! GetModuleFileName(g_hdll, evtsrc_file_buf, ! sizeof evtsrc_file_buf/sizeof TCHAR); ! evtsrc_file = evtsrc_file_buf; ! } else { ! if (!evtsrc_name || !evtsrc_file) ! return FALSE; _tcsncpy(g_szEventSourceName, evtsrc_name, sizeof g_szEventSourceName/sizeof TCHAR); ! } ! // And register the event source with the event log. ! HKEY hkey; ! TCHAR keyName[MAX_PATH]; ! _tcscpy(keyName, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\")); ! _tcscat(keyName, g_szEventSourceName ); ! // ignore all failures when setting up - for whatever reason it fails, ! // we are probably still better off calling ReportEvent than ! // not calling due to some other failure here. ! BOOL rc = FALSE; ! if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, ! keyName, ! 0, ! NULL, ! REG_OPTION_NON_VOLATILE, ! KEY_WRITE, NULL, ! &hkey, ! NULL) == ERROR_SUCCESS) { ! RegSetValueEx(hkey, TEXT("EventMessageFile"), 0, REG_SZ, ! (const BYTE *)evtsrc_file, (_tcslen(evtsrc_file)+1)*sizeof(TCHAR)); ! DWORD types = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; ! RegSetValueEx(hkey, TEXT("TypesSupported"), 0, REG_DWORD, ! (const BYTE *)&types, sizeof(types)); ! RegCloseKey(hkey); ! rc = TRUE; ! } ! return rc; } --- 630,640 ---- BOOL PythonService_Initialize( const TCHAR *evtsrc_name, const TCHAR *evtsrc_file) { ! if (evtsrc_name && *evtsrc_name) _tcsncpy(g_szEventSourceName, evtsrc_name, sizeof g_szEventSourceName/sizeof TCHAR); ! if (evtsrc_file && *evtsrc_file) ! _tcsncpy(g_szEventSourceFileName, evtsrc_file, ! sizeof g_szEventSourceFileName/sizeof TCHAR); ! return TRUE; } *************** *** 1416,1419 **** --- 1405,1447 ---- } + // register the event source with the event log. + static void CheckRegisterEventSourceFile() + { + // ignore all failures when setting up - for whatever reason it fails, + // we are probably still better off calling ReportEvent than + // not calling due to some other failure here. + if (g_bRegisteredEventSource) + return; + + if (!g_szEventSourceFileName[0]) + GetModuleFileName(g_hdll, g_szEventSourceFileName, + sizeof g_szEventSourceFileName/sizeof TCHAR); + + HKEY hkey; + TCHAR keyName[MAX_PATH]; + + _tcscpy(keyName, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\")); + _tcscat(keyName, g_szEventSourceName ); + + BOOL rc = FALSE; + if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, + keyName, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, + &hkey, + NULL) == ERROR_SUCCESS) { + RegSetValueEx(hkey, TEXT("EventMessageFile"), 0, REG_SZ, + (const BYTE *)g_szEventSourceFileName, + (_tcslen(g_szEventSourceFileName)+1)*sizeof(TCHAR)); + DWORD types = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; + RegSetValueEx(hkey, TEXT("TypesSupported"), 0, REG_DWORD, + (const BYTE *)&types, sizeof(types)); + RegCloseKey(hkey); + } + g_bRegisteredEventSource = TRUE; + } + static BOOL ReportError(DWORD code, LPCTSTR *inserts, WORD errorType /* = EVENTLOG_ERROR_TYPE*/) { *************** *** 1421,1428 **** while (inserts && inserts[numInserts]!=NULL) numInserts++; ! HANDLE hEventSource; // Use event logging to log the error. - // if (bServiceDebug) { --- 1449,1455 ---- while (inserts && inserts[numInserts]!=NULL) numInserts++; ! HANDLE hEventSource; // Use event logging to log the error. if (bServiceDebug) { *************** *** 1455,1458 **** --- 1482,1486 ---- return TRUE; } else { + CheckRegisterEventSourceFile(); hEventSource = RegisterEventSource(NULL, g_szEventSourceName); if (hEventSource==NULL) |
From: Lars I. <la...@ib...> - 2005-04-07 08:02:07
|
Dear Roger, I cannot compile win32security_sspi.cpp, because I don't have schannel.h. Where should that file come from? - Lars |
From: Mark H. <mha...@us...> - 2005-03-31 00:21:11
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1966 Modified Files: PythonService.cpp Log Message: Fix "[ 1064265 ] Having system32 in sys.path causes problems for services" by having pythonservice.pyd change the current directory before initializing Python. Index: PythonService.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/PythonService.cpp,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** PythonService.cpp 11 Oct 2004 06:17:49 -0000 1.16 --- PythonService.cpp 31 Mar 2005 00:21:01 -0000 1.17 *************** *** 1020,1024 **** targv = argv; #endif ! if ( (argc > 1) && ((*argv[1] == '-') || (*argv[1] == '/')) ) --- 1020,1035 ---- targv = argv; #endif ! // Before we start, change directory to our executable's dir. This ! // is to prevent our cwd being SYSTEM32, which can have undesired ! // side effects (ie, it ends up on sys.path and, eg, 'import zlib' may ! // locate zlib.dll in that directory rather than the correct zlib.pyd. ! TCHAR dir[MAX_PATH] = _T(""); ! GetModuleFileName(0, dir, sizeof(dir)/sizeof(dir[0])); ! TCHAR *slash = _tcsrchr(dir, _T('\\')); ! if (slash) { ! *slash = '\0'; ! _tchdir(dir); ! } ! // Process the args if ( (argc > 1) && ((*argv[1] == '-') || (*argv[1] == '/')) ) |
Update of /cvsroot/pywin32/pywin32/com/win32comext/directsound/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27495/com/win32comext/directsound/src Modified Files: PyDSBCAPS.cpp PyDSBUFFERDESC.cpp PyDSCAPS.cpp PyDSCBCAPS.cpp PyDSCBUFFERDESC.cpp PyDSCCAPS.cpp directsound.cpp Log Message: Documentation improvemets: - fixed copy & paste errors - added and unified flag explanations. Index: PyDSCAPS.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyDSCAPS.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PyDSCAPS.cpp 1 Dec 2004 23:13:57 -0000 1.2 --- PyDSCAPS.cpp 25 Mar 2005 01:52:11 -0000 1.3 *************** *** 8,12 **** #include "directsound_pch.h" ! // @pymethod <o PyDSCAPS>|pywintypes|DSCAPS|Creates a new DSCAPS object PyObject *PyWinMethod_NewDSCAPS(PyObject *self, PyObject *args) { --- 8,12 ---- #include "directsound_pch.h" ! // @pymethod <o PyDSCAPS>|directsound|DSCAPS|Creates a new PyDSCAPS object. PyObject *PyWinMethod_NewDSCAPS(PyObject *self, PyObject *args) { *************** *** 89,93 **** /*static*/ struct PyMemberDef PyDSCAPS::members[] = { {"dwFlags", T_INT, OFF(m_caps.dwFlags), 0, "Specifies device capabilities."}, ! // @prop integer|dwFlags|Specifies device capabilities. {"dwMinSecondarySampleRate", T_INT, OFF(m_caps.dwMinSecondarySampleRate), 0, "Minimum sample rate supported by this device's hardware secondary sound buffers."}, // @prop integer|dwMinSecondarySampleRate|Minimum sample rate supported by this device's hardware secondary sound buffers. --- 89,105 ---- /*static*/ struct PyMemberDef PyDSCAPS::members[] = { {"dwFlags", T_INT, OFF(m_caps.dwFlags), 0, "Specifies device capabilities."}, ! // @prop integer|dwFlags|Specifies device capabilities. Can be one or more of the following: ! // @flagh Flag|Description ! // @flag DSCAPS_PRIMARYMONO|The device supports monophonic primary buffers. ! // @flag DSCAPS_PRIMARYSTEREO|The device supports stereo primary buffers. ! // @flag DSCAPS_PRIMARY8BIT|The device supports hardware-mixed secondary buffers with 8-bit samples. ! // @flag DSCAPS_PRIMARY16BIT|The device supports primary sound buffers with 16-bit samples. ! // @flag DSCAPS_CONTINUOUSRATE|The device supports all sample rates between the dwMinSecondarySampleRate and dwMaxSecondarySampleRate member values. Typically, this means that the actual output rate will be within +/- 10 hertz (Hz) of the requested frequency. ! // @flag DSCAPS_EMULDRIVER|The device does not have a DirectSound driver installed, so it is being emulated through the waveform-audio functions. Performance degradation should be expected. ! // @flag DSCAPS_CERTIFIED|This driver has been tested and certified by Microsoft. ! // @flag DSCAPS_SECONDARYMONO|The device supports hardware-mixed monophonic secondary buffers. ! // @flag DSCAPS_SECONDARYSTEREO|The device supports hardware-mixed stereo secondary buffers. ! // @flag DSCAPS_SECONDARY8BIT|The device supports hardware-mixed secondary buffers with 8-bit samples. ! // @flag DSCAPS_SECONDARY16BIT|The device supports hardware-mixed secondary sound buffers with 16-bit samples. {"dwMinSecondarySampleRate", T_INT, OFF(m_caps.dwMinSecondarySampleRate), 0, "Minimum sample rate supported by this device's hardware secondary sound buffers."}, // @prop integer|dwMinSecondarySampleRate|Minimum sample rate supported by this device's hardware secondary sound buffers. Index: PyDSBUFFERDESC.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyDSBUFFERDESC.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PyDSBUFFERDESC.cpp 23 Mar 2005 22:51:08 -0000 1.2 --- PyDSBUFFERDESC.cpp 25 Mar 2005 01:52:11 -0000 1.3 *************** *** 8,12 **** #include "directsound_pch.h" ! // @pymethod <o PyDSBUFFERDESC>|pywintypes|DSBUFFERDESC|Creates a new DSBUFFERDESC object PyObject *PyWinMethod_NewDSBUFFERDESC(PyObject *self, PyObject *args) { --- 8,12 ---- #include "directsound_pch.h" ! // @pymethod <o PyDSBUFFERDESC>|directsound|DSBUFFERDESC|Creates a new PyDSBUFFERDESC object PyObject *PyWinMethod_NewDSBUFFERDESC(PyObject *self, PyObject *args) { Index: PyDSCCAPS.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyDSCCAPS.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyDSCCAPS.cpp 7 Mar 2005 22:18:45 -0000 1.1 --- PyDSCCAPS.cpp 25 Mar 2005 01:52:11 -0000 1.2 *************** *** 8,12 **** #include "directsound_pch.h" ! // @pymethod <o PyDSCCAPS>|pywintypes|DSCCAPS|Creates a new DSCCAPS object PyObject *PyWinMethod_NewDSCCAPS(PyObject *self, PyObject *args) { --- 8,12 ---- #include "directsound_pch.h" ! // @pymethod <o PyDSCCAPS>|directsound|DSCCAPS|Creates a new PyDSCCAPS object PyObject *PyWinMethod_NewDSCCAPS(PyObject *self, PyObject *args) { *************** *** 89,95 **** /*static*/ struct PyMemberDef PyDSCCAPS::members[] = { {"dwFlags", T_INT, OFF(m_caps.dwFlags), 0, "Specifies device capabilities. Can be 0 or DSCCAPS_EMULDRIVER (indicates that no DirectSoundCapture device is available and standard wave audio functions are being used)"}, ! // @prop integer|dwFlags|Specifies device capabilities. Can be 0 or DSCCAPS_EMULDRIVER (indicates that no DirectSound Device is available and standard wave audio functions are being used). {"dwFormats", T_INT, OFF(m_caps.dwFormats), 0, "Supported WAVE_FORMAT formats."}, ! // @prop integer|dwFormats|Supported WAVE_FORMAT formats. {"dwChannels", T_INT, OFF(m_caps.dwChannels), 0, "Number of channels supported by the device."}, // @prop integer|dwChannels|Number of channels supported by the device. --- 89,97 ---- /*static*/ struct PyMemberDef PyDSCCAPS::members[] = { {"dwFlags", T_INT, OFF(m_caps.dwFlags), 0, "Specifies device capabilities. Can be 0 or DSCCAPS_EMULDRIVER (indicates that no DirectSoundCapture device is available and standard wave audio functions are being used)"}, ! // @prop integer|dwFlags|Specifies device capabilities. Can be zero or the following flag: ! // @flagh Flag|Description ! // @flag DSCCAPS_EMULDRIVER|Indicates that no DirectSound Device is available and standard wave audio functions are being used. {"dwFormats", T_INT, OFF(m_caps.dwFormats), 0, "Supported WAVE_FORMAT formats."}, ! // @prop integer|dwFormats|Bitset of supported WAVE_FORMAT formats. {"dwChannels", T_INT, OFF(m_caps.dwChannels), 0, "Number of channels supported by the device."}, // @prop integer|dwChannels|Number of channels supported by the device. Index: directsound.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/directsound.cpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** directsound.cpp 23 Mar 2005 22:51:09 -0000 1.7 --- directsound.cpp 25 Mar 2005 01:52:11 -0000 1.8 *************** *** 352,355 **** --- 352,356 ---- ADD_CONSTANT(DSBCAPS_MUTE3DATMAXDISTANCE); + // @const directsound|DSCBCAPS_WAVEMAPPED|The Win32 wave mapper will be used for formats not supported by the device. ADD_CONSTANT(DSCBCAPS_WAVEMAPPED); Index: PyDSBCAPS.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyDSBCAPS.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PyDSBCAPS.cpp 23 Mar 2005 22:51:06 -0000 1.2 --- PyDSBCAPS.cpp 25 Mar 2005 01:52:11 -0000 1.3 *************** *** 7,11 **** #include "directsound_pch.h" ! // @pymethod <o PyDSBCAPS>|pywintypes|DSBCAPS|Creates a new DSBCAPS object PyObject *PyWinMethod_NewDSBCAPS(PyObject *self, PyObject *args) { --- 7,11 ---- #include "directsound_pch.h" ! // @pymethod <o PyDSBCAPS>|directsound|DSBCAPS|Creates a new PyDSBCAPS object PyObject *PyWinMethod_NewDSBCAPS(PyObject *self, PyObject *args) { Index: PyDSCBCAPS.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyDSCBCAPS.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyDSCBCAPS.cpp 7 Mar 2005 22:18:45 -0000 1.1 --- PyDSCBCAPS.cpp 25 Mar 2005 01:52:11 -0000 1.2 *************** *** 8,12 **** #include "directsound_pch.h" ! // @pymethod <o PyDSCBCAPS>|pywintypes|DSCBCAPS|Creates a new DSCBCAPS object PyObject *PyWinMethod_NewDSCBCAPS(PyObject *self, PyObject *args) { --- 8,12 ---- #include "directsound_pch.h" ! // @pymethod <o PyDSCBCAPS>|directsound|DSCBCAPS|Creates a new PyDSCBCAPS object PyObject *PyWinMethod_NewDSCBCAPS(PyObject *self, PyObject *args) { Index: PyDSCBUFFERDESC.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyDSCBUFFERDESC.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyDSCBUFFERDESC.cpp 7 Mar 2005 22:18:45 -0000 1.1 --- PyDSCBUFFERDESC.cpp 25 Mar 2005 01:52:11 -0000 1.2 *************** *** 8,12 **** #include "directsound_pch.h" ! // @pymethod <o PyDSCBUFFERDESC>|pywintypes|DSCBUFFERDESC|Creates a new DSCBUFFERDESC object PyObject *PyWinMethod_NewDSCBUFFERDESC(PyObject *self, PyObject *args) { --- 8,12 ---- #include "directsound_pch.h" ! // @pymethod <o PyDSCBUFFERDESC>|directsound|DSCBUFFERDESC|Creates a new PyDSCBUFFERDESC object PyObject *PyWinMethod_NewDSCBUFFERDESC(PyObject *self, PyObject *args) { *************** *** 93,97 **** /*static*/ struct PyMemberDef PyDSCBUFFERDESC::members[] = { {"dwFlags", T_INT, OFF(m_dscbd.dwFlags), 0, "Identifies the capabilities to include when creating a new DirectSoundBuffer object"}, ! // @prop integer|dwFlags|Identifies the capabilities to include when creating a new DirectSoundBuffer object. {"dwBufferBytes", T_INT, OFF(m_dscbd.dwBufferBytes), 0, "Size of the new buffer, in bytes. This value must be 0 when creating primary buffers. For secondary buffers, the minimum and maximum sizes allowed are specified by DSBSIZE_MIN and DSBSIZE_MAX"}, // @prop integer|dwBufferBytes|Size of the new buffer, in bytes. This value must be 0 when creating primary buffers. For secondary buffers, the minimum and maximum sizes allowed are specified by DSBSIZE_MIN and DSBSIZE_MAX. --- 93,99 ---- /*static*/ struct PyMemberDef PyDSCBUFFERDESC::members[] = { {"dwFlags", T_INT, OFF(m_dscbd.dwFlags), 0, "Identifies the capabilities to include when creating a new DirectSoundBuffer object"}, ! // @prop integer|dwFlags|Identifies the capabilities to include when creating a new DirectSoundBuffer object. Can be zero or the following flag: ! // @flagh Flag|Description ! // @flag DSCBCAPS_WAVEMAPPED|The Win32 wave mapper will be used for formats not supported by the device. {"dwBufferBytes", T_INT, OFF(m_dscbd.dwBufferBytes), 0, "Size of the new buffer, in bytes. This value must be 0 when creating primary buffers. For secondary buffers, the minimum and maximum sizes allowed are specified by DSBSIZE_MIN and DSBSIZE_MAX"}, // @prop integer|dwBufferBytes|Size of the new buffer, in bytes. This value must be 0 when creating primary buffers. For secondary buffers, the minimum and maximum sizes allowed are specified by DSBSIZE_MIN and DSBSIZE_MAX. |
From: Lars I. <lar...@us...> - 2005-03-23 22:52:10
|
Update of /cvsroot/pywin32/pywin32/com/win32comext/directsound/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25396/com/win32comext/directsound/src Modified Files: PyDSBCAPS.cpp PyDSBUFFERDESC.cpp PyIDirectSound.cpp directsound.cpp Log Message: Documentation improvements - work in progress. Index: PyDSBUFFERDESC.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyDSBUFFERDESC.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyDSBUFFERDESC.cpp 30 Nov 2004 21:30:28 -0000 1.1 --- PyDSBUFFERDESC.cpp 23 Mar 2005 22:51:08 -0000 1.2 *************** *** 93,97 **** /*static*/ struct PyMemberDef PyDSBUFFERDESC::members[] = { {"dwFlags", T_INT, OFF(m_dsbd.dwFlags), 0, "Identifies the capabilities to include when creating a new DirectSoundBuffer object"}, ! // @prop integer|dwFlags|Identifies the capabilities to include when creating a new DirectSoundBuffer object. {"dwBufferBytes", T_INT, OFF(m_dsbd.dwBufferBytes), 0, "Size of the new buffer, in bytes. This value must be 0 when creating primary buffers. For secondary buffers, the minimum and maximum sizes allowed are specified by DSBSIZE_MIN and DSBSIZE_MAX"}, // @prop integer|dwBufferBytes|Size of the new buffer, in bytes. This value must be 0 when creating primary buffers. For secondary buffers, the minimum and maximum sizes allowed are specified by DSBSIZE_MIN and DSBSIZE_MAX. --- 93,111 ---- /*static*/ struct PyMemberDef PyDSBUFFERDESC::members[] = { {"dwFlags", T_INT, OFF(m_dsbd.dwFlags), 0, "Identifies the capabilities to include when creating a new DirectSoundBuffer object"}, ! // @prop integer|dwFlags|Identifies the capabilities to include when creating a new DirectSoundBuffer object. Specify one or more of the following: ! // @flagh Flag|Description ! // @flag DSBCAPS_PRIMARYBUFFER|Indicates that the buffer is a primary sound buffer. If this value is not specified, a secondary sound buffer will be created. ! // @flag DSBCAPS_STATIC|Indicates that the buffer will be used for static sound data. Typically, these buffers are loaded once and played many times. These buffers are candidates for hardware memory. ! // @flag DSBCAPS_LOCHARDWARE|The buffer is in hardware memory and uses hardware mixing. ! // @flag DSBCAPS_LOCSOFTWARE|The buffer is in software memory and uses software mixing. ! // @flag DSBCAPS_CTRL3D|The buffer is either a primary buffer or a secondary buffer that uses 3-D control. To create a primary buffer, the dwFlags member of the DSBUFFERDESC structure should include the DSBCAPS_PRIMARYBUFFER flag. ! // @flag DSBCAPS_CTRLFREQUENCY|The buffer must have frequency control capability. ! // @flag DSBCAPS_CTRLPAN|The buffer must have pan control capability. ! // @flag DSBCAPS_CTRLVOLUME|The buffer must have volume control capability. ! // @flag DSBCAPS_CTRLPOSITIONNOTIFY|The buffer must have control position notify capability. ! // @flag DSBCAPS_STICKYFOCUS|Changes the focus behavior of the sound buffer. This flag can be specified in an IDirectSound::CreateSoundBuffer call. With this flag set, an application using DirectSound can continue to play its sticky focus buffers if the user switches to another application not using DirectSound. In this situation, the application's normal buffers are muted, but the sticky focus buffers are still audible. This is useful for nongame applications, such as movie playback (DirectShow), when the user wants to hear the soundtrack while typing in Microsoft Word or Microsoft® Excel, for example. However, if the user switches to another DirectSound application, all sound buffers, both normal and sticky focus, in the previous application are muted. ! // @flag DSBCAPS_GLOBALFOCUS|The buffer is a global sound buffer. With this flag set, an application using DirectSound can continue to play its buffers if the user switches focus to another application, even if the new application uses DirectSound. The one exception is if you switch focus to a DirectSound application that uses the DSSCL_EXCLUSIVE or DSSCL_WRITEPRIMARY flag for its cooperative level. In this case, the global sounds from other applications will not be audible. ! // @flag DSBCAPS_GETCURRENTPOSITION2|Indicates that IDirectSoundBuffer::GetCurrentPosition should use the new behavior of the play cursor. In DirectSound in DirectX 1, the play cursor was significantly ahead of the actual playing sound on emulated sound cards; it was directly behind the write cursor. Now, if the DSBCAPS_GETCURRENTPOSITION2 flag is specified, the application can get a more accurate play position. If this flag is not specified, the old behavior is preserved for compatibility. Note that this flag affects only emulated sound cards; if a DirectSound driver is present, the play cursor is accurate for DirectSound in all versions of DirectX. ! // @flag DSBCAPS_MUTE3DATMAXDISTANCE|The sound is reduced to silence at the maximum distance. The buffer will stop playing when the maximum distance is exceeded, so that processor time is not wasted. {"dwBufferBytes", T_INT, OFF(m_dsbd.dwBufferBytes), 0, "Size of the new buffer, in bytes. This value must be 0 when creating primary buffers. For secondary buffers, the minimum and maximum sizes allowed are specified by DSBSIZE_MIN and DSBSIZE_MAX"}, // @prop integer|dwBufferBytes|Size of the new buffer, in bytes. This value must be 0 when creating primary buffers. For secondary buffers, the minimum and maximum sizes allowed are specified by DSBSIZE_MIN and DSBSIZE_MAX. Index: PyIDirectSound.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyIDirectSound.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** PyIDirectSound.cpp 10 Mar 2005 23:23:58 -0000 1.4 --- PyIDirectSound.cpp 23 Mar 2005 22:51:09 -0000 1.5 *************** *** 76,80 **** if ( !PyArg_ParseTuple(args, "Oi:SetCooperativeLevel", &obHWND, // @pyparm int|hwnd||Window handle to the application or None. ! &level) ) // @pyparm int|level||Requested priority level. See the DSSCL constants. return NULL; --- 76,86 ---- if ( !PyArg_ParseTuple(args, "Oi:SetCooperativeLevel", &obHWND, // @pyparm int|hwnd||Window handle to the application or None. ! &level) ) // @pyparm int|level||Requested priority level. Specify one of the following values: ! // @flagh Level|Description ! // @flag DSSCL_NORMAL|Sets the application to a fully cooperative status. Most applications should use this level, because it has the smoothest multitasking and resource-sharing behavior. ! // @flag DSSCL_PRIORITY|Sets the application to the priority level. Applications with this cooperative level can call the DirectSoundBuffer.setFormat and DirectSound.compact methods. ! // @flag DSSCL_EXCLUSIVE|Sets the application to the exclusive level. When it has the input focus, the application will be the only one audible (sounds from applications with the DSBCAPS_GLOBALFOCUS flag set will be muted). With this level, it also has all the privileges of the DSSCL_PRIORITY level. DirectSound will restore the hardware format, as specified by the most recent call to the DirectSoundBuffer.setFormat method, once the application gains the input focus. (Note that DirectSound will always restore the wave format, no matter what priority level is set.) ! // @flag DSSCL_WRITEPRIMARY|This is the highest priority level. The application has write access to the primary sound buffers. No secondary sound buffers in any application can be played. ! return NULL; Index: PyDSBCAPS.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyDSBCAPS.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyDSBCAPS.cpp 30 Nov 2004 21:30:28 -0000 1.1 --- PyDSBCAPS.cpp 23 Mar 2005 22:51:06 -0000 1.2 *************** *** 88,91 **** --- 88,105 ---- /*static*/ struct PyMemberDef PyDSBCAPS::members[] = { {"dwFlags", T_INT, OFF(m_caps.dwFlags), 0, "Flags that specify buffer-object capabilities."}, // @prop integer|dwFlags|Flags that specify buffer-object capabilities. + // @flagh Flag|Description + // @flag DSBCAPS_PRIMARYBUFFER|Indicates that the buffer is a primary sound buffer. If this value is not specified, a secondary sound buffer will be created. + // @flag DSBCAPS_STATIC|Indicates that the buffer will be used for static sound data. Typically, these buffers are loaded once and played many times. These buffers are candidates for hardware memory. + // @flag DSBCAPS_LOCHARDWARE|The buffer is in hardware memory and uses hardware mixing. + // @flag DSBCAPS_LOCSOFTWARE|The buffer is in software memory and uses software mixing. + // @flag DSBCAPS_CTRL3D|The buffer is either a primary buffer or a secondary buffer that uses 3-D control. To create a primary buffer, the dwFlags member of the DSBUFFERDESC structure should include the DSBCAPS_PRIMARYBUFFER flag. + // @flag DSBCAPS_CTRLFREQUENCY|The buffer must have frequency control capability. + // @flag DSBCAPS_CTRLPAN|The buffer must have pan control capability. + // @flag DSBCAPS_CTRLVOLUME|The buffer must have volume control capability. + // @flag DSBCAPS_CTRLPOSITIONNOTIFY|The buffer must have control position notify capability. + // @flag DSBCAPS_STICKYFOCUS|Changes the focus behavior of the sound buffer. This flag can be specified in an IDirectSound::CreateSoundBuffer call. With this flag set, an application using DirectSound can continue to play its sticky focus buffers if the user switches to another application not using DirectSound. In this situation, the application's normal buffers are muted, but the sticky focus buffers are still audible. This is useful for nongame applications, such as movie playback (DirectShow), when the user wants to hear the soundtrack while typing in Microsoft Word or Microsoft® Excel, for example. However, if the user switches to another DirectSound application, all sound buffers, both normal and sticky focus, in the previous application are muted. + // @flag DSBCAPS_GLOBALFOCUS|The buffer is a global sound buffer. With this flag set, an application using DirectSound can continue to play its buffers if the user switches focus to another application, even if the new application uses DirectSound. The one exception is if you switch focus to a DirectSound application that uses the DSSCL_EXCLUSIVE or DSSCL_WRITEPRIMARY flag for its cooperative level. In this case, the global sounds from other applications will not be audible. + // @flag DSBCAPS_GETCURRENTPOSITION2|Indicates that IDirectSoundBuffer::GetCurrentPosition should use the new behavior of the play cursor. In DirectSound in DirectX 1, the play cursor was significantly ahead of the actual playing sound on emulated sound cards; it was directly behind the write cursor. Now, if the DSBCAPS_GETCURRENTPOSITION2 flag is specified, the application can get a more accurate play position. If this flag is not specified, the old behavior is preserved for compatibility. Note that this flag affects only emulated sound cards; if a DirectSound driver is present, the play cursor is accurate for DirectSound in all versions of DirectX. + // @flag DSBCAPS_MUTE3DATMAXDISTANCE|The sound is reduced to silence at the maximum distance. The buffer will stop playing when the maximum distance is exceeded, so that processor time is not wasted. {"dwBufferBytes", T_INT, OFF(m_caps.dwBufferBytes), 0, "Size of the buffer, in bytes"}, // @prop integer|nChannels|Size of the buffer, in bytes. {"dwUnlockTransferRate", T_INT, OFF(m_caps.dwUnlockTransferRate), 0, Index: directsound.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/directsound.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** directsound.cpp 8 Mar 2005 20:46:49 -0000 1.6 --- directsound.cpp 23 Mar 2005 22:51:09 -0000 1.7 *************** *** 228,237 **** { "DirectSoundCaptureCreate", directsound_DirectSoundCaptureCreate, 1}, // @pymeth DirectSoundCaptureCreate|The DirectSoundCaptureCreate function creates and initializes an object that supports the IDirectSoundCapture interface. { "DirectSoundCaptureEnumerate", directsound_DirectSoundCaptureEnumerate, 1}, // @pymeth DirectSoundCaptureEnumerate|The DirectSoundCaptureEnumerate function enumerates the DirectSoundCapture objects installed in the system. ! {"DSCAPS", PyWinMethod_NewDSCAPS, 1 }, // @pymeth DSCAPS|Creates a new <o PyDSCAPS> object. ! {"DSBCAPS", PyWinMethod_NewDSBCAPS, 1 }, // @pymeth DSBCAPS|Creates a new <o PyDSBCAPS> object. ! {"DSCCAPS", PyWinMethod_NewDSCCAPS, 1 }, // @pymeth DSCCAPS|Creates a new <o PyDSCCAPS> object. ! {"DSCBCAPS", PyWinMethod_NewDSCBCAPS, 1 }, // @pymeth DSCBCAPS|Creates a new <o PyDSCBCAPS> object. ! {"DSBUFFERDESC", PyWinMethod_NewDSBUFFERDESC, 1 }, // @pymeth DSBUFFERDESC|Creates a new <o PyDSBUFFERDESC> object. ! {"DSCBUFFERDESC", PyWinMethod_NewDSCBUFFERDESC, 1 }, // @pymeth DSCBUFFERDESC|Creates a new <o PyDSCBUFFERDESC> object. { NULL, NULL }, }; --- 228,237 ---- { "DirectSoundCaptureCreate", directsound_DirectSoundCaptureCreate, 1}, // @pymeth DirectSoundCaptureCreate|The DirectSoundCaptureCreate function creates and initializes an object that supports the IDirectSoundCapture interface. { "DirectSoundCaptureEnumerate", directsound_DirectSoundCaptureEnumerate, 1}, // @pymeth DirectSoundCaptureEnumerate|The DirectSoundCaptureEnumerate function enumerates the DirectSoundCapture objects installed in the system. ! {"DSCAPS", PyWinMethod_NewDSCAPS, 1 }, // @pymeth DSCAPS|Creates a new <o PyDSCAPS> object. ! {"DSBCAPS", PyWinMethod_NewDSBCAPS, 1 }, // @pymeth DSBCAPS|Creates a new <o PyDSBCAPS> object. ! {"DSCCAPS", PyWinMethod_NewDSCCAPS, 1 }, // @pymeth DSCCAPS|Creates a new <o PyDSCCAPS> object. ! {"DSCBCAPS", PyWinMethod_NewDSCBCAPS, 1 }, // @pymeth DSCBCAPS|Creates a new <o PyDSCBCAPS> object. ! {"DSBUFFERDESC", PyWinMethod_NewDSBUFFERDESC, 1 }, // @pymeth DSBUFFERDESC|Creates a new <o PyDSBUFFERDESC> object. ! {"DSCBUFFERDESC", PyWinMethod_NewDSCBUFFERDESC, 1 }, // @pymeth DSCBUFFERDESC|Creates a new <o PyDSCBUFFERDESC> object. { NULL, NULL }, }; *************** *** 275,280 **** PyCom_RegisterExtensionSupport(dict, g_interfaceSupportData, sizeof(g_interfaceSupportData)/sizeof(g_interfaceSupportData[0])); - // @topic DSCAPS constants| - // @const directsound|DSCAPS_PRIMARYMONO|The device supports monophonic primary buffers. ADD_CONSTANT(DSCAPS_PRIMARYMONO); --- 275,278 ---- *************** *** 327,332 **** ADD_CONSTANT(DS3DMODE_DISABLE); - // @topic DSCAPS constants| - // @const directsound|DSBCAPS_PRIMARYBUFFER|Indicates that the buffer is a primary sound buffer. If this value is not specified, a secondary sound buffer will be created. ADD_CONSTANT(DSBCAPS_PRIMARYBUFFER); --- 325,328 ---- *************** *** 432,436 **** # Play a wav file and wait until it's finished - fname = os.path.join(os.path.dirname(__file__), "01-Intro.wav") f = open(fname, 'rb') --- 428,431 ---- *************** *** 451,468 **** event = win32event.CreateEvent(None, 0, 0, None) - notify = buffer.QueryInterface(ds.IID_IDirectSoundNotify) notify.SetNotificationPositions((ds.DSBPN_OFFSETSTOP, event)) buffer.Update(0, f.read(size)) - buffer.Play(0) - win32event.WaitForSingleObject(event, -1) - */ - - /* @topic DirectSoundCapture examples| ! @ex This shows how to record into a wav file:| import pywintypes --- 446,458 ---- event = win32event.CreateEvent(None, 0, 0, None) + notify = buffer.QueryInterface(ds.IID_IDirectSoundNotify) notify.SetNotificationPositions((ds.DSBPN_OFFSETSTOP, event)) buffer.Update(0, f.read(size)) buffer.Play(0) win32event.WaitForSingleObject(event, -1) ! @ex This example shows how to record into a wav file:| import pywintypes |
From: Lars I. <lar...@us...> - 2005-03-10 23:24:09
|
Update of /cvsroot/pywin32/pywin32/com/win32comext/directsound/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6586/win32comext/directsound/src Modified Files: PyIDirectSound.cpp Log Message: Added AutoDuck doc comments. (Either I don't get AutoDuck or it sucks) Index: PyIDirectSound.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyIDirectSound.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** PyIDirectSound.cpp 7 Mar 2005 22:18:45 -0000 1.3 --- PyIDirectSound.cpp 10 Mar 2005 23:23:58 -0000 1.4 *************** *** 34,38 **** if ( pIDS == NULL ) return NULL; ! if ( !PyArg_ParseTuple(args, "|O:Initialize", &obGUID) ) return NULL; --- 34,40 ---- if ( pIDS == NULL ) return NULL; ! if ( !PyArg_ParseTuple(args, "|O:Initialize", ! &obGUID) ) // @pyparm <o PyIID>|guid||Globally unique identifier (GUID) specifying the sound driver to which this DirectSound object binds. Pass None to select the primary sound driver. ! return NULL; *************** *** 72,76 **** if ( pIDS == NULL ) return NULL; ! if ( !PyArg_ParseTuple(args, "Oi:SetCooperativeLevel", &obHWND, &level) ) return NULL; --- 74,80 ---- if ( pIDS == NULL ) return NULL; ! if ( !PyArg_ParseTuple(args, "Oi:SetCooperativeLevel", ! &obHWND, // @pyparm int|hwnd||Window handle to the application or None. ! &level) ) // @pyparm int|level||Requested priority level. See the DSSCL constants. return NULL; *************** *** 234,238 **** if ( pIDS == NULL ) return NULL; ! if ( !PyArg_ParseTuple(args, "i:SetSpeakerConfig", &config) ) return NULL; --- 238,243 ---- if ( pIDS == NULL ) return NULL; ! if ( !PyArg_ParseTuple(args, "i:SetSpeakerConfig", ! &config) ) // @pyparm int|dwSpeakerConfig||Speaker configuration of the specified DirectSound object. See the DSSPEAKER constants. return NULL; |
From: Roger U. <ru...@us...> - 2005-03-09 10:23:53
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29820/win32/src Modified Files: win32security_sspi.cpp Log Message: Make directory services handle a subtype of PyHANDLE so it can call DsUnBind on destruction Index: win32security_sspi.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/win32security_sspi.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** win32security_sspi.cpp 8 Mar 2005 13:13:03 -0000 1.2 --- win32security_sspi.cpp 9 Mar 2005 10:23:42 -0000 1.3 *************** *** 1216,1219 **** --- 1216,1249 ---- } + // Directory service handle, yet another type of PyHANDLE + // @object PyDS_HANDLE|Directory service handle, returned by <om win32security.DsBind> + // Subtype of <o PyHANDLE>, inherits all properties and methods + class PyDS_HANDLE: public PyHANDLE + { + public: + PyDS_HANDLE(HANDLE hInit) : PyHANDLE(hInit) {} + virtual BOOL Close(void) { + DWORD err; + if (!m_handle) + return TRUE; // already closed or Detached, nothing to do + if (pfnDsUnBind==NULL){ + // should not happen if functions to create a Ds handle exist ... + PyErr_SetString(PyExc_SystemError,"Error closing PyDS_HANDLE, DsUnBind is NULL"); + return FALSE; + } + err = (*pfnDsUnBind)(&m_handle); + // ??? This function apparently never returns an error, no matter what you pass to it ??? + if (err==NO_ERROR){ + m_handle = 0; + return TRUE; + } + PyWin_SetAPIError("PyDS_HANDLE::Close", err); + return FALSE; + } + virtual const char *GetTypeName(){ + return "PyDS_HANDLE"; + } + }; + // directory service functions for registering target Spns to be used with Kerberos extern PyObject *PyDsBind(PyObject *self, PyObject *args) *************** *** 1232,1236 **** err=(*pfnDsBind)(dc, domain, &dshandle); if (err==NO_ERROR) ! ret=PyWinObject_FromHANDLE(dshandle); else PyWin_SetAPIError("DsBind",err); --- 1262,1266 ---- err=(*pfnDsBind)(dc, domain, &dshandle); if (err==NO_ERROR) ! ret=new PyDS_HANDLE(dshandle); else PyWin_SetAPIError("DsBind",err); |
From: Lars I. <lar...@us...> - 2005-03-08 20:46:59
|
Update of /cvsroot/pywin32/pywin32/com/win32comext/directsound/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24870 Modified Files: directsound.cpp Log Message: Added documentation (example) for DirectSoundCapture. Index: directsound.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/directsound.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** directsound.cpp 7 Mar 2005 22:18:45 -0000 1.5 --- directsound.cpp 8 Mar 2005 20:46:49 -0000 1.6 *************** *** 461,462 **** --- 461,509 ---- win32event.WaitForSingleObject(event, -1) */ + + /* @topic DirectSoundCapture examples| + + @ex This shows how to record into a wav file:| + + import pywintypes + import struct + import win32event + import win32com.directsound.directsound as ds + + def wav_header_pack(wfx, datasize): + return struct.pack('<4sl4s4slhhllhh4sl', 'RIFF', 36 + datasize, + 'WAVE', 'fmt ', 16, + wfx.wFormatTag, wfx.nChannels, wfx.nSamplesPerSec, + wfx.nAvgBytesPerSec, wfx.nBlockAlign, + wfx.wBitsPerSample, 'data', datasize); + + d = ds.DirectSoundCaptureCreate(None, None) + + sdesc = ds.DSCBUFFERDESC() + sdesc.dwBufferBytes = 352800 # 2 seconds + sdesc.lpwfxFormat = pywintypes.WAVEFORMATEX() + sdesc.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM + sdesc.lpwfxFormat.nChannels = 2 + sdesc.lpwfxFormat.nSamplesPerSec = 44100 + sdesc.lpwfxFormat.nAvgBytesPerSec = 176400 + sdesc.lpwfxFormat.nBlockAlign = 4 + sdesc.lpwfxFormat.wBitsPerSample = 16 + + buffer = d.CreateCaptureBuffer(sdesc) + + event = win32event.CreateEvent(None, 0, 0, None) + notify = buffer.QueryInterface(ds.IID_IDirectSoundNotify) + + notify.SetNotificationPositions((ds.DSBPN_OFFSETSTOP, event)) + + buffer.Start(0) + + win32event.WaitForSingleObject(event, -1) + + # in real life, more, smaller buffers should be retrieved + data = buffer.Update(0, 352800) + + f = open('recording.wav', 'wb') + f.write(wav_header_pack(sdesc.lpwfxFormat, 352800)) + f.write(data) + */ |
From: Roger U. <ru...@us...> - 2005-03-08 13:13:19
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28356/win32/src Modified Files: win32security.i win32security_sspi.cpp win32security_sspi.h Log Message: Add directory service functions to create and register service principal names, and fix a crash if more than 5 buffers were appended to a PySecBufferDesc Index: win32security.i =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/win32security.i,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** win32security.i 7 Mar 2005 11:57:41 -0000 1.22 --- win32security.i 8 Mar 2005 13:13:03 -0000 1.23 *************** *** 20,24 **** #include "aclapi.h" #include "Ntsecapi.h" - #include "subauth.h" #include "lmshare.h" #include "sddl.h" --- 20,23 ---- *************** *** 26,30 **** #include "win32security_sspi.h" - #define CHECK_PFN(fname) if (pfn##fname==NULL) return PyErr_Format(PyExc_NotImplementedError,"%s is not available on this platform", #fname); typedef NTSTATUS (WINAPI *LsaRegisterLogonProcessfunc) --- 25,28 ---- *************** *** 79,86 **** --- 77,92 ---- extern PSecurityFunctionTableW psecurityfunctiontable=NULL; + // function pointers used in win32security_sspi.cpp + extern DsBindfunc pfnDsBind=NULL; + extern DsUnBindfunc pfnDsUnBind=NULL; + extern DsGetSpnfunc pfnDsGetSpn=NULL; + extern DsWriteAccountSpnfunc pfnDsWriteAccountSpn=NULL; + extern DsFreeSpnArrayfunc pfnDsFreeSpnArray=NULL; + static HMODULE advapi32_dll=NULL; static HMODULE secur32_dll =NULL; static HMODULE security_dll=NULL; static HMODULE ntdll_dll =NULL; + static HMODULE ntdsapi_dll =NULL; HMODULE loadmodule(WCHAR *dllname) *************** *** 571,575 **** security_dll=loadmodule(_T("security.dll")); ntdll_dll =loadmodule(_T("ntdll.dll")); ! pfnCheckTokenMembership=(CheckTokenMembershipfunc)loadapifunc("CheckTokenMembership", advapi32_dll); pfnCreateRestrictedToken=(CreateRestrictedTokenfunc)loadapifunc("CreateRestrictedToken", advapi32_dll); --- 577,582 ---- security_dll=loadmodule(_T("security.dll")); ntdll_dll =loadmodule(_T("ntdll.dll")); ! ntdsapi_dll =loadmodule(_T("ntdsapi.dll")); ! pfnCheckTokenMembership=(CheckTokenMembershipfunc)loadapifunc("CheckTokenMembership", advapi32_dll); pfnCreateRestrictedToken=(CreateRestrictedTokenfunc)loadapifunc("CreateRestrictedToken", advapi32_dll); *************** *** 610,614 **** if (pfnInitSecurityInterface!=NULL) psecurityfunctiontable=(*pfnInitSecurityInterface)(); ! PyDict_SetItemString(d, "SecBufferType", (PyObject *)&PySecBufferType); PyDict_SetItemString(d, "SecBufferDescType", (PyObject *)&PySecBufferDescType); --- 617,627 ---- if (pfnInitSecurityInterface!=NULL) psecurityfunctiontable=(*pfnInitSecurityInterface)(); ! ! pfnDsBind=(DsBindfunc)loadapifunc("DsBindW", ntdsapi_dll); ! pfnDsUnBind=(DsUnBindfunc)loadapifunc("DsUnBindW", ntdsapi_dll); ! pfnDsGetSpn=(DsGetSpnfunc)loadapifunc("DsGetSpnW", ntdsapi_dll); ! pfnDsWriteAccountSpn=(DsWriteAccountSpnfunc)loadapifunc("DsWriteAccountSpnW", ntdsapi_dll); ! pfnDsFreeSpnArray=(DsFreeSpnArrayfunc)loadapifunc("DsFreeSpnArrayW", ntdsapi_dll); ! PyDict_SetItemString(d, "SecBufferType", (PyObject *)&PySecBufferType); PyDict_SetItemString(d, "SecBufferDescType", (PyObject *)&PySecBufferDescType); *************** *** 617,620 **** --- 630,659 ---- %} + // functions bodies in win32security_sspi.cpp + %native(DsGetSpn) PyDsGetSpn; + // @pyswig (<o PyUnicode>,...)|DsGetSpn|Compose one or more service principal names to be registered using <om win32security.DsWriteAccountSpn> + // @pyparm int|ServiceType||Type of Spn to create, one of the DS_SPN_* constants + // @pyparm <o PyUnicode>|ServiceClass||Arbitrary string that describes type of service, eg http + // @pyparm <o PyUnicode>|ServiceName||Name of service, can be None (not required for DS_SPN_*_HOST Spn's) + // @pyparm int|InstancePort|0|Port nbr for service instance, use 0 for no port + // @pyparm (<o PyUnicode>,...)|InstanceNames|None|A sequence of service instance names, can be None - not required for for host Spn's + // @pyparm (int,...)|InstancePorts|None|A sequence of extra instance ports. If specified, must be same length as InstanceNames. + + %native(DsWriteAccountSpn) PyDsWriteAccountSpn; + // @pyswig |DsWriteAccountSpn|Associates a set of service principal names with an account + // @pyparm <o PyHANDLE>|hDS||Directory service handle as returned from <om win32security.DsBind> + // @pyparm int|Operation||Constant from DS_SPN_WRITE_OP enum + // @pyparm <o PyUnicode>|Account||Distinguished name of account whose Spn's will be modified + // @pyparm (<o PyUnicode>,...)|Spns||A sequence of target Spn's as returned by <om win32security.DsGetSpn> + + %native (DsBind) PyDsBind; + // @pyswig <o PyHANDLE>|DsBind|Creates a connection to a directory service + // @pyparm <o PyUnicode>|DomainController||Name of domain controller to contact, can be None + // @pyparm <o PyUnicode>|DnsDomainName||Dotted name of domain to bind to, can be None + + %native (DsUnBind) PyDsUnBind; + // @pyswig |DsUnBind|Closes a directory services handle created by <om win32security.DsBind> + // @pyparm <o PyHANDLE>|hDS||A handle to a directory service as returned by <om win32security.DsBind> + // @pyswig PyACL|ACL|Creates a new <o PyACL> object. // @pyparm int|bufSize|64|The size of the buffer for the ACL. *************** *** 3585,3586 **** --- 3624,3637 ---- #define SANDBOX_INERT SANDBOX_INERT + // Spn types used with DsGetSpn (from ntdsapi.h) + #define DS_SPN_DNS_HOST DS_SPN_DNS_HOST + #define DS_SPN_DN_HOST DS_SPN_DN_HOST + #define DS_SPN_NB_HOST DS_SPN_NB_HOST + #define DS_SPN_DOMAIN DS_SPN_DOMAIN + #define DS_SPN_NB_DOMAIN DS_SPN_NB_DOMAIN + #define DS_SPN_SERVICE DS_SPN_SERVICE + + #Spn operations used with DsWriteAccountSpn + #define DS_SPN_ADD_SPN_OP DS_SPN_ADD_SPN_OP + #define DS_SPN_REPLACE_SPN_OP DS_SPN_REPLACE_SPN_OP + #define DS_SPN_DELETE_SPN_OP DS_SPN_DELETE_SPN_OP Index: win32security_sspi.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/win32security_sspi.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** win32security_sspi.cpp 6 Mar 2005 23:27:02 -0000 1.1 --- win32security_sspi.cpp 8 Mar 2005 13:13:03 -0000 1.2 *************** *** 254,262 **** return NULL; } } // keep reference to PySecBuffers that contain the actual allocated buffers so they can be kept in sync psecbufferdesc->pBuffers[psecbufferdesc->cBuffers-1]=*psecbuffer; This->obBuffers[psecbufferdesc->cBuffers-1]=ob; - This->max_buffers++; Py_INCREF(ob); Py_INCREF(Py_None); --- 254,262 ---- return NULL; } + This->max_buffers++; } // keep reference to PySecBuffers that contain the actual allocated buffers so they can be kept in sync psecbufferdesc->pBuffers[psecbufferdesc->cBuffers-1]=*psecbuffer; This->obBuffers[psecbufferdesc->cBuffers-1]=ob; Py_INCREF(ob); Py_INCREF(Py_None); *************** *** 1216,1218 **** --- 1216,1428 ---- } + // directory service functions for registering target Spns to be used with Kerberos + extern PyObject *PyDsBind(PyObject *self, PyObject *args) + { + WCHAR *dc=NULL, *domain=NULL; + PyObject *obdc=Py_None, *obdomain=Py_None; + PyObject *ret=NULL; + DWORD err; + HANDLE dshandle; + + CHECK_PFN(DsBind); + if (!PyArg_ParseTuple(args, "|OO:DsBind", obdc, obdomain)) + return NULL; + if (PyWinObject_AsWCHAR(obdc, &dc, TRUE) && + PyWinObject_AsWCHAR(obdomain, &domain, TRUE)){ + err=(*pfnDsBind)(dc, domain, &dshandle); + if (err==NO_ERROR) + ret=PyWinObject_FromHANDLE(dshandle); + else + PyWin_SetAPIError("DsBind",err); + } + PyWinObject_FreeWCHAR(dc); + PyWinObject_FreeWCHAR(domain); + return ret; + } + + extern PyObject *PyDsUnBind(PyObject *self, PyObject *args) + { + DWORD err; + HANDLE dshandle; + PyObject *obhandle; + + CHECK_PFN(DsUnBind); + if (!PyArg_ParseTuple(args, "O:DsUnBind", &obhandle)) + return NULL; + if (!PyWinObject_AsHANDLE(obhandle, &dshandle)) + return NULL; + err=(*pfnDsUnBind)(&dshandle); + if (err==NO_ERROR){ + Py_INCREF(Py_None); + return Py_None; + } + PyWin_SetAPIError("DsUnBind",err); + return NULL; + } + + void PyWinObject_FreeWCHARArray(LPWSTR *wchars, DWORD str_cnt) + { + if (wchars!=NULL){ + for (DWORD wchar_index=0; wchar_index<str_cnt; wchar_index++) + PyWinObject_FreeWCHAR(wchars[wchar_index]); + free(wchars); + } + } + + BOOL PyWinObject_AsWCHARArray(PyObject *str_seq, LPWSTR **wchars, DWORD *str_cnt) + { + BOOL ret=FALSE; + PyObject *str_tuple=NULL, *tuple_item; + DWORD bufsize, tuple_index; + *wchars=NULL; + *str_cnt=0; + if ((str_tuple=PySequence_Tuple(str_seq))==NULL) + return FALSE; + *str_cnt=PyTuple_Size(str_tuple); + bufsize=*str_cnt * sizeof(LPWSTR); + *wchars=(LPWSTR *)malloc(bufsize); + if (*wchars==NULL){ + PyErr_Format(PyExc_MemoryError, "Unable to allocate %d bytes", bufsize); + goto done; + } + ZeroMemory(*wchars, bufsize); + for (tuple_index=0;tuple_index<*str_cnt;tuple_index++){ + tuple_item=PyTuple_GET_ITEM(str_tuple, tuple_index); + if (!PyWinObject_AsWCHAR(tuple_item, &((*wchars)[tuple_index]), FALSE)){ + PyWinObject_FreeWCHARArray(*wchars, *str_cnt); + *wchars=NULL; + *str_cnt=0; + goto done; + } + } + ret=TRUE; + done: + Py_XDECREF(str_tuple); + return ret; + } + + extern PyObject *PyDsGetSpn(PyObject *self, PyObject *args) + { + DWORD err, cSpns, bufsize, name_cnt; + DS_SPN_NAME_TYPE ServiceType; + WCHAR *ServiceClass=NULL, *ServiceName=NULL; + PyObject *obServiceClass, *obServiceName; + PyObject *ret=NULL, *tuple_item; + LPWSTR *Spns=NULL, *InstanceNames=NULL; + USHORT tuple_index, InstancePort=0, cInstanceNames=0, *InstancePorts=NULL; + long port_nbr; + PyObject *obInstanceNames=Py_None, *obInstancePorts=Py_None; + PyObject *obInstancePorts_tuple=NULL; + + CHECK_PFN(DsGetSpn); + CHECK_PFN(DsFreeSpnArray); + + if (!PyArg_ParseTuple(args,"lOO|HOO:DsGetSpn", &ServiceType, &obServiceClass, &obServiceName, + &InstancePort, &obInstanceNames, &obInstancePorts)) + return NULL; + if (!PyWinObject_AsWCHAR(obServiceClass, &ServiceClass, FALSE)) + goto done; + if (!PyWinObject_AsWCHAR(obServiceName, &ServiceName, TRUE)) + goto done; + if (obInstanceNames!=Py_None){ + if (!PyWinObject_AsWCHARArray(obInstanceNames, &InstanceNames, &name_cnt)) + goto done; + if (name_cnt>USHRT_MAX){ + PyErr_Format(PyExc_ValueError, "Count of InstanceNames cannot exceed %d", USHRT_MAX); + goto done; + } + cInstanceNames=(USHORT)name_cnt; + } + + if (obInstancePorts!=Py_None){ + if ((obInstancePorts_tuple=PySequence_Tuple(obInstancePorts))==NULL) + goto done; + if (PyTuple_Size(obInstancePorts_tuple)!=cInstanceNames){ + PyErr_SetString(PyExc_ValueError,"DsGetSpn: InstancePorts must be same size sequence as InstanceNames"); + goto done; + } + bufsize=cInstanceNames * sizeof(USHORT); + InstancePorts=(USHORT *)malloc(bufsize); + if (InstancePorts==NULL){ + PyErr_Format(PyExc_MemoryError, "DsGetSpn: Unable to allocate %d bytes", bufsize); + goto done; + } + for (tuple_index=0;tuple_index<cInstanceNames;tuple_index++){ + tuple_item=PyTuple_GET_ITEM(obInstancePorts_tuple,tuple_index); + // convert a python int to a USHORT + // ??? any API function to do this other than H format of PyArg_ParseTuple ??? + port_nbr=PyInt_AsLong(tuple_item); + if ((port_nbr==(unsigned long)-1 && PyErr_Occurred()) || (port_nbr<0)){ + PyErr_Clear(); + PyErr_Format(PyExc_TypeError,"InstancePorts must be a sequence of ints in the range 0-%d",USHRT_MAX); + goto done; + } + if (port_nbr > USHRT_MAX){ + PyErr_Format(PyExc_ValueError, "InstancePorts values cannot exceed %d", USHRT_MAX); + goto done; + } + InstancePorts[tuple_index]=(USHORT)port_nbr; + } + } + + err=(*pfnDsGetSpn)(ServiceType, ServiceClass, ServiceName, + InstancePort, cInstanceNames, (LPCWSTR *)InstanceNames, + InstancePorts, &cSpns, &Spns); + if (err!=STATUS_SUCCESS) + PyWin_SetAPIError("DsGetSpn",err); + else{ + ret=PyTuple_New(cSpns); + if (ret!=NULL){ + for (tuple_index=0;tuple_index<cSpns;tuple_index++){ + tuple_item=PyWinObject_FromWCHAR(Spns[tuple_index]); + if (tuple_item==NULL){ + Py_DECREF(ret); + ret=NULL; + break; + } + PyTuple_SET_ITEM(ret, tuple_index, tuple_item); + } + } + } + done: + if (Spns!=NULL) + (*pfnDsFreeSpnArray)(cSpns, Spns); + PyWinObject_FreeWCHARArray(InstanceNames, cInstanceNames); + + if (InstancePorts!=NULL) + free(InstancePorts); + if (obInstancePorts_tuple!=NULL) + Py_DECREF(obInstancePorts_tuple); + PyWinObject_FreeWCHAR(ServiceClass); + PyWinObject_FreeWCHAR(ServiceName); + return ret; + } + extern PyObject *PyDsWriteAccountSpn(PyObject *self, PyObject *args) + { + DWORD err, spn_cnt; + HANDLE dshandle; + DS_SPN_WRITE_OP Operation; + LPWSTR acct, *spns=NULL; + PyObject *ret=NULL, *obhandle, *obacct, *obspns; + CHECK_PFN(DsWriteAccountSpn); + if (!PyArg_ParseTuple(args, "OlOO:DsWriteAccountSpn", &obhandle, &Operation, &obacct, &obspns)) + return NULL; + if (!PyWinObject_AsHANDLE(obhandle, &dshandle)) + return NULL; + if (!PyWinObject_AsWCHAR(obacct, &acct)) + goto done; + if (!PyWinObject_AsWCHARArray(obspns, &spns, &spn_cnt)) + goto done; + err=(*pfnDsWriteAccountSpn)(dshandle, Operation, acct, spn_cnt, (LPCWSTR *)spns); + if (err!=STATUS_SUCCESS) + PyWin_SetAPIError("DsWriteAccountSpn", err); + else{ + Py_INCREF(Py_None); + ret=Py_None; + } + done: + PyWinObject_FreeWCHAR(acct); + PyWinObject_FreeWCHARArray(spns, spn_cnt); + return ret; + } Index: win32security_sspi.h =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/win32security_sspi.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** win32security_sspi.h 6 Mar 2005 23:27:02 -0000 1.1 --- win32security_sspi.h 8 Mar 2005 13:13:03 -0000 1.2 *************** *** 4,8 **** #define SECURITY_WIN32 #include "Security.h" ! // SecBuffer objects for SSPI functionality --- 4,9 ---- #define SECURITY_WIN32 #include "Security.h" ! #include "ntdsapi.h" ! #include "subauth.h" // SecBuffer objects for SSPI functionality *************** *** 153,154 **** --- 154,181 ---- CredHandle credhandle; }; + + // functions implemented in win32security_sspi.cpp and wrapped as %native with SWIG + PyObject *PyDsGetSpn(PyObject *self, PyObject *args); + PyObject *PyDsWriteAccountSpn(PyObject *self, PyObject *args); + PyObject *PyDsBind(PyObject *self, PyObject *args); + PyObject *PyDsUnBind(PyObject *self, PyObject *args); + + // function pointers that are initialized in win32security.i and used in win32security_sspi.cpp + typedef DWORD (WINAPI *DsBindfunc)(LPCTSTR, LPCTSTR, HANDLE*); + extern DsBindfunc pfnDsBind; + + typedef DWORD (WINAPI *DsUnBindfunc)(HANDLE*); + extern DsUnBindfunc pfnDsUnBind; + + typedef DWORD (WINAPI *DsGetSpnfunc)(DS_SPN_NAME_TYPE, LPCTSTR, LPCTSTR, + USHORT, USHORT, LPCTSTR*, USHORT*, DWORD*, LPTSTR**); + extern DsGetSpnfunc pfnDsGetSpn; + + typedef void (WINAPI *DsFreeSpnArrayfunc)(DWORD, LPTSTR*); + extern DsFreeSpnArrayfunc pfnDsFreeSpnArray; + + typedef DWORD (WINAPI *DsWriteAccountSpnfunc)(HANDLE, DS_SPN_WRITE_OP, LPCTSTR, DWORD, LPCTSTR*); + extern DsWriteAccountSpnfunc pfnDsWriteAccountSpn; + + #define CHECK_PFN(fname) if (pfn##fname==NULL) return PyErr_Format(PyExc_NotImplementedError,"%s is not available on this platform", #fname); + |
From: Lars I. <lar...@us...> - 2005-03-07 22:35:51
|
Update of /cvsroot/pywin32/pywin32/com/win32comext/directsound/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10529/com/win32comext/directsound/src Modified Files: PyIDirectSoundBuffer.h PyIDirectSoundCapture.h PyIDirectSoundCaptureBuffer.cpp Log Message: Comment changes. Index: PyIDirectSoundCapture.h =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyIDirectSoundCapture.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyIDirectSoundCapture.h 7 Mar 2005 22:18:45 -0000 1.1 --- PyIDirectSoundCapture.h 7 Mar 2005 22:35:42 -0000 1.2 *************** *** 1,3 **** ! // This file declares the IDirectSound Interface for Python. // --------------------------------------------------- // --- 1,3 ---- ! // This file declares the IDirectSoundCapture Interface for Python. // --------------------------------------------------- // Index: PyIDirectSoundCaptureBuffer.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyIDirectSoundCaptureBuffer.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyIDirectSoundCaptureBuffer.cpp 7 Mar 2005 22:18:45 -0000 1.1 --- PyIDirectSoundCaptureBuffer.cpp 7 Mar 2005 22:35:42 -0000 1.2 *************** *** 1,3 **** ! // This file implements the IDirectSound Interface for Python. #include "directsound_pch.h" --- 1,3 ---- ! // This file implements the IDirectSoundCaptureBuffer Interface for Python. #include "directsound_pch.h" Index: PyIDirectSoundBuffer.h =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyIDirectSoundBuffer.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PyIDirectSoundBuffer.h 30 Nov 2004 21:30:28 -0000 1.1 --- PyIDirectSoundBuffer.h 7 Mar 2005 22:35:41 -0000 1.2 *************** *** 1,3 **** ! // This file declares the IDirectSound Interface for Python. // --------------------------------------------------- // --- 1,3 ---- ! // This file declares the IDirectSoundBuffer Interface for Python. // --------------------------------------------------- // |
From: Lars I. <lar...@us...> - 2005-03-07 22:18:59
|
Update of /cvsroot/pywin32/pywin32/com/win32comext/directsound/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4072/com/win32comext/directsound/src Modified Files: PyIDirectSound.cpp PyIDirectSoundBuffer.cpp directsound.cpp directsound_pch.h Added Files: PyDSCBCAPS.cpp PyDSCBUFFERDESC.cpp PyDSCCAPS.cpp PyIDirectSoundCapture.cpp PyIDirectSoundCapture.h PyIDirectSoundCaptureBuffer.cpp PyIDirectSoundCaptureBuffer.h Log Message: Added IDirectSoundCapture, IDirectSoundCaptureBuffer, related structures and functions. Basic regression are included. --- NEW FILE: PyIDirectSoundCapture.h --- // This file declares the IDirectSound Interface for Python. // --------------------------------------------------- // // Interface Declaration class PyIDirectSoundCapture : public PyIUnknown { public: MAKE_PYCOM_CTOR(PyIDirectSoundCapture); static IDirectSoundCapture *GetI(PyObject *self); static PyComTypeObject type; static PyObject *QueryInterface(PyObject *self, PyObject *args); // The Python methods static PyObject *Initialize(PyObject *self, PyObject *args); static PyObject *CreateCaptureBuffer(PyObject *self, PyObject *args); static PyObject *GetCaps(PyObject *self, PyObject *args); PyIDirectSoundCapture(IUnknown *pdisp); ~PyIDirectSoundCapture(); PyObject *m_DS; }; --- NEW FILE: PyIDirectSoundCaptureBuffer.cpp --- // This file implements the IDirectSound Interface for Python. #include "directsound_pch.h" #include "PySoundObjects.h" #include "PyIDirectSoundCaptureBuffer.h" #include "PyIDirectSoundNotify.h" // @doc - This file contains autoduck documentation // --------------------------------------------------- // // Interface Implementation PyIDirectSoundCaptureBuffer::PyIDirectSoundCaptureBuffer(IUnknown *pdisp): PyIUnknown(pdisp), m_DS(NULL) { ob_type = &type; } PyIDirectSoundCaptureBuffer::~PyIDirectSoundCaptureBuffer() { // Release should be called before IDirectSound::Release, which may be // triggered below SafeRelease(this); // This may trigger IDirectSound::Release if (m_DS) Py_DECREF(m_DS); } /* static */ IDirectSoundCaptureBuffer *PyIDirectSoundCaptureBuffer::GetI(PyObject *self) { return (IDirectSoundCaptureBuffer*)PyIUnknown::GetI(self); } /* static */ PyObject *PyIDirectSoundCaptureBuffer::QueryInterface(PyObject *self, PyObject *args) { PyObject *obiid; PyObject *obUseIID = NULL; if (!PyArg_ParseTuple(args, "O|O:QueryInterface", &obiid, &obUseIID )) return NULL; PyObject *rc = PyIUnknown::QueryInterface(self, args); // Special treatment for PyIDirectSoundNotify // This is a workaround for a reference counting bug in IDirectSound: // If IDirectSound::Release() is called before IDirectSoundCaptureBuffer::Release() // or IDirectSoundNotify::Release(), we will get an Access Violation // We work around this by manipulating the reference count on the Python objects // that encapsulate them if (PyIBase::is_object(rc, &PyIDirectSoundNotify::type)) { PyIDirectSoundNotify *notify = (PyIDirectSoundNotify*)rc; PyIDirectSoundCaptureBuffer *me = (PyIDirectSoundCaptureBuffer*)self; Py_INCREF(me->m_DS); notify->m_DS = me->m_DS; } return rc; } // @pymethod |PyIDirectSoundCaptureBuffer|GetCaps|Returns the capabilities of the DirectSound Capture Buffer. PyObject *PyIDirectSoundCaptureBuffer::GetCaps(PyObject *self, PyObject *args) { IDirectSoundCaptureBuffer *pIDSCB = GetI(self); if ( pIDSCB == NULL ) return NULL; if ( !PyArg_ParseTuple(args, ":GetCaps") ) return NULL; HRESULT hr; PyDSCBCAPS *caps = new PyDSCBCAPS(); PY_INTERFACE_PRECALL; hr = pIDSCB->GetCaps(caps->GetCAPS()); PY_INTERFACE_POSTCALL; if (FAILED(hr)) { PyWin_SetAPIError("GetCaps", hr); return NULL; } Py_INCREF(caps); return caps; } // @pymethod |PyIDirectSoundCaptureBuffer|GetFormat|Retrieves the current format of the sound capture buffer as a WAVEFORMATEX object. PyObject *PyIDirectSoundCaptureBuffer::GetFormat(PyObject *self, PyObject *args) { IDirectSoundCaptureBuffer *pIDSCB = GetI(self); if ( pIDSCB == NULL ) return NULL; if ( !PyArg_ParseTuple(args, ":GetFormat") ) return NULL; HRESULT hr; PyWAVEFORMATEX *wfx = new PyWAVEFORMATEX(); PY_INTERFACE_PRECALL; // We don't support getting more than standard wave headers hr = pIDSCB->GetFormat(&wfx->m_wfx, sizeof(WAVEFORMATEX), NULL); PY_INTERFACE_POSTCALL; if (FAILED(hr)) { PyWin_SetAPIError("GetFormat", hr); return NULL; } Py_INCREF(wfx); return wfx; } // @pymethod |PyIDirectSoundCaptureBuffer|GetStatus|Retrieves the current status of the sound capture buffer. PyObject *PyIDirectSoundCaptureBuffer::GetStatus(PyObject *self, PyObject *args) { IDirectSoundCaptureBuffer *pIDSCB = GetI(self); if ( pIDSCB == NULL ) return NULL; if ( !PyArg_ParseTuple(args, ":GetStatus") ) return NULL; HRESULT hr; DWORD dwStatus; PY_INTERFACE_PRECALL; hr = pIDSCB->GetStatus(&dwStatus); PY_INTERFACE_POSTCALL; if (FAILED(hr)) { PyWin_SetAPIError("GetStatus", hr); return NULL; } return PyInt_FromLong(dwStatus); } // @pymethod |PyIDirectSoundCaptureBuffer|Initialize|Not normally used. Used IDirectSoundCapture.CreateCaptureBuffer instead. PyObject *PyIDirectSoundCaptureBuffer::Initialize(PyObject *self, PyObject *args) { PyObject *obDSCBD = NULL; PyObject *obDSC = NULL; IDirectSoundCapture *pIDSC = NULL; IDirectSoundCaptureBuffer *pIDSCB = GetI(self); if ( pIDSCB == NULL ) return NULL; if ( !PyArg_ParseTuple(args, "OO:Initialize", &obDSC, &obDSCBD) ) return NULL; // Todo - check and initialize pIDS if (!PyDSCBUFFERDESC_Check(obDSCBD)) { PyErr_SetString(PyExc_TypeError, "Argument 2 must be of type DSCBUFFERDESC"); return NULL; } HRESULT hr; PY_INTERFACE_PRECALL; hr = pIDSCB->Initialize(pIDSC, &((PyDSCBUFFERDESC*)obDSCBD)->m_dscbd); PY_INTERFACE_POSTCALL; if (FAILED(hr)) { PyWin_SetAPIError("Initialize", hr); return NULL; } Py_INCREF(Py_None); return Py_None; } // @pymethod |PyIDirectSoundCaptureBuffer|GetCurrentPosition|Returns a tuple of the current capture and read position in the buffer. The capture position is ahead of the read position. These positions are not always identical due to possible buffering of captured data either on the physical device or in the host. The data after the read position up to and including the capture position is not necessarily valid data. PyObject *PyIDirectSoundCaptureBuffer::GetCurrentPosition(PyObject *self, PyObject *args) { IDirectSoundCaptureBuffer *pIDSCB = GetI(self); if ( pIDSCB == NULL ) return NULL; if ( !PyArg_ParseTuple(args, ":GetCurrentPosition") ) return NULL; HRESULT hr; DWORD dwCapture = 0, dwRead = 0; PY_INTERFACE_PRECALL; hr = pIDSCB->GetCurrentPosition(&dwCapture, &dwRead); PY_INTERFACE_POSTCALL; if (FAILED(hr)) { PyWin_SetAPIError("GetCurrentPosition", hr); return NULL; } PyObject *result = PyTuple_New(2); if (!result) return NULL; PyTuple_SetItem(result, 0, PyInt_FromLong(dwCapture)); PyTuple_SetItem(result, 1, PyInt_FromLong(dwRead)); return result; } // @pymethod |PyIDirectSoundCaptureBuffer|Start|The PyIDirectSoundCaptureBuffer::Start method puts the capture buffer into the capture state and begins capturing data into the buffer. If the capture buffer is already in the capture state then the method has no effect. PyObject *PyIDirectSoundCaptureBuffer::Start(PyObject *self, PyObject *args) { // @pyparm int|dwFlags|0|Flags that specify the behavior for the capture buffer when capturing sound data. Possible values for dwFlags can be one of the following: // DSCBSTART_LOOPING DWORD dwFlags; IDirectSoundCaptureBuffer *pIDSCB = GetI(self); if ( pIDSCB == NULL ) return NULL; if ( !PyArg_ParseTuple(args, "i:Start", &dwFlags) ) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIDSCB->Start(dwFlags); PY_INTERFACE_POSTCALL; if (FAILED(hr)) { PyWin_SetAPIError("Start", hr); return NULL; } Py_INCREF(Py_None); return Py_None; } // @pymethod |PyIDirectSoundCaptureBuffer|Stop|The IDirectSoundCaptureBuffer::Stop method puts the capture buffer into the "stop" state and stops capturing data. If the capture buffer is already in the stop state then the method has no effect. PyObject *PyIDirectSoundCaptureBuffer::Stop(PyObject *self, PyObject *args) { IDirectSoundCaptureBuffer *pIDSCB = GetI(self); if ( pIDSCB == NULL ) return NULL; if ( !PyArg_ParseTuple(args, ":Stop") ) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIDSCB->Stop(); PY_INTERFACE_POSTCALL; if (FAILED(hr)) { PyWin_SetAPIError("Stop", hr); return NULL; } Py_INCREF(Py_None); return Py_None; } // @pymethod |PyIDirectSoundCaptureBuffer|Update|Retrieve data from the capture buffer. PyObject *PyIDirectSoundCaptureBuffer::Update(PyObject *self, PyObject *args) { // @pyparm int|dwReadCursor||Offset, in bytes, from the start of the buffer to where the update begins. // @pyparm int|dwReadBytes||Size, in bytes, of the portion of the buffer to update. // @pyparm int|dwFlags|0|Flags modifying the update event. This value can be 0 or the following flag: DSCBLOCK_ENTIREBUFFER // The dwReadBytes parameter is to be ignored and the entire capture buffer is to be locked. DWORD dwReadCursor = 0; DWORD dwReadBytes = 0; DWORD dwFlags = 0; IDirectSoundCaptureBuffer *pIDSCB = GetI(self); if ( pIDSCB == NULL ) return NULL; if ( !PyArg_ParseTuple(args, "ii|i:Update", &dwReadCursor, &dwReadBytes, &dwFlags) ) return NULL; HRESULT hr; LPVOID lpAudioPtr1 = NULL; DWORD dwAudioBytes1 = 0; LPVOID lpAudioPtr2 = NULL; DWORD dwAudioBytes2 = 0; PY_INTERFACE_PRECALL; hr = pIDSCB->Lock(dwReadCursor, dwReadBytes, &lpAudioPtr1, &dwAudioBytes1, &lpAudioPtr2, &dwAudioBytes2, dwFlags); PY_INTERFACE_POSTCALL; if (FAILED(hr)) { PyWin_SetAPIError("Update(Lock)", hr); return NULL; } // The capture buffer is circular, so we may get two pointers and have to // do the wrap-around ourselves. PyObject *obData = PyString_FromStringAndSize((char*)lpAudioPtr1, dwAudioBytes1); if (!obData) { PyErr_SetString(PyExc_MemoryError, "Update: could not allocate result string"); goto error; } if (lpAudioPtr2) { PyObject *obData2 = PyString_FromStringAndSize((char*)lpAudioPtr2, dwAudioBytes2); PyString_Concat(&obData, obData2); if (!obData) { PyErr_SetString(PyExc_MemoryError, "Update: could not append to result string"); goto error; } } { // need extra block for local variables from PY_INTERFACE_UPCALL macro PY_INTERFACE_PRECALL; hr = pIDSCB->Unlock(lpAudioPtr1, dwAudioBytes1, lpAudioPtr2, dwAudioBytes2); PY_INTERFACE_POSTCALL; } if (FAILED(hr)) { Py_DECREF(obData); PyWin_SetAPIError("Update(Unlock)", hr); return NULL; } return obData; error: { // need extra block for local variables from PY_INTERFACE_UPCALL macro PY_INTERFACE_PRECALL; hr = pIDSCB->Unlock(lpAudioPtr1, dwAudioBytes1, lpAudioPtr2, dwAudioBytes2); PY_INTERFACE_POSTCALL; } return NULL; } // @object PyIDirectSoundCaptureBuffer|The methods of the IDirectSoundCaptureBuffer interface are used to manipulate sound capture buffers. static struct PyMethodDef PyIDirectSoundCaptureBuffer_methods[] = { { "QueryInterface", PyIDirectSoundCaptureBuffer::QueryInterface, 1 }, { "GetCaps", PyIDirectSoundCaptureBuffer::GetCaps, 1 }, // @pymeth Initialize|Description of GetCaps. { "GetFormat", PyIDirectSoundCaptureBuffer::GetFormat, 1 }, // @pymeth SetCooperativeLevel|Description of GetFormat. { "GetStatus", PyIDirectSoundCaptureBuffer::GetStatus, 1 }, // @pymeth GetStatus|Description of GetStatus. { "Initialize", PyIDirectSoundCaptureBuffer::Initialize, 1 }, // @pymeth Initialize|Description of Initialize. { "GetCurrentPosition", PyIDirectSoundCaptureBuffer::GetCurrentPosition, 1 }, // @pymeth GetCurrentPosition|Description of GetCaps. { "Start", PyIDirectSoundCaptureBuffer::Start, 1 }, // @pymeth Play|Description of Start. { "Stop", PyIDirectSoundCaptureBuffer::Stop, 1 }, // @pymeth Stop|Description of Stop. { "Update", PyIDirectSoundCaptureBuffer::Update, 1 }, // @pymeth Unlock|Description of Update. { NULL } }; PyComTypeObject PyIDirectSoundCaptureBuffer::type("PyIDirectSoundCaptureBuffer", &PyIUnknown::type, sizeof(PyIDirectSoundCaptureBuffer), PyIDirectSoundCaptureBuffer_methods, GET_PYCOM_CTOR(PyIDirectSoundCaptureBuffer)); Index: PyIDirectSound.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyIDirectSound.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** PyIDirectSound.cpp 6 Dec 2004 20:09:41 -0000 1.2 --- PyIDirectSound.cpp 7 Mar 2005 22:18:45 -0000 1.3 *************** *** 118,130 **** if ( pIDS == NULL ) return NULL; ! if ( !PyArg_ParseTuple(args, "O|O:CreateSoundBuffer", &obDSBD, &obUnk) ) return NULL; if (!PyDSBUFFERDESC_Check(obDSBD)) { ! PyErr_SetString(PyExc_TypeError, "Argument 1 must be of type PyDSBUFFERDESC"); return NULL; } ! if (!PyCom_InterfaceFromPyInstanceOrObject(obUnk, IID_IUnknown, (void **)&pUnkIn, TRUE)) { return NULL; } --- 118,132 ---- if ( pIDS == NULL ) return NULL; ! if ( !PyArg_ParseTuple(args, "O|O:CreateSoundBuffer", ! &obDSBD, // @pyparm <o PyDSCBUFFERDESC>|lpDSCBufferDesc||a DSBUFFERDESC structure containing values for the sound buffer being created. ! &obUnk) ) // @pyparm <o PyIUknown>|unk|None|The IUnknown for COM aggregation. return NULL; if (!PyDSBUFFERDESC_Check(obDSBD)) { ! PyErr_SetString(PyExc_TypeError, "Argument 1 must be of type DSBUFFERDESC"); return NULL; } ! if (obUnk && !PyCom_InterfaceFromPyInstanceOrObject(obUnk, IID_IUnknown, (void **)&pUnkIn, TRUE)) { return NULL; } Index: PyIDirectSoundBuffer.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/PyIDirectSoundBuffer.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** PyIDirectSoundBuffer.cpp 2 Dec 2004 09:48:36 -0000 1.4 --- PyIDirectSoundBuffer.cpp 7 Mar 2005 22:18:45 -0000 1.5 *************** *** 62,66 **** } ! // @pymethod |PyIDirectSoundBuffer|GetCaps|Description of GetCaps. PyObject *PyIDirectSoundBuffer::GetCaps(PyObject *self, PyObject *args) { --- 62,66 ---- } ! // @pymethod |PyIDirectSoundBuffer|GetCaps|Retrieves the capabilities of the DirectSoundBuffer object as a DSBCAPS object. PyObject *PyIDirectSoundBuffer::GetCaps(PyObject *self, PyObject *args) { *************** *** 90,100 **** PyObject *PyIDirectSoundBuffer::GetFormat(PyObject *self, PyObject *args) { - int level; - HWND hwnd; - IDirectSoundBuffer *pIDSB = GetI(self); if ( pIDSB == NULL ) return NULL; ! if ( !PyArg_ParseTuple(args, ":GetFormat", &hwnd, &level) ) return NULL; --- 90,97 ---- PyObject *PyIDirectSoundBuffer::GetFormat(PyObject *self, PyObject *args) { IDirectSoundBuffer *pIDSB = GetI(self); if ( pIDSB == NULL ) return NULL; ! if ( !PyArg_ParseTuple(args, ":GetFormat") ) return NULL; *************** *** 117,121 **** } ! // @pymethod |PyIDirectSoundBuffer|GetStatus|Description of GetStatus. PyObject *PyIDirectSoundBuffer::GetStatus(PyObject *self, PyObject *args) { --- 114,118 ---- } ! // @pymethod |PyIDirectSoundBuffer|GetStatus|Retrieves the current status of the sound buffer. PyObject *PyIDirectSoundBuffer::GetStatus(PyObject *self, PyObject *args) { *************** *** 141,147 **** } ! // @pymethod |PyIDirectSoundBuffer|SetFormat|Description of SetFormat. PyObject *PyIDirectSoundBuffer::SetFormat(PyObject *self, PyObject *args) { PyObject *obWfx; IDirectSoundBuffer *pIDSB = GetI(self); --- 138,146 ---- } ! // @pymethod |PyIDirectSoundBuffer|SetFormat|Sets the format of the primary sound buffer for the application. Whenever this application has the input focus, DirectSound will set the primary buffer to the specified format. PyObject *PyIDirectSoundBuffer::SetFormat(PyObject *self, PyObject *args) { + // @pyparm WAVEFORMATEX|format||A WAVEFORMATEX object that describes the new format for the primary sound buffer. + PyObject *obWfx; IDirectSoundBuffer *pIDSB = GetI(self); *************** *** 152,156 **** if (!PyWAVEFORMATEX_Check(obWfx)) { ! PyErr_SetString(PyExc_TypeError, "Argument 1 must be of type PyWAVEFORMATEX"); return NULL; } --- 151,155 ---- if (!PyWAVEFORMATEX_Check(obWfx)) { ! PyErr_SetString(PyExc_TypeError, "Argument 1 must be of type WAVEFORMATEX"); return NULL; } *************** *** 187,191 **** if (!PyDSBUFFERDESC_Check(obDSBD)) { ! PyErr_SetString(PyExc_TypeError, "Argument 2 must be of type PyDSBUFFERDESC"); return NULL; } --- 186,190 ---- if (!PyDSBUFFERDESC_Check(obDSBD)) { ! PyErr_SetString(PyExc_TypeError, "Argument 2 must be of type DSBUFFERDESC"); return NULL; } *************** *** 206,210 **** } ! // @pymethod |PyIDirectSoundBuffer|Restore|Description of Initialize. PyObject *PyIDirectSoundBuffer::Restore(PyObject *self, PyObject *args) { --- 205,209 ---- } ! // @pymethod |PyIDirectSoundBuffer|Restore|Restores the memory allocation for a lost sound buffer for the specified DirectSoundBuffer object. PyObject *PyIDirectSoundBuffer::Restore(PyObject *self, PyObject *args) { --- NEW FILE: PyDSCCAPS.cpp --- // // @doc #include "PyWinTypes.h" #include "PyWinObjects.h" #include "PySoundObjects.h" #include "structmember.h" #include "directsound_pch.h" // @pymethod <o PyDSCCAPS>|pywintypes|DSCCAPS|Creates a new DSCCAPS object PyObject *PyWinMethod_NewDSCCAPS(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":DSCCAPS")) return NULL; return new PyDSCCAPS(); } PyObject *PyWinObject_FromDSCCAPS(const DSCCAPS &caps) { return new PyDSCCAPS(caps); } BOOL PyWinObject_AsDSCCAPS(PyObject *ob, DSCCAPS **ppDSCCAPS, BOOL bNoneOK /*= TRUE*/) { if (bNoneOK && ob==Py_None) { *ppDSCCAPS = NULL; } else if (!PyDSCCAPS_Check(ob)) { PyErr_SetString(PyExc_TypeError, "The object is not a PyDSCCAPS object"); return FALSE; } else { PyDSCCAPS *pycaps= (PyDSCCAPS *)ob; *ppDSCCAPS = pycaps->GetCAPS(); } return TRUE; } // @object PyDSCCAPS|A Python object, representing a DSCCAPS structure static struct PyMethodDef PyDSCCAPS_methods[] = { {NULL} }; PyTypeObject PyDSCCAPSType = { PyObject_HEAD_INIT(&PyType_Type) 0, "PyDSCCAPSType", sizeof(PyDSCCAPSType), 0, PyDSCCAPS::deallocFunc, 0, // tp_print; 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr 0, // tp_as_number 0, // tp_as_sequence 0, // tp_as_mapping 0, 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, PyObject_GenericSetAttr, 0, // tp_as_buffer; Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags; 0, // tp_doc; /* Documentation string */ 0, // traverseproc tp_traverse; 0, // tp_clear; 0, // tp_richcompare; 0, // tp_weaklistoffset; 0, // tp_iter 0, // iternextfunc tp_iternext 0, // methods PyDSCCAPS::members, 0, // tp_getset; 0, // tp_base; 0, // tp_dict; 0, // tp_descr_get; 0, // tp_descr_set; 0, // tp_dictoffset; 0, // tp_init; 0, // tp_alloc; 0 // newfunc tp_new; }; #define OFF(e) offsetof(PyDSCCAPS, e) /*static*/ struct PyMemberDef PyDSCCAPS::members[] = { {"dwFlags", T_INT, OFF(m_caps.dwFlags), 0, "Specifies device capabilities. Can be 0 or DSCCAPS_EMULDRIVER (indicates that no DirectSoundCapture device is available and standard wave audio functions are being used)"}, // @prop integer|dwFlags|Specifies device capabilities. Can be 0 or DSCCAPS_EMULDRIVER (indicates that no DirectSound Device is available and standard wave audio functions are being used). {"dwFormats", T_INT, OFF(m_caps.dwFormats), 0, "Supported WAVE_FORMAT formats."}, // @prop integer|dwFormats|Supported WAVE_FORMAT formats. {"dwChannels", T_INT, OFF(m_caps.dwChannels), 0, "Number of channels supported by the device."}, // @prop integer|dwChannels|Number of channels supported by the device. {NULL} }; PyDSCCAPS::PyDSCCAPS(void) { ob_type = &PyDSCCAPSType; _Py_NewReference(this); memset(&m_caps, 0, sizeof(m_caps)); } PyDSCCAPS::PyDSCCAPS(const DSCCAPS &caps) { ob_type = &PyDSCCAPSType; _Py_NewReference(this); m_caps = caps; m_caps.dwSize = sizeof(DSCCAPS); } PyDSCCAPS::~PyDSCCAPS() { } /*static*/ void PyDSCCAPS::deallocFunc(PyObject *ob) { delete (PyDSCCAPS *)ob; } --- NEW FILE: PyIDirectSoundCaptureBuffer.h --- // This file declares the IDirectSoundCaptureBuffer Interface for Python. // --------------------------------------------------- // // Interface Declaration class PyIDirectSoundCaptureBuffer : public PyIUnknown { public: MAKE_PYCOM_CTOR(PyIDirectSoundCaptureBuffer); static IDirectSoundCaptureBuffer *GetI(PyObject *self); static PyComTypeObject type; static PyObject *QueryInterface(PyObject *self, PyObject *args); // The Python methods // Information methods static PyObject *GetCaps(PyObject *self, PyObject *args); static PyObject *GetFormat(PyObject *self, PyObject *args); static PyObject *GetStatus(PyObject *self, PyObject *args); static PyObject *GetCurrentPosition(PyObject *self, PyObject *args); // Memory management static PyObject *Initialize(PyObject *self, PyObject *args); // Capture management static PyObject *Start(PyObject *self, PyObject *args); static PyObject *Stop(PyObject *self, PyObject *args); static PyObject *Update(PyObject *self, PyObject *args); PyIDirectSoundCaptureBuffer(IUnknown *pdisp); ~PyIDirectSoundCaptureBuffer(); PyObject *m_DS; }; Index: directsound.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/directsound.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** directsound.cpp 6 Dec 2004 20:09:41 -0000 1.4 --- directsound.cpp 7 Mar 2005 22:18:45 -0000 1.5 *************** *** 19,23 **** #include "PyIDirectSoundBuffer.h" #include "PyIDirectSoundNotify.h" ! // @pymethod <o PyIUnknown>|directsound|DirectSoundCreate|Creates and initializes a new object that supports the IDirectSound interface. --- 19,24 ---- #include "PyIDirectSoundBuffer.h" #include "PyIDirectSoundNotify.h" ! #include "PyIDirectSoundCapture.h" ! #include "PyIDirectSoundCaptureBuffer.h" // @pymethod <o PyIUnknown>|directsound|DirectSoundCreate|Creates and initializes a new object that supports the IDirectSound interface. *************** *** 126,133 **** --- 127,216 ---- if (PyErr_Occurred()) { + Py_DECREF(list); return NULL; } if (FAILED(hr)) { + Py_DECREF(list); + PyCom_BuildPyException(hr); + return NULL; + } + + return list; + } + + // @pymethod <o PyIUnknown>|directsound|DirectSoundCaptureCreate|Creates and initializes a new object that supports the IDirectSoundCapture interface. + static PyObject *directsound_DirectSoundCaptureCreate(PyObject *, PyObject *args) + { + PyObject *ret = NULL; + PyObject *obGUID = NULL, *obUnk = NULL; + IUnknown *pUnkIn = NULL; + GUID guid, *pguid = NULL; + LPDIRECTSOUNDCAPTURE dsc; + HRESULT hr; + + if (!PyArg_ParseTuple(args, "|OO:DirectSoundCaptureCreate", + &obGUID, // @pyparm <o PyIID>|guid|None|Address of the GUID that identifies the sound device. The value of this parameter must be one of the GUIDs returned by DirectSoundCaptureEnumerate, or None for the default device. + &obUnk)) // @pyparm <o PyIUknown>|unk|None|The IUnknown for COM aggregation. + { + return NULL; + } + + if (obUnk) + { + if (!PyCom_InterfaceFromPyInstanceOrObject(obUnk, IID_IUnknown, (void **)&pUnkIn, TRUE)) + goto done; + } + + if (obGUID && obGUID != Py_None) + { + if (!PyWinObject_AsIID(obGUID, &guid)) + goto done; + + pguid = &guid; + } + + Py_BEGIN_ALLOW_THREADS + hr = ::DirectSoundCaptureCreate(pguid, &dsc, pUnkIn); + Py_END_ALLOW_THREADS + if (FAILED(hr)) { + PyCom_BuildPyException(hr); + goto done; + } + ret = new PyIDirectSoundCapture(dsc); + done: + if (pUnkIn) + pUnkIn->Release(); + + return ret; + } + + // @pymethod <o list>|directsound|DirectSoundCaptureEnumerate|Enumerates DirectSoundCapture drivers installed in the system. + static PyObject *directsound_DirectSoundCaptureEnumerate(PyObject *, PyObject *args) + { + if (!PyArg_ParseTuple(args, ":DirectSoundCaptureEnumerate")) + { + return NULL; + } + + PyObject *list = PyList_New(0); + if (!list) + { + return NULL; + } + + HRESULT hr; + Py_BEGIN_ALLOW_THREADS + hr = ::DirectSoundCaptureEnumerate(dsEnumCallback, list); + Py_END_ALLOW_THREADS + + if (PyErr_Occurred()) + { + Py_DECREF(list); + return NULL; + } + + if (FAILED(hr)) { + Py_DECREF(list); PyCom_BuildPyException(hr); return NULL; *************** *** 143,152 **** { "DirectSoundCreate", directsound_DirectSoundCreate, 1 }, // @pymeth DirectSoundCreate|Creates and initializes a new object that supports the IDirectSound interface. { "DirectSoundEnumerate", directsound_DirectSoundEnumerate, 1 }, // @pymeth DirectSoundEnumerate|The DirectSoundEnumerate function enumerates the DirectSound drivers installed in the system. ! ! // { "DirectSoundCaptureCreate", directsound_DirectSoundCaptureCreate, 1}, // @pymeth DirectSoundCaptureCreate|The DirectSoundCaptureCreate function creates and initializes an object that supports the IDirectSoundCapture interface. ! // { "DirectSoundCaptureEnumerate", directsound_DirectSoundCaptureEnumerate, 1}, // @pymeth DirectSoundCaptureEnumerate|The DirectSoundCaptureEnumerate function enumerates the DirectSoundCapture objects installed in the system. {"DSCAPS", PyWinMethod_NewDSCAPS, 1 }, // @pymeth DSCAPS|Creates a new <o PyDSCAPS> object. {"DSBCAPS", PyWinMethod_NewDSBCAPS, 1 }, // @pymeth DSBCAPS|Creates a new <o PyDSBCAPS> object. {"DSBUFFERDESC", PyWinMethod_NewDSBUFFERDESC, 1 }, // @pymeth DSBUFFERDESC|Creates a new <o PyDSBUFFERDESC> object. { NULL, NULL }, }; --- 226,237 ---- { "DirectSoundCreate", directsound_DirectSoundCreate, 1 }, // @pymeth DirectSoundCreate|Creates and initializes a new object that supports the IDirectSound interface. { "DirectSoundEnumerate", directsound_DirectSoundEnumerate, 1 }, // @pymeth DirectSoundEnumerate|The DirectSoundEnumerate function enumerates the DirectSound drivers installed in the system. ! { "DirectSoundCaptureCreate", directsound_DirectSoundCaptureCreate, 1}, // @pymeth DirectSoundCaptureCreate|The DirectSoundCaptureCreate function creates and initializes an object that supports the IDirectSoundCapture interface. ! { "DirectSoundCaptureEnumerate", directsound_DirectSoundCaptureEnumerate, 1}, // @pymeth DirectSoundCaptureEnumerate|The DirectSoundCaptureEnumerate function enumerates the DirectSoundCapture objects installed in the system. {"DSCAPS", PyWinMethod_NewDSCAPS, 1 }, // @pymeth DSCAPS|Creates a new <o PyDSCAPS> object. {"DSBCAPS", PyWinMethod_NewDSBCAPS, 1 }, // @pymeth DSBCAPS|Creates a new <o PyDSBCAPS> object. + {"DSCCAPS", PyWinMethod_NewDSCCAPS, 1 }, // @pymeth DSCCAPS|Creates a new <o PyDSCCAPS> object. + {"DSCBCAPS", PyWinMethod_NewDSCBCAPS, 1 }, // @pymeth DSCBCAPS|Creates a new <o PyDSCBCAPS> object. {"DSBUFFERDESC", PyWinMethod_NewDSBUFFERDESC, 1 }, // @pymeth DSBUFFERDESC|Creates a new <o PyDSBUFFERDESC> object. + {"DSCBUFFERDESC", PyWinMethod_NewDSCBUFFERDESC, 1 }, // @pymeth DSCBUFFERDESC|Creates a new <o PyDSCBUFFERDESC> object. { NULL, NULL }, }; *************** *** 171,174 **** --- 256,261 ---- PYCOM_INTERFACE_CLIENT_ONLY (DirectSoundBuffer), PYCOM_INTERFACE_CLIENT_ONLY (DirectSoundNotify), + PYCOM_INTERFACE_CLIENT_ONLY (DirectSoundCapture), + PYCOM_INTERFACE_CLIENT_ONLY (DirectSoundCaptureBuffer), }; *************** *** 211,227 **** ADD_CONSTANT(DSCAPS_SECONDARY8BIT); // @const directsound|DSCAPS_SECONDARY16BIT|The device supports hardware-mixed secondary sound buffers with 16-bit samples. ! ADD_CONSTANT(DSBPLAY_LOOPING); // @const directsound|DSBPLAY_LOOPING|text. ! ADD_CONSTANT(DSBSTATUS_PLAYING); ADD_CONSTANT(DSBSTATUS_BUFFERLOST); ADD_CONSTANT(DSBSTATUS_LOOPING); ADD_CONSTANT(DSBLOCK_FROMWRITECURSOR); ADD_CONSTANT(DSBLOCK_ENTIREBUFFER); ADD_CONSTANT(DSSCL_NORMAL); ADD_CONSTANT(DSSCL_PRIORITY); ADD_CONSTANT(DSSCL_EXCLUSIVE); ADD_CONSTANT(DSSCL_WRITEPRIMARY); ADD_CONSTANT(DS3DMODE_NORMAL); ADD_CONSTANT(DS3DMODE_HEADRELATIVE); ADD_CONSTANT(DS3DMODE_DISABLE); --- 298,328 ---- ADD_CONSTANT(DSCAPS_SECONDARY8BIT); // @const directsound|DSCAPS_SECONDARY16BIT|The device supports hardware-mixed secondary sound buffers with 16-bit samples. + ADD_CONSTANT(DSCAPS_SECONDARY16BIT); ! // @const directsound|DSBPLAY_LOOPING|Once the end of the audio buffer is reached, play restarts at the beginning of the buffer. Play continues until explicitly stopped. This flag must be set when playing primary sound buffers. ! ADD_CONSTANT(DSBPLAY_LOOPING); ! // @const directsound|DSBSTATUS_PLAYING|The buffer is playing. If this value is not set, the buffer is stopped. ! ADD_CONSTANT(DSBSTATUS_PLAYING); ! // @const directsound|DSBSTATUS_BUFFERLOST|The buffer is lost and must be restored before it can be played or locked. ADD_CONSTANT(DSBSTATUS_BUFFERLOST); + // @const directsound|DSBSTATUS_LOOPING|The buffer is being looped. If this value is not set, the buffer will stop when it reaches the end of the sound data. Note that if this value is set, the buffer must also be playing. ADD_CONSTANT(DSBSTATUS_LOOPING); + // @const directsound|DSBLOCK_FROMWRITECURSOR|Locks from the current write cursor, making a call to DirectSoundBuffer.getCurrentPosition unnecessary. If this flag is specified, the start parameter is ignored. This flag is optional. ADD_CONSTANT(DSBLOCK_FROMWRITECURSOR); + // @const directsound|DSBLOCK_ENTIREBUFFER|Unknown. ADD_CONSTANT(DSBLOCK_ENTIREBUFFER); + // @const directsound|DSSCL_NORMAL|Sets the application to a fully cooperative status. Most applications should use this level, because it has the smoothest multitasking and resource-sharing behavior. ADD_CONSTANT(DSSCL_NORMAL); + // @const directsound|DSSCL_PRIORITY|Sets the application to the priority level. Applications with this cooperative level can call the DirectSoundBuffer.setFormat and DirectSound.compact methods. ADD_CONSTANT(DSSCL_PRIORITY); + // @const directsound|DSSCL_EXCLUSIVE|Sets the application to the exclusive level. When it has the input focus, the application will be the only one audible (sounds from applications with the DSBCAPS_GLOBALFOCUS flag set will be muted). With this level, it also has all the privileges of the DSSCL_PRIORITY level. DirectSound will restore the hardware format, as specified by the most recent call to the DirectSoundBuffer.setFormat method, once the application gains the input focus. (Note that DirectSound will always restore the wave format, no matter what priority level is set.) ADD_CONSTANT(DSSCL_EXCLUSIVE); + // @const directsound|DSSCL_WRITEPRIMARY|This is the highest priority level. The application has write access to the primary sound buffers. No secondary sound buffers in any application can be played. ADD_CONSTANT(DSSCL_WRITEPRIMARY); + // @const directsound|DS3DMODE_NORMAL|Normal processing. This is the default mode. ADD_CONSTANT(DS3DMODE_NORMAL); + // @const directsound|DS3DMODE_HEADRELATIVE|Sound parameters (position, velocity, and orientation) are relative to the listener's parameters. In this mode, the absolute parameters of the sound are updated automatically as the listener's parameters change, so that the relative parameters remain constant. ADD_CONSTANT(DS3DMODE_HEADRELATIVE); + // @const directsound|DS3DMODE_DISABLE|Processing of 3D sound is disabled. The sound seems to originate from the center of the listener's head. ADD_CONSTANT(DS3DMODE_DISABLE); *************** *** 289,292 **** --- 390,394 ---- ADD_CONSTANT(DSBSIZE_MIN); ADD_CONSTANT(DSBSIZE_MAX); + // @const directsound|DSCCAPS_EMULDRIVER|The device does not have a DirectSound driver installed, so it is being emulated through the waveform-audio functions. Performance degradation should be expected. ADD_CONSTANT(DSCCAPS_EMULDRIVER); ADD_CONSTANT(DSCBLOCK_ENTIREBUFFER); *************** *** 299,302 **** --- 401,407 ---- PyDict_SetItemString(dict, "DSBCAPSType", (PyObject *)&PyDSBCAPSType); PyDict_SetItemString(dict, "DSBUFFERDESCType", (PyObject *)&PyDSBUFFERDESCType); + PyDict_SetItemString(dict, "DSCCAPSType", (PyObject *)&PyDSCCAPSType); + PyDict_SetItemString(dict, "DSCBCAPSType", (PyObject *)&PyDSCBCAPSType); + PyDict_SetItemString(dict, "DSCBUFFERDESCType", (PyObject *)&PyDSCBUFFERDESCType); } *************** *** 328,332 **** # Play a wav file and wait until it's finished ! fname=os.path.join(os.path.dirname(__file__), "01-Intro.wav") f = open(fname, 'rb') --- 433,437 ---- # Play a wav file and wait until it's finished ! fname = os.path.join(os.path.dirname(__file__), "01-Intro.wav") f = open(fname, 'rb') Index: directsound_pch.h =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/src/directsound_pch.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** directsound_pch.h 30 Nov 2004 21:30:28 -0000 1.1 --- directsound_pch.h 7 Mar 2005 22:18:45 -0000 1.2 *************** *** 17,20 **** --- 17,30 ---- /* + ** DSCBUFFERDESC support + */ + + PyObject *PyWinMethod_NewDSCBUFFERDESC(PyObject *self, PyObject *args); + PyObject *PyWinObject_FromWAVEFROMATEX(const DSCBUFFERDESC &dsbd); + BOOL PyWinObject_AsDSCBUFFERDESC(PyObject *ob, DSCBUFFERDESC **ppDSCBUFFERDESC, BOOL bNoneOK = TRUE); + extern PyTypeObject PyDSCBUFFERDESCType; + #define PyDSCBUFFERDESC_Check(ob) ((ob)->ob_type == &PyDSCBUFFERDESCType) + + /* ** DSCAPS support */ *************** *** 36,39 **** --- 46,69 ---- #define PyDSBCAPS_Check(ob) ((ob)->ob_type == &PyDSBCAPSType) + /* + ** DSCCAPS support + */ + + PyObject *PyWinMethod_NewDSCCAPS(PyObject *self, PyObject *args); + PyObject *PyWinObject_FromDSCCAPS(const DSBUFFERDESC &dsbd); + BOOL PyWinObject_AsDSCCAPS(PyObject *ob, DSCCAPS **ppDSCCAPS, BOOL bNoneOK = TRUE); + extern PyTypeObject PyDSCCAPSType; + #define PyDSCCAPS_Check(ob) ((ob)->ob_type == &PyDSCCAPSType) + + /* + ** DSCBCAPS support + */ + + PyObject *PyWinMethod_NewDSCBCAPS(PyObject *self, PyObject *args); + PyObject *PyWinObject_FromDSCBCAPS(const DSBUFFERDESC &dsbd); + BOOL PyWinObject_AsDSCBCAPS(PyObject *ob, DSCBCAPS **ppDSCBCAPS, BOOL bNoneOK = TRUE); + extern PyTypeObject PyDSCBCAPSType; + #define PyDSCBCAPS_Check(ob) ((ob)->ob_type == &PyDSCBCAPSType) + class PyDSBUFFERDESC : public PyObject *************** *** 62,65 **** --- 92,165 ---- }; + class PyDSCBUFFERDESC : public PyObject + { + public: + + PyDSCBUFFERDESC(void); + PyDSCBUFFERDESC(const DSCBUFFERDESC &); + ~PyDSCBUFFERDESC(); + + /* Python support */ + static void deallocFunc(PyObject *ob); + + static int setattro(PyObject *self, PyObject *obname, PyObject *obvalue); + + PyObject *m_obWFX; + + #ifdef _MSC_VER + #pragma warning( disable : 4251 ) + #endif // _MSC_VER + static struct PyMemberDef members[]; + #ifdef _MSC_VER + #pragma warning( default : 4251 ) + #endif // _MSC_VER + DSCBUFFERDESC m_dscbd; + }; + + class PyDSCCAPS : public PyObject + { + public: + + DSCCAPS *GetCAPS() {return &m_caps;} + + PyDSCCAPS(void); + PyDSCCAPS(const DSCCAPS &); + ~PyDSCCAPS(); + + /* Python support */ + static void deallocFunc(PyObject *ob); + + #ifdef _MSC_VER + #pragma warning( disable : 4251 ) + #endif // _MSC_VER + static struct PyMemberDef members[]; + #ifdef _MSC_VER + #pragma warning( default : 4251 ) + #endif // _MSC_VER + DSCCAPS m_caps; + }; + + class PyDSCBCAPS : public PyObject + { + public: + + DSCBCAPS *GetCAPS() {return &m_caps;} + + PyDSCBCAPS(void); + PyDSCBCAPS(const DSCBCAPS &); + ~PyDSCBCAPS(); + + /* Python support */ + static void deallocFunc(PyObject *ob); + + #ifdef _MSC_VER + #pragma warning( disable : 4251 ) + #endif // _MSC_VER + static struct PyMemberDef members[]; + #ifdef _MSC_VER + #pragma warning( default : 4251 ) + #endif // _MSC_VER + DSCBCAPS m_caps; + }; class PyDSCAPS : public PyObject --- NEW FILE: PyIDirectSoundCapture.cpp --- // This file implements the IDirectSoundCapture Interface for Python. #include "directsound_pch.h" #include "PySoundObjects.h" #include "PyIDirectSoundCapture.h" #include "PyIDirectSoundCaptureBuffer.h" #include "PyIDirectSoundNotify.h" // @doc - This file contains autoduck documentation // --------------------------------------------------- // // Interface Implementation PyIDirectSoundCapture::PyIDirectSoundCapture(IUnknown *pdisp): PyIUnknown(pdisp), m_DS(NULL) { ob_type = &type; } PyIDirectSoundCapture::~PyIDirectSoundCapture() { // Release should be called before IDirectSound::Release, which may be // triggered below SafeRelease(this); // This may trigger IDirectSound::Release if (m_DS) Py_DECREF(m_DS); } /* static */ IDirectSoundCapture *PyIDirectSoundCapture::GetI(PyObject *self) { return (IDirectSoundCapture*)PyIUnknown::GetI(self); } /* static */ PyObject *PyIDirectSoundCapture::QueryInterface(PyObject *self, PyObject *args) { PyObject *obiid; PyObject *obUseIID = NULL; if (!PyArg_ParseTuple(args, "O|O:QueryInterface", &obiid, &obUseIID )) return NULL; PyObject *rc = PyIUnknown::QueryInterface(self, args); // Special treatment for PyIDirectSoundNotify // This is a workaround for a reference counting bug in IDirectSound: // If IDirectSound::Release() is called before IDirectSoundCapture::Release() // or IDirectSoundNotify::Release(), we will get an Access Violation // We work around this by manipulating the reference count on the Python objects // that encapsulate them if (PyIBase::is_object(rc, &PyIDirectSoundNotify::type)) { PyIDirectSoundNotify *notify = (PyIDirectSoundNotify*)rc; PyIDirectSoundCapture *me = (PyIDirectSoundCapture*)self; Py_INCREF(me->m_DS); notify->m_DS = me->m_DS; } return rc; } // @pymethod |PyIDirectSoundCapture|Initialize|Not normally called directly. Use DirectSoundCaptureCreate instead. PyObject *PyIDirectSoundCapture::Initialize(PyObject *self, PyObject *args) { PyObject *obGUID; IDirectSoundCapture *pIDSC = GetI(self); if ( pIDSC == NULL ) return NULL; if ( !PyArg_ParseTuple(args, "|O:Initialize", &obGUID) ) return NULL; GUID guid; LPGUID pguid = NULL; if (!obGUID && obGUID != Py_None) { if (!PyWinObject_AsIID(obGUID, &guid)) return NULL; pguid = &guid; } HRESULT hr; PY_INTERFACE_PRECALL; hr = pIDSC->Initialize(pguid); PY_INTERFACE_POSTCALL; if (FAILED(hr)) { PyWin_SetAPIError("Initialize", hr); return NULL; } Py_INCREF(Py_None); return Py_None; } // @pymethod |PyIDirectSoundCapture|CreateCaptureBuffer|The IDirectSoundCapture::CreateSoundBuffer method creates a DirectSoundBuffer object to hold a sequence of audio samples. PyObject *PyIDirectSoundCapture::CreateCaptureBuffer(PyObject *self, PyObject *args) { PyObject *obDSCBD = NULL; PyObject *obUnk = NULL; IUnknown *pUnkIn = NULL; IDirectSoundCapture *pIDSC = GetI(self); if ( pIDSC == NULL ) return NULL; if ( !PyArg_ParseTuple(args, "O|O:CreateCaptureBuffer", &obDSCBD, // @pyparm <o PyDSCBUFFERDESC>|lpDSCBufferDesc||a DSCBUFFERDESC structure containing values for the capture buffer being created. &obUnk) ) // @pyparm <o PyIUknown>|unk|None|The IUnknown for COM aggregation. return NULL; if (!PyDSCBUFFERDESC_Check(obDSCBD)) { PyErr_SetString(PyExc_TypeError, "Argument 1 must be of type DSCBUFFERDESC"); return NULL; } if (obUnk && !PyCom_InterfaceFromPyInstanceOrObject(obUnk, IID_IUnknown, (void **)&pUnkIn, TRUE)) { return NULL; } DSCBUFFERDESC *pdscbd = &((PyDSCBUFFERDESC*)obDSCBD)->m_dscbd; HRESULT hr; IDirectSoundCaptureBuffer *buffer; PY_INTERFACE_PRECALL; hr = pIDSC->CreateCaptureBuffer(pdscbd, &buffer, pUnkIn); PY_INTERFACE_POSTCALL; if (FAILED(hr)) { PyWin_SetAPIError("CreateCaptureBuffer", hr); return NULL; } PyIDirectSoundCaptureBuffer *rc = new PyIDirectSoundCaptureBuffer(buffer); Py_INCREF(self); rc->m_DS = self; return rc; } // @pymethod |PyIDirectSoundCapture|GetCaps|The GetCaps method retrieves the capabilities of the hardware device that is represented by the DirectSound object. See <l DSCAPS contants>. PyObject *PyIDirectSoundCapture::GetCaps(PyObject *self, PyObject *args) { IDirectSoundCapture *pIDSC = GetI(self); if ( pIDSC == NULL ) return NULL; if ( !PyArg_ParseTuple(args, ":GetCaps") ) return NULL; HRESULT hr; PyDSCCAPS *caps = new PyDSCCAPS(); PY_INTERFACE_PRECALL; hr = pIDSC->GetCaps(caps->GetCAPS()); PY_INTERFACE_POSTCALL; if (FAILED(hr)) { PyWin_SetAPIError("GetCaps", hr); return NULL; } Py_INCREF(caps); return caps; } // @object PyIDirectSoundCapture|The methods of the IDirectSoundCapture interface are used to create sound capture buffers. static struct PyMethodDef PyIDirectSoundCapture_methods[] = { { "Initialize", PyIDirectSoundCapture::Initialize, 1 }, // @pymeth Initialize|Description of Initialize. { "CreateCaptureBuffer", PyIDirectSoundCapture::CreateCaptureBuffer, 1 }, // @pymeth CreateSoundBuffer|Description of CreateSoundBuffer. { "GetCaps", PyIDirectSoundCapture::GetCaps, 1 }, // @pymeth GetCaps|Description of GetCaps. { NULL } }; PyComTypeObject PyIDirectSoundCapture::type("PyIDirectSoundCapture", &PyIUnknown::type, sizeof(PyIDirectSoundCapture), PyIDirectSoundCapture_methods, GET_PYCOM_CTOR(PyIDirectSoundCapture)); --- NEW FILE: PyDSCBCAPS.cpp --- // // @doc #include "PyWinTypes.h" #include "PyWinObjects.h" #include "PySoundObjects.h" #include "structmember.h" #include "directsound_pch.h" // @pymethod <o PyDSCBCAPS>|pywintypes|DSCBCAPS|Creates a new DSCBCAPS object PyObject *PyWinMethod_NewDSCBCAPS(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":DSCBCAPS")) return NULL; return new PyDSCBCAPS(); } PyObject *PyWinObject_FromDSCBCAPS(const DSCBCAPS &caps) { return new PyDSCBCAPS(caps); } BOOL PyWinObject_AsDSCBCAPS(PyObject *ob, DSCBCAPS **ppDSCBCAPS, BOOL bNoneOK /*= TRUE*/) { if (bNoneOK && ob==Py_None) { *ppDSCBCAPS = NULL; } else if (!PyDSCBCAPS_Check(ob)) { PyErr_SetString(PyExc_TypeError, "The object is not a PyDSCBCAPS object"); return FALSE; } else { PyDSCBCAPS *pycaps= (PyDSCBCAPS *)ob; *ppDSCBCAPS = pycaps->GetCAPS(); } return TRUE; } // @object PyDSCBCAPS|A Python object, representing a DSCBCAPS structure static struct PyMethodDef PyDSCBCAPS_methods[] = { {NULL} }; PyTypeObject PyDSCBCAPSType = { PyObject_HEAD_INIT(&PyType_Type) 0, "PyDSCBCAPSType", sizeof(PyDSCBCAPSType), 0, PyDSCBCAPS::deallocFunc, 0, // tp_print; 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr 0, // tp_as_number 0, // tp_as_sequence 0, // tp_as_mapping 0, 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, PyObject_GenericSetAttr, 0, // tp_as_buffer; Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags; 0, // tp_doc; /* Documentation string */ 0, // traverseproc tp_traverse; 0, // tp_clear; 0, // tp_richcompare; 0, // tp_weaklistoffset; 0, // tp_iter 0, // iternextfunc tp_iternext 0, // methods PyDSCBCAPS::members, 0, // tp_getset; 0, // tp_base; 0, // tp_dict; 0, // tp_descr_get; 0, // tp_descr_set; 0, // tp_dictoffset; 0, // tp_init; 0, // tp_alloc; 0 // newfunc tp_new; }; #define OFF(e) offsetof(PyDSCBCAPS, e) /*static*/ struct PyMemberDef PyDSCBCAPS::members[] = { {"dwFlags", T_INT, OFF(m_caps.dwFlags), 0, "Specifies device capabilities. Can be 0 or DSCBCAPS_EMULDRIVER (indicates that no DirectSoundCapture device is available and standard wave audio functions are being used)"}, // @prop integer|dwFlags|Specifies device capabilities. Can be 0 or DSCBCAPS_EMULDRIVER (indicates that no DirectSound Device is available and standard wave audio functions are being used). {"dwBufferBytes", T_INT, OFF(m_caps.dwBufferBytes), 0, "The size, in bytes, of the capture buffer."}, // @prop integer|dwBufferBytes|The size, in bytes, of the capture buffer. {NULL} }; PyDSCBCAPS::PyDSCBCAPS(void) { ob_type = &PyDSCBCAPSType; _Py_NewReference(this); memset(&m_caps, 0, sizeof(m_caps)); } PyDSCBCAPS::PyDSCBCAPS(const DSCBCAPS &caps) { ob_type = &PyDSCBCAPSType; _Py_NewReference(this); m_caps = caps; m_caps.dwSize = sizeof(DSCBCAPS); } PyDSCBCAPS::~PyDSCBCAPS() { } /*static*/ void PyDSCBCAPS::deallocFunc(PyObject *ob) { delete (PyDSCBCAPS *)ob; } --- NEW FILE: PyDSCBUFFERDESC.cpp --- // // @doc #include "PyWinTypes.h" #include "PyWinObjects.h" #include "PySoundObjects.h" #include "structmember.h" #include "directsound_pch.h" // @pymethod <o PyDSCBUFFERDESC>|pywintypes|DSCBUFFERDESC|Creates a new DSCBUFFERDESC object PyObject *PyWinMethod_NewDSCBUFFERDESC(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":DSCBUFFERDESC")) return NULL; return new PyDSCBUFFERDESC(); } PyObject *PyWinObject_FromDSCBUFFERDESC(const DSCBUFFERDESC &dscbd) { return new PyDSCBUFFERDESC(dscbd); } BOOL PyWinObject_AsDSCBUFFERDESC(PyObject *ob, DSCBUFFERDESC **ppDSCBUFFERDESC, BOOL bNoneOK /*= TRUE*/) { if (bNoneOK && ob==Py_None) { *ppDSCBUFFERDESC = NULL; } else if (!PyDSCBUFFERDESC_Check(ob)) { PyErr_SetString(PyExc_TypeError, "The object is not a PyDSCBUFFERDESC object"); return FALSE; } else { PyDSCBUFFERDESC *pydscbd= (PyDSCBUFFERDESC *)ob; *ppDSCBUFFERDESC = &pydscbd->m_dscbd; // in case the PyWAVEFORMATEX has been manipulated and points to a different address now ((DSCBUFFERDESC *)*ppDSCBUFFERDESC)->lpwfxFormat = &((PyWAVEFORMATEX *)pydscbd->m_obWFX)->m_wfx; } return TRUE; } // @object PyDSCBUFFERDESC|A Python object, representing a DSCBUFFERDESC structure static struct PyMethodDef PyDSCBUFFERDESC_methods[] = { {NULL} }; PyTypeObject PyDSCBUFFERDESCType = { PyObject_HEAD_INIT(&PyType_Type) 0, "PyDSCBUFFERDESC", sizeof(PyDSCBUFFERDESC), 0, PyDSCBUFFERDESC::deallocFunc, 0, // tp_print; 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr 0, // tp_as_number 0, // tp_as_sequence 0, // tp_as_mapping 0, 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, PyDSCBUFFERDESC::setattro, 0, // tp_as_buffer; Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags; 0, // tp_doc; /* Documentation string */ 0, // traverseproc tp_traverse; 0, // tp_clear; 0, // tp_richcompare; 0, // tp_weaklistoffset; 0, // tp_iter 0, // iternextfunc tp_iternext 0, // methods PyDSCBUFFERDESC::members, 0, // tp_getset; 0, // tp_base; 0, // tp_dict; 0, // tp_descr_get; 0, // tp_descr_set; 0, // tp_dictoffset; 0, // tp_init; 0, // tp_alloc; 0 // newfunc tp_new; }; #define OFF(e) offsetof(PyDSCBUFFERDESC, e) /*static*/ struct PyMemberDef PyDSCBUFFERDESC::members[] = { {"dwFlags", T_INT, OFF(m_dscbd.dwFlags), 0, "Identifies the capabilities to include when creating a new DirectSoundBuffer object"}, // @prop integer|dwFlags|Identifies the capabilities to include when creating a new DirectSoundBuffer object. {"dwBufferBytes", T_INT, OFF(m_dscbd.dwBufferBytes), 0, "Size of the new buffer, in bytes. This value must be 0 when creating primary buffers. For secondary buffers, the minimum and maximum sizes allowed are specified by DSBSIZE_MIN and DSBSIZE_MAX"}, // @prop integer|dwBufferBytes|Size of the new buffer, in bytes. This value must be 0 when creating primary buffers. For secondary buffers, the minimum and maximum sizes allowed are specified by DSBSIZE_MIN and DSBSIZE_MAX. {"lpwfxFormat", T_OBJECT, OFF(m_obWFX), 0, "Structure specifying the waveform format for the buffer. This value must be None for primary buffers. The application can use IDirectSoundCaptureBuffer::SetFormat to set the format of the primary buffer."}, // @prop WAVEFORMATEX|lpwfxFormat|Structure specifying the waveform format for the buffer. This value must be None for primary buffers. The application can use IDirectSoundBuffer::SetFormat to set the format of the primary buffer. {NULL} /* Sentinel */ }; PyDSCBUFFERDESC::PyDSCBUFFERDESC(void) { ob_type = &PyDSCBUFFERDESCType; _Py_NewReference(this); memset(&m_dscbd, 0, sizeof(m_dscbd)); m_dscbd.dwSize = sizeof(DSCBUFFERDESC); Py_INCREF(Py_None); m_obWFX = Py_None; } PyDSCBUFFERDESC::PyDSCBUFFERDESC(const DSCBUFFERDESC &dscbd) { m_dscbd.dwSize = sizeof(DSCBUFFERDESC); ob_type = &PyDSCBUFFERDESCType; _Py_NewReference(this); m_dscbd = dscbd; if (dscbd.lpwfxFormat) { m_obWFX = new PyWAVEFORMATEX(*dscbd.lpwfxFormat); m_dscbd.lpwfxFormat = &((PyWAVEFORMATEX*)m_obWFX)->m_wfx; } else { Py_INCREF(Py_None); m_obWFX = Py_None; } } PyDSCBUFFERDESC::~PyDSCBUFFERDESC() { Py_XDECREF( m_obWFX ); } /*static*/ void PyDSCBUFFERDESC::deallocFunc(PyObject *ob) { delete (PyDSCBUFFERDESC *)ob; } int PyDSCBUFFERDESC::setattro(PyObject *self, PyObject *obname, PyObject *obvalue) { PyDSCBUFFERDESC *obself = (PyDSCBUFFERDESC*)self; char *name=PyString_AsString(obname); if (name==NULL) return -1; if (strcmp(name,"lpwfxFormat") == 0) { if (obvalue == Py_None) { obself->m_dscbd.lpwfxFormat = NULL; } else if (!PyWAVEFORMATEX_Check(obvalue)) { PyErr_SetString(PyExc_ValueError,"lpwfxFormat must be a WAVEFORMATEX instance"); return -1; } else { obself->m_dscbd.lpwfxFormat = &((PyWAVEFORMATEX*)obvalue)->m_wfx; } } return PyObject_GenericSetAttr(self, obname, obvalue); } |
From: Lars I. <lar...@us...> - 2005-03-07 22:18:56
|
Update of /cvsroot/pywin32/pywin32/com/win32comext/directsound/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4072/com/win32comext/directsound/test Modified Files: ds_test.py Added Files: ds_record.py Log Message: Added IDirectSoundCapture, IDirectSoundCaptureBuffer, related structures and functions. Basic regression are included. --- NEW FILE: ds_record.py --- import pywintypes import struct import win32event import win32com.directsound.directsound as ds def wav_header_pack(wfx, datasize): return struct.pack('<4sl4s4slhhllhh4sl', 'RIFF', 36 + datasize, 'WAVE', 'fmt ', 16, wfx.wFormatTag, wfx.nChannels, wfx.nSamplesPerSec, wfx.nAvgBytesPerSec, wfx.nBlockAlign, wfx.wBitsPerSample, 'data', datasize); d = ds.DirectSoundCaptureCreate(None, None) sdesc = ds.DSCBUFFERDESC() sdesc.dwBufferBytes = 352800 # 2 seconds sdesc.lpwfxFormat = pywintypes.WAVEFORMATEX() sdesc.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM sdesc.lpwfxFormat.nChannels = 2 sdesc.lpwfxFormat.nSamplesPerSec = 44100 sdesc.lpwfxFormat.nAvgBytesPerSec = 176400 sdesc.lpwfxFormat.nBlockAlign = 4 sdesc.lpwfxFormat.wBitsPerSample = 16 print sdesc print d buffer = d.CreateCaptureBuffer(sdesc) event = win32event.CreateEvent(None, 0, 0, None) notify = buffer.QueryInterface(ds.IID_IDirectSoundNotify) notify.SetNotificationPositions((ds.DSBPN_OFFSETSTOP, event)) buffer.Start(0) win32event.WaitForSingleObject(event, -1) data = buffer.Update(0, 352800) f = open('recording.wav', 'wb') f.write(wav_header_pack(sdesc.lpwfxFormat, 352800)) f.write(data) Index: ds_test.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32comext/directsound/test/ds_test.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ds_test.py 6 Dec 2004 20:08:00 -0000 1.3 --- ds_test.py 7 Mar 2005 22:18:45 -0000 1.4 *************** *** 10,14 **** # import directsound as ds - WAV_FORMAT_PCM = 1 WAV_HEADER_SIZE = struct.calcsize('<4sl4s4slhhllhh4sl') --- 10,13 ---- *************** *** 19,24 **** = struct.unpack('<4sl4s4slhhllhh4sl', data) ! if riff != 'RIFF' or fmtsize != 16 or fmt != 'fmt ' or data != 'data': ! raise ValueError, 'illegal wav header' wfx = pywintypes.WAVEFORMATEX() --- 18,28 ---- = struct.unpack('<4sl4s4slhhllhh4sl', data) ! if riff != 'RIFF': ! raise ValueError, 'invalid wav header' ! ! if fmtsize != 16 or fmt != 'fmt ' or data != 'data': ! # fmt chuck is not first chunk, directly followed by data chuck ! # It is nowhere required that they are, it is just very common ! raise ValueError, 'cannot understand wav header' wfx = pywintypes.WAVEFORMATEX() *************** *** 32,35 **** --- 36,46 ---- return wfx, datalength + def wav_header_pack(wfx, datasize): + return struct.pack('<4sl4s4slhhllhh4sl', 'RIFF', 36 + datasize, + 'WAVE', 'fmt ', 16, + wfx.wFormatTag, wfx.nChannels, wfx.nSamplesPerSec, + wfx.nAvgBytesPerSec, wfx.nBlockAlign, + wfx.wBitsPerSample, 'data', datasize); + class WAVEFORMATTest(unittest.TestCase): def test_1_Type(self): *************** *** 128,131 **** --- 139,174 ---- self.failUnless(c.dwPlayCpuOverhead == 4) + class DSCCAPSTest(unittest.TestCase): + def test_1_Type(self): + 'DSCCAPS type' + c = ds.DSCCAPS() + self.failUnless(type(c) == ds.DSCCAPSType) + + def test_2_Attr(self): + 'DSCCAPS attribute access' + c = ds.DSCCAPS() + c.dwFlags = 1 + c.dwFormats = 2 + c.dwChannels = 4 + + self.failUnless(c.dwFlags == 1) + self.failUnless(c.dwFormats == 2) + self.failUnless(c.dwChannels == 4) + + class DSCBCAPSTest(unittest.TestCase): + def test_1_Type(self): + 'DSCBCAPS type' + c = ds.DSCBCAPS() + self.failUnless(type(c) == ds.DSCBCAPSType) + + def test_2_Attr(self): + 'DSCBCAPS attribute access' + c = ds.DSCBCAPS() + c.dwFlags = 1 + c.dwBufferBytes = 2 + + self.failUnless(c.dwFlags == 1) + self.failUnless(c.dwBufferBytes == 2) + class DSBUFFERDESCTest(unittest.TestCase): def test_1_Type(self): *************** *** 164,167 **** --- 207,246 ---- self.failUnlessRaises(ValueError, self.invalid_format, c) + class DSCBUFFERDESCTest(unittest.TestCase): + def test_1_Type(self): + 'DSCBUFFERDESC type' + c = ds.DSCBUFFERDESC() + self.failUnless(type(c) == ds.DSCBUFFERDESCType) + + def test_2_Attr(self): + 'DSCBUFFERDESC attribute access' + c = ds.DSCBUFFERDESC() + c.dwFlags = 1 + c.dwBufferBytes = 2 + c.lpwfxFormat = pywintypes.WAVEFORMATEX() + c.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM + c.lpwfxFormat.nChannels = 2 + c.lpwfxFormat.nSamplesPerSec = 44100 + c.lpwfxFormat.nAvgBytesPerSec = 176400 + c.lpwfxFormat.nBlockAlign = 4 + c.lpwfxFormat.wBitsPerSample = 16 + + self.failUnless(c.dwFlags == 1) + self.failUnless(c.dwBufferBytes == 2) + self.failUnless(c.lpwfxFormat.wFormatTag == 1) + self.failUnless(c.lpwfxFormat.nChannels == 2) + self.failUnless(c.lpwfxFormat.nSamplesPerSec == 44100) + self.failUnless(c.lpwfxFormat.nAvgBytesPerSec == 176400) + self.failUnless(c.lpwfxFormat.nBlockAlign == 4) + self.failUnless(c.lpwfxFormat.wBitsPerSample == 16) + + def invalid_format(self, c): + c.lpwfxFormat = 17 + + def test_3_invalid_format(self): + 'DSCBUFFERDESC invalid lpwfxFormat assignment' + c = ds.DSCBUFFERDESC() + self.failUnlessRaises(ValueError, self.invalid_format, c) + class DirectSoundTest(unittest.TestCase): # basic tests - mostly just exercise the functions *************** *** 181,185 **** def testPlay(self): ! '''Play a file''' fname=os.path.join(os.path.dirname(__file__), "01-Intro.wav") f = open(fname, 'rb') --- 260,264 ---- def testPlay(self): ! '''Mesdames et Messieurs, la cour de Devin Dazzle''' fname=os.path.join(os.path.dirname(__file__), "01-Intro.wav") f = open(fname, 'rb') *************** *** 208,211 **** --- 287,338 ---- win32event.WaitForSingleObject(event, -1) + class DirectSoundCaptureTest(unittest.TestCase): + # basic tests - mostly just exercise the functions + + def testEnumerate(self): + '''DirectSoundCaptureEnumerate() sanity tests''' + + devices = ds.DirectSoundCaptureEnumerate() + # this might fail on machines without a sound card + self.failUnless(len(devices)) + # if we have an entry, it must be a tuple of size 3 + self.failUnless(len(devices[0]) == 3) + + def testCreate(self): + '''DirectSoundCreate()''' + d = ds.DirectSoundCaptureCreate(None, None) + + def testRecord(self): + d = ds.DirectSoundCaptureCreate(None, None) + + sdesc = ds.DSCBUFFERDESC() + sdesc.dwBufferBytes = 352800 # 2 seconds + sdesc.lpwfxFormat = pywintypes.WAVEFORMATEX() + sdesc.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM + sdesc.lpwfxFormat.nChannels = 2 + sdesc.lpwfxFormat.nSamplesPerSec = 44100 + sdesc.lpwfxFormat.nAvgBytesPerSec = 176400 + sdesc.lpwfxFormat.nBlockAlign = 4 + sdesc.lpwfxFormat.wBitsPerSample = 16 + + buffer = d.CreateCaptureBuffer(sdesc) + + event = win32event.CreateEvent(None, 0, 0, None) + notify = buffer.QueryInterface(ds.IID_IDirectSoundNotify) + + notify.SetNotificationPositions((ds.DSBPN_OFFSETSTOP, event)) + + buffer.Start(0) + + win32event.WaitForSingleObject(event, -1) + event.Close() + + data = buffer.Update(0, 352800) + + f = open('recording.wav', 'wb') + f.write(wav_header_pack(sdesc.lpwfxFormat, 352800)) + f.write(data) + f.close() + if __name__ == '__main__': unittest.main() |
From: Lars I. <lar...@us...> - 2005-03-07 22:18:54
|
Update of /cvsroot/pywin32/pywin32/com In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4072/com Modified Files: directsound.dsp Log Message: Added IDirectSoundCapture, IDirectSoundCaptureBuffer, related structures and functions. Basic regression are included. Index: directsound.dsp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/directsound.dsp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** directsound.dsp 30 Nov 2004 21:30:27 -0000 1.1 --- directsound.dsp 7 Mar 2005 22:18:44 -0000 1.2 *************** *** 113,116 **** --- 113,128 ---- # Begin Source File + SOURCE=.\win32comext\directsound\src\PyDSCBCAPS.cpp + # End Source File + # Begin Source File + + SOURCE=.\win32comext\directsound\src\PyDSCBUFFERDESC.cpp + # End Source File + # Begin Source File + + SOURCE=.\win32comext\directsound\src\PyDSCCAPS.cpp + # End Source File + # Begin Source File + SOURCE=.\win32comext\directsound\src\PyIDirectSound.cpp # End Source File *************** *** 121,124 **** --- 133,144 ---- # Begin Source File + SOURCE=.\win32comext\directsound\src\PyIDirectSoundCapture.cpp + # End Source File + # Begin Source File + + SOURCE=.\win32comext\directsound\src\PyIDirectSoundCaptureBuffer.cpp + # End Source File + # Begin Source File + SOURCE=.\win32comext\directsound\src\PyIDirectSoundNotify.cpp # End Source File *************** *** 141,144 **** --- 161,172 ---- # Begin Source File + SOURCE=.\win32comext\directsound\src\PyIDirectSoundCapture.h + # End Source File + # Begin Source File + + SOURCE=.\win32comext\directsound\src\PyIDirectSoundCaptureBuffer.h + # End Source File + # Begin Source File + SOURCE=.\win32comext\directsound\src\PyIDirectSoundNotify.h # End Source File |
From: Mark H. <mha...@us...> - 2005-03-07 11:57:51
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7849 Modified Files: win32security.i Log Message: autoduck correction Index: win32security.i =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/win32security.i,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** win32security.i 6 Mar 2005 23:27:01 -0000 1.21 --- win32security.i 7 Mar 2005 11:57:41 -0000 1.22 *************** *** 3186,3190 **** goto done; break; ! // @flag KerbPurgeTicketCacheMessage|(long, <o PyUnicode>, <o PyUnicode) - tuple containing (LogonId, ServerName, RealmName) case KerbPurgeTicketCacheMessage: PyObject *obLogonId, *obServerName, *obRealmName; --- 3186,3190 ---- goto done; break; ! // @flag KerbPurgeTicketCacheMessage|(long, <o PyUnicode>, <o PyUnicode>) - tuple containing (LogonId, ServerName, RealmName) case KerbPurgeTicketCacheMessage: PyObject *obLogonId, *obServerName, *obRealmName; |
From: Mark H. <mha...@us...> - 2005-03-07 11:52:45
|
Update of /cvsroot/pywin32/pywin32 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6831 Modified Files: MANIFEST.in Log Message: don't know how to include "Python and Extensions.dsw" - spaces upset things Index: MANIFEST.in =================================================================== RCS file: /cvsroot/pywin32/pywin32/MANIFEST.in,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** MANIFEST.in 13 Feb 2005 12:27:54 -0000 1.7 --- MANIFEST.in 7 Mar 2005 11:52:29 -0000 1.8 *************** *** 10,14 **** include setup_win32all.py include setup.py ! include Python and Extensions.dsw # Core win32 stuff include win32/src/*.rc --- 10,14 ---- include setup_win32all.py include setup.py ! # don't know how to include "Python and Extensions.dsw" - spaces upset things # Core win32 stuff include win32/src/*.rc |
From: Mark H. <mha...@us...> - 2005-03-07 11:16:59
|
Update of /cvsroot/pywin32/pywin32/win32/Demos/security/sspi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29814/Demos/security/sspi Modified Files: socket_server.py validate_password.py Log Message: * Have encrypt/sign etc return the data and the security info as discrete objects rather than merging them. * Support sequence-numbering - Kerberos appears to insist in incrementing sequence numbers with our default flags - passing zero does not work. * Demos tests updated accordingly. Index: validate_password.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/Demos/security/sspi/validate_password.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** validate_password.py 6 Mar 2005 23:27:00 -0000 1.1 --- validate_password.py 7 Mar 2005 11:16:19 -0000 1.2 *************** *** 1,4 **** --- 1,7 ---- # Demonstrates how to validate a password. # See also MSKB article Q180548 + # + # To use with Kerberos you need to jump through the 'targetspn' hoops. + import win32security import sys Index: socket_server.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/Demos/security/sspi/socket_server.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** socket_server.py 6 Mar 2005 23:27:00 -0000 1.1 --- socket_server.py 7 Mar 2005 11:16:18 -0000 1.2 *************** *** 1,4 **** ! # A sample socket server and client, based on the standard MS samples ! # "Using SSPI with a Windows Sockets Client[/Server]" import sys --- 1,23 ---- ! """A sample socket server and client using SSPI authentication and encryption. ! ! You must run with either 'client' or 'server' as arguments. A server must be ! running before a client can connect. ! ! To use with Kerberos you should include in the client options ! --target-spn=username, where 'username' is the user under which the server is ! being run. ! ! Running either the client or server as a different user can be informative. ! A command-line such as the following may be useful: ! `runas /user:{user} {fqp}\python.exe {fqp}\socket_server.py --wait client|server` ! ! {fqp} should specify the relevant fully-qualified path names. ! ! To use 'runas' with Kerberos, the client program will need to ! specify --target-spn with the username under which the *server* is running. ! ! See the SSPI documentation for more details. ! """ ! import sys *************** *** 7,14 **** --- 26,49 ---- import win32api import httplib + import traceback import win32security import sspi, sspicon + import optparse # sorry, this demo needs 2.3+ + + options = None # set to optparse object. + + def GetUserName(): + try: + return win32api.GetUserName() + except win32api.error, details: + # Seeing 'access denied' errors here for non-local users (presumably + # without permission to login locally). Get the fully-qualified + # username, although a side-effect of these permission-denied errors + # is a lack of Python codecs - so printing the Unicode value fails. + # So just return the repr(), and avoid codecs completely. + return repr(win32api.GetUserNameEx(win32api.NameSamCompatible)) + # Send a simple "message" over a socket - send the number of bytes first, # then the string. Ditto for receive. *************** *** 27,31 **** def __init__(self, *args, **kw): SocketServer.TCPServer.__init__(self, *args, **kw) ! self.sa = sspi.ServerAuth("NTLM") def verify_request(self, sock, ca): --- 62,66 ---- def __init__(self, *args, **kw): SocketServer.TCPServer.__init__(self, *args, **kw) ! self.sa = sspi.ServerAuth(options.package) def verify_request(self, sock, ca): *************** *** 36,40 **** if data is None: return False ! err, sec_buffer = self.sa.authorize(data) if err==0: break --- 71,80 ---- if data is None: return False ! try: ! err, sec_buffer = self.sa.authorize(data) ! except sspi.error, details: ! print "FAILED to authorize client:", details ! return False ! if err==0: break *************** *** 44,72 **** def process_request(self, request, client_address): # An example using the connection once it is established. ! print "The server is running as user", win32api.GetUserName() self.sa.ctxt.ImpersonateSecurityContext() try: ! print "Having conversation with client as user", win32api.GetUserName() while 1: data = _get_msg(request) ! if not data: break ! data = self.sa.decrypt(data) print "Client sent:", repr(data) finally: self.sa.ctxt.RevertSecurityContext() self.close_request(request) ! print "The server is back to user", win32api.GetUserName() def serve(): ! s = SSPISocketServer(("localhost", 8181), None) print "Running test server..." s.serve_forever() def sspi_client(): ! c = httplib.HTTPConnection("localhost", 8181) c.connect() # Do the auth dance. ! ca = sspi.ClientAuth("NTLM") data = None while 1: --- 84,115 ---- def process_request(self, request, client_address): # An example using the connection once it is established. ! print "The server is running as user", GetUserName() self.sa.ctxt.ImpersonateSecurityContext() try: ! print "Having conversation with client as user", GetUserName() while 1: + # we need to grab 2 bits of data - the encrypted data, and the + # 'key' data = _get_msg(request) ! key = _get_msg(request) ! if data is None or key is None: break ! data = self.sa.decrypt(data, key) print "Client sent:", repr(data) finally: self.sa.ctxt.RevertSecurityContext() self.close_request(request) ! print "The server is back to user", GetUserName() def serve(): ! s = SSPISocketServer(("localhost", options.port), None) print "Running test server..." s.serve_forever() def sspi_client(): ! c = httplib.HTTPConnection("localhost", options.port) c.connect() # Do the auth dance. ! ca = sspi.ClientAuth(options.package, targetspn=options.target_spn) data = None while 1: *************** *** 76,102 **** break data = _get_msg(c.sock) ! print "Auth dance complete - sending single encryted message" # Assume out data is sensitive - encrypt the message. ! _send_msg(c.sock, ca.encrypt("Hello")) c.sock.close() print "Client completed." if __name__=='__main__': ! command = "" ! if len(sys.argv)>1: command = sys.argv[1] ! if command == "client": ! sspi_client() ! elif command == "server": ! serve() ! else: ! print "You must execute this with either 'client' or 'server'" ! print "Start an instance with 'server', then connect to it with 'client'" ! print ! print "Running either the client or server as a different user is" ! print "recommended. A command-line such as the following may be useful:" try: ! un = win32api.GetUserNameEx(win32api.NameSamCompatible) ! except win32api.error: ! # not in a domain ! un = win32api.GetUserName() ! print "runas /user:%s {path_to}\python.exe {path_to}\%s client|server" % (un, __file__) --- 119,178 ---- break data = _get_msg(c.sock) ! print "Auth dance complete - sending a few encryted messages" # Assume out data is sensitive - encrypt the message. ! for data in "Hello from the client".split(): ! blob, key = ca.encrypt(data) ! _send_msg(c.sock, blob) ! _send_msg(c.sock, key) c.sock.close() print "Client completed." if __name__=='__main__': ! parser = optparse.OptionParser("%prog [options] client|server", ! description=__doc__) ! ! parser.add_option("", "--package", action="store", default="NTLM", ! help="The SSPI package to use (eg, Kerberos) - default is NTLM") ! ! parser.add_option("", "--target-spn", action="store", ! help="""The target security provider name to use. The ! string contents are security-package specific. For ! example, 'Kerberos' or 'Negotiate' require the server ! principal name (SPN) (ie, the username) of the remote ! process. For NTLM this must be blank.""") ! ! parser.add_option("", "--port", action="store", default="8181", ! help="The port number to use (default=8181)") ! ! parser.add_option("", "--wait", action="store_true", ! help="""Cause the program to wait for input just before ! terminating. Useful when using via runas to see ! any error messages before termination. ! """) ! ! options, args = parser.parse_args() ! try: ! options.port = int(options.port) ! except (ValueError, TypeError): ! parser.error("--port must be an integer") ! ! try: try: ! if not args: ! args = [''] ! if args[0]=="client": ! sspi_client() ! elif args[0]=="server": ! serve() ! else: ! parser.error("You must supply 'client' or 'server' - " \ ! "use --help for details") ! except KeyboardInterrupt: ! pass ! except SystemExit: ! pass ! except: ! traceback.print_exc() ! finally: ! if options.wait: ! raw_input("Press enter to continue") |
From: Mark H. <mha...@us...> - 2005-03-07 11:16:50
|
Update of /cvsroot/pywin32/pywin32/win32/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29814/Lib Modified Files: sspi.py Log Message: * Have encrypt/sign etc return the data and the security info as discrete objects rather than merging them. * Support sequence-numbering - Kerberos appears to insist in incrementing sequence numbers with our default flags - passing zero does not work. * Demos tests updated accordingly. Index: sspi.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/Lib/sspi.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** sspi.py 6 Mar 2005 23:27:00 -0000 1.1 --- sspi.py 7 Mar 2005 11:16:19 -0000 1.2 *************** *** 8,12 **** These classes attempt to hide these details from you until you really need ! to know. """ # Based on Roger Upole's sspi demos. --- 8,14 ---- These classes attempt to hide these details from you until you really need ! to know. They are not designed to handle all cases, just the common ones. ! If you need finer control than offered here, just use the win32security ! functions directly. """ # Based on Roger Upole's sspi demos. *************** *** 14,17 **** --- 16,21 ---- import win32security, sspicon + error = win32security.error + try: True, False *************** *** 25,33 **** def reset(self): self.ctxt = None self.authenticated = False def encrypt(self, data): ! """Encrypt a string, returning a string suitable for transmission""" pkg_size_info=self.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_SIZES) trailersize=pkg_size_info['SecurityTrailer'] --- 29,50 ---- def reset(self): + """Reset everything to an unauthorized state""" self.ctxt = None self.authenticated = False + # The next seq_num for an encrypt/sign operation + self.next_seq_num = 0 + + def _get_next_seq_num(self): + """Get the next sequence number for a transmission. Default + implementation is to increment a counter + """ + ret = self.next_seq_num + self.next_seq_num = self.next_seq_num + 1 + return ret def encrypt(self, data): ! """Encrypt a string, returning a tuple of (encrypted_data, encryption_data). ! These can be passed to decrypt to get back the original string. ! """ pkg_size_info=self.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_SIZES) trailersize=pkg_size_info['SecurityTrailer'] *************** *** 37,62 **** encbuf.append(win32security.SecBufferType(trailersize, sspicon.SECBUFFER_TOKEN)) encbuf[0].Buffer=data ! self.ctxt.EncryptMessage(0,encbuf,1) ! # And return all buffers as a string ! return "".join([b.Buffer for b in encbuf]) ! def decrypt(self, data): """Decrypt a previously encrypted string, returning the orignal data""" - pkg_size_info=self.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_SIZES) - trailersize=pkg_size_info['SecurityTrailer'] - msgsize = len(data)-trailersize - assert msgsize >= 0, "trailer is %d bytes, but data only %d long" \ - % (trailersize, len(data)) - encbuf=win32security.SecBufferDescType() ! encbuf.append(win32security.SecBufferType(msgsize, sspicon.SECBUFFER_DATA)) ! encbuf.append(win32security.SecBufferType(trailersize, sspicon.SECBUFFER_TOKEN)) ! encbuf[0].Buffer=data[:msgsize] ! encbuf[1].Buffer=data[msgsize:] ! self.ctxt.DecryptMessage(encbuf,1) return encbuf[0].Buffer def sign(self, data): ! """sign a string suitable for transmission. """ pkg_size_info=self.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_SIZES) --- 54,74 ---- encbuf.append(win32security.SecBufferType(trailersize, sspicon.SECBUFFER_TOKEN)) encbuf[0].Buffer=data ! self.ctxt.EncryptMessage(0,encbuf,self._get_next_seq_num()) ! return encbuf[0].Buffer, encbuf[1].Buffer ! def decrypt(self, data, trailer): """Decrypt a previously encrypted string, returning the orignal data""" encbuf=win32security.SecBufferDescType() ! encbuf.append(win32security.SecBufferType(len(data), sspicon.SECBUFFER_DATA)) ! encbuf.append(win32security.SecBufferType(len(trailer), sspicon.SECBUFFER_TOKEN)) ! encbuf[0].Buffer=data ! encbuf[1].Buffer=trailer ! self.ctxt.DecryptMessage(encbuf,self._get_next_seq_num()) return encbuf[0].Buffer def sign(self, data): ! """sign a string suitable for transmission, returning the signature. ! Passing the data and signature to verify will determine if the data ! is unchanged. """ pkg_size_info=self.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_SIZES) *************** *** 67,91 **** sigbuf[0].Buffer=data ! self.ctxt.MakeSignature(0,sigbuf,1) ! # And return all buffers as a string ! return "".join([b.Buffer for b in sigbuf]) ! def unsign(self, data): ! """Takes a message as a 'signed' string, verifies the signature and ! returns the original data""" ! pkg_size_info=self.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_SIZES) ! sigsize=pkg_size_info['MaxSignature'] ! msgsize = len(data)-sigsize ! assert msgsize >= 0, "signature is %d bytes, but data only %d long" \ ! % (sigsize, len(data)) sigbuf=win32security.SecBufferDescType() ! sigbuf.append(win32security.SecBufferType(msgsize, sspicon.SECBUFFER_DATA)) ! sigbuf.append(win32security.SecBufferType(sigsize, sspicon.SECBUFFER_TOKEN)) ! ! sigbuf[0].Buffer=data[:msgsize] ! sigbuf[1].Buffer=data[msgsize:] ! self.ctxt.VerifySignature(sigbuf,1) ! return sigbuf[0].Buffer class ClientAuth(_BaseAuth): --- 79,96 ---- sigbuf[0].Buffer=data ! self.ctxt.MakeSignature(0,sigbuf,self._get_next_seq_num()) ! return sigbuf[1].Buffer ! def verify(self, data, sig): ! """Verifies data and its signature. If verification fails, an sspi.error ! will be raised. ! """ sigbuf=win32security.SecBufferDescType() ! sigbuf.append(win32security.SecBufferType(len(data), sspicon.SECBUFFER_DATA)) ! sigbuf.append(win32security.SecBufferType(len(sig), sspicon.SECBUFFER_TOKEN)) + sigbuf[0].Buffer=data + sigbuf[1].Buffer=sig + self.ctxt.VerifySignature(sigbuf,self._get_next_seq_num()) class ClientAuth(_BaseAuth): *************** *** 219,224 **** if err==0: break ! assert sspiserver.unsign(sspiclient.sign("hello")) == "hello" ! assert sspiserver.decrypt(sspiclient.encrypt("hello")) == "hello" print "cool!" - \ No newline at end of file --- 224,231 ---- if err==0: break ! sig = sspiclient.sign("hello") ! sspiserver.verify("hello", sig) ! ! data, key = sspiclient.encrypt("hello") ! assert sspiserver.decrypt(data, key) == "hello" print "cool!" |
From: Mark H. <mha...@us...> - 2005-03-07 11:16:47
|
Update of /cvsroot/pywin32/pywin32/win32/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29814/test Modified Files: test_sspi.py Log Message: * Have encrypt/sign etc return the data and the security info as discrete objects rather than merging them. * Support sequence-numbering - Kerberos appears to insist in incrementing sequence numbers with our default flags - passing zero does not work. * Demos tests updated accordingly. Index: test_sspi.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/test/test_sspi.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_sspi.py 6 Mar 2005 23:27:02 -0000 1.1 --- test_sspi.py 7 Mar 2005 11:16:36 -0000 1.2 *************** *** 7,10 **** --- 7,17 ---- class TestSSPI(unittest.TestCase): + def assertRaisesHRESULT(self, hr, func, *args): + try: + return func(*args) + raise RuntimeError, "expecting %s failure" % (hr,) + except win32security.error, (hr_got, func, msg): + self.failUnlessEqual(hr_got, hr) + def _doAuth(self, pkg_name): sspiclient=sspi.ClientAuth(pkg_name,targetspn=win32api.GetUserName()) *************** *** 46,51 **** self.failUnlessEqual(msg, encbuf[0].Buffer) # and test the higher-level functions ! self.assertEqual(sspiserver.decrypt(sspiclient.encrypt("hello")), "hello") ! self.assertEqual(sspiclient.decrypt(sspiserver.encrypt("hello")), "hello") def testEncryptNTLM(self): --- 53,61 ---- self.failUnlessEqual(msg, encbuf[0].Buffer) # and test the higher-level functions ! data, sig = sspiclient.encrypt("hello") ! self.assertEqual(sspiserver.decrypt(data, sig), "hello") ! ! data, sig = sspiserver.encrypt("hello") ! self.assertEqual(sspiclient.decrypt(data, sig), "hello") def testEncryptNTLM(self): *************** *** 67,76 **** sigbuf.append(win32security.SecBufferType(sigsize, sspicon.SECBUFFER_TOKEN)) sigbuf[0].Buffer=msg ! sspiclient.ctxt.MakeSignature(0,sigbuf,1) ! sspiserver.ctxt.VerifySignature(sigbuf,1) # and test the higher-level functions ! self.assertEqual(sspiserver.unsign(sspiclient.sign("hello")), "hello") # and the other way ! self.assertEqual(sspiclient.unsign(sspiserver.sign("hello")), "hello") def testSignNTLM(self): --- 77,97 ---- sigbuf.append(win32security.SecBufferType(sigsize, sspicon.SECBUFFER_TOKEN)) sigbuf[0].Buffer=msg ! sspiclient.ctxt.MakeSignature(0,sigbuf,0) ! sspiserver.ctxt.VerifySignature(sigbuf,0) # and test the higher-level functions ! sspiclient.next_seq_num = 1 ! sspiserver.next_seq_num = 1 ! key = sspiclient.sign("hello") ! sspiserver.verify("hello", key) ! key = sspiclient.sign("hello") ! self.assertRaisesHRESULT(sspicon.SEC_E_MESSAGE_ALTERED, ! sspiserver.verify, "hellox", key) ! # and the other way ! key = sspiserver.sign("hello") ! sspiclient.verify("hello", key) ! key = sspiserver.sign("hello") ! self.assertRaisesHRESULT(sspicon.SEC_E_MESSAGE_ALTERED, ! sspiclient.verify, "hellox", key) def testSignNTLM(self): *************** *** 80,83 **** --- 101,120 ---- self._doTestSign("Kerberos") + def testSequenceSign(self): + # Only Kerberos supports sequence detection. + sspiclient, sspiserver = self._doAuth("Kerberos") + key = sspiclient.sign("hello") + sspiclient.sign("hello") + self.assertRaisesHRESULT(sspicon.SEC_E_OUT_OF_SEQUENCE, + sspiserver.verify, 'hello', key) + + def testSequenceEncrypt(self): + # Only Kerberos supports sequence detection. + sspiclient, sspiserver = self._doAuth("Kerberos") + blob, key = sspiclient.encrypt("hello",) + blob, key = sspiclient.encrypt("hello") + self.assertRaisesHRESULT(sspicon.SEC_E_OUT_OF_SEQUENCE, + sspiserver.decrypt, blob, key) + if __name__=='__main__': unittest.main() |
From: Mark H. <mha...@us...> - 2005-03-07 11:08:52
|
Update of /cvsroot/pywin32/pywin32/win32/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28309 Modified Files: sspicon.py Log Message: Convert constants to integers, mainly so error codes match up with the exception values. Index: sspicon.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/Lib/sspicon.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** sspicon.py 6 Mar 2005 23:27:00 -0000 1.1 --- sspicon.py 7 Mar 2005 11:08:41 -0000 1.2 *************** *** 8,31 **** def SEC_SUCCESS(Status): return ((Status) >= 0) ! SECPKG_FLAG_INTEGRITY = 0x00000001 ! SECPKG_FLAG_PRIVACY = 0x00000002 ! SECPKG_FLAG_TOKEN_ONLY = 0x00000004 ! SECPKG_FLAG_DATAGRAM = 0x00000008 ! SECPKG_FLAG_CONNECTION = 0x00000010 ! SECPKG_FLAG_MULTI_REQUIRED = 0x00000020 ! SECPKG_FLAG_CLIENT_ONLY = 0x00000040 ! SECPKG_FLAG_EXTENDED_ERROR = 0x00000080 ! SECPKG_FLAG_IMPERSONATION = 0x00000100 ! SECPKG_FLAG_ACCEPT_WIN32_NAME = 0x00000200 ! SECPKG_FLAG_STREAM = 0x00000400 ! SECPKG_FLAG_NEGOTIABLE = 0x00000800 ! SECPKG_FLAG_GSS_COMPATIBLE = 0x00001000 ! SECPKG_FLAG_LOGON = 0x00002000 ! SECPKG_FLAG_ASCII_BUFFERS = 0x00004000 ! SECPKG_FLAG_FRAGMENT = 0x00008000 ! SECPKG_FLAG_MUTUAL_AUTH = 0x00010000 ! SECPKG_FLAG_DELEGATION = 0x00020000 ! SECPKG_FLAG_READONLY_WITH_CHECKSUM = 0x00040000 ! SECPKG_ID_NONE = 0xFFFF SECBUFFER_VERSION = 0 --- 8,31 ---- def SEC_SUCCESS(Status): return ((Status) >= 0) ! SECPKG_FLAG_INTEGRITY = 1 ! SECPKG_FLAG_PRIVACY = 2 ! SECPKG_FLAG_TOKEN_ONLY = 4 ! SECPKG_FLAG_DATAGRAM = 8 ! SECPKG_FLAG_CONNECTION = 16 ! SECPKG_FLAG_MULTI_REQUIRED = 32 ! SECPKG_FLAG_CLIENT_ONLY = 64 ! SECPKG_FLAG_EXTENDED_ERROR = 128 ! SECPKG_FLAG_IMPERSONATION = 256 ! SECPKG_FLAG_ACCEPT_WIN32_NAME = 512 ! SECPKG_FLAG_STREAM = 1024 ! SECPKG_FLAG_NEGOTIABLE = 2048 ! SECPKG_FLAG_GSS_COMPATIBLE = 4096 ! SECPKG_FLAG_LOGON = 8192 ! SECPKG_FLAG_ASCII_BUFFERS = 16384 ! SECPKG_FLAG_FRAGMENT = 32768 ! SECPKG_FLAG_MUTUAL_AUTH = 65536 ! SECPKG_FLAG_DELEGATION = 131072 ! SECPKG_FLAG_READONLY_WITH_CHECKSUM = 262144 ! SECPKG_ID_NONE = 65535 SECBUFFER_VERSION = 0 *************** *** 47,150 **** SECBUFFER_ATTRMASK = (-268435456) SECBUFFER_READONLY = (-2147483648) ! SECBUFFER_READONLY_WITH_CHECKSUM = 0x10000000 ! SECBUFFER_RESERVED = 0x60000000 ! SECURITY_NATIVE_DREP = 0x00000010 ! SECURITY_NETWORK_DREP = 0x00000000 ! SECPKG_CRED_INBOUND = 0x00000001 ! SECPKG_CRED_OUTBOUND = 0x00000002 ! SECPKG_CRED_BOTH = 0x00000003 ! SECPKG_CRED_DEFAULT = 0x00000004 SECPKG_CRED_RESERVED = -268435456 ! ISC_REQ_DELEGATE = 0x00000001 ! ISC_REQ_MUTUAL_AUTH = 0x00000002 ! ISC_REQ_REPLAY_DETECT = 0x00000004 ! ISC_REQ_SEQUENCE_DETECT = 0x00000008 ! ISC_REQ_CONFIDENTIALITY = 0x00000010 ! ISC_REQ_USE_SESSION_KEY = 0x00000020 ! ISC_REQ_PROMPT_FOR_CREDS = 0x00000040 ! ISC_REQ_USE_SUPPLIED_CREDS = 0x00000080 ! ISC_REQ_ALLOCATE_MEMORY = 0x00000100 ! ISC_REQ_USE_DCE_STYLE = 0x00000200 ! ISC_REQ_DATAGRAM = 0x00000400 ! ISC_REQ_CONNECTION = 0x00000800 ! ISC_REQ_CALL_LEVEL = 0x00001000 ! ISC_REQ_FRAGMENT_SUPPLIED = 0x00002000 ! ISC_REQ_EXTENDED_ERROR = 0x00004000 ! ISC_REQ_STREAM = 0x00008000 ! ISC_REQ_INTEGRITY = 0x00010000 ! ISC_REQ_IDENTIFY = 0x00020000 ! ISC_REQ_NULL_SESSION = 0x00040000 ! ISC_REQ_MANUAL_CRED_VALIDATION = 0x00080000 ! ISC_REQ_RESERVED1 = 0x00100000 ! ISC_REQ_FRAGMENT_TO_FIT = 0x00200000 ! ISC_RET_DELEGATE = 0x00000001 ! ISC_RET_MUTUAL_AUTH = 0x00000002 ! ISC_RET_REPLAY_DETECT = 0x00000004 ! ISC_RET_SEQUENCE_DETECT = 0x00000008 ! ISC_RET_CONFIDENTIALITY = 0x00000010 ! ISC_RET_USE_SESSION_KEY = 0x00000020 ! ISC_RET_USED_COLLECTED_CREDS = 0x00000040 ! ISC_RET_USED_SUPPLIED_CREDS = 0x00000080 ! ISC_RET_ALLOCATED_MEMORY = 0x00000100 ! ISC_RET_USED_DCE_STYLE = 0x00000200 ! ISC_RET_DATAGRAM = 0x00000400 ! ISC_RET_CONNECTION = 0x00000800 ! ISC_RET_INTERMEDIATE_RETURN = 0x00001000 ! ISC_RET_CALL_LEVEL = 0x00002000 ! ISC_RET_EXTENDED_ERROR = 0x00004000 ! ISC_RET_STREAM = 0x00008000 ! ISC_RET_INTEGRITY = 0x00010000 ! ISC_RET_IDENTIFY = 0x00020000 ! ISC_RET_NULL_SESSION = 0x00040000 ! ISC_RET_MANUAL_CRED_VALIDATION = 0x00080000 ! ISC_RET_RESERVED1 = 0x00100000 ! ISC_RET_FRAGMENT_ONLY = 0x00200000 ! ASC_REQ_DELEGATE = 0x00000001 ! ASC_REQ_MUTUAL_AUTH = 0x00000002 ! ASC_REQ_REPLAY_DETECT = 0x00000004 ! ASC_REQ_SEQUENCE_DETECT = 0x00000008 ! ASC_REQ_CONFIDENTIALITY = 0x00000010 ! ASC_REQ_USE_SESSION_KEY = 0x00000020 ! ASC_REQ_ALLOCATE_MEMORY = 0x00000100 ! ASC_REQ_USE_DCE_STYLE = 0x00000200 ! ASC_REQ_DATAGRAM = 0x00000400 ! ASC_REQ_CONNECTION = 0x00000800 ! ASC_REQ_CALL_LEVEL = 0x00001000 ! ASC_REQ_EXTENDED_ERROR = 0x00008000 ! ASC_REQ_STREAM = 0x00010000 ! ASC_REQ_INTEGRITY = 0x00020000 ! ASC_REQ_LICENSING = 0x00040000 ! ASC_REQ_IDENTIFY = 0x00080000 ! ASC_REQ_ALLOW_NULL_SESSION = 0x00100000 ! ASC_REQ_ALLOW_NON_USER_LOGONS = 0x00200000 ! ASC_REQ_ALLOW_CONTEXT_REPLAY = 0x00400000 ! ASC_REQ_FRAGMENT_TO_FIT = 0x00800000 ! ASC_REQ_FRAGMENT_SUPPLIED = 0x00002000 ! ASC_REQ_NO_TOKEN = 0x01000000 ! ASC_RET_DELEGATE = 0x00000001 ! ASC_RET_MUTUAL_AUTH = 0x00000002 ! ASC_RET_REPLAY_DETECT = 0x00000004 ! ASC_RET_SEQUENCE_DETECT = 0x00000008 ! ASC_RET_CONFIDENTIALITY = 0x00000010 ! ASC_RET_USE_SESSION_KEY = 0x00000020 ! ASC_RET_ALLOCATED_MEMORY = 0x00000100 ! ASC_RET_USED_DCE_STYLE = 0x00000200 ! ASC_RET_DATAGRAM = 0x00000400 ! ASC_RET_CONNECTION = 0x00000800 ! ASC_RET_CALL_LEVEL = 0x00002000 ! ASC_RET_THIRD_LEG_FAILED = 0x00004000 ! ASC_RET_EXTENDED_ERROR = 0x00008000 ! ASC_RET_STREAM = 0x00010000 ! ASC_RET_INTEGRITY = 0x00020000 ! ASC_RET_LICENSING = 0x00040000 ! ASC_RET_IDENTIFY = 0x00080000 ! ASC_RET_NULL_SESSION = 0x00100000 ! ASC_RET_ALLOW_NON_USER_LOGONS = 0x00200000 ! ASC_RET_ALLOW_CONTEXT_REPLAY = 0x00400000 ! ASC_RET_FRAGMENT_ONLY = 0x00800000 SECPKG_CRED_ATTR_NAMES = 1 --- 47,150 ---- SECBUFFER_ATTRMASK = (-268435456) SECBUFFER_READONLY = (-2147483648) ! SECBUFFER_READONLY_WITH_CHECKSUM = 268435456 ! SECBUFFER_RESERVED = 1610612736 ! SECURITY_NATIVE_DREP = 16 ! SECURITY_NETWORK_DREP = 0 ! SECPKG_CRED_INBOUND = 1 ! SECPKG_CRED_OUTBOUND = 2 ! SECPKG_CRED_BOTH = 3 ! SECPKG_CRED_DEFAULT = 4 SECPKG_CRED_RESERVED = -268435456 ! ISC_REQ_DELEGATE = 1 ! ISC_REQ_MUTUAL_AUTH = 2 ! ISC_REQ_REPLAY_DETECT = 4 ! ISC_REQ_SEQUENCE_DETECT = 8 ! ISC_REQ_CONFIDENTIALITY = 16 ! ISC_REQ_USE_SESSION_KEY = 32 ! ISC_REQ_PROMPT_FOR_CREDS = 64 ! ISC_REQ_USE_SUPPLIED_CREDS = 128 ! ISC_REQ_ALLOCATE_MEMORY = 256 ! ISC_REQ_USE_DCE_STYLE = 512 ! ISC_REQ_DATAGRAM = 1024 ! ISC_REQ_CONNECTION = 2048 ! ISC_REQ_CALL_LEVEL = 4096 ! ISC_REQ_FRAGMENT_SUPPLIED = 8192 ! ISC_REQ_EXTENDED_ERROR = 16384 ! ISC_REQ_STREAM = 32768 ! ISC_REQ_INTEGRITY = 65536 ! ISC_REQ_IDENTIFY = 131072 ! ISC_REQ_NULL_SESSION = 262144 ! ISC_REQ_MANUAL_CRED_VALIDATION = 524288 ! ISC_REQ_RESERVED1 = 1048576 ! ISC_REQ_FRAGMENT_TO_FIT = 2097152 ! ISC_RET_DELEGATE = 1 ! ISC_RET_MUTUAL_AUTH = 2 ! ISC_RET_REPLAY_DETECT = 4 ! ISC_RET_SEQUENCE_DETECT = 8 ! ISC_RET_CONFIDENTIALITY = 16 ! ISC_RET_USE_SESSION_KEY = 32 ! ISC_RET_USED_COLLECTED_CREDS = 64 ! ISC_RET_USED_SUPPLIED_CREDS = 128 ! ISC_RET_ALLOCATED_MEMORY = 256 ! ISC_RET_USED_DCE_STYLE = 512 ! ISC_RET_DATAGRAM = 1024 ! ISC_RET_CONNECTION = 2048 ! ISC_RET_INTERMEDIATE_RETURN = 4096 ! ISC_RET_CALL_LEVEL = 8192 ! ISC_RET_EXTENDED_ERROR = 16384 ! ISC_RET_STREAM = 32768 ! ISC_RET_INTEGRITY = 65536 ! ISC_RET_IDENTIFY = 131072 ! ISC_RET_NULL_SESSION = 262144 ! ISC_RET_MANUAL_CRED_VALIDATION = 524288 ! ISC_RET_RESERVED1 = 1048576 ! ISC_RET_FRAGMENT_ONLY = 2097152 ! ASC_REQ_DELEGATE = 1 ! ASC_REQ_MUTUAL_AUTH = 2 ! ASC_REQ_REPLAY_DETECT = 4 ! ASC_REQ_SEQUENCE_DETECT = 8 ! ASC_REQ_CONFIDENTIALITY = 16 ! ASC_REQ_USE_SESSION_KEY = 32 ! ASC_REQ_ALLOCATE_MEMORY = 256 ! ASC_REQ_USE_DCE_STYLE = 512 ! ASC_REQ_DATAGRAM = 1024 ! ASC_REQ_CONNECTION = 2048 ! ASC_REQ_CALL_LEVEL = 4096 ! ASC_REQ_EXTENDED_ERROR = 32768 ! ASC_REQ_STREAM = 65536 ! ASC_REQ_INTEGRITY = 131072 ! ASC_REQ_LICENSING = 262144 ! ASC_REQ_IDENTIFY = 524288 ! ASC_REQ_ALLOW_NULL_SESSION = 1048576 ! ASC_REQ_ALLOW_NON_USER_LOGONS = 2097152 ! ASC_REQ_ALLOW_CONTEXT_REPLAY = 4194304 ! ASC_REQ_FRAGMENT_TO_FIT = 8388608 ! ASC_REQ_FRAGMENT_SUPPLIED = 8192 ! ASC_REQ_NO_TOKEN = 16777216 ! ASC_RET_DELEGATE = 1 ! ASC_RET_MUTUAL_AUTH = 2 ! ASC_RET_REPLAY_DETECT = 4 ! ASC_RET_SEQUENCE_DETECT = 8 ! ASC_RET_CONFIDENTIALITY = 16 ! ASC_RET_USE_SESSION_KEY = 32 ! ASC_RET_ALLOCATED_MEMORY = 256 ! ASC_RET_USED_DCE_STYLE = 512 ! ASC_RET_DATAGRAM = 1024 ! ASC_RET_CONNECTION = 2048 ! ASC_RET_CALL_LEVEL = 8192 ! ASC_RET_THIRD_LEG_FAILED = 16384 ! ASC_RET_EXTENDED_ERROR = 32768 ! ASC_RET_STREAM = 65536 ! ASC_RET_INTEGRITY = 131072 ! ASC_RET_LICENSING = 262144 ! ASC_RET_IDENTIFY = 524288 ! ASC_RET_NULL_SESSION = 1048576 ! ASC_RET_ALLOW_NON_USER_LOGONS = 2097152 ! ASC_RET_ALLOW_CONTEXT_REPLAY = 4194304 ! ASC_RET_FRAGMENT_ONLY = 8388608 SECPKG_CRED_ATTR_NAMES = 1 *************** *** 190,195 **** SECPKG_NEGOTIATION_DIRECT = 3 SECPKG_NEGOTIATION_TRY_MULTICRED = 4 ! SECPKG_CONTEXT_EXPORT_RESET_NEW = 0x00000001 ! SECPKG_CONTEXT_EXPORT_DELETE_OLD = 0x00000002 SECQOP_WRAP_NO_ENCRYPT = (-2147483647) SECURITY_ENTRYPOINT_ANSIW = "InitSecurityInterfaceW" --- 190,195 ---- SECPKG_NEGOTIATION_DIRECT = 3 SECPKG_NEGOTIATION_TRY_MULTICRED = 4 ! SECPKG_CONTEXT_EXPORT_RESET_NEW = 1 ! SECPKG_CONTEXT_EXPORT_DELETE_OLD = 2 SECQOP_WRAP_NO_ENCRYPT = (-2147483647) SECURITY_ENTRYPOINT_ANSIW = "InitSecurityInterfaceW" *************** *** 206,281 **** SASL_OPTION_AUTHZ_STRING = 3 SASL_OPTION_AUTHZ_PROCESSING = 4 ! SEC_WINNT_AUTH_IDENTITY_ANSI = 0x1 ! SEC_WINNT_AUTH_IDENTITY_UNICODE = 0x2 ! SEC_WINNT_AUTH_IDENTITY_VERSION = 0x200 ! SEC_WINNT_AUTH_IDENTITY_MARSHALLED = 0x4 ! SEC_WINNT_AUTH_IDENTITY_ONLY = 0x8 SECPKG_OPTIONS_TYPE_UNKNOWN = 0 SECPKG_OPTIONS_TYPE_LSA = 1 SECPKG_OPTIONS_TYPE_SSPI = 2 ! SECPKG_OPTIONS_PERMANENT = 0x00000001 ! SEC_E_INSUFFICIENT_MEMORY = 0x80090300L ! SEC_E_INVALID_HANDLE = 0x80090301L ! SEC_E_UNSUPPORTED_FUNCTION = 0x80090302L ! SEC_E_TARGET_UNKNOWN = 0x80090303L ! SEC_E_INTERNAL_ERROR = 0x80090304L ! SEC_E_SECPKG_NOT_FOUND = 0x80090305L ! SEC_E_NOT_OWNER = 0x80090306L ! SEC_E_CANNOT_INSTALL = 0x80090307L ! SEC_E_INVALID_TOKEN = 0x80090308L ! SEC_E_CANNOT_PACK = 0x80090309L ! SEC_E_QOP_NOT_SUPPORTED = 0x8009030AL ! SEC_E_NO_IMPERSONATION = 0x8009030BL ! SEC_E_LOGON_DENIED = 0x8009030CL ! SEC_E_UNKNOWN_CREDENTIALS = 0x8009030DL ! SEC_E_NO_CREDENTIALS = 0x8009030EL ! SEC_E_MESSAGE_ALTERED = 0x8009030FL ! SEC_E_OUT_OF_SEQUENCE = 0x80090310L ! SEC_E_NO_AUTHENTICATING_AUTHORITY = 0x80090311L ! SEC_I_CONTINUE_NEEDED = 0x00090312L ! SEC_I_COMPLETE_NEEDED = 0x00090313L ! SEC_I_COMPLETE_AND_CONTINUE = 0x00090314L ! SEC_I_LOCAL_LOGON = 0x00090315L ! SEC_E_BAD_PKGID = 0x80090316L ! SEC_E_CONTEXT_EXPIRED = 0x80090317L ! SEC_I_CONTEXT_EXPIRED = 0x00090317L ! SEC_E_INCOMPLETE_MESSAGE = 0x80090318L ! SEC_E_INCOMPLETE_CREDENTIALS = 0x80090320L ! SEC_E_BUFFER_TOO_SMALL = 0x80090321L ! SEC_I_INCOMPLETE_CREDENTIALS = 0x00090320L ! SEC_I_RENEGOTIATE = 0x00090321L ! SEC_E_WRONG_PRINCIPAL = 0x80090322L ! SEC_I_NO_LSA_CONTEXT = 0x00090323L ! SEC_E_TIME_SKEW = 0x80090324L ! SEC_E_UNTRUSTED_ROOT = 0x80090325L ! SEC_E_ILLEGAL_MESSAGE = 0x80090326L ! SEC_E_CERT_UNKNOWN = 0x80090327L ! SEC_E_CERT_EXPIRED = 0x80090328L ! SEC_E_ENCRYPT_FAILURE = 0x80090329L ! SEC_E_DECRYPT_FAILURE = 0x80090330L ! SEC_E_ALGORITHM_MISMATCH = 0x80090331L ! SEC_E_SECURITY_QOS_FAILED = 0x80090332L ! SEC_E_UNFINISHED_CONTEXT_DELETED = 0x80090333L ! SEC_E_NO_TGT_REPLY = 0x80090334L ! SEC_E_NO_IP_ADDRESSES = 0x80090335L ! SEC_E_WRONG_CREDENTIAL_HANDLE = 0x80090336L ! SEC_E_CRYPTO_SYSTEM_INVALID = 0x80090337L ! SEC_E_MAX_REFERRALS_EXCEEDED = 0x80090338L ! SEC_E_MUST_BE_KDC = 0x80090339L ! SEC_E_STRONG_CRYPTO_NOT_SUPPORTED = 0x8009033AL ! SEC_E_TOO_MANY_PRINCIPALS = 0x8009033BL ! SEC_E_NO_PA_DATA = 0x8009033CL ! SEC_E_PKINIT_NAME_MISMATCH = 0x8009033DL ! SEC_E_SMARTCARD_LOGON_REQUIRED = 0x8009033EL ! SEC_E_SHUTDOWN_IN_PROGRESS = 0x8009033FL ! SEC_E_KDC_INVALID_REQUEST = 0x80090340L ! SEC_E_KDC_UNABLE_TO_REFER = 0x80090341L ! SEC_E_KDC_UNKNOWN_ETYPE = 0x80090342L ! SEC_E_UNSUPPORTED_PREAUTH = 0x80090343L ! SEC_E_DELEGATION_REQUIRED = 0x80090345L ! SEC_E_BAD_BINDINGS = 0x80090346L ! SEC_E_MULTIPLE_ACCOUNTS = 0x80090347L ! SEC_E_NO_KERB_KEY = 0x80090348L ERROR_IPSEC_QM_POLICY_EXISTS = 13000L --- 206,281 ---- SASL_OPTION_AUTHZ_STRING = 3 SASL_OPTION_AUTHZ_PROCESSING = 4 ! SEC_WINNT_AUTH_IDENTITY_ANSI = 1 ! SEC_WINNT_AUTH_IDENTITY_UNICODE = 2 ! SEC_WINNT_AUTH_IDENTITY_VERSION = 512 ! SEC_WINNT_AUTH_IDENTITY_MARSHALLED = 4 ! SEC_WINNT_AUTH_IDENTITY_ONLY = 8 SECPKG_OPTIONS_TYPE_UNKNOWN = 0 SECPKG_OPTIONS_TYPE_LSA = 1 SECPKG_OPTIONS_TYPE_SSPI = 2 ! SECPKG_OPTIONS_PERMANENT = 1 ! SEC_E_INSUFFICIENT_MEMORY = -2146893056 ! SEC_E_INVALID_HANDLE = -2146893055 ! SEC_E_UNSUPPORTED_FUNCTION = -2146893054 ! SEC_E_TARGET_UNKNOWN = -2146893053 ! SEC_E_INTERNAL_ERROR = -2146893052 ! SEC_E_SECPKG_NOT_FOUND = -2146893051 ! SEC_E_NOT_OWNER = -2146893050 ! SEC_E_CANNOT_INSTALL = -2146893049 ! SEC_E_INVALID_TOKEN = -2146893048 ! SEC_E_CANNOT_PACK = -2146893047 ! SEC_E_QOP_NOT_SUPPORTED = -2146893046 ! SEC_E_NO_IMPERSONATION = -2146893045 ! SEC_E_LOGON_DENIED = -2146893044 ! SEC_E_UNKNOWN_CREDENTIALS = -2146893043 ! SEC_E_NO_CREDENTIALS = -2146893042 ! SEC_E_MESSAGE_ALTERED = -2146893041 ! SEC_E_OUT_OF_SEQUENCE = -2146893040 ! SEC_E_NO_AUTHENTICATING_AUTHORITY = -2146893039 ! SEC_I_CONTINUE_NEEDED = 590610 ! SEC_I_COMPLETE_NEEDED = 590611 ! SEC_I_COMPLETE_AND_CONTINUE = 590612 ! SEC_I_LOCAL_LOGON = 590613 ! SEC_E_BAD_PKGID = -2146893034 ! SEC_E_CONTEXT_EXPIRED = -2146893033 ! SEC_I_CONTEXT_EXPIRED = 590615 ! SEC_E_INCOMPLETE_MESSAGE = -2146893032 ! SEC_E_INCOMPLETE_CREDENTIALS = -2146893024 ! SEC_E_BUFFER_TOO_SMALL = -2146893023 ! SEC_I_INCOMPLETE_CREDENTIALS = 590624 ! SEC_I_RENEGOTIATE = 590625 ! SEC_E_WRONG_PRINCIPAL = -2146893022 ! SEC_I_NO_LSA_CONTEXT = 590627 ! SEC_E_TIME_SKEW = -2146893020 ! SEC_E_UNTRUSTED_ROOT = -2146893019 ! SEC_E_ILLEGAL_MESSAGE = -2146893018 ! SEC_E_CERT_UNKNOWN = -2146893017 ! SEC_E_CERT_EXPIRED = -2146893016 ! SEC_E_ENCRYPT_FAILURE = -2146893015 ! SEC_E_DECRYPT_FAILURE = -2146893008 ! SEC_E_ALGORITHM_MISMATCH = -2146893007 ! SEC_E_SECURITY_QOS_FAILED = -2146893006 ! SEC_E_UNFINISHED_CONTEXT_DELETED = -2146893005 ! SEC_E_NO_TGT_REPLY = -2146893004 ! SEC_E_NO_IP_ADDRESSES = -2146893003 ! SEC_E_WRONG_CREDENTIAL_HANDLE = -2146893002 ! SEC_E_CRYPTO_SYSTEM_INVALID = -2146893001 ! SEC_E_MAX_REFERRALS_EXCEEDED = -2146893000 ! SEC_E_MUST_BE_KDC = -2146892999 ! SEC_E_STRONG_CRYPTO_NOT_SUPPORTED = -2146892998 ! SEC_E_TOO_MANY_PRINCIPALS = -2146892997 ! SEC_E_NO_PA_DATA = -2146892996 ! SEC_E_PKINIT_NAME_MISMATCH = -2146892995 ! SEC_E_SMARTCARD_LOGON_REQUIRED = -2146892994 ! SEC_E_SHUTDOWN_IN_PROGRESS = -2146892993 ! SEC_E_KDC_INVALID_REQUEST = -2146892992 ! SEC_E_KDC_UNABLE_TO_REFER = -2146892991 ! SEC_E_KDC_UNKNOWN_ETYPE = -2146892990 ! SEC_E_UNSUPPORTED_PREAUTH = -2146892989 ! SEC_E_DELEGATION_REQUIRED = -2146892987 ! SEC_E_BAD_BINDINGS = -2146892986 ! SEC_E_MULTIPLE_ACCOUNTS = -2146892985 ! SEC_E_NO_KERB_KEY = -2146892984 ERROR_IPSEC_QM_POLICY_EXISTS = 13000L *************** *** 404,408 **** CRYPT_E_STREAM_MSG_NOT_READY = ((-2146889712)) CRYPT_E_STREAM_INSUFFICIENT_DATA = ((-2146889711)) ! CRYPT_I_NEW_PROTECTION_REQUIRED = (0x00091012L) CRYPT_E_BAD_LEN = ((-2146885631)) CRYPT_E_BAD_ENCODE = ((-2146885630)) --- 404,408 ---- CRYPT_E_STREAM_MSG_NOT_READY = ((-2146889712)) CRYPT_E_STREAM_INSUFFICIENT_DATA = ((-2146889711)) ! CRYPT_I_NEW_PROTECTION_REQUIRED = (593938) CRYPT_E_BAD_LEN = ((-2146885631)) CRYPT_E_BAD_ENCODE = ((-2146885630)) |
From: Mark H. <mha...@us...> - 2005-03-07 01:19:16
|
Update of /cvsroot/pywin32/pywin32 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21860 Modified Files: setup.py Log Message: Insist on the Exchange 2000 SDK in order to build the exchange and mapi modules - ie, drop support for the VC6 MAPI libraries. This works with both VC6 and 7 and makes life simpler. Index: setup.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/setup.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** setup.py 25 Jan 2005 04:16:49 -0000 1.5 --- setup.py 7 Mar 2005 01:19:06 -0000 1.6 *************** *** 19,23 **** warnings; if you do use them, you must install the correct libraries. ! The 'axdebug' extension requires Active Debugging dev files available here: http://support.microsoft.com/default.aspx?kbid=223389 Download Scriptng.exe, unpack the files to a temporary directory and manually --- 19,28 ---- warnings; if you do use them, you must install the correct libraries. ! The 'mapi' and 'exchange' extensions require the Exchange 2000 SDK from: ! http://www.microsoft.com/downloads/details.aspx?FamilyID={guid} ! where guid is 4afe3504-c209-4a73-ac5d-ff2a4a3b48b7 ! Just install it - this setup script will automatically locate it. ! ! The 'axdebug' extension requires Active Debugging dev files available from: http://support.microsoft.com/default.aspx?kbid=223389 Download Scriptng.exe, unpack the files to a temporary directory and manually *************** *** 27,34 **** To install the pywin32 extensions, execute: python setup.py -q install ! This will install the built extensions into your site-packages directory, create an appropriate .pth file, and should leave everything ready to use. ! There should be no need to modify the registry. To build or install debug (_d) versions of these extensions, ensure you have --- 32,39 ---- To install the pywin32 extensions, execute: python setup.py -q install ! This will install the built extensions into your site-packages directory, create an appropriate .pth file, and should leave everything ready to use. ! There is no need to modify the registry. To build or install debug (_d) versions of these extensions, ensure you have *************** *** 220,223 **** --- 225,229 ---- # * Look for the Exchange SDK in the registry. # * Output directory is different than the module's basename. + # * Require use of the Exchange 2000 SDK - this works for both VC6 and 7 class WinExt_win32com_mapi(WinExt_win32com): def __init__ (self, name, **kw): *************** *** 244,253 **** if os.path.isdir(d): kw.setdefault("library_dirs", []).insert(0, d) ! # The stand-alone exchange SDK has these libs ! libs += " Ex2KSdk sadapi mapi32 netapi32" ! else: ! # The MSVC6 included exchange SDK has these libs ! libs += """ MBLOGON ADDRLKUP mapi32 exchinst ! EDKCFG EDKUTILS EDKMAPI ACLCLS""" kw["libraries"] = libs WinExt_win32com.__init__(self, name, **kw) --- 250,256 ---- if os.path.isdir(d): kw.setdefault("library_dirs", []).insert(0, d) ! ! # The stand-alone exchange SDK has these libs ! libs += " Ex2KSdk sadapi mapi32 netapi32" kw["libraries"] = libs WinExt_win32com.__init__(self, name, **kw) *************** *** 908,919 **** WinExt_win32com('internet'), WinExt_win32com('mapi', libraries="mapi32", pch_header="PythonCOM.h"), ! WinExt_win32com_mapi('exchange', ! libraries="""version""", ! extra_link_args=["/nodefaultlib:libc"]), ! WinExt_win32com_mapi('exchdapi', ! # This still needs work for vs.net. ! libraries="""DAPI ADDRLKUP exchinst EDKCFG EDKUTILS ! EDKMAPI mapi32 version""", ! extra_link_args=["/nodefaultlib:libc"]), WinExt_win32com('shell', libraries='shell32', pch_header="shell_pch.h"), WinExt_win32com('taskscheduler', libraries='mstask'), --- 911,916 ---- WinExt_win32com('internet'), WinExt_win32com('mapi', libraries="mapi32", pch_header="PythonCOM.h"), ! WinExt_win32com_mapi('exchange', libraries="version"), ! WinExt_win32com_mapi('exchdapi'), WinExt_win32com('shell', libraries='shell32', pch_header="shell_pch.h"), WinExt_win32com('taskscheduler', libraries='mstask'), |
From: Mark H. <mha...@us...> - 2005-03-06 23:56:11
|
Update of /cvsroot/pywin32/pywin32/win32/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1508 Modified Files: test_win32trace.py Log Message: Allow the test to pass even when another "writer" process is running (so long as it isn't actively writing during the test!) Index: test_win32trace.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/test/test_win32trace.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_win32trace.py 3 May 2004 01:56:29 -0000 1.4 --- test_win32trace.py 6 Mar 2005 23:55:59 -0000 1.5 *************** *** 22,25 **** --- 22,31 ---- class TestInitOps(unittest.TestCase): + def setUp(self): + # clear old data + win32trace.InitRead() + win32trace.read() + win32trace.TermRead() + def tearDown(self): try: *************** *** 59,66 **** # if we both Write and Read are terminated at the same time, ! # we lose the data is that acceptable? win32trace.TermWrite() win32trace.InitRead() ! self.assertEquals('', win32trace.read()) win32trace.TermRead() --- 65,74 ---- # if we both Write and Read are terminated at the same time, ! # we lose the data as the win32 object is closed. Note that ! # if another writer is running, we do *not* lose the data - so ! # test for either the correct data or an empty string win32trace.TermWrite() win32trace.InitRead() ! self.failUnless(win32trace.read() in ['Ta da', '']) win32trace.TermRead() *************** *** 77,80 **** --- 85,92 ---- def setUp(self): win32trace.InitRead() + # If any other writers are running (even if not actively writing), + # terminating the module will *not* close the handle, meaning old data + # will remain. This can cause other tests to fail. + win32trace.read() win32trace.InitWrite() *************** *** 141,144 **** --- 153,157 ---- WriterThread.BucketCount = self.BucketCount win32trace.InitRead() + win32trace.read() # clear any old data. win32trace.InitWrite() CheckNoOtherReaders() *************** *** 189,192 **** --- 202,206 ---- def setUp(self): win32trace.InitRead() + win32trace.read() # clear any old data win32trace.InitWrite() def testHugeChunks(self): |
From: Mark H. <mha...@us...> - 2005-03-06 23:27:39
|
Update of /cvsroot/pywin32/pywin32/win32 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25147 Modified Files: win32security.dsp Log Message: Some excellent sspi additions to win32security, and a number of tests and demos, originally from Roger Upole. Index: win32security.dsp =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/win32security.dsp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** win32security.dsp 1 Dec 2003 11:04:05 -0000 1.5 --- win32security.dsp 6 Mar 2005 23:26:59 -0000 1.6 *************** *** 124,127 **** --- 124,131 ---- # Begin Source File + SOURCE=.\src\win32security_sspi.cpp + # End Source File + # Begin Source File + SOURCE=.\src\win32securitymodule.cpp # End Source File |
From: Mark H. <mha...@us...> - 2005-03-06 23:27:12
|
Update of /cvsroot/pywin32/pywin32/win32/Demos/security/sspi In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25147/Demos/security/sspi Added Files: fetch_url.py simple_auth.py socket_server.py validate_password.py Log Message: Some excellent sspi additions to win32security, and a number of tests and demos, originally from Roger Upole. --- NEW FILE: simple_auth.py --- # A demo of basic SSPI authentication. # There is a 'client' context and a 'server' context - typically these will # be on different machines (here they are in the same process, but the same # concepts apply) import sspi import win32security, sspicon, win32api def lookup_ret_code(err): for k,v in sspicon.__dict__.items(): if k[0:6] in ('SEC_I_','SEC_E_') and v==err: return k """ pkg_name='Kerberos' sspiclient=SSPIClient(pkg_name, win32api.GetUserName(), ## target spn is ourself None, None, ## use none for client name and authentication information for current context ## u'username', (u'username',u'domain.com',u'passwd'), sspicon.ISC_REQ_INTEGRITY|sspicon.ISC_REQ_SEQUENCE_DETECT|sspicon.ISC_REQ_REPLAY_DETECT| \ sspicon.ISC_REQ_DELEGATE|sspicon.ISC_REQ_CONFIDENTIALITY|sspicon.ISC_REQ_USE_SESSION_KEY) sspiserver=SSPIServer(pkg_name, None, sspicon.ASC_REQ_INTEGRITY|sspicon.ASC_REQ_SEQUENCE_DETECT|sspicon.ASC_REQ_REPLAY_DETECT| \ sspicon.ASC_REQ_DELEGATE|sspicon.ASC_REQ_CONFIDENTIALITY|sspicon.ASC_REQ_STREAM|sspicon.ASC_REQ_USE_SESSION_KEY) """ pkg_name='NTLM' # Setup the 2 contexts. sspiclient=sspi.ClientAuth(pkg_name) sspiserver=sspi.ServerAuth(pkg_name) # Perform the authentication dance, each loop exchanging more information # on the way to completing authentication. sec_buffer=None while 1: err, sec_buffer = sspiclient.authorize(sec_buffer) err, sec_buffer = sspiserver.authorize(sec_buffer) if err==0: break # The server can now impersonate the client. In this demo the 2 users will # always be the same. sspiserver.ctxt.ImpersonateSecurityContext() print 'Impersonated user: ',win32api.GetUserNameEx(win32api.NameSamCompatible) sspiserver.ctxt.RevertSecurityContext() print 'Reverted to self: ',win32api.GetUserName() pkg_size_info=sspiclient.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_SIZES) # Now sign some data msg='some data to be encrypted ......' sigsize=pkg_size_info['MaxSignature'] sigbuf=win32security.SecBufferDescType() sigbuf.append(win32security.SecBufferType(len(msg), sspicon.SECBUFFER_DATA)) sigbuf.append(win32security.SecBufferType(sigsize, sspicon.SECBUFFER_TOKEN)) sigbuf[0].Buffer=msg sspiclient.ctxt.MakeSignature(0,sigbuf,1) sspiserver.ctxt.VerifySignature(sigbuf,1) # And finally encrypt some. trailersize=pkg_size_info['SecurityTrailer'] encbuf=win32security.SecBufferDescType() encbuf.append(win32security.SecBufferType(len(msg), sspicon.SECBUFFER_DATA)) encbuf.append(win32security.SecBufferType(trailersize, sspicon.SECBUFFER_TOKEN)) encbuf[0].Buffer=msg sspiclient.ctxt.EncryptMessage(0,encbuf,1) print 'Encrypted data:',repr(encbuf[0].Buffer) sspiserver.ctxt.DecryptMessage(encbuf,1) print 'Unencrypted data:',encbuf[0].Buffer --- NEW FILE: validate_password.py --- # Demonstrates how to validate a password. # See also MSKB article Q180548 import win32security import sys from sspi import ClientAuth, ServerAuth def validate(username, password, domain = ""): auth_info = username, domain, password ca = ClientAuth("NTLM", auth_info = auth_info) sa = ServerAuth("NTLM") data = err = None while err != 0: err, data = ca.authorize(data) err, data = sa.authorize(data) # If we get here without exception, we worked! if __name__=='__main__': if len(sys.argv) not in [3,4]: print "Usage: %s username password [domain]" % (__file__,) sys.exit(1) domain = "" # optional! if len(sys.argv)==4: domain = sys.argv[3] try: validate(sys.argv[1], sys.argv[2], domain) print "Validated OK" except win32security.error, details: hr, func, msg = details print "Validation failed: %s (%d)" % (msg, hr) --- NEW FILE: socket_server.py --- # A sample socket server and client, based on the standard MS samples # "Using SSPI with a Windows Sockets Client[/Server]" import sys import struct import SocketServer import win32api import httplib import win32security import sspi, sspicon # Send a simple "message" over a socket - send the number of bytes first, # then the string. Ditto for receive. def _send_msg(s, m): s.send(struct.pack("i", len(m))) s.send(m) def _get_msg(s): size_data = s.recv(struct.calcsize("i")) if not size_data: return None cb = struct.unpack("i", size_data)[0] return s.recv(cb) class SSPISocketServer(SocketServer.TCPServer): def __init__(self, *args, **kw): SocketServer.TCPServer.__init__(self, *args, **kw) self.sa = sspi.ServerAuth("NTLM") def verify_request(self, sock, ca): # Do the sspi auth dance self.sa.reset() while 1: data = _get_msg(sock) if data is None: return False err, sec_buffer = self.sa.authorize(data) if err==0: break _send_msg(sock, sec_buffer[0].Buffer) return True def process_request(self, request, client_address): # An example using the connection once it is established. print "The server is running as user", win32api.GetUserName() self.sa.ctxt.ImpersonateSecurityContext() try: print "Having conversation with client as user", win32api.GetUserName() while 1: data = _get_msg(request) if not data: break data = self.sa.decrypt(data) print "Client sent:", repr(data) finally: self.sa.ctxt.RevertSecurityContext() self.close_request(request) print "The server is back to user", win32api.GetUserName() def serve(): s = SSPISocketServer(("localhost", 8181), None) print "Running test server..." s.serve_forever() def sspi_client(): c = httplib.HTTPConnection("localhost", 8181) c.connect() # Do the auth dance. ca = sspi.ClientAuth("NTLM") data = None while 1: err, out_buf = ca.authorize(data) _send_msg(c.sock, out_buf[0].Buffer) if err==0: break data = _get_msg(c.sock) print "Auth dance complete - sending single encryted message" # Assume out data is sensitive - encrypt the message. _send_msg(c.sock, ca.encrypt("Hello")) c.sock.close() print "Client completed." if __name__=='__main__': command = "" if len(sys.argv)>1: command = sys.argv[1] if command == "client": sspi_client() elif command == "server": serve() else: print "You must execute this with either 'client' or 'server'" print "Start an instance with 'server', then connect to it with 'client'" print print "Running either the client or server as a different user is" print "recommended. A command-line such as the following may be useful:" try: un = win32api.GetUserNameEx(win32api.NameSamCompatible) except win32api.error: # not in a domain un = win32api.GetUserName() print "runas /user:%s {path_to}\python.exe {path_to}\%s client|server" % (un, __file__) --- NEW FILE: fetch_url.py --- """ Fetches a URL from a web-server supporting NTLM authentication eg, IIS. If no arguments are specified, a default of http://localhost/localstart.asp is used. This script does follow simple 302 redirections, so pointing at the root of an IIS server is should work. """ import sys import urllib import httplib import urlparse from base64 import encodestring, decodestring from sspi import ClientAuth import optparse # sorry, this demo needs 2.3+ options = None # set to optparse options object def open_url(host, url): h = httplib.HTTPConnection(host) # h.set_debuglevel(9) h.putrequest('GET', url) h.endheaders() resp = h.getresponse() print "Initial response is", resp.status, resp.reason body = resp.read() if resp.status == 302: # object moved url = "/" + resp.msg["location"] resp.close() h.putrequest('GET', url) h.endheaders() resp = h.getresponse() print "After redirect response is", resp.status, resp.reason if options.show_headers: print "Initial response headers:" for name, val in resp.msg.items(): print " %s: %s" % (name, val) if options.show_body: print body if resp.status == 401: # 401: Unauthorized - here is where the real work starts auth_info = None if options.user or options.domain or options.password: auth_info = options.user, options.domain, options.password ca = ClientAuth("NTLM", auth_info=auth_info) auth_scheme = ca.pkg_info['Name'] data = None while 1: err, out_buf = ca.authorize(data) data = out_buf[0].Buffer # Encode it as base64 as required by HTTP auth = encodestring(data).replace("\012", "") h.putrequest('GET', url) h.putheader('Authorization', auth_scheme + ' ' + auth) h.putheader('Content-Length', '0') h.endheaders() resp = h.getresponse() if options.show_headers: print "Token dance headers:" for name, val in resp.msg.items(): print " %s: %s" % (name, val) if err==0: break else: if resp.status != 401: print "Eeek - got response", resp.status cl = resp.msg.get("content-length") if cl: print repr(resp.read(int(cl))) else: print "no content!" assert resp.status == 401, resp.status assert not resp.will_close, "NTLM is per-connection - must not close" schemes = [s.strip() for s in resp.msg.get("WWW-Authenticate", "").split(",")] for scheme in schemes: if scheme.startswith(auth_scheme): data = decodestring(scheme[len(auth_scheme)+1:]) break else: print "Could not find scheme '%s' in schemes %r" % (auth_scheme, schemes) break resp.read() print "Final response status is", resp.status, resp.reason if resp.status == 200: # Worked! # Check we can read it again without re-authenticating. if resp.will_close: print "EEEK - response will close, but NTLM is per connection - it must stay open" body = resp.read() if options.show_body: print "Final response body:" print body h.putrequest('GET', url) h.endheaders() resp = h.getresponse() print "Second fetch response is", resp.status, resp.reason if options.show_headers: print "Second response headers:" for name, val in resp.msg.items(): print " %s: %s" % (name, val) resp.read(int(resp.msg.get("content-length", 0))) elif resp.status == 500: print "Error text" print resp.read() else: if options.show_body: cl = resp.msg.get("content-length") print resp.read(int(cl)) if __name__=='__main__': parser = optparse.OptionParser(description=__doc__) parser.add_option("", "--show-body", action="store_true", help="print the body of each response as it is received") parser.add_option("", "--show-headers", action="store_true", help="print the headers of each response as it is received") parser.add_option("", "--user", action="store", help="The username to login with") parser.add_option("", "--password", action="store", help="The password to login with") parser.add_option("", "--domain", action="store", help="The domain to login to") options, args = parser.parse_args() if not args: print "Run with --help for usage details" args = ["http://localhost/localstart.asp"] for url in args: scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) if (scheme != "http") or params or query or fragment: parser.error("Scheme must be http, URL must be simple") print "Opening '%s' from '%s'" % (path, netloc) r = open_url(netloc, path) |