From solarjoe at posteo.org Thu Aug 16 03:02:19 2018 From: solarjoe at posteo.org (Joe) Date: Thu, 16 Aug 2018 09:02:19 +0200 Subject: [python-win32] Using DirectShow API to access webcam Message-ID: Hello, I have a question an hope you can help me. I am trying to control a UVC webcam using the DirectShow API, but could not get anything to work. The question is already posted on StackOverflow: https://stackoverflow.com/questions/51843523/accessing-webcam-via-directshow-using-com-with-python I am not familiar with using CLSID, IID so playing with the few examples I found got my nowhere: # IID_IAMVideoProcAmp is C6E13360-30AC-11d0-A18C-00A0C9118956 from win32com.client import Dispatch from win32com.client.gencache import EnsureDispatch,GetClassForProgID, GetClassForCLSID, GetModuleForProgID, GetModuleForCLSID iid = '{c6e13360-30ac-11d0-a18c-00a0c9118956}' print(GetClassForCLSID(iid)) print(GetModuleForProgID(iid)) print(GetModuleForCLSID(iid)) CLSID = IID('{c6e13360-30ac-11d0-a18c-00a0c9118956}') print(CLSID) print(Dispatch(CLSID)) >>> pywintypes.com_error: (-2147220990, 'CONNECT_E_CANNOTCONNECT', None, >>> None) Could someone of you point me in the right direction and maybe put together a few lines to get me started? Kind regards, Joe From timr at probo.com Thu Aug 16 13:41:06 2018 From: timr at probo.com (Tim Roberts) Date: Thu, 16 Aug 2018 10:41:06 -0700 Subject: [python-win32] Using DirectShow API to access webcam In-Reply-To: References: Message-ID: Joe wrote: > > I have a question an hope you can help me. I am trying to control a > UVC webcam > using the DirectShow API, but could not get anything to work. > > The question is already posted on StackOverflow: > > https://stackoverflow.com/questions/51843523/accessing-webcam-via-directshow-using-com-with-python > > > I am not familiar with using CLSID, IID so playing with the few > examples I found > got my nowhere: > > # IID_IAMVideoProcAmp is C6E13360-30AC-11d0-A18C-00A0C9118956 > from win32com.client import Dispatch > from win32com.client.gencache import EnsureDispatch,GetClassForProgID, > GetClassForCLSID, GetModuleForProgID, GetModuleForCLSID > > iid = '{c6e13360-30ac-11d0-a18c-00a0c9118956}' > > print(GetClassForCLSID(iid)) > print(GetModuleForProgID(iid)) > print(GetModuleForCLSID(iid)) > > CLSID = IID('{c6e13360-30ac-11d0-a18c-00a0c9118956}') > print(CLSID) > > print(Dispatch(CLSID)) > >>>> pywintypes.com_error: (-2147220990, 'CONNECT_E_CANNOTCONNECT', >>>> None, None) > > Could someone of you point me in the right direction and maybe put > together a few lines to get me started? I am not entirely convinced it is possible to control DirectShow from Python, but I'll give you some general information. An "interface" in COM terms, described by an IID, is just a set of functions declarations.? It defines the things you can do with an object, but it is not actually an object.? A "CLSID", on the other hand, defines a COM object.? The CLSID doesn't tell you what the object can do, it's just a way of creating an object.? Once you have used a CLSID to create an object, you can ask it for an interface. So, you can't just create IID_IAMVideoProcAmp.? You have to ask an existing object for its IAMVideoProcAmp interface.? You would create your camera object, and then query the camera object for IAMVideoProcAmp. Creating a DirectShow graph is a multi-step process.? You create a filter graph, you add your camera to the graph, you tell the graph to render the stream (which means it automatically fills in the other filters), and you control it.? Here is some sample code that does this: ??? https://gist.github.com/dust8/3890196 This is actually more complicated than it needs to be, because it's trying to handle TV devices with tuner and audio filters as well. You don't need that.? Once you have a device from VideoInputDeviceCategory, you don't need the video decoder or the audio.? You can just render the graph at that point. Alternatively, it looks like this package might be more applicable: ??? http://videocapture.sourceforge.net/ -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 3980 bytes Desc: S/MIME Cryptographic Signature URL: From robin at reportlab.com Fri Aug 17 06:25:48 2018 From: robin at reportlab.com (Robin Becker) Date: Fri, 17 Aug 2018 11:25:48 +0100 Subject: [python-win32] LNK4197 error building c++ extension Message-ID: <3f5f7081-6747-699b-c407-29f31338548d@chamonix.reportlab.co.uk> I am not a great C++ person so as I am building my first C++ extension I am seeing this error which I don't understand > _aggstate.obj : warning LNK4197: export 'init_aggstate' specified multiple times; using first specification > Creating library build\temp.win-amd64-2.7\Release\_aggstate.lib and object build\temp.win-amd64-2.7\Release\_aggstate > .exp I looked in the preprecessor output(_aggstate.i) and see this single occurrence of aggstate_init > #line 1191 "_aggstate.cxx" > extern "C" __declspec(dllexport) void init_aggstate(void) > { > aggstate_init(); > } is this some feature of C++ or is there a real issue here? > creating build\lib.win-amd64-2.7 > c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\amd64\link.exe /DLL /nologo /INCREMENTAL:NO /LIBPATH:c:\python > 27\Libs /LIBPATH:C:\code\hg-repos\taggstate\libs /LIBPATH:C:\code\hg-repos\taggstate\PCbuild\amd64 /LIBPATH:C:\code\hg-r > epos\taggstate\PC\VS9.0\amd64 /EXPORT:init_aggstate build\temp.win-amd64-2.7\Release\_aggstate.obj build\temp.win-amd64- > 2.7\Release\agg25\src\agg_arc.obj build\temp.win-amd64-2.7\Release\agg25\src\agg_bezier_arc.obj build\temp.win-amd64-2.7 > \Release\agg25\src\agg_curves.obj build\temp.win-amd64-2.7\Release\agg25\src\agg_trans_affine.obj build\temp.win-amd64-2 > .7\Release\agg25\src\agg_vcgen_contour.obj build\temp.win-amd64-2.7\Release\agg25\src\agg_vcgen_stroke.obj /OUT:build\li > b.win-amd64-2.7\_aggstate.pyd /IMPLIB:build\temp.win-amd64-2.7\Release\_aggstate.lib /MANIFESTFILE:build\temp.win-amd64- > 2.7\Release\_aggstate.pyd.manifest > _aggstate.obj : warning LNK4197: export 'init_aggstate' specified multiple times; using first specification > Creating library build\temp.win-amd64-2.7\Release\_aggstate.lib and object build\temp.win-amd64-2.7\Release\_aggstate > .exp *PS this also occurs when compiling with 3.7, but there the initializer function is PyInit__aggstate -- Robin Becker From nulla.epistola at web.de Fri Aug 17 10:10:37 2018 From: nulla.epistola at web.de (Sibylle Koczian) Date: Fri, 17 Aug 2018 16:10:37 +0200 Subject: [python-win32] Python 3.7: difficulties importing adodbapi after installation Message-ID: Fresh install of Python 3.7 on Windows 10. Installed pywin32-223.win-amd64.py3.7.exe (from python.org) without error messages, but the adodbapi directory didn't contain apibase.py and so adodbapi couldn't be imported. Next step: "pip install adodbapi --upgrade" again seemed to work normally, but now 4 files contained line endings "\r\r\n": apibase.py is64bit.py process_connect_string.py server.py This caused an IndentationError at the first line continuation in apibase.py (whitespace after the \): line 249, pythonDateTimeConverter.DateObjectFromCOMDate, dte=datetime.datetime.fromordinal(integerPart + self._ordinal_1899_12_31) \ + datetime.timedelta(milliseconds=floatpart*86400000) I couldn't find differences to the module version in my Python 3.6 installation, other than the line endings, so I copied the 4 files from there. Last problem: now adodbapi missed ...\python37\lib\site-packages\win32com\gen_py\dicts.dat. The second exception in the traceback said something about missing rights, so I opened a Python shell as administrator and imported adodbapi there. That created the file. Now everything works as it should, but why the hassle? Greetings Sibylle From vernondcole at gmail.com Fri Aug 17 10:34:51 2018 From: vernondcole at gmail.com (Vernon D. Cole) Date: Fri, 17 Aug 2018 08:34:51 -0600 Subject: [python-win32] Python 3.7: difficulties importing adodbapi after installation In-Reply-To: References: Message-ID: The hassle is because I have not fulfilled my responsibility to keep adodbapi maintained properly for these last few years. I now work in a Linux shop and have almost nothing to do with databases, so my work on Windows database software keeps taking a back seat to other responsibilities. This weekend, I will finally have some time. That said: this is an open invitation for someone to step in and help out. On Fri, Aug 17, 2018 at 8:10 AM Sibylle Koczian wrote: > Fresh install of Python 3.7 on Windows 10. > > Installed pywin32-223.win-amd64.py3.7.exe (from python.org) without > error messages, but the adodbapi directory didn't contain apibase.py and > so adodbapi couldn't be imported. > > Next step: "pip install adodbapi --upgrade" again seemed to work > normally, but now 4 files contained line endings "\r\r\n": > apibase.py > is64bit.py > process_connect_string.py > server.py > This caused an IndentationError at the first line continuation in > apibase.py (whitespace after the \): > line 249, pythonDateTimeConverter.DateObjectFromCOMDate, > dte=datetime.datetime.fromordinal(integerPart + > self._ordinal_1899_12_31) \ > + datetime.timedelta(milliseconds=floatpart*86400000) > > I couldn't find differences to the module version in my Python 3.6 > installation, other than the line endings, so I copied the 4 files from > there. > > Last problem: now adodbapi missed > ...\python37\lib\site-packages\win32com\gen_py\dicts.dat. The second > exception in the traceback said something about missing rights, so I > opened a Python shell as administrator and imported adodbapi there. That > created the file. > > Now everything works as it should, but why the hassle? > > Greetings > Sibylle > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > https://mail.python.org/mailman/listinfo/python-win32 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From timr at probo.com Fri Aug 17 13:32:59 2018 From: timr at probo.com (Tim Roberts) Date: Fri, 17 Aug 2018 10:32:59 -0700 Subject: [python-win32] LNK4197 error building c++ extension In-Reply-To: <3f5f7081-6747-699b-c407-29f31338548d@chamonix.reportlab.co.uk> References: <3f5f7081-6747-699b-c407-29f31338548d@chamonix.reportlab.co.uk> Message-ID: <9565c95e-0d2c-6ee8-ed18-2c1ad3ef2679@probo.com> Robin Becker wrote: > I am not a great C++ person so as I am building my first C++ extension > I am seeing this error which I don't understand > > > _aggstate.obj : warning LNK4197: export 'init_aggstate' specified > multiple times; using first specification > >??? Creating library build\temp.win-amd64-2.7\Release\_aggstate.lib > and object build\temp.win-amd64-2.7\Release\_aggstate > > .exp It's not an error, it's a warning.? And this has nothing to do with C++.? Is this your own private project, or is it one I can go look up? > I looked in the preprecessor output(_aggstate.i) and see this single > occurrence of aggstate_init > >> #line 1191 "_aggstate.cxx" >> extern "C" __declspec(dllexport) void init_aggstate(void) >> { >> ???????? aggstate_init(); >> } > > is this some feature of C++ or is there a real issue here? My guess is that you have listed "init_aggstate" in the ".def" file that lists the exported functions.? That's the first export specification.? You are also using __declspec(dllexport) in the function definition, and that's the second export specification. When you use __declspec(dllexport), you don't need the ".def" file. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From solarjoe at posteo.org Fri Aug 17 02:09:06 2018 From: solarjoe at posteo.org (Joe) Date: Fri, 17 Aug 2018 08:09:06 +0200 Subject: [python-win32] Using DirectShow API to access webcam In-Reply-To: References: Message-ID: Hello Tim, thanks for your helpful answer and the explanations. Following up on your comment on http://videocapture.sourceforge.net/ I found that there is jaraco.video, which seems to be "a port of the VideoCapture module in pure Python using ctypes and comtypes." (https://github.com/jaraco/jaraco.video) It is using a 'DirectShow.tlb' file, whatever that is, to get the definitions into comtypes. https://github.com/jaraco/jaraco.video/blob/master/jaraco/video/api/__init__.py#L35 https://github.com/jaraco/jaraco.video/blob/master/jaraco/video/api/objects.py#L9 If your interested, I will post my progress on SO. Kind regards, Joe > > An "interface" in COM terms, described by an IID, is just a set of > functions declarations.? It defines the things you can do with an > object, but it is not actually an object.? A "CLSID", on the other > hand, defines a COM object.? The CLSID doesn't tell you what the > object can do, it's just a way of creating an object.? Once you have > used a CLSID to create an object, you can ask it for an interface. > > So, you can't just create IID_IAMVideoProcAmp.? You have to ask an > existing object for its IAMVideoProcAmp interface.? You would create > your camera object, and then query the camera object for > IAMVideoProcAmp. > > Creating a DirectShow graph is a multi-step process.? You create a > filter graph, you add your camera to the graph, you tell the graph to > render the stream (which means it automatically fills in the other > filters), and you control it.? Here is some sample code that does > this: > > ??? https://gist.github.com/dust8/3890196 > > This is actually more complicated than it needs to be, because it's > trying to handle TV devices with tuner and audio filters as well. You > don't need that.? Once you have a device from > VideoInputDeviceCategory, you don't need the video decoder or the > audio.? You can just render the graph at that point. > > Alternatively, it looks like this package might be more applicable: > > ??? http://videocapture.sourceforge.net/ > > _______________________________________________ > python-win32 mailing list > python-win32 at python.org > https://mail.python.org/mailman/listinfo/python-win32 From timr at probo.com Fri Aug 17 17:12:57 2018 From: timr at probo.com (Tim Roberts) Date: Fri, 17 Aug 2018 14:12:57 -0700 Subject: [python-win32] Using DirectShow API to access webcam In-Reply-To: References: Message-ID: Joe wrote: > > thanks for your helpful answer and the explanations. > Following up on your comment on http://videocapture.sourceforge.net/ > I found that there is jaraco.video, which seems to be > "a port of the VideoCapture module in pure Python using ctypes and > comtypes." > (https://github.com/jaraco/jaraco.video) > > It is using a 'DirectShow.tlb' file, whatever that is, to get the > definitions into comtypes. A TLB file is a "type library".? It is a compiled version of the IDL for a set of COM interfaces.? IDL is modified subset of C++ that is used to declare the functions within a COM interface, their parameters, and their types.? It is intended to be? a language-independent way to define the functions within an interface. Looks like you're on your way. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From Sibylle.Koczian at t-online.de Sun Aug 19 14:45:43 2018 From: Sibylle.Koczian at t-online.de (Sibylle Koczian) Date: Sun, 19 Aug 2018 20:45:43 +0200 Subject: [python-win32] Python 3.7: difficulties importing adodbapi after installation In-Reply-To: References: Message-ID: Hello, Am 17.08.2018 um 16:34 schrieb Vernon D. Cole: > The hassle is because I have not fulfilled my responsibility to keep > adodbapi maintained properly for these last few years. I now work in a > Linux shop and have almost nothing to do with databases, so my work on > Windows database software keeps taking a back seat to other > responsibilities.? This weekend, I will finally have some time. > Thank you for your answer - but now I've got something I really can't understand: I can connect to MS Access databases (*.mdb and *.accdb), and I can execute SELECT queries (didn't try any writing to the databases yet) - as long as the field list doesn't contain a DateTime field. If it does, then the query is executed, but as soon as I try to get to the results, the program simply finishes. No error message of any kind, and if the call to curs.fetchall() (or a loop "for record in curs: ...") is enclosed in try ... finally, then not even the "finally" part seems to be reached. This is new. Using Python 3.6 and earlier versions queries with DateTime fields in the field list had the expected results. The same queries using pyodbc are executed correctly. Script to try this (needs database and table informations, of course): ##################################################################### import logging import adodbapi # Connection information cConnform = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};" cDatabase = r"X:\Path\to\database\db.accdb" # or db.mdb sql_nodate = """SELECT ID, Item FROM mytable WHERE ID > ?""" sql_date = """SELECT ID, Item, datefield FROM mytable WHERE ID > ?""" def exec_query(sql, params, conn): curs = conn.cursor() try: curs.execute(sql, params) logging.debug("Query executed: %s, Parameter: %s", sql, params) result = curs.fetchall() logging.debug("Results: %d", len(result)) finally: logging.debug("Cursor closed.") curs.close() return result def test(connstr): testid = 700 # must be adapted conn = adodbapi.connect(connstr) try: nodate = exec_query(sql_nodate, (testid,), conn) logging.debug("Query without date field: %d records", len(nodate)) for record in nodate: print(record) withdate = exec_query(sql_date, (testid,), conn) logging.debug("Query with date field") for record in withdate: print(record) finally: conn.close() logging.debug("Fertig.") def main(): logging.basicConfig(level=logging.DEBUG) connstr = cConnform.format(cDatabase) test(connstr) if __name__ == "__main__": main() From robin at reportlab.com Tue Aug 21 08:59:34 2018 From: robin at reportlab.com (Robin Becker) Date: Tue, 21 Aug 2018 13:59:34 +0100 Subject: [python-win32] LNK4197 error building c++ extension In-Reply-To: <9565c95e-0d2c-6ee8-ed18-2c1ad3ef2679@probo.com> References: <3f5f7081-6747-699b-c407-29f31338548d@chamonix.reportlab.co.uk> <9565c95e-0d2c-6ee8-ed18-2c1ad3ef2679@probo.com> Message-ID: <6d07a222-9e6c-aebb-b282-fd23145c3bbd@chamonix.reportlab.co.uk> On 17/08/2018 18:32, Tim Roberts wrote: ......... > It's not an error, it's a warning.? And this has nothing to do with C++.? Is this your own private project, or is it one I can go > look up? > it's an experiment to see if the ageing libart_lgpl code which reportlab uses can be replaced with something based on antigrain so not yet public. However, I see a similar error in aggdraw (se eg https://github.com/pytroll/aggdraw). > >> I looked in the preprecessor output(_aggstate.i) and see this single occurrence of aggstate_init >> >>> #line 1191 "_aggstate.cxx" >>> extern "C" __declspec(dllexport) void init_aggstate(void) >>> { >>> ???????? aggstate_init(); >>> } >> >> is this some feature of C++ or is there a real issue here? > > My guess is that you have listed "init_aggstate" in the ".def" file that lists the exported functions.? That's the first export > specification. You are also using __declspec(dllexport) in the function definition, and that's the second export specification. > When you use __declspec(dllexport), you don't need the ".def" file. > I don't have a .def file; the compilation is being handled purely by python setup.py build_ext which might be creating a temporary one somehow, but I cannot find it. Needless to say this is happening only on windows. I have these in temp C:\code\hg-repos\taggstate\REPOS\aggstate>ls build\temp.win-amd64-2.7\Release _aggstate.exp _aggstate.obj agg25 _aggstate.lib _aggstate.pyd.manifest digging a bit deeper I find taht the problem comes from the exp file and the linker /EXPORT. It seems that the /EXPORT:init_aggstate can be suppressed for this build and the warning disappears, but something (I assume the exp) supplies the export. Certainly the pyd appears to work. -- Robin Becker From timr at probo.com Tue Aug 21 21:12:25 2018 From: timr at probo.com (Tim Roberts) Date: Tue, 21 Aug 2018 18:12:25 -0700 Subject: [python-win32] LNK4197 error building c++ extension In-Reply-To: <6d07a222-9e6c-aebb-b282-fd23145c3bbd@chamonix.reportlab.co.uk> References: <3f5f7081-6747-699b-c407-29f31338548d@chamonix.reportlab.co.uk> <9565c95e-0d2c-6ee8-ed18-2c1ad3ef2679@probo.com> <6d07a222-9e6c-aebb-b282-fd23145c3bbd@chamonix.reportlab.co.uk> Message-ID: On Aug 21, 2018, at 5:59 AM, Robin Becker wrote: > > C:\code\hg-repos\taggstate\REPOS\aggstate>ls build\temp.win-amd64-2.7\Release > _aggstate.exp _aggstate.obj agg25 > _aggstate.lib _aggstate.pyd.manifest > > digging a bit deeper I find taht the problem comes from the exp file and the linker /EXPORT. It seems that the /EXPORT:init_aggstate can be suppressed for this build and the warning disappears, but something (I assume the exp) supplies the export. Certainly the pyd appears to work. Yes, the /EXPORT linker command is just an alias for the .def file. You need to mention the entry point EITHER (1) in a .def file, (2) in a /EXPORT, or (3) with a __declspec(dll export). One and one only. ? Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. From tfa.signup.test1 at gmail.com Mon Aug 27 07:23:50 2018 From: tfa.signup.test1 at gmail.com (Goku Balu) Date: Mon, 27 Aug 2018 16:53:50 +0530 Subject: [python-win32] Reg. taking folder ownership Message-ID: Hi, My use case is this. Folder1 is created by Admin1 and ACL is set by Admin1. Now Admin2 wants to change the ACL. I think we have two options here 1) Take folder ownership and the do the changes 2) Take elevated privileges for Admin2 account and add/remove ACL entries (Similar to "Run as Administrator" and using icalcs in cmd) I'm trying to solve this with the first approach. After Googling around, here is the code I'm trying to run for taking ownership from Admin1 and assign it to Admin2. import win32api import win32con import win32security import ntsecuritycon def take_owner(path,account_name): #print("sid=",sid) owner_sid = win32security.LookupAccountName(None, account_name)[0] new_privs = ( (win32security.LookupPrivilegeValue( '', ntsecuritycon.SE_RESTORE_NAME), win32con.SE_PRIVILEGE_ENABLED), (win32security.LookupPrivilegeValue( '', ntsecuritycon.SE_TAKE_OWNERSHIP_NAME), win32con.SE_PRIVILEGE_ENABLED)) flags = win32security.TOKEN_ALL_ACCESS\ | win32con.TOKEN_ADJUST_PRIVILEGES\ | win32con.TOKEN_IMPERSONATE try: thread = win32api.GetCurrentThread() handle = win32security.OpenThreadToken( thread, flags, False) except win32security.error as e: if e.errno == 1008: handle = win32security.OpenProcessToken(win32api.GetCurrentProcess (), flags) win32security.AdjustTokenPrivileges(handle, 0, new_privs) fs = win32security.GetFileSecurity( path, win32security.OWNER_SECURITY_INFORMATION) fs.SetSecurityDescriptorOwner(owner_sid, True) win32security.SetFileSecurity( path, win32security.OWNER_SECURITY_INFORMATION, fs) FILENAME = "D:\\Test" account_name=win32api.GetUserNameEx (win32con.NameSamCompatible) sd = win32security.GetFileSecurity (FILENAME, win32security.OWNER_SECURITY_INFORMATION) owner_sid = sd.GetSecurityDescriptorOwner () name, domain, type = win32security.LookupAccountSid (None, owner_sid) file_owner = domain+"\\"+name if account_name != file_owner: print("Account name and file owner is different") take_owner(FILENAME,account_name) else: print("Account name and file owner is Same") I'm getting (5, Access Denied) in SetFileSecurity. Am I missing something? Also I would like to know is this the right way of doing things? Thanks - Goku -------------- next part -------------- An HTML attachment was scrubbed... URL: From timr at probo.com Mon Aug 27 11:40:25 2018 From: timr at probo.com (Tim Roberts) Date: Mon, 27 Aug 2018 08:40:25 -0700 Subject: [python-win32] Reg. taking folder ownership In-Reply-To: References: Message-ID: <4ae8df4b-3cd5-1ff5-15b1-1aa32006f720@probo.com> Goku Balu wrote: > > My use case is this. Folder1 is created by Admin1 and ACL is set by > Admin1. Now Admin2 wants to change the ACL. I think we have two > options here > 1) Take folder ownership and the do the changes > 2) Take elevated privileges for Admin2 account and add/remove ACL > entries (Similar to "Run as Administrator" and using icalcs in cmd) > > I'm trying to solve this with the first approach. After Googling > around, here is the code I'm trying to run for taking ownership from > Admin1 and assign it to Admin2. The Windows file permission ecosystem makes my head hurt, so I'm going to avoid answering your exact question, but I would point out that Admin1 can change the ACL to give Admin2 the right to change the ACL.? In the file permission dialog, that's the "Change permissions" right.? In code, it's the "WRITE_DAC" file permission. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 3980 bytes Desc: S/MIME Cryptographic Signature URL: From eryksun at gmail.com Mon Aug 27 15:37:33 2018 From: eryksun at gmail.com (eryk sun) Date: Mon, 27 Aug 2018 14:37:33 -0500 Subject: [python-win32] Reg. taking folder ownership In-Reply-To: References: Message-ID: On Mon, Aug 27, 2018 at 6:23 AM, Goku Balu wrote: > > My use case is this. Folder1 is created by Admin1 and ACL is set by Admin1. > Now Admin2 wants to change the ACL. I think we have two options here > 1) Take folder ownership and the do the changes > 2) Take elevated privileges for Admin2 account and add/remove ACL entries If the current DACL doesn't grant Admin2 the right to change the owner or change the DACL (i.e. to acquire said right), then you'll need to either enable SeTakeOwnershipPrivilege or enable SeRestorePrivilege with backup semantics. Under UAC restriction, an administrator only has these privileges when elevated, so option (2) is your only choice. SeRestorePrivilege also allows setting the owner to an arbitrary user or group. Otherwise you can only set the owner to either the current user or any of the user's groups that have the group-owner flag (e.g. the administrators group). > win32security.AdjustTokenPrivileges(handle, 0, new_privs) This call will succeed even if one or more of the privileges wasn't modified. In this case GetLastError() returns ERROR_NOT_ALL_ASSIGNED (1300). This will be the case if you try to enable the take-ownership and restore privileges for a UAC restricted token. > fs = win32security.GetFileSecurity( > path, win32security.OWNER_SECURITY_INFORMATION) > fs.SetSecurityDescriptorOwner(owner_sid, True) > > win32security.SetFileSecurity( > path, win32security.OWNER_SECURITY_INFORMATION, fs) Use GetNamedSecurityInfo and SetNamedSecurityInfo instead. These newer functions handle inheritance correctly. They also open the file with backup semantics. The I/O manager grants all requested modify access (including write-owner) if backup semantics is combined with SeRestorePrivilege. In this case you don't need SeTakeOwnershipPrivilege. From tfa.signup.test1 at gmail.com Tue Aug 28 06:03:18 2018 From: tfa.signup.test1 at gmail.com (Goku Balu) Date: Tue, 28 Aug 2018 15:33:18 +0530 Subject: [python-win32] Reg. taking folder ownership In-Reply-To: References: Message-ID: > Eryk wrote: > This call will succeed even if one or more of the privileges wasn't > modified. In this case GetLastError() returns ERROR_NOT_ALL_ASSIGNED > (1300). This will be the case if you try to enable the take-ownership > and restore privileges for a UAC restricted token. Thanks Eryk for responding. Yes it failed with 1300 and I'm running the code from another admin account. But I think it's not a restricted account. I could run any exe with Admin elevated privilege by right clicking and choosing the option from context menu. I tried with just Take ownership privilege for the current admin user. I've changed the SetFileSecurity API to SetNamedSecurityInfo as suggested. Below is the code I tried running. Getting (5, Access Denied) for SetNamedSecurityInfo. Am I missing something? def take_owner(path,account_name): owner_sid = win32security.LookupAccountName(None, account_name)[0] new_privs = ( (win32security.LookupPrivilegeValue( '', ntsecuritycon.SE_TAKE_OWNERSHIP_NAME), win32con.SE_PRIVILEGE_ENABLED),) flags = win32security.TOKEN_ALL_ACCESS\ | win32con.TOKEN_ADJUST_PRIVILEGES\ | win32con.TOKEN_IMPERSONATE try: thread = win32api.GetCurrentThread() handle = win32security.OpenThreadToken( thread, flags, False) except win32security.error as e: # if e.errno == 1008: handle = win32security.OpenProcessToken(win32api.GetCurrentProcess (), flags) win32security.AdjustTokenPrivileges(handle, 0, new_privs) lastError = win32api.GetLastError() print("last error=",lastError) # fs = win32security.GetNamedSecurityInfo(path, win32security.SE_FILE_OBJECT, win32security.OWNER_SECURITY_INFORMATION) # fs.SetSecurityDescriptorOwner(owner_sid, True) win32security.SetNamedSecurityInfo(path, win32security.SE_FILE_OBJECT, win32security.OWNER_SECURITY_INFORMATION, owner_sid, None, None, None) > Tim Wrote: > Admin1 can change the ACL to give Admin2 the right to change the ACL.? > In the file permission dialog, that's the "Change permissions" right.? > In code, it's the "WRITE_DAC" file permission. @Tim Thanks for the tip. Regards, Goku -------------- next part -------------- An HTML attachment was scrubbed... URL: From eryksun at gmail.com Tue Aug 28 06:31:19 2018 From: eryksun at gmail.com (eryk sun) Date: Tue, 28 Aug 2018 05:31:19 -0500 Subject: [python-win32] Reg. taking folder ownership In-Reply-To: References: Message-ID: On Tue, Aug 28, 2018 at 5:03 AM, Goku Balu wrote: >> Eryk wrote: >> This call will succeed even if one or more of the privileges wasn't >> modified. In this case GetLastError() returns ERROR_NOT_ALL_ASSIGNED >> (1300). This will be the case if you try to enable the take-ownership >> and restore privileges for a UAC restricted token. > > Thanks Eryk for responding. Yes it failed with 1300 and I'm running the code > from another admin account. But I think it's not a restricted account. I > could run any exe with Admin elevated privilege by right clicking and > choosing the option from context menu. Under UAC, administrators get logged on with two tokens. The one that LSA returns is a limited token with medium integrity level, from which administrative privileges have been stripped and for which the administrators group is enabled only for deny access checks. This limited token is paired with an elevated token, which has high integrity, full administrative privileges, and the administrators group enabled for both allow and deny access checks. The elevated token can only be obtained by a user with SeTcbPrivilege, such as the SYSTEM account. Creating an elevated process is commonly handled by the Application Information service, which runs as SYSTEM. It displays the consent dialog on the secure (Winlogon) desktop, gets the elevated token, and creates the process via CreateProcessAsUser. Run Python elevated, enable SeRestorePrivilege, and use GetNamedSecurityInfo and SetNamedSecurityInfo. This will allow modifying the owner or DACL regardless of the current DACL, even if no access is specifically granted to administrators. From ktan at greenpeace.org Wed Aug 29 21:34:03 2018 From: ktan at greenpeace.org (Kairen Tan) Date: Wed, 29 Aug 2018 21:34:03 -0400 Subject: [python-win32] Writing event handlers Message-ID: Hi all, I?m trying to write some python to consume events from an Event Handler?.without much success. I?m using a class created using makepy, and on inspecting the file, there is a block of commented code like: # Event Handlers # If you create handlers, they should have the following prototypes: # def OnBeforeOpen(self, oRecord=defaultNamedNotOptArg): # def OnBeforeSave(self, oRecord=defaultNamedNotOptArg, bCancel=defaultNamedNotOptArg): # def OnAfterSave(self, oRecord=defaultNamedNotOptArg): # def OnBeforeDelete(self, oRecord=defaultNamedNotOptArg, bCancel=defaultNamedNotOptArg): # def OnCloseRecord(self): # def OnAfterDelete(self, lDatabaseID=defaultNamedNotOptArg, sImportID=defaultNamedNotOptArg): *My question is simply, how do I implement this? * I?ve tried using win32com.server.register.RegisterServer, but I?m stumped as to what comes after that. Thanks in advance! Kai -------------- next part -------------- An HTML attachment was scrubbed... URL: From timr at probo.com Thu Aug 30 13:11:26 2018 From: timr at probo.com (Tim Roberts) Date: Thu, 30 Aug 2018 10:11:26 -0700 Subject: [python-win32] Writing event handlers In-Reply-To: References: Message-ID: Kairen Tan wrote: > > I?m trying to write some python to consume events from an Event > Handler?.without much success. > > I?m using a class created using makepy, and on inspecting the file, > there is a block of commented code like: > > # Event Handlers > # If you create handlers, they should have the following prototypes: > #def OnBeforeOpen(self, oRecord=defaultNamedNotOptArg): > #def OnBeforeSave(self, oRecord=defaultNamedNotOptArg, > bCancel=defaultNamedNotOptArg): > #def OnAfterSave(self, oRecord=defaultNamedNotOptArg): > #def OnBeforeDelete(self, oRecord=defaultNamedNotOptArg, > bCancel=defaultNamedNotOptArg): > #def OnCloseRecord(self): > #def OnAfterDelete(self, lDatabaseID=defaultNamedNotOptArg, > sImportID=defaultNamedNotOptArg): > > *My question is simply, how do I implement this? * > * > * > I?ve tried using win32com.server.register.RegisterServer, but I?m > stumped as to what comes after that. It would have been helpful if you had told us what server you were trying to work with here. You don't need to register yourself as a server.? Registration is only needed if someone else is going to look for your object by its CLSID, but that's not the case here.? There's really no such thing as an "event handler" in COM.? I'm guessing that the server you're working with wants you to hand it a COM interface, and it will call methods of that COM interface when certain events occur. So, you need to use the magic _reg_ names so that win32com recognizes you as a COM object, but after that, all you should need to do is create an instance of your object, and pass it to whatever method your server uses to register the callback object. -- Tim Roberts, timr at probo.com Providenza & Boekelheide, Inc. -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 3980 bytes Desc: S/MIME Cryptographic Signature URL: