├── CHANGELOG.md ├── tox.ini ├── docs ├── html │ ├── _static │ │ ├── custom.css │ │ ├── up.png │ │ ├── down.png │ │ ├── file.png │ │ ├── minus.png │ │ ├── plus.png │ │ ├── comment.png │ │ ├── up-pressed.png │ │ ├── ajax-loader.gif │ │ ├── comment-close.png │ │ ├── down-pressed.png │ │ ├── comment-bright.png │ │ ├── documentation_options.js │ │ ├── pygments.css │ │ ├── doctools.js │ │ ├── underscore.js │ │ ├── basic.css │ │ ├── alabaster.css │ │ └── searchtools.js │ ├── objects.inv │ ├── _sources │ │ ├── modules.rst.txt │ │ ├── cwmi.rst.txt │ │ └── index.rst.txt │ ├── .buildinfo │ ├── searchindex.js │ ├── search.html │ ├── py-modindex.html │ ├── modules.html │ ├── index.html │ ├── genindex.html │ └── cwmi.html ├── modules.rst ├── doctrees │ ├── cwmi.doctree │ ├── index.doctree │ ├── modules.doctree │ └── environment.pickle ├── cwmi.rst ├── index.rst ├── Makefile ├── make.bat └── conf.py ├── setup.cfg ├── cwmi ├── wintype.py ├── com.py └── __init__.py ├── tests ├── test_wmi.py ├── test_com.py └── test_cwmi.py ├── examples ├── list_processes.py ├── create_process.py └── control_service.py ├── setup.py ├── Readme.md ├── LICENSE.txt └── utils └── i_to_m.py /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | v0.0.1 2 | ------ 3 | - Initial version -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = F403,F405 3 | max-line-length = 120 -------------------------------------------------------------------------------- /docs/html/_static/custom.css: -------------------------------------------------------------------------------- 1 | /* This file intentionally left blank. */ 2 | -------------------------------------------------------------------------------- /docs/html/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/html/objects.inv -------------------------------------------------------------------------------- /docs/html/_static/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/html/_static/up.png -------------------------------------------------------------------------------- /docs/modules.rst: -------------------------------------------------------------------------------- 1 | cwmi 2 | ===== 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | cwmi 8 | -------------------------------------------------------------------------------- /docs/doctrees/cwmi.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/doctrees/cwmi.doctree -------------------------------------------------------------------------------- /docs/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/doctrees/index.doctree -------------------------------------------------------------------------------- /docs/html/_static/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/html/_static/down.png -------------------------------------------------------------------------------- /docs/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/html/_static/file.png -------------------------------------------------------------------------------- /docs/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/html/_static/minus.png -------------------------------------------------------------------------------- /docs/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/html/_static/plus.png -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.md 3 | 4 | [flake8] 5 | max-line-length = 120 6 | -------------------------------------------------------------------------------- /docs/doctrees/modules.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/doctrees/modules.doctree -------------------------------------------------------------------------------- /docs/html/_static/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/html/_static/comment.png -------------------------------------------------------------------------------- /docs/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/doctrees/environment.pickle -------------------------------------------------------------------------------- /docs/html/_sources/modules.rst.txt: -------------------------------------------------------------------------------- 1 | cwmi 2 | ===== 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | cwmi 8 | -------------------------------------------------------------------------------- /docs/html/_static/up-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/html/_static/up-pressed.png -------------------------------------------------------------------------------- /docs/html/_static/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/html/_static/ajax-loader.gif -------------------------------------------------------------------------------- /docs/html/_static/comment-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/html/_static/comment-close.png -------------------------------------------------------------------------------- /docs/html/_static/down-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/html/_static/down-pressed.png -------------------------------------------------------------------------------- /docs/html/_static/comment-bright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireeye/cWMI/HEAD/docs/html/_static/comment-bright.png -------------------------------------------------------------------------------- /docs/cwmi.rst: -------------------------------------------------------------------------------- 1 | cwmi package 2 | ============= 3 | 4 | Module contents 5 | --------------- 6 | 7 | .. automodule:: cwmi 8 | :members: 9 | :undoc-members: 10 | :show-inheritance: 11 | -------------------------------------------------------------------------------- /docs/html/_sources/cwmi.rst.txt: -------------------------------------------------------------------------------- 1 | cwmi package 2 | ============= 3 | 4 | Module contents 5 | --------------- 6 | 7 | .. automodule:: cwmi 8 | :members: 9 | :undoc-members: 10 | :show-inheritance: 11 | -------------------------------------------------------------------------------- /docs/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: ceeb1358cd89ba1462043444393c62cb 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /docs/html/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_OPTIONS = { 2 | URL_ROOT: '', 3 | VERSION: '', 4 | LANGUAGE: 'None', 5 | COLLAPSE_INDEX: false, 6 | FILE_SUFFIX: '.html', 7 | HAS_SOURCE: true, 8 | SOURCELINK_SUFFIX: '.txt' 9 | }; -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. cWMI documentation master file, created by 2 | sphinx-quickstart on Wed May 9 15:00:19 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to cWMI's documentation! 7 | ================================= 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | 14 | 15 | Indices and tables 16 | ================== 17 | 18 | * :ref:`genindex` 19 | * :ref:`modindex` 20 | * :ref:`search` 21 | -------------------------------------------------------------------------------- /docs/html/_sources/index.rst.txt: -------------------------------------------------------------------------------- 1 | .. cWMI documentation master file, created by 2 | sphinx-quickstart on Wed May 9 15:00:19 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to cWMI's documentation! 7 | ================================= 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | 14 | 15 | Indices and tables 16 | ================== 17 | 18 | * :ref:`genindex` 19 | * :ref:`modindex` 20 | * :ref:`search` 21 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = cwmi 8 | SOURCEDIR = . 9 | BUILDDIR = . 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=. 12 | set SPHINXPROJ=cwmi 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /cwmi/wintype.py: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Copyright 2018 FireEye Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ######################################################################## 16 | 17 | import ctypes 18 | from ctypes import wintypes 19 | 20 | 21 | HRESULT = wintypes.LONG 22 | OLECHAR = wintypes.WCHAR 23 | BSTR = ctypes.POINTER(OLECHAR) 24 | CIMTYPE = wintypes.LONG 25 | -------------------------------------------------------------------------------- /tests/test_wmi.py: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Copyright 2018 FireEye Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ######################################################################## 16 | 17 | import unittest 18 | 19 | from cwmi import wmi 20 | 21 | 22 | class TestWMI(unittest.TestCase): 23 | 24 | def test_connect(self): 25 | """ 26 | Tests calling connect wrapper 27 | 28 | :return: None 29 | """ 30 | with wmi.WMI('root\\cimv2') as svc: 31 | assert svc 32 | 33 | 34 | if __name__ == '__main__': 35 | unittest.main() 36 | -------------------------------------------------------------------------------- /examples/list_processes.py: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Copyright 2018 FireEye Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ######################################################################## 16 | 17 | import cwmi 18 | 19 | 20 | def list_processes(): 21 | processes = cwmi.query('root\\cimv2', 'SELECT * FROM Win32_Process') 22 | print('NAME\t\tPROCESS ID') 23 | print('=' * 80) 24 | for process, values in processes.items(): 25 | print('{:s}\t\t{:d}'.format(values['Name'], values['ProcessId'])) 26 | 27 | 28 | if __name__ == '__main__': 29 | list_processes() 30 | -------------------------------------------------------------------------------- /examples/create_process.py: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Copyright 2018 FireEye Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ######################################################################## 16 | 17 | import argparse 18 | 19 | import cwmi 20 | 21 | 22 | def create_process(path): 23 | out = cwmi.call_method('root\\cimv2', 'Win32_Process', 'Create', {'CommandLine': path}) 24 | ret = out['ReturnValue'] 25 | if not ret: 26 | print('Process created successfully with process id of {:d}'.format(out['ProcessId'])) 27 | else: 28 | print('Process not created successfully, ERROR is {:d}'.format(ret)) 29 | 30 | 31 | if __name__ == '__main__': 32 | parser = argparse.ArgumentParser() 33 | parser.add_argument('--path', help='Full path to executable', required=True) 34 | parsed_args = parser.parse_args() 35 | create_process(parsed_args.path) 36 | -------------------------------------------------------------------------------- /docs/html/searchindex.js: -------------------------------------------------------------------------------- 1 | Search.setIndex({docnames:["cwmi","index","modules"],envversion:53,filenames:["cwmi.rst","index.rst","modules.rst"],objects:{"":{cwmi:[0,0,0,"-"]},cwmi:{call_method:[0,1,1,""],create_variant:[0,1,1,""],destroy_variant:[0,1,1,""],does_object_exist:[0,1,1,""],get_all_object_info:[0,1,1,""],get_method_info:[0,1,1,""],get_method_names:[0,1,1,""],get_object_info:[0,1,1,""],get_object_names:[0,1,1,""],obj_to_dict:[0,1,1,""],query:[0,1,1,""],safe_array_to_list:[0,1,1,""]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"]},objtypes:{"0":"py:module","1":"py:function"},terms:{"class":0,"int":0,"return":0,"true":0,"var":0,The:0,all:0,ani:0,api:0,arg:0,arrai:0,bool:0,call:0,call_method:0,connect:0,contain:0,content:2,convert:0,creat:0,create_vari:0,data:0,desir:0,destroi:0,destroy_vari:0,dict:0,dictionari:0,does_object_exist:0,element:0,element_typ:0,exist:0,fals:0,flag:0,from:0,get:0,get_all_object_info:0,get_method_info:0,get_method_nam:0,get_object_info:0,get_object_nam:0,given:0,includ:0,include_var_typ:0,index:1,info:0,inform:0,initi:0,input:0,input_param:0,instanc:0,list:0,method:0,method_nam:0,modul:[1,2],name:0,namespac:0,none:0,noth:0,obj:0,obj_nam:0,obj_path:0,obj_to_dict:0,object:0,packag:2,page:1,paramet:0,pass:0,password:0,path:0,perform:0,pull:0,python:0,queri:0,query_str:0,query_typ:0,remot:0,safe_arrai:0,safe_array_to_list:0,safearrai:0,search:1,str:0,string:0,structur:0,system:0,test:0,type:0,use:0,user:0,usernam:0,v_type:0,val:0,valu:0,variant:0,when:0,wmi:0,wql:0},titles:["cwmi package","Welcome to cWMI\u2019s documentation!","cwmi"],titleterms:{content:0,cwmi:[0,1,2],document:1,indic:1,modul:0,packag:0,tabl:1,welcom:1}}) -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Copyright 2017 FireEye Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ######################################################################## 16 | 17 | import platform 18 | from setuptools import setup 19 | 20 | 21 | system = platform.system() 22 | if system != 'Windows': 23 | print('ERROR: Cannot install this module on {:s}. This package is compatible with Windows only'.format(system)) 24 | exit(-1) 25 | 26 | 27 | setup(name='cwmi', 28 | version='0.1.0', 29 | description='ctypes wrapper for WMI', 30 | author='Anthony Berglund', 31 | author_email='anthony.berglund@fireeye.com', 32 | url='https://github.com/fireeye/cwmi', 33 | download_url='https://github.com/fireeye/cwmi/archive/v0.0.1.tar.gz', 34 | platforms=['Windows'], 35 | license='Apache', 36 | packages=['cwmi'], 37 | scripts=['utils/i_to_m.py'], 38 | classifiers=['Environment :: Console', 39 | 'Operating System :: Microsoft :: Windows', 40 | 'License :: OSI Approved :: Apache Software License', 41 | 'Programming Language :: Python :: 3', 42 | 'Programming Language :: Python :: 2.7', 43 | 'Topic :: Software Development :: Libraries'] 44 | ) 45 | -------------------------------------------------------------------------------- /examples/control_service.py: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Copyright 2018 FireEye Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ######################################################################## 16 | 17 | import sys 18 | import argparse 19 | 20 | import cwmi 21 | 22 | 23 | def control_service(service_name, action): 24 | svc_name = 'Win32_Service.Name="{:s}"'.format(service_name) 25 | if action == 'START': 26 | method_name = 'StartService' 27 | elif action == 'STOP': 28 | method_name = 'StopService' 29 | elif action == 'PAUSE': 30 | method_name = 'PauseService' 31 | else: 32 | method_name = 'ResumeService' 33 | 34 | print('Attempting to {:s} {:s} service'.format(action, service_name)) 35 | out = cwmi.call_method('root\\cimv2', svc_name, method_name, None) 36 | ret = out['ReturnValue'] 37 | if not ret: 38 | print('Service state changed successfully') 39 | else: 40 | print('Service state not changed successfully, ERROR is {:d}'.format(ret)) 41 | 42 | 43 | if __name__ == '__main__': 44 | parser = argparse.ArgumentParser() 45 | parser.add_argument('--service', help='Service short name', required=True) 46 | parser.add_argument('--action', help='Action [START|STOP|PAUSE|RESUME]', required=True) 47 | parsed_args = parser.parse_args() 48 | if parsed_args.action != 'START' and \ 49 | parsed_args.action != 'STOP' and \ 50 | parsed_args.action != 'PAUSE' and \ 51 | parsed_args.action != 'RESUME': 52 | print('Action must be one of [START|STOP|PAUSE|RESUME]') 53 | sys.exit(-1) 54 | control_service(parsed_args.service, parsed_args.action) 55 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # cWMI 2 | This project is a lightweight wrapper for interacting with WMI using python/ctypes without any external dependencies. It allows a lower level of interaction with WMI, but requires a greater knowledge of WMI internals. There are several helpers included that will come in handy for those who don't need to do anything low level, or just want a quick start. 3 | 4 | This project was not intended to be a replacement for the existing (and very good) `wmi` module, but as a pure python alternative without additional dependencies. 5 | 6 | ## Usage 7 | 8 | To use this module `import cwmi` and either use the helper functions, or the WMI APIs directly. 9 | 10 | Easy way, using helper functions. 11 | 12 | ``` 13 | import cwmi 14 | 15 | 16 | def list_processes(): 17 | processes = cwmi.query('root\\cimv2', 'SELECT * FROM Win32_Process') 18 | print('NAME\t\tPROCESS ID') 19 | print('=' * 80) 20 | for process, values in processes.items(): 21 | print('{:s}\t\t{:d}'.format(values['Name'], values['ProcessId'])) 22 | ``` 23 | 24 | Not as easy way, directly interacting with WMI APIs. 25 | 26 | ``` 27 | import cwmi 28 | 29 | def list_processes(): 30 | with cwmi.WMI('root\\cimv2') as svc: 31 | with svc.ExecQuery('WQL', 'SELECT * FROM Win32_Process', 0, None) as enum: 32 | 33 | print('NAME\t\tPROCESS ID') 34 | while True: 35 | try: 36 | with enum.Next(cwmi.WBEM_INFINITE) as obj: 37 | obj.BeginEnumeration(0) 38 | proc_data = {} 39 | while True: 40 | try: 41 | prop_name, var, _, _ = obj.Next(0) 42 | proc_data[prop_name] = cwmi.V_TO_TYPE(var) 43 | except WindowsError: 44 | break 45 | 46 | obj.EndEnumeration() 47 | 48 | print('{:s}\t\t{:d}'.format(proc_data['Name'], 49 | proc_data['ProcessId'])) 50 | 51 | except WindowsError: 52 | break 53 | ``` 54 | 55 | For more examples see [examples](examples). 56 | 57 | Microsoft's [WMI documentation](https://docs.microsoft.com/en-us/windows/desktop/wmisdk/using-wmi) will be helpful if directly interacting with the APIs. 58 | 59 | Some things to note are that while the documentation specifies input pointer parameters to some methods, this will not be necessary when using the wrapper APIs. The wrappers also handle python `str` to `BSTR` conversion and resource management. 60 | -------------------------------------------------------------------------------- /docs/html/search.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | Search — cwmi documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
36 |
37 |
38 |
39 | 40 |

Search

41 |
42 | 43 |

44 | Please activate JavaScript to enable the search 45 | functionality. 46 |

47 |
48 |

49 | From here you can search these documents. Enter your search 50 | words into the box below and click "search". Note that the search 51 | function will automatically search for all of the words. Pages 52 | containing fewer words won't appear in the result list. 53 |

54 |
55 | 56 | 57 | 58 |
59 | 60 |
61 | 62 |
63 | 64 |
65 |
66 |
67 | 77 |
78 |
79 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /docs/html/py-modindex.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | Python Module Index — cwmi documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 |
37 |
38 | 39 | 40 |

Python Module Index

41 | 42 |
43 | c 44 |
45 | 46 | 47 | 48 | 50 | 51 | 52 | 55 |
 
49 | c
53 | cwmi 54 |
56 | 57 | 58 |
59 |
60 |
61 | 83 |
84 |
85 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /tests/test_com.py: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Copyright 2018 FireEye Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ######################################################################## 16 | 17 | import unittest 18 | 19 | from cwmi import com 20 | from cwmi import wmi 21 | from cwmi import winapi 22 | 23 | 24 | class TestCOM(unittest.TestCase): 25 | 26 | def setUp(self): 27 | self.instance = com.COM() 28 | self.instance.init() 29 | 30 | self.instance.initialize_security() 31 | 32 | def tearDown(self): 33 | self.instance.fini() 34 | 35 | def test_iunknown(self): 36 | """ 37 | Tests the IUnknown interface 38 | 39 | :return: None 40 | """ 41 | obj = self.instance.create_instance(winapi.CLSID_WbemLocator, 42 | None, 43 | com.CLSCTX_INPROC_SERVER, 44 | winapi.IID_IWbemLocator, 45 | com.IUnknown) 46 | obj.QueryInterface(winapi.IID_IWbemLocator) 47 | count = obj.AddRef() 48 | assert count == 3 49 | count = obj.Release() 50 | assert count == 2 51 | count = obj.Release() 52 | assert count == 1 53 | count = obj.Release() 54 | assert count == 0 55 | 56 | def test_com_create_instance(self): 57 | """ 58 | Tests the ability to create a COM object instance 59 | 60 | :return: None 61 | """ 62 | 63 | obj = self.instance.create_instance(winapi.CLSID_WbemLocator, 64 | None, 65 | com.CLSCTX_INPROC_SERVER, 66 | winapi.IID_IWbemLocator, 67 | wmi.IWbemLocator) 68 | assert obj.Release() == 0 69 | 70 | def test_com_set_proxy_blanket(self): 71 | """ 72 | Tests the ability to set security on object 73 | 74 | :return: None 75 | """ 76 | 77 | locator = self.instance.create_instance(winapi.CLSID_WbemLocator, 78 | None, 79 | com.CLSCTX_INPROC_SERVER, 80 | winapi.IID_IWbemLocator, 81 | wmi.IWbemLocator) 82 | assert locator.this 83 | 84 | svc = locator.ConnectServer('root\\cimv2', None, None, None, 0, None, None) 85 | assert svc.this 86 | self.instance.set_proxy_blanket(svc.this) 87 | assert locator.Release() == 0 88 | assert svc.Release() == 0 89 | 90 | 91 | if __name__ == '__main__': 92 | unittest.main() 93 | -------------------------------------------------------------------------------- /docs/html/modules.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | cwmi — cwmi documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
30 |
31 | 32 |
33 |

cwmi

34 |
35 | 41 |
42 |
43 | 44 | 45 |
46 |
47 |
48 | 77 |
78 |
79 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /tests/test_cwmi.py: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Copyright 2018 FireEye Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ######################################################################## 16 | 17 | import ctypes 18 | import unittest 19 | 20 | import cwmi 21 | 22 | 23 | class TestCWMI(unittest.TestCase): 24 | 25 | def test_get_object_info(self): 26 | """ 27 | Tests calling get_object_info function 28 | 29 | :return: None 30 | """ 31 | info = cwmi.get_object_info('root\\cimv2', 'Win32_BaseBoard.Tag="Base Board"', ['Caption']) 32 | assert info 33 | 34 | def test_get_all_object_info(self): 35 | """ 36 | Tests calling get_all_object_info function 37 | 38 | :return: None 39 | """ 40 | info = cwmi.get_all_object_info('root\\cimv2', 'Win32_BaseBoard.Tag="Base Board"') 41 | assert info 42 | 43 | def test_get_object_names(self): 44 | """ 45 | Tests calling get_object_names function 46 | 47 | :return: None 48 | """ 49 | names = cwmi.get_object_names('root\\cimv2', 'Win32_BaseBoard.Tag="Base Board"') 50 | assert names 51 | 52 | def test_query(self): 53 | """ 54 | Tests calling query function 55 | 56 | :return: None 57 | """ 58 | info = cwmi.query('root\\cimv2', 'SELECT * FROM Win32_BaseBoard') 59 | assert info 60 | assert len(info) == 1 61 | 62 | def test_does_object_exist(self): 63 | """ 64 | Tests calling does_object_exist function 65 | 66 | :return: None 67 | """ 68 | assert cwmi.does_object_exist('root\\cimv2', 'Win32_BaseBoard.Tag="Base Board"') 69 | assert not cwmi.does_object_exist('root\\cimv2', 'Win32_BaseBoard.Tag="Fake Base Board"') 70 | 71 | def test_get_method_names(self): 72 | """ 73 | Tests calling get_method_names function 74 | 75 | :return: None 76 | """ 77 | names = cwmi.get_method_names('root\\cimv2', 'Win32_Process') 78 | assert names 79 | 80 | def test_get_method_info(self): 81 | """ 82 | Tests calling get_method_info function 83 | 84 | :return: None 85 | """ 86 | info = cwmi.get_method_info('root\\cimv2', 'Win32_Process') 87 | assert info 88 | 89 | def test_call_method(self): 90 | """ 91 | Tests calling call_method function 92 | 93 | :return: None 94 | """ 95 | out = cwmi.call_method('root\\cimv2', 96 | 'Win32_Process', 97 | 'Create', 98 | {'CommandLine': 'c:\\windows\\system32\\notepad.exe'}) 99 | assert out 100 | assert not out['ReturnValue'] 101 | pid = out['ProcessId'] 102 | handle = ctypes.windll.kernel32.OpenProcess(1, False, pid) 103 | ctypes.windll.kernel32.TerminateProcess(handle, 0) 104 | ctypes.windll.kernel32.CloseHandle(handle) 105 | 106 | if __name__ == '__main__': 107 | unittest.main() 108 | -------------------------------------------------------------------------------- /docs/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | Welcome to cWMI’s documentation! — cwmi documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
30 |
31 | 32 |
33 |

Welcome to cWMI’s documentation!

34 |
35 |
36 |
37 |
38 |

Indices and tables

39 | 44 |
45 | 46 | 47 |
48 |
49 |
50 | 85 |
86 |
87 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /docs/html/_static/pygments.css: -------------------------------------------------------------------------------- 1 | .highlight .hll { background-color: #ffffcc } 2 | .highlight { background: #eeffcc; } 3 | .highlight .c { color: #408090; font-style: italic } /* Comment */ 4 | .highlight .err { border: 1px solid #FF0000 } /* Error */ 5 | .highlight .k { color: #007020; font-weight: bold } /* Keyword */ 6 | .highlight .o { color: #666666 } /* Operator */ 7 | .highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ 8 | .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ 9 | .highlight .cp { color: #007020 } /* Comment.Preproc */ 10 | .highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ 11 | .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ 12 | .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ 13 | .highlight .gd { color: #A00000 } /* Generic.Deleted */ 14 | .highlight .ge { font-style: italic } /* Generic.Emph */ 15 | .highlight .gr { color: #FF0000 } /* Generic.Error */ 16 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 17 | .highlight .gi { color: #00A000 } /* Generic.Inserted */ 18 | .highlight .go { color: #333333 } /* Generic.Output */ 19 | .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ 20 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 21 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 22 | .highlight .gt { color: #0044DD } /* Generic.Traceback */ 23 | .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ 24 | .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ 25 | .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ 26 | .highlight .kp { color: #007020 } /* Keyword.Pseudo */ 27 | .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ 28 | .highlight .kt { color: #902000 } /* Keyword.Type */ 29 | .highlight .m { color: #208050 } /* Literal.Number */ 30 | .highlight .s { color: #4070a0 } /* Literal.String */ 31 | .highlight .na { color: #4070a0 } /* Name.Attribute */ 32 | .highlight .nb { color: #007020 } /* Name.Builtin */ 33 | .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ 34 | .highlight .no { color: #60add5 } /* Name.Constant */ 35 | .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ 36 | .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ 37 | .highlight .ne { color: #007020 } /* Name.Exception */ 38 | .highlight .nf { color: #06287e } /* Name.Function */ 39 | .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ 40 | .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ 41 | .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ 42 | .highlight .nv { color: #bb60d5 } /* Name.Variable */ 43 | .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ 44 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 45 | .highlight .mb { color: #208050 } /* Literal.Number.Bin */ 46 | .highlight .mf { color: #208050 } /* Literal.Number.Float */ 47 | .highlight .mh { color: #208050 } /* Literal.Number.Hex */ 48 | .highlight .mi { color: #208050 } /* Literal.Number.Integer */ 49 | .highlight .mo { color: #208050 } /* Literal.Number.Oct */ 50 | .highlight .sa { color: #4070a0 } /* Literal.String.Affix */ 51 | .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ 52 | .highlight .sc { color: #4070a0 } /* Literal.String.Char */ 53 | .highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ 54 | .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ 55 | .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ 56 | .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ 57 | .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ 58 | .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ 59 | .highlight .sx { color: #c65d09 } /* Literal.String.Other */ 60 | .highlight .sr { color: #235388 } /* Literal.String.Regex */ 61 | .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ 62 | .highlight .ss { color: #517918 } /* Literal.String.Symbol */ 63 | .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ 64 | .highlight .fm { color: #06287e } /* Name.Function.Magic */ 65 | .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ 66 | .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ 67 | .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ 68 | .highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ 69 | .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Configuration file for the Sphinx documentation builder. 4 | # 5 | # This file does only contain a selection of the most common options. For a 6 | # full list see the documentation: 7 | # http://www.sphinx-doc.org/en/master/config 8 | 9 | # -- Path setup -------------------------------------------------------------- 10 | 11 | # If extensions (or modules to document with autodoc) are in another directory, 12 | # add these directories to sys.path here. If the directory is relative to the 13 | # documentation root, use os.path.abspath to make it absolute, like shown here. 14 | # 15 | import os 16 | import sys 17 | sys.path.insert(0, os.path.abspath('../')) 18 | 19 | 20 | # -- Project information ----------------------------------------------------- 21 | 22 | project = 'cwmi' 23 | copyright = '2018, FireEye' 24 | author = 'ICE' 25 | 26 | # The short X.Y version 27 | version = '' 28 | # The full version, including alpha/beta/rc tags 29 | release = '' 30 | 31 | 32 | # -- General configuration --------------------------------------------------- 33 | 34 | # If your documentation needs a minimal Sphinx version, state it here. 35 | # 36 | # needs_sphinx = '1.0' 37 | 38 | # Add any Sphinx extension module names here, as strings. They can be 39 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 40 | # ones. 41 | extensions = [ 42 | 'sphinx.ext.autodoc' 43 | ] 44 | 45 | # Add any paths that contain templates here, relative to this directory. 46 | templates_path = ['_templates'] 47 | 48 | # The suffix(es) of source filenames. 49 | # You can specify multiple suffix as a list of string: 50 | # 51 | # source_suffix = ['.rst', '.md'] 52 | source_suffix = '.rst' 53 | 54 | # The master toctree document. 55 | master_doc = 'index' 56 | 57 | # The language for content autogenerated by Sphinx. Refer to documentation 58 | # for a list of supported languages. 59 | # 60 | # This is also used if you do content translation via gettext catalogs. 61 | # Usually you set "language" from the command line for these cases. 62 | language = None 63 | 64 | # List of patterns, relative to source directory, that match files and 65 | # directories to ignore when looking for source files. 66 | # This pattern also affects html_static_path and html_extra_path . 67 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] 68 | 69 | # The name of the Pygments (syntax highlighting) style to use. 70 | pygments_style = 'sphinx' 71 | 72 | 73 | # -- Options for HTML output ------------------------------------------------- 74 | 75 | # The theme to use for HTML and HTML Help pages. See the documentation for 76 | # a list of builtin themes. 77 | # 78 | html_theme = 'alabaster' 79 | 80 | # Theme options are theme-specific and customize the look and feel of a theme 81 | # further. For a list of options available for each theme, see the 82 | # documentation. 83 | # 84 | # html_theme_options = {} 85 | 86 | # Add any paths that contain custom static files (such as style sheets) here, 87 | # relative to this directory. They are copied after the builtin static files, 88 | # so a file named "default.css" will overwrite the builtin "default.css". 89 | html_static_path = ['_static'] 90 | 91 | # Custom sidebar templates, must be a dictionary that maps document names 92 | # to template names. 93 | # 94 | # The default sidebars (for documents that don't match any pattern) are 95 | # defined by theme itself. Builtin themes are using these templates by 96 | # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', 97 | # 'searchbox.html']``. 98 | # 99 | # html_sidebars = {} 100 | 101 | 102 | # -- Options for HTMLHelp output --------------------------------------------- 103 | 104 | # Output file base name for HTML help builder. 105 | htmlhelp_basename = 'cWMIdoc' 106 | 107 | 108 | # -- Options for LaTeX output ------------------------------------------------ 109 | 110 | latex_elements = { 111 | # The paper size ('letterpaper' or 'a4paper'). 112 | # 113 | # 'papersize': 'letterpaper', 114 | 115 | # The font size ('10pt', '11pt' or '12pt'). 116 | # 117 | # 'pointsize': '10pt', 118 | 119 | # Additional stuff for the LaTeX preamble. 120 | # 121 | # 'preamble': '', 122 | 123 | # Latex figure (float) alignment 124 | # 125 | # 'figure_align': 'htbp', 126 | } 127 | 128 | # Grouping the document tree into LaTeX files. List of tuples 129 | # (source start file, target name, title, 130 | # author, documentclass [howto, manual, or own class]). 131 | latex_documents = [ 132 | (master_doc, 'cWMI.tex', 'cWMI Documentation', 133 | 'ICE', 'manual'), 134 | ] 135 | 136 | 137 | # -- Options for manual page output ------------------------------------------ 138 | 139 | # One entry per manual page. List of tuples 140 | # (source start file, name, description, authors, manual section). 141 | man_pages = [ 142 | (master_doc, 'cwmi', 'cWMI Documentation', 143 | [author], 1) 144 | ] 145 | 146 | 147 | # -- Options for Texinfo output ---------------------------------------------- 148 | 149 | # Grouping the document tree into Texinfo files. List of tuples 150 | # (source start file, target name, title, author, 151 | # dir menu entry, description, category) 152 | texinfo_documents = [ 153 | (master_doc, 'cWMI', 'cWMI Documentation', 154 | author, 'cWMI', 'One line description of project.', 155 | 'Miscellaneous'), 156 | ] -------------------------------------------------------------------------------- /docs/html/genindex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | Index — cwmi documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
30 |
31 |
32 | 33 | 34 |

Index

35 | 36 |
37 | C 38 | | D 39 | | G 40 | | O 41 | | Q 42 | | S 43 | 44 |
45 |

C

46 | 47 | 51 | 57 |
58 | 59 |

D

60 | 61 | 65 | 69 |
70 | 71 |

G

72 | 73 | 79 | 87 |
88 | 89 |

O

90 | 91 | 95 |
96 | 97 |

Q

98 | 99 | 103 |
104 | 105 |

S

106 | 107 | 111 |
112 | 113 | 114 | 115 |
116 |
117 |
118 | 140 |
141 |
142 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /cwmi/com.py: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Copyright 2018 FireEye Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ######################################################################## 16 | 17 | import ctypes 18 | from ctypes import wintypes 19 | 20 | from . import winapi 21 | from .wintype import HRESULT 22 | 23 | 24 | _In_ = 1 25 | _Out_ = 2 26 | 27 | CLSCTX_INPROC_SERVER = 0x1 28 | CLSCTX_INPROC_HANDLER = 0x2 29 | CLSCTX_LOCAL_SERVER = 0x4 30 | CLSCTX_INPROC_SERVER16 = 0x8 31 | CLSCTX_REMOTE_SERVER = 0x10 32 | CLSCTX_INPROC_HANDLER16 = 0x20 33 | CLSCTX_RESERVED1 = 0x40 34 | CLSCTX_RESERVED2 = 0x80 35 | CLSCTX_RESERVED3 = 0x100 36 | CLSCTX_RESERVED4 = 0x200 37 | CLSCTX_NO_CODE_DOWNLOAD = 0x400 38 | CLSCTX_RESERVED5 = 0x800 39 | CLSCTX_NO_CUSTOM_MARSHAL = 0x1000 40 | CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000 41 | CLSCTX_NO_FAILURE_LOG = 0x4000 42 | CLSCTX_DISABLE_AAA = 0x8000 43 | CLSCTX_ENABLE_AAA = 0x10000 44 | CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000 45 | CLSCTX_ACTIVATE_32_BIT_SERVER = 0x40000 46 | CLSCTX_ACTIVATE_64_BIT_SERVER = 0x80000 47 | CLSCTX_ENABLE_CLOAKING = 0x100000 48 | CLSCTX_APPCONTAINER = 0x400000 49 | CLSCTX_ACTIVATE_AAA_AS_IU = 0x800000 50 | CLSCTX_PS_DLL = 0x80000000 51 | 52 | CLSCTX_SERVER = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER 53 | 54 | COINIT_MULTITHREADED = 0 55 | COINIT_APARTMENTTHREADED = 2 56 | 57 | IUnknown_QueryInterface_Idx = 0 58 | IUnknown_AddRef_Idx = 1 59 | IUnknown_Release_Idx = 2 60 | 61 | 62 | class ComClassInstance(ctypes.Structure): 63 | ''' 64 | COM instance class. This class represents an instantiated class. Class construction will fail a null pointer is 65 | passed into constructor. 66 | ''' 67 | def __init__(self, this): 68 | if not this: 69 | raise WindowsError('Could not construct {}'.format(self.__class__)) 70 | self.this = ctypes.cast(this, ctypes.POINTER(self.__class__)) 71 | ctypes.Structure.__init__(self) 72 | 73 | def __getattr__(self, item): 74 | if item == 'this': 75 | return self.this 76 | else: 77 | raise NameError(item) 78 | 79 | def __eq__(self, other): 80 | if isinstance(other, ComClassInstance): 81 | ret = self.this == other.this 82 | else: 83 | ret = self.this == other 84 | return ret 85 | 86 | def __ne__(self, other): 87 | if isinstance(other, ComClassInstance): 88 | ret = self.this != other.this 89 | else: 90 | ret = self.this != other 91 | return ret 92 | 93 | def __lt__(self, other): 94 | if isinstance(other, ComClassInstance): 95 | ret = self.this < other.this 96 | else: 97 | ret = self.this < other 98 | return ret 99 | 100 | def __le__(self, other): 101 | if isinstance(other, ComClassInstance): 102 | ret = self.this <= other.this 103 | else: 104 | ret = self.this <= other 105 | return ret 106 | 107 | def __gt__(self, other): 108 | if isinstance(other, ComClassInstance): 109 | ret = self.this > other.this 110 | else: 111 | ret = self.this > other 112 | return ret 113 | 114 | def __ge__(self, other): 115 | if isinstance(other, ComClassInstance): 116 | ret = self.this >= other.this 117 | else: 118 | ret = self.this >= other 119 | return ret 120 | 121 | 122 | class IUnknown(ComClassInstance): 123 | 124 | def __enter__(self): 125 | return self 126 | 127 | def __exit__(self, exc_type, exc_val, exc_tb): 128 | if self.AddRef() > 0: 129 | while self.Release(): 130 | pass 131 | 132 | def QueryInterface(self, riid): 133 | prototype = ctypes.WINFUNCTYPE(HRESULT, 134 | ctypes.POINTER(winapi.GUID), 135 | ctypes.POINTER(wintypes.LPVOID)) 136 | 137 | paramflags = ((_In_, 'riid'), 138 | (_Out_, 'ppvObject', ctypes.pointer(wintypes.LPVOID(None))) 139 | ) 140 | 141 | _QueryInterface = prototype(IUnknown_QueryInterface_Idx, 142 | 'QueryInterface', 143 | paramflags) 144 | _QueryInterface.errcheck = winapi.RAISE_NON_ZERO_ERR 145 | return_ptr = _QueryInterface(self.this, 146 | ctypes.byref(riid)) 147 | return IUnknown(return_ptr.contents) 148 | 149 | def AddRef(self): 150 | prototype = ctypes.WINFUNCTYPE(wintypes.LONG) 151 | paramflags = () 152 | _AddRef = prototype(IUnknown_AddRef_Idx, 153 | 'AddRef', 154 | paramflags) 155 | return _AddRef(self.this) 156 | 157 | def Release(self): 158 | prototype = ctypes.WINFUNCTYPE(wintypes.LONG) 159 | paramflags = () 160 | _Release = prototype(IUnknown_Release_Idx, 161 | 'Release', 162 | paramflags) 163 | return _Release(self.this) 164 | 165 | 166 | class COM(object): 167 | ''' 168 | COM wrapper class. Wraps COM initialization / uninitialization via ctxmgr. 169 | 170 | N.B. If using this class, do not call init() and fini() directly. Only use through via ctxmgr 171 | ''' 172 | def __init__(self, coinit=COINIT_MULTITHREADED): 173 | self._coinit = coinit 174 | self._initialized = False 175 | 176 | def __enter__(self): 177 | self.init() 178 | return self 179 | 180 | def __exit__(self, exc_type, exc_val, exc_tb): 181 | self.fini() 182 | 183 | def init(self): 184 | winapi.CoInitializeEx(None, self._coinit) 185 | self._initialized = True 186 | 187 | def fini(self): 188 | if self._initialized is True: 189 | winapi.CoUninitialize() 190 | self._initialized = False 191 | 192 | def create_instance(self, clsid, outer, ctx, iid, obj_type=None): 193 | obj = winapi.CoCreateInstance(clsid, 194 | outer, 195 | ctx, 196 | iid) 197 | if obj_type: 198 | obj = obj_type(obj) 199 | return obj 200 | 201 | def initialize_security(self, 202 | desc=None, 203 | auth_svc=-1, 204 | as_auth_svc=None, 205 | auth_level=winapi.RPC_C_AUTHN_LEVEL_DEFAULT, 206 | imp_level=winapi.RPC_C_IMP_LEVEL_IMPERSONATE, 207 | auth_list=None, 208 | capabilities=winapi.EOAC_NONE): 209 | winapi.CoInitializeSecurity(desc, 210 | auth_svc, 211 | as_auth_svc, 212 | None, 213 | auth_level, 214 | imp_level, 215 | auth_list, 216 | capabilities, 217 | None) 218 | 219 | def set_proxy_blanket(self, 220 | proxy, 221 | auth_svc=winapi.RPC_C_AUTHN_WINNT, 222 | authz_svc=winapi.RPC_C_AUTHZ_NONE, 223 | name=None, 224 | auth_level=winapi.RPC_C_AUTHN_LEVEL_CALL, 225 | imp_level=winapi.RPC_C_IMP_LEVEL_IMPERSONATE, 226 | auth_info=None, 227 | capabilities=winapi.EOAC_NONE): 228 | winapi.CoSetProxyBlanket(proxy, 229 | auth_svc, 230 | authz_svc, 231 | name, 232 | auth_level, 233 | imp_level, 234 | auth_info, 235 | capabilities) 236 | -------------------------------------------------------------------------------- /docs/html/_static/doctools.js: -------------------------------------------------------------------------------- 1 | /* 2 | * doctools.js 3 | * ~~~~~~~~~~~ 4 | * 5 | * Sphinx JavaScript utilities for all documentation. 6 | * 7 | * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | /** 13 | * select a different prefix for underscore 14 | */ 15 | $u = _.noConflict(); 16 | 17 | /** 18 | * make the code below compatible with browsers without 19 | * an installed firebug like debugger 20 | if (!window.console || !console.firebug) { 21 | var names = ["log", "debug", "info", "warn", "error", "assert", "dir", 22 | "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", 23 | "profile", "profileEnd"]; 24 | window.console = {}; 25 | for (var i = 0; i < names.length; ++i) 26 | window.console[names[i]] = function() {}; 27 | } 28 | */ 29 | 30 | /** 31 | * small helper function to urldecode strings 32 | */ 33 | jQuery.urldecode = function(x) { 34 | return decodeURIComponent(x).replace(/\+/g, ' '); 35 | }; 36 | 37 | /** 38 | * small helper function to urlencode strings 39 | */ 40 | jQuery.urlencode = encodeURIComponent; 41 | 42 | /** 43 | * This function returns the parsed url parameters of the 44 | * current request. Multiple values per key are supported, 45 | * it will always return arrays of strings for the value parts. 46 | */ 47 | jQuery.getQueryParameters = function(s) { 48 | if (typeof s === 'undefined') 49 | s = document.location.search; 50 | var parts = s.substr(s.indexOf('?') + 1).split('&'); 51 | var result = {}; 52 | for (var i = 0; i < parts.length; i++) { 53 | var tmp = parts[i].split('=', 2); 54 | var key = jQuery.urldecode(tmp[0]); 55 | var value = jQuery.urldecode(tmp[1]); 56 | if (key in result) 57 | result[key].push(value); 58 | else 59 | result[key] = [value]; 60 | } 61 | return result; 62 | }; 63 | 64 | /** 65 | * highlight a given string on a jquery object by wrapping it in 66 | * span elements with the given class name. 67 | */ 68 | jQuery.fn.highlightText = function(text, className) { 69 | function highlight(node, addItems) { 70 | if (node.nodeType === 3) { 71 | var val = node.nodeValue; 72 | var pos = val.toLowerCase().indexOf(text); 73 | if (pos >= 0 && 74 | !jQuery(node.parentNode).hasClass(className) && 75 | !jQuery(node.parentNode).hasClass("nohighlight")) { 76 | var span; 77 | var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); 78 | if (isInSVG) { 79 | span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); 80 | } else { 81 | span = document.createElement("span"); 82 | span.className = className; 83 | } 84 | span.appendChild(document.createTextNode(val.substr(pos, text.length))); 85 | node.parentNode.insertBefore(span, node.parentNode.insertBefore( 86 | document.createTextNode(val.substr(pos + text.length)), 87 | node.nextSibling)); 88 | node.nodeValue = val.substr(0, pos); 89 | if (isInSVG) { 90 | var bbox = span.getBBox(); 91 | var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); 92 | rect.x.baseVal.value = bbox.x; 93 | rect.y.baseVal.value = bbox.y; 94 | rect.width.baseVal.value = bbox.width; 95 | rect.height.baseVal.value = bbox.height; 96 | rect.setAttribute('class', className); 97 | var parentOfText = node.parentNode.parentNode; 98 | addItems.push({ 99 | "parent": node.parentNode, 100 | "target": rect}); 101 | } 102 | } 103 | } 104 | else if (!jQuery(node).is("button, select, textarea")) { 105 | jQuery.each(node.childNodes, function() { 106 | highlight(this, addItems); 107 | }); 108 | } 109 | } 110 | var addItems = []; 111 | var result = this.each(function() { 112 | highlight(this, addItems); 113 | }); 114 | for (var i = 0; i < addItems.length; ++i) { 115 | jQuery(addItems[i].parent).before(addItems[i].target); 116 | } 117 | return result; 118 | }; 119 | 120 | /* 121 | * backward compatibility for jQuery.browser 122 | * This will be supported until firefox bug is fixed. 123 | */ 124 | if (!jQuery.browser) { 125 | jQuery.uaMatch = function(ua) { 126 | ua = ua.toLowerCase(); 127 | 128 | var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || 129 | /(webkit)[ \/]([\w.]+)/.exec(ua) || 130 | /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || 131 | /(msie) ([\w.]+)/.exec(ua) || 132 | ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || 133 | []; 134 | 135 | return { 136 | browser: match[ 1 ] || "", 137 | version: match[ 2 ] || "0" 138 | }; 139 | }; 140 | jQuery.browser = {}; 141 | jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; 142 | } 143 | 144 | /** 145 | * Small JavaScript module for the documentation. 146 | */ 147 | var Documentation = { 148 | 149 | init : function() { 150 | this.fixFirefoxAnchorBug(); 151 | this.highlightSearchWords(); 152 | this.initIndexTable(); 153 | 154 | }, 155 | 156 | /** 157 | * i18n support 158 | */ 159 | TRANSLATIONS : {}, 160 | PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, 161 | LOCALE : 'unknown', 162 | 163 | // gettext and ngettext don't access this so that the functions 164 | // can safely bound to a different name (_ = Documentation.gettext) 165 | gettext : function(string) { 166 | var translated = Documentation.TRANSLATIONS[string]; 167 | if (typeof translated === 'undefined') 168 | return string; 169 | return (typeof translated === 'string') ? translated : translated[0]; 170 | }, 171 | 172 | ngettext : function(singular, plural, n) { 173 | var translated = Documentation.TRANSLATIONS[singular]; 174 | if (typeof translated === 'undefined') 175 | return (n == 1) ? singular : plural; 176 | return translated[Documentation.PLURALEXPR(n)]; 177 | }, 178 | 179 | addTranslations : function(catalog) { 180 | for (var key in catalog.messages) 181 | this.TRANSLATIONS[key] = catalog.messages[key]; 182 | this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); 183 | this.LOCALE = catalog.locale; 184 | }, 185 | 186 | /** 187 | * add context elements like header anchor links 188 | */ 189 | addContextElements : function() { 190 | $('div[id] > :header:first').each(function() { 191 | $('\u00B6'). 192 | attr('href', '#' + this.id). 193 | attr('title', _('Permalink to this headline')). 194 | appendTo(this); 195 | }); 196 | $('dt[id]').each(function() { 197 | $('\u00B6'). 198 | attr('href', '#' + this.id). 199 | attr('title', _('Permalink to this definition')). 200 | appendTo(this); 201 | }); 202 | }, 203 | 204 | /** 205 | * workaround a firefox stupidity 206 | * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 207 | */ 208 | fixFirefoxAnchorBug : function() { 209 | if (document.location.hash && $.browser.mozilla) 210 | window.setTimeout(function() { 211 | document.location.href += ''; 212 | }, 10); 213 | }, 214 | 215 | /** 216 | * highlight the search words provided in the url in the text 217 | */ 218 | highlightSearchWords : function() { 219 | var params = $.getQueryParameters(); 220 | var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; 221 | if (terms.length) { 222 | var body = $('div.body'); 223 | if (!body.length) { 224 | body = $('body'); 225 | } 226 | window.setTimeout(function() { 227 | $.each(terms, function() { 228 | body.highlightText(this.toLowerCase(), 'highlighted'); 229 | }); 230 | }, 10); 231 | $('') 233 | .appendTo($('#searchbox')); 234 | } 235 | }, 236 | 237 | /** 238 | * init the domain index toggle buttons 239 | */ 240 | initIndexTable : function() { 241 | var togglers = $('img.toggler').click(function() { 242 | var src = $(this).attr('src'); 243 | var idnum = $(this).attr('id').substr(7); 244 | $('tr.cg-' + idnum).toggle(); 245 | if (src.substr(-9) === 'minus.png') 246 | $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); 247 | else 248 | $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); 249 | }).css('display', ''); 250 | if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { 251 | togglers.click(); 252 | } 253 | }, 254 | 255 | /** 256 | * helper function to hide the search marks again 257 | */ 258 | hideSearchWords : function() { 259 | $('#searchbox .highlight-link').fadeOut(300); 260 | $('span.highlighted').removeClass('highlighted'); 261 | }, 262 | 263 | /** 264 | * make the url absolute 265 | */ 266 | makeURL : function(relativeURL) { 267 | return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; 268 | }, 269 | 270 | /** 271 | * get the current relative url 272 | */ 273 | getCurrentURL : function() { 274 | var path = document.location.pathname; 275 | var parts = path.split(/\//); 276 | $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { 277 | if (this === '..') 278 | parts.pop(); 279 | }); 280 | var url = parts.join('/'); 281 | return path.substring(url.lastIndexOf('/') + 1, path.length - 1); 282 | }, 283 | 284 | initOnKeyListeners: function() { 285 | $(document).keyup(function(event) { 286 | var activeElementType = document.activeElement.tagName; 287 | // don't navigate when in search box or textarea 288 | if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { 289 | switch (event.keyCode) { 290 | case 37: // left 291 | var prevHref = $('link[rel="prev"]').prop('href'); 292 | if (prevHref) { 293 | window.location.href = prevHref; 294 | return false; 295 | } 296 | case 39: // right 297 | var nextHref = $('link[rel="next"]').prop('href'); 298 | if (nextHref) { 299 | window.location.href = nextHref; 300 | return false; 301 | } 302 | } 303 | } 304 | }); 305 | } 306 | }; 307 | 308 | // quick alias for translations 309 | _ = Documentation.gettext; 310 | 311 | $(document).ready(function() { 312 | Documentation.init(); 313 | }); -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | -------------------------------------------------------------------------------- /docs/html/_static/underscore.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 1.3.1 2 | // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. 3 | // Underscore is freely distributable under the MIT license. 4 | // Portions of Underscore are inspired or borrowed from Prototype, 5 | // Oliver Steele's Functional, and John Resig's Micro-Templating. 6 | // For all details and documentation: 7 | // http://documentcloud.github.com/underscore 8 | (function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== 9 | c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c, 10 | h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each= 11 | b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a== 12 | null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect= 13 | function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e= 14 | e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck= 15 | function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a, 17 | c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}}; 24 | b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments, 25 | 1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)}; 26 | b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"}; 27 | b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a), 28 | function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+ 29 | u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]= 30 | function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain= 31 | true;return this};m.prototype.value=function(){return this._wrapped}}).call(this); 32 | -------------------------------------------------------------------------------- /docs/html/cwmi.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | cwmi package — cwmi documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
30 |
31 | 32 |
33 |

cwmi package

34 |
35 |

Module contents

36 |
37 |
38 | cwmi.call_method(namespace, obj_path, method_name, input_params=None, user=None, password=None, flags=0)
39 |

Calls object method

40 |
41 |
Args:
42 |
namespace (str): Namespace to connect to 43 | obj_path (str): Path to object instance/class 44 | method_name (str): Name of the method to call 45 | input_params (dict): Method input parameters 46 | user (str): Username to use when connecting to remote system 47 | password (str): Password to use for remote connection 48 | flags (int): Flags to pass into WMI API(s)
49 |
Returns:
50 |
Dictionary containing data returned from the called method
51 |
52 |
53 | 54 |
55 |
56 | cwmi.create_variant(val, v_type=None)
57 |

Creates a VARIANT instance from a given value

58 |
59 |
Args:
60 |
val (any): The value to use when creating the VARIANT instance 61 | v_type (int): Variant type
62 |
Returns:
63 |
Initialized VARIANT instance
64 |
65 |
66 | 67 |
68 |
69 | cwmi.destroy_variant(var)
70 |

Destroys an instance of a VARIANT

71 |
72 |
Args:
73 |
var (VARIANT): Instance to destroy
74 |
Returns:
75 |
Nothing
76 |
77 |
78 | 79 |
80 |
81 | cwmi.does_object_exist(namespace, obj_name, user=None, password=None, flags=0)
82 |

Tests if a given object exists

83 |
84 |
Args:
85 |
namespace (str): Namespace to connect to 86 | obj_name (str): Path to object instance/class 87 | user (str): Username to use when connecting to remote system 88 | password (str): Password to use for remote connection 89 | flags (int): Flags to pass into WMI API(s)
90 |
Returns:
91 |
True if object exists, or False if not
92 |
93 |
94 | 95 |
96 |
97 | cwmi.get_all_object_info(namespace, obj_name, user=None, password=None, include_var_type=False, flags=0)
98 |

Gets all data from an object

99 |
100 |
Args:
101 |
namespace (str): Namespace to connect to 102 | obj_name (str): Path to object instance/class 103 | user (str): Username to use when connecting to remote system 104 | password (str): Password to use for remote connection 105 | include_var_type (bool): Include variant type 106 | flags (int): Flags to pass into WMI API(s)
107 |
Returns:
108 |
Dictionary containing object data
109 |
110 |
111 | 112 |
113 |
114 | cwmi.get_method_info(namespace, obj_name, user=None, password=None, flags=0)
115 |

Gets method information for a given object/method

116 |
117 |
Args:
118 |
namespace (str): Namespace to connect to 119 | obj_name (str): Path to object instance/class 120 | user (str): Username to use when connecting to remote system 121 | password (str): Password to use for remote connection 122 | flags (int): Flags to pass into WMI API(s)
123 |
Returns:
124 |
Dictionary containing method parameter info
125 |
126 |
127 | 128 |
129 |
130 | cwmi.get_method_names(namespace, obj_name, user=None, password=None, flags=0)
131 |

Gets all method names from a given object

132 |
133 |
Args:
134 |
namespace (str): Namespace to connect to 135 | obj_name (str): Path to object instance/class 136 | user (str): Username to use when connecting to remote system 137 | password (str): Password to use for remote connection 138 | flags (int): Flags to pass into WMI API(s)
139 |
Returns:
140 |
List of method names
141 |
142 |
143 | 144 |
145 |
146 | cwmi.get_object_info(namespace, obj_name, values, user=None, password=None, include_var_type=False, flags=0)
147 |

Gets desired values from an object.

148 |
149 |
Args:
150 |
namespace (str): Namespace to connect to 151 | obj_name (str): Path to object instance/class 152 | values (list): List of values to pull from object 153 | user (str): Username to use when connecting to remote system 154 | password (str): Password to use for remote connection 155 | include_var_type (bool): Include variant type 156 | flags (int): Flags to pass into WMI API(s)
157 |
Returns:
158 |
Dictionary containing object data
159 |
160 |
161 | 162 |
163 |
164 | cwmi.get_object_names(namespace, obj_name, user=None, password=None, flags=0)
165 |

Gets all names from a given object

166 |
167 |
Args:
168 |
namespace (str): Namespace to connect to 169 | obj_name (str): Path to object instance/class 170 | user (str): Username to use when connecting to remote system 171 | password (str): Password to use for remote connection 172 | flags (int): Flags to pass into WMI API(s)
173 |
Returns:
174 |
List containing object names
175 |
176 |
177 | 178 |
179 |
180 | cwmi.obj_to_dict(obj, include_var_type=False, flags=0)
181 |

Converts WMI object to python dictionary

182 |
183 |
Args:
184 |
obj (any): The object to convert 185 | include_var_type (bool): Include variant type 186 | flags (int): Flags to pass into WMI API(s)
187 |
Returns:
188 |
Dictionary containing object information
189 |
190 |
191 | 192 |
193 |
194 | cwmi.query(namespace, query_str, query_type='WQL', user=None, password=None, include_var_type=False, flags=0)
195 |

Performs a WMI query

196 |
197 |
Args:
198 |
namespace (str): Namespace to connect to 199 | query_str (str): String to use for the query 200 | query_type (str): Path to object instance/class 201 | user (str): Username to use when connecting to remote system 202 | password (str): Password to use for remote connection 203 | include_var_type (bool): Include variant type 204 | flags (int): Flags to pass into WMI API(s)
205 |
Returns:
206 |
Dictionary containing all objects returned by query
207 |
208 |
209 | 210 |
211 |
212 | cwmi.safe_array_to_list(safe_array, element_type)
213 |

Converts SAFEARRAY structure to python list

214 |
215 |
Args:
216 |
safe_array (SAFEARRAY): Array structure to convert 217 | element_type (any): Type of the elements contained in the structure
218 |
Returns:
219 |
List containing the converted array elements
220 |
221 |
222 | 223 |
224 |
225 | 226 | 227 |
228 |
229 |
230 | 267 |
268 |
269 | 280 | 281 | 282 | 283 | 284 | 285 | -------------------------------------------------------------------------------- /docs/html/_static/basic.css: -------------------------------------------------------------------------------- 1 | /* 2 | * basic.css 3 | * ~~~~~~~~~ 4 | * 5 | * Sphinx stylesheet -- basic theme. 6 | * 7 | * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | /* -- main layout ----------------------------------------------------------- */ 13 | 14 | div.clearer { 15 | clear: both; 16 | } 17 | 18 | /* -- relbar ---------------------------------------------------------------- */ 19 | 20 | div.related { 21 | width: 100%; 22 | font-size: 90%; 23 | } 24 | 25 | div.related h3 { 26 | display: none; 27 | } 28 | 29 | div.related ul { 30 | margin: 0; 31 | padding: 0 0 0 10px; 32 | list-style: none; 33 | } 34 | 35 | div.related li { 36 | display: inline; 37 | } 38 | 39 | div.related li.right { 40 | float: right; 41 | margin-right: 5px; 42 | } 43 | 44 | /* -- sidebar --------------------------------------------------------------- */ 45 | 46 | div.sphinxsidebarwrapper { 47 | padding: 10px 5px 0 10px; 48 | } 49 | 50 | div.sphinxsidebar { 51 | float: left; 52 | width: 230px; 53 | margin-left: -100%; 54 | font-size: 90%; 55 | word-wrap: break-word; 56 | overflow-wrap : break-word; 57 | } 58 | 59 | div.sphinxsidebar ul { 60 | list-style: none; 61 | } 62 | 63 | div.sphinxsidebar ul ul, 64 | div.sphinxsidebar ul.want-points { 65 | margin-left: 20px; 66 | list-style: square; 67 | } 68 | 69 | div.sphinxsidebar ul ul { 70 | margin-top: 0; 71 | margin-bottom: 0; 72 | } 73 | 74 | div.sphinxsidebar form { 75 | margin-top: 10px; 76 | } 77 | 78 | div.sphinxsidebar input { 79 | border: 1px solid #98dbcc; 80 | font-family: sans-serif; 81 | font-size: 1em; 82 | } 83 | 84 | div.sphinxsidebar #searchbox input[type="text"] { 85 | float: left; 86 | width: 80%; 87 | padding: 0.25em; 88 | box-sizing: border-box; 89 | } 90 | 91 | div.sphinxsidebar #searchbox input[type="submit"] { 92 | float: left; 93 | width: 20%; 94 | border-left: none; 95 | padding: 0.25em; 96 | box-sizing: border-box; 97 | } 98 | 99 | 100 | img { 101 | border: 0; 102 | max-width: 100%; 103 | } 104 | 105 | /* -- search page ----------------------------------------------------------- */ 106 | 107 | ul.search { 108 | margin: 10px 0 0 20px; 109 | padding: 0; 110 | } 111 | 112 | ul.search li { 113 | padding: 5px 0 5px 20px; 114 | background-image: url(file.png); 115 | background-repeat: no-repeat; 116 | background-position: 0 7px; 117 | } 118 | 119 | ul.search li a { 120 | font-weight: bold; 121 | } 122 | 123 | ul.search li div.context { 124 | color: #888; 125 | margin: 2px 0 0 30px; 126 | text-align: left; 127 | } 128 | 129 | ul.keywordmatches li.goodmatch a { 130 | font-weight: bold; 131 | } 132 | 133 | /* -- index page ------------------------------------------------------------ */ 134 | 135 | table.contentstable { 136 | width: 90%; 137 | margin-left: auto; 138 | margin-right: auto; 139 | } 140 | 141 | table.contentstable p.biglink { 142 | line-height: 150%; 143 | } 144 | 145 | a.biglink { 146 | font-size: 1.3em; 147 | } 148 | 149 | span.linkdescr { 150 | font-style: italic; 151 | padding-top: 5px; 152 | font-size: 90%; 153 | } 154 | 155 | /* -- general index --------------------------------------------------------- */ 156 | 157 | table.indextable { 158 | width: 100%; 159 | } 160 | 161 | table.indextable td { 162 | text-align: left; 163 | vertical-align: top; 164 | } 165 | 166 | table.indextable ul { 167 | margin-top: 0; 168 | margin-bottom: 0; 169 | list-style-type: none; 170 | } 171 | 172 | table.indextable > tbody > tr > td > ul { 173 | padding-left: 0em; 174 | } 175 | 176 | table.indextable tr.pcap { 177 | height: 10px; 178 | } 179 | 180 | table.indextable tr.cap { 181 | margin-top: 10px; 182 | background-color: #f2f2f2; 183 | } 184 | 185 | img.toggler { 186 | margin-right: 3px; 187 | margin-top: 3px; 188 | cursor: pointer; 189 | } 190 | 191 | div.modindex-jumpbox { 192 | border-top: 1px solid #ddd; 193 | border-bottom: 1px solid #ddd; 194 | margin: 1em 0 1em 0; 195 | padding: 0.4em; 196 | } 197 | 198 | div.genindex-jumpbox { 199 | border-top: 1px solid #ddd; 200 | border-bottom: 1px solid #ddd; 201 | margin: 1em 0 1em 0; 202 | padding: 0.4em; 203 | } 204 | 205 | /* -- domain module index --------------------------------------------------- */ 206 | 207 | table.modindextable td { 208 | padding: 2px; 209 | border-collapse: collapse; 210 | } 211 | 212 | /* -- general body styles --------------------------------------------------- */ 213 | 214 | div.body { 215 | min-width: 450px; 216 | max-width: 800px; 217 | } 218 | 219 | div.body p, div.body dd, div.body li, div.body blockquote { 220 | -moz-hyphens: auto; 221 | -ms-hyphens: auto; 222 | -webkit-hyphens: auto; 223 | hyphens: auto; 224 | } 225 | 226 | a.headerlink { 227 | visibility: hidden; 228 | } 229 | 230 | h1:hover > a.headerlink, 231 | h2:hover > a.headerlink, 232 | h3:hover > a.headerlink, 233 | h4:hover > a.headerlink, 234 | h5:hover > a.headerlink, 235 | h6:hover > a.headerlink, 236 | dt:hover > a.headerlink, 237 | caption:hover > a.headerlink, 238 | p.caption:hover > a.headerlink, 239 | div.code-block-caption:hover > a.headerlink { 240 | visibility: visible; 241 | } 242 | 243 | div.body p.caption { 244 | text-align: inherit; 245 | } 246 | 247 | div.body td { 248 | text-align: left; 249 | } 250 | 251 | .first { 252 | margin-top: 0 !important; 253 | } 254 | 255 | p.rubric { 256 | margin-top: 30px; 257 | font-weight: bold; 258 | } 259 | 260 | img.align-left, .figure.align-left, object.align-left { 261 | clear: left; 262 | float: left; 263 | margin-right: 1em; 264 | } 265 | 266 | img.align-right, .figure.align-right, object.align-right { 267 | clear: right; 268 | float: right; 269 | margin-left: 1em; 270 | } 271 | 272 | img.align-center, .figure.align-center, object.align-center { 273 | display: block; 274 | margin-left: auto; 275 | margin-right: auto; 276 | } 277 | 278 | .align-left { 279 | text-align: left; 280 | } 281 | 282 | .align-center { 283 | text-align: center; 284 | } 285 | 286 | .align-right { 287 | text-align: right; 288 | } 289 | 290 | /* -- sidebars -------------------------------------------------------------- */ 291 | 292 | div.sidebar { 293 | margin: 0 0 0.5em 1em; 294 | border: 1px solid #ddb; 295 | padding: 7px 7px 0 7px; 296 | background-color: #ffe; 297 | width: 40%; 298 | float: right; 299 | } 300 | 301 | p.sidebar-title { 302 | font-weight: bold; 303 | } 304 | 305 | /* -- topics ---------------------------------------------------------------- */ 306 | 307 | div.topic { 308 | border: 1px solid #ccc; 309 | padding: 7px 7px 0 7px; 310 | margin: 10px 0 10px 0; 311 | } 312 | 313 | p.topic-title { 314 | font-size: 1.1em; 315 | font-weight: bold; 316 | margin-top: 10px; 317 | } 318 | 319 | /* -- admonitions ----------------------------------------------------------- */ 320 | 321 | div.admonition { 322 | margin-top: 10px; 323 | margin-bottom: 10px; 324 | padding: 7px; 325 | } 326 | 327 | div.admonition dt { 328 | font-weight: bold; 329 | } 330 | 331 | div.admonition dl { 332 | margin-bottom: 0; 333 | } 334 | 335 | p.admonition-title { 336 | margin: 0px 10px 5px 0px; 337 | font-weight: bold; 338 | } 339 | 340 | div.body p.centered { 341 | text-align: center; 342 | margin-top: 25px; 343 | } 344 | 345 | /* -- tables ---------------------------------------------------------------- */ 346 | 347 | table.docutils { 348 | border: 0; 349 | border-collapse: collapse; 350 | } 351 | 352 | table.align-center { 353 | margin-left: auto; 354 | margin-right: auto; 355 | } 356 | 357 | table caption span.caption-number { 358 | font-style: italic; 359 | } 360 | 361 | table caption span.caption-text { 362 | } 363 | 364 | table.docutils td, table.docutils th { 365 | padding: 1px 8px 1px 5px; 366 | border-top: 0; 367 | border-left: 0; 368 | border-right: 0; 369 | border-bottom: 1px solid #aaa; 370 | } 371 | 372 | table.footnote td, table.footnote th { 373 | border: 0 !important; 374 | } 375 | 376 | th { 377 | text-align: left; 378 | padding-right: 5px; 379 | } 380 | 381 | table.citation { 382 | border-left: solid 1px gray; 383 | margin-left: 1px; 384 | } 385 | 386 | table.citation td { 387 | border-bottom: none; 388 | } 389 | 390 | /* -- figures --------------------------------------------------------------- */ 391 | 392 | div.figure { 393 | margin: 0.5em; 394 | padding: 0.5em; 395 | } 396 | 397 | div.figure p.caption { 398 | padding: 0.3em; 399 | } 400 | 401 | div.figure p.caption span.caption-number { 402 | font-style: italic; 403 | } 404 | 405 | div.figure p.caption span.caption-text { 406 | } 407 | 408 | /* -- field list styles ----------------------------------------------------- */ 409 | 410 | table.field-list td, table.field-list th { 411 | border: 0 !important; 412 | } 413 | 414 | .field-list ul { 415 | margin: 0; 416 | padding-left: 1em; 417 | } 418 | 419 | .field-list p { 420 | margin: 0; 421 | } 422 | 423 | .field-name { 424 | -moz-hyphens: manual; 425 | -ms-hyphens: manual; 426 | -webkit-hyphens: manual; 427 | hyphens: manual; 428 | } 429 | 430 | /* -- other body styles ----------------------------------------------------- */ 431 | 432 | ol.arabic { 433 | list-style: decimal; 434 | } 435 | 436 | ol.loweralpha { 437 | list-style: lower-alpha; 438 | } 439 | 440 | ol.upperalpha { 441 | list-style: upper-alpha; 442 | } 443 | 444 | ol.lowerroman { 445 | list-style: lower-roman; 446 | } 447 | 448 | ol.upperroman { 449 | list-style: upper-roman; 450 | } 451 | 452 | dl { 453 | margin-bottom: 15px; 454 | } 455 | 456 | dd p { 457 | margin-top: 0px; 458 | } 459 | 460 | dd ul, dd table { 461 | margin-bottom: 10px; 462 | } 463 | 464 | dd { 465 | margin-top: 3px; 466 | margin-bottom: 10px; 467 | margin-left: 30px; 468 | } 469 | 470 | dt:target, span.highlighted { 471 | background-color: #fbe54e; 472 | } 473 | 474 | rect.highlighted { 475 | fill: #fbe54e; 476 | } 477 | 478 | dl.glossary dt { 479 | font-weight: bold; 480 | font-size: 1.1em; 481 | } 482 | 483 | .optional { 484 | font-size: 1.3em; 485 | } 486 | 487 | .sig-paren { 488 | font-size: larger; 489 | } 490 | 491 | .versionmodified { 492 | font-style: italic; 493 | } 494 | 495 | .system-message { 496 | background-color: #fda; 497 | padding: 5px; 498 | border: 3px solid red; 499 | } 500 | 501 | .footnote:target { 502 | background-color: #ffa; 503 | } 504 | 505 | .line-block { 506 | display: block; 507 | margin-top: 1em; 508 | margin-bottom: 1em; 509 | } 510 | 511 | .line-block .line-block { 512 | margin-top: 0; 513 | margin-bottom: 0; 514 | margin-left: 1.5em; 515 | } 516 | 517 | .guilabel, .menuselection { 518 | font-family: sans-serif; 519 | } 520 | 521 | .accelerator { 522 | text-decoration: underline; 523 | } 524 | 525 | .classifier { 526 | font-style: oblique; 527 | } 528 | 529 | abbr, acronym { 530 | border-bottom: dotted 1px; 531 | cursor: help; 532 | } 533 | 534 | /* -- code displays --------------------------------------------------------- */ 535 | 536 | pre { 537 | overflow: auto; 538 | overflow-y: hidden; /* fixes display issues on Chrome browsers */ 539 | } 540 | 541 | span.pre { 542 | -moz-hyphens: none; 543 | -ms-hyphens: none; 544 | -webkit-hyphens: none; 545 | hyphens: none; 546 | } 547 | 548 | td.linenos pre { 549 | padding: 5px 0px; 550 | border: 0; 551 | background-color: transparent; 552 | color: #aaa; 553 | } 554 | 555 | table.highlighttable { 556 | margin-left: 0.5em; 557 | } 558 | 559 | table.highlighttable td { 560 | padding: 0 0.5em 0 0.5em; 561 | } 562 | 563 | div.code-block-caption { 564 | padding: 2px 5px; 565 | font-size: small; 566 | } 567 | 568 | div.code-block-caption code { 569 | background-color: transparent; 570 | } 571 | 572 | div.code-block-caption + div > div.highlight > pre { 573 | margin-top: 0; 574 | } 575 | 576 | div.code-block-caption span.caption-number { 577 | padding: 0.1em 0.3em; 578 | font-style: italic; 579 | } 580 | 581 | div.code-block-caption span.caption-text { 582 | } 583 | 584 | div.literal-block-wrapper { 585 | padding: 1em 1em 0; 586 | } 587 | 588 | div.literal-block-wrapper div.highlight { 589 | margin: 0; 590 | } 591 | 592 | code.descname { 593 | background-color: transparent; 594 | font-weight: bold; 595 | font-size: 1.2em; 596 | } 597 | 598 | code.descclassname { 599 | background-color: transparent; 600 | } 601 | 602 | code.xref, a code { 603 | background-color: transparent; 604 | font-weight: bold; 605 | } 606 | 607 | h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { 608 | background-color: transparent; 609 | } 610 | 611 | .viewcode-link { 612 | float: right; 613 | } 614 | 615 | .viewcode-back { 616 | float: right; 617 | font-family: sans-serif; 618 | } 619 | 620 | div.viewcode-block:target { 621 | margin: -1px -10px; 622 | padding: 0 10px; 623 | } 624 | 625 | /* -- math display ---------------------------------------------------------- */ 626 | 627 | img.math { 628 | vertical-align: middle; 629 | } 630 | 631 | div.body div.math p { 632 | text-align: center; 633 | } 634 | 635 | span.eqno { 636 | float: right; 637 | } 638 | 639 | span.eqno a.headerlink { 640 | position: relative; 641 | left: 0px; 642 | z-index: 1; 643 | } 644 | 645 | div.math:hover a.headerlink { 646 | visibility: visible; 647 | } 648 | 649 | /* -- printout stylesheet --------------------------------------------------- */ 650 | 651 | @media print { 652 | div.document, 653 | div.documentwrapper, 654 | div.bodywrapper { 655 | margin: 0 !important; 656 | width: 100%; 657 | } 658 | 659 | div.sphinxsidebar, 660 | div.related, 661 | div.footer, 662 | #top-link { 663 | display: none; 664 | } 665 | } -------------------------------------------------------------------------------- /docs/html/_static/alabaster.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | @import url("basic.css"); 54 | 55 | /* -- page layout ----------------------------------------------------------- */ 56 | 57 | body { 58 | font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro', serif; 59 | font-size: 17px; 60 | background-color: #fff; 61 | color: #000; 62 | margin: 0; 63 | padding: 0; 64 | } 65 | 66 | 67 | div.document { 68 | width: 940px; 69 | margin: 30px auto 0 auto; 70 | } 71 | 72 | div.documentwrapper { 73 | float: left; 74 | width: 100%; 75 | } 76 | 77 | div.bodywrapper { 78 | margin: 0 0 0 220px; 79 | } 80 | 81 | div.sphinxsidebar { 82 | width: 220px; 83 | font-size: 14px; 84 | line-height: 1.5; 85 | } 86 | 87 | hr { 88 | border: 1px solid #B1B4B6; 89 | } 90 | 91 | div.body { 92 | background-color: #fff; 93 | color: #3E4349; 94 | padding: 0 30px 0 30px; 95 | } 96 | 97 | div.body > .section { 98 | text-align: left; 99 | } 100 | 101 | div.footer { 102 | width: 940px; 103 | margin: 20px auto 30px auto; 104 | font-size: 14px; 105 | color: #888; 106 | text-align: right; 107 | } 108 | 109 | div.footer a { 110 | color: #888; 111 | } 112 | 113 | p.caption { 114 | font-family: inherit; 115 | font-size: inherit; 116 | } 117 | 118 | 119 | div.relations { 120 | display: none; 121 | } 122 | 123 | 124 | div.sphinxsidebar a { 125 | color: #444; 126 | text-decoration: none; 127 | border-bottom: 1px dotted #999; 128 | } 129 | 130 | div.sphinxsidebar a:hover { 131 | border-bottom: 1px solid #999; 132 | } 133 | 134 | div.sphinxsidebarwrapper { 135 | padding: 18px 10px; 136 | } 137 | 138 | div.sphinxsidebarwrapper p.logo { 139 | padding: 0; 140 | margin: -10px 0 0 0px; 141 | text-align: center; 142 | } 143 | 144 | div.sphinxsidebarwrapper h1.logo { 145 | margin-top: -10px; 146 | text-align: center; 147 | margin-bottom: 5px; 148 | text-align: left; 149 | } 150 | 151 | div.sphinxsidebarwrapper h1.logo-name { 152 | margin-top: 0px; 153 | } 154 | 155 | div.sphinxsidebarwrapper p.blurb { 156 | margin-top: 0; 157 | font-style: normal; 158 | } 159 | 160 | div.sphinxsidebar h3, 161 | div.sphinxsidebar h4 { 162 | font-family: 'Garamond', 'Georgia', serif; 163 | color: #444; 164 | font-size: 24px; 165 | font-weight: normal; 166 | margin: 0 0 5px 0; 167 | padding: 0; 168 | } 169 | 170 | div.sphinxsidebar h4 { 171 | font-size: 20px; 172 | } 173 | 174 | div.sphinxsidebar h3 a { 175 | color: #444; 176 | } 177 | 178 | div.sphinxsidebar p.logo a, 179 | div.sphinxsidebar h3 a, 180 | div.sphinxsidebar p.logo a:hover, 181 | div.sphinxsidebar h3 a:hover { 182 | border: none; 183 | } 184 | 185 | div.sphinxsidebar p { 186 | color: #555; 187 | margin: 10px 0; 188 | } 189 | 190 | div.sphinxsidebar ul { 191 | margin: 10px 0; 192 | padding: 0; 193 | color: #000; 194 | } 195 | 196 | div.sphinxsidebar ul li.toctree-l1 > a { 197 | font-size: 120%; 198 | } 199 | 200 | div.sphinxsidebar ul li.toctree-l2 > a { 201 | font-size: 110%; 202 | } 203 | 204 | div.sphinxsidebar input { 205 | border: 1px solid #CCC; 206 | font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro', serif; 207 | font-size: 1em; 208 | } 209 | 210 | div.sphinxsidebar hr { 211 | border: none; 212 | height: 1px; 213 | color: #AAA; 214 | background: #AAA; 215 | 216 | text-align: left; 217 | margin-left: 0; 218 | width: 50%; 219 | } 220 | 221 | /* -- body styles ----------------------------------------------------------- */ 222 | 223 | a { 224 | color: #004B6B; 225 | text-decoration: underline; 226 | } 227 | 228 | a:hover { 229 | color: #6D4100; 230 | text-decoration: underline; 231 | } 232 | 233 | div.body h1, 234 | div.body h2, 235 | div.body h3, 236 | div.body h4, 237 | div.body h5, 238 | div.body h6 { 239 | font-family: 'Garamond', 'Georgia', serif; 240 | font-weight: normal; 241 | margin: 30px 0px 10px 0px; 242 | padding: 0; 243 | } 244 | 245 | div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } 246 | div.body h2 { font-size: 180%; } 247 | div.body h3 { font-size: 150%; } 248 | div.body h4 { font-size: 130%; } 249 | div.body h5 { font-size: 100%; } 250 | div.body h6 { font-size: 100%; } 251 | 252 | a.headerlink { 253 | color: #DDD; 254 | padding: 0 4px; 255 | text-decoration: none; 256 | } 257 | 258 | a.headerlink:hover { 259 | color: #444; 260 | background: #EAEAEA; 261 | } 262 | 263 | div.body p, div.body dd, div.body li { 264 | line-height: 1.4em; 265 | } 266 | 267 | div.admonition { 268 | margin: 20px 0px; 269 | padding: 10px 30px; 270 | background-color: #EEE; 271 | border: 1px solid #CCC; 272 | } 273 | 274 | div.admonition tt.xref, div.admonition code.xref, div.admonition a tt { 275 | background-color: #FBFBFB; 276 | border-bottom: 1px solid #fafafa; 277 | } 278 | 279 | div.admonition p.admonition-title { 280 | font-family: 'Garamond', 'Georgia', serif; 281 | font-weight: normal; 282 | font-size: 24px; 283 | margin: 0 0 10px 0; 284 | padding: 0; 285 | line-height: 1; 286 | } 287 | 288 | div.admonition p.last { 289 | margin-bottom: 0; 290 | } 291 | 292 | div.highlight { 293 | background-color: #fff; 294 | } 295 | 296 | dt:target, .highlight { 297 | background: #FAF3E8; 298 | } 299 | 300 | div.warning { 301 | background-color: #FCC; 302 | border: 1px solid #FAA; 303 | } 304 | 305 | div.danger { 306 | background-color: #FCC; 307 | border: 1px solid #FAA; 308 | -moz-box-shadow: 2px 2px 4px #D52C2C; 309 | -webkit-box-shadow: 2px 2px 4px #D52C2C; 310 | box-shadow: 2px 2px 4px #D52C2C; 311 | } 312 | 313 | div.error { 314 | background-color: #FCC; 315 | border: 1px solid #FAA; 316 | -moz-box-shadow: 2px 2px 4px #D52C2C; 317 | -webkit-box-shadow: 2px 2px 4px #D52C2C; 318 | box-shadow: 2px 2px 4px #D52C2C; 319 | } 320 | 321 | div.caution { 322 | background-color: #FCC; 323 | border: 1px solid #FAA; 324 | } 325 | 326 | div.attention { 327 | background-color: #FCC; 328 | border: 1px solid #FAA; 329 | } 330 | 331 | div.important { 332 | background-color: #EEE; 333 | border: 1px solid #CCC; 334 | } 335 | 336 | div.note { 337 | background-color: #EEE; 338 | border: 1px solid #CCC; 339 | } 340 | 341 | div.tip { 342 | background-color: #EEE; 343 | border: 1px solid #CCC; 344 | } 345 | 346 | div.hint { 347 | background-color: #EEE; 348 | border: 1px solid #CCC; 349 | } 350 | 351 | div.seealso { 352 | background-color: #EEE; 353 | border: 1px solid #CCC; 354 | } 355 | 356 | div.topic { 357 | background-color: #EEE; 358 | } 359 | 360 | p.admonition-title { 361 | display: inline; 362 | } 363 | 364 | p.admonition-title:after { 365 | content: ":"; 366 | } 367 | 368 | pre, tt, code { 369 | font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; 370 | font-size: 0.9em; 371 | } 372 | 373 | .hll { 374 | background-color: #FFC; 375 | margin: 0 -12px; 376 | padding: 0 12px; 377 | display: block; 378 | } 379 | 380 | img.screenshot { 381 | } 382 | 383 | tt.descname, tt.descclassname, code.descname, code.descclassname { 384 | font-size: 0.95em; 385 | } 386 | 387 | tt.descname, code.descname { 388 | padding-right: 0.08em; 389 | } 390 | 391 | img.screenshot { 392 | -moz-box-shadow: 2px 2px 4px #EEE; 393 | -webkit-box-shadow: 2px 2px 4px #EEE; 394 | box-shadow: 2px 2px 4px #EEE; 395 | } 396 | 397 | table.docutils { 398 | border: 1px solid #888; 399 | -moz-box-shadow: 2px 2px 4px #EEE; 400 | -webkit-box-shadow: 2px 2px 4px #EEE; 401 | box-shadow: 2px 2px 4px #EEE; 402 | } 403 | 404 | table.docutils td, table.docutils th { 405 | border: 1px solid #888; 406 | padding: 0.25em 0.7em; 407 | } 408 | 409 | table.field-list, table.footnote { 410 | border: none; 411 | -moz-box-shadow: none; 412 | -webkit-box-shadow: none; 413 | box-shadow: none; 414 | } 415 | 416 | table.footnote { 417 | margin: 15px 0; 418 | width: 100%; 419 | border: 1px solid #EEE; 420 | background: #FDFDFD; 421 | font-size: 0.9em; 422 | } 423 | 424 | table.footnote + table.footnote { 425 | margin-top: -15px; 426 | border-top: none; 427 | } 428 | 429 | table.field-list th { 430 | padding: 0 0.8em 0 0; 431 | } 432 | 433 | table.field-list td { 434 | padding: 0; 435 | } 436 | 437 | table.field-list p { 438 | margin-bottom: 0.8em; 439 | } 440 | 441 | /* Cloned from 442 | * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68 443 | */ 444 | .field-name { 445 | -moz-hyphens: manual; 446 | -ms-hyphens: manual; 447 | -webkit-hyphens: manual; 448 | hyphens: manual; 449 | } 450 | 451 | table.footnote td.label { 452 | width: .1px; 453 | padding: 0.3em 0 0.3em 0.5em; 454 | } 455 | 456 | table.footnote td { 457 | padding: 0.3em 0.5em; 458 | } 459 | 460 | dl { 461 | margin: 0; 462 | padding: 0; 463 | } 464 | 465 | dl dd { 466 | margin-left: 30px; 467 | } 468 | 469 | blockquote { 470 | margin: 0 0 0 30px; 471 | padding: 0; 472 | } 473 | 474 | ul, ol { 475 | /* Matches the 30px from the narrow-screen "li > ul" selector below */ 476 | margin: 10px 0 10px 30px; 477 | padding: 0; 478 | } 479 | 480 | pre { 481 | background: #EEE; 482 | padding: 7px 30px; 483 | margin: 15px 0px; 484 | line-height: 1.3em; 485 | } 486 | 487 | div.viewcode-block:target { 488 | background: #ffd; 489 | } 490 | 491 | dl pre, blockquote pre, li pre { 492 | margin-left: 0; 493 | padding-left: 30px; 494 | } 495 | 496 | tt, code { 497 | background-color: #ecf0f3; 498 | color: #222; 499 | /* padding: 1px 2px; */ 500 | } 501 | 502 | tt.xref, code.xref, a tt { 503 | background-color: #FBFBFB; 504 | border-bottom: 1px solid #fff; 505 | } 506 | 507 | a.reference { 508 | text-decoration: none; 509 | border-bottom: 1px dotted #004B6B; 510 | } 511 | 512 | /* Don't put an underline on images */ 513 | a.image-reference, a.image-reference:hover { 514 | border-bottom: none; 515 | } 516 | 517 | a.reference:hover { 518 | border-bottom: 1px solid #6D4100; 519 | } 520 | 521 | a.footnote-reference { 522 | text-decoration: none; 523 | font-size: 0.7em; 524 | vertical-align: top; 525 | border-bottom: 1px dotted #004B6B; 526 | } 527 | 528 | a.footnote-reference:hover { 529 | border-bottom: 1px solid #6D4100; 530 | } 531 | 532 | a:hover tt, a:hover code { 533 | background: #EEE; 534 | } 535 | 536 | 537 | @media screen and (max-width: 870px) { 538 | 539 | div.sphinxsidebar { 540 | display: none; 541 | } 542 | 543 | div.document { 544 | width: 100%; 545 | 546 | } 547 | 548 | div.documentwrapper { 549 | margin-left: 0; 550 | margin-top: 0; 551 | margin-right: 0; 552 | margin-bottom: 0; 553 | } 554 | 555 | div.bodywrapper { 556 | margin-top: 0; 557 | margin-right: 0; 558 | margin-bottom: 0; 559 | margin-left: 0; 560 | } 561 | 562 | ul { 563 | margin-left: 0; 564 | } 565 | 566 | li > ul { 567 | /* Matches the 30px from the "ul, ol" selector above */ 568 | margin-left: 30px; 569 | } 570 | 571 | .document { 572 | width: auto; 573 | } 574 | 575 | .footer { 576 | width: auto; 577 | } 578 | 579 | .bodywrapper { 580 | margin: 0; 581 | } 582 | 583 | .footer { 584 | width: auto; 585 | } 586 | 587 | .github { 588 | display: none; 589 | } 590 | 591 | 592 | 593 | } 594 | 595 | 596 | 597 | @media screen and (max-width: 875px) { 598 | 599 | body { 600 | margin: 0; 601 | padding: 20px 30px; 602 | } 603 | 604 | div.documentwrapper { 605 | float: none; 606 | background: #fff; 607 | } 608 | 609 | div.sphinxsidebar { 610 | display: block; 611 | float: none; 612 | width: 102.5%; 613 | margin: 50px -30px -20px -30px; 614 | padding: 10px 20px; 615 | background: #333; 616 | color: #FFF; 617 | } 618 | 619 | div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, 620 | div.sphinxsidebar h3 a { 621 | color: #fff; 622 | } 623 | 624 | div.sphinxsidebar a { 625 | color: #AAA; 626 | } 627 | 628 | div.sphinxsidebar p.logo { 629 | display: none; 630 | } 631 | 632 | div.document { 633 | width: 100%; 634 | margin: 0; 635 | } 636 | 637 | div.footer { 638 | display: none; 639 | } 640 | 641 | div.bodywrapper { 642 | margin: 0; 643 | } 644 | 645 | div.body { 646 | min-height: 0; 647 | padding: 0; 648 | } 649 | 650 | .rtd_doc_footer { 651 | display: none; 652 | } 653 | 654 | .document { 655 | width: auto; 656 | } 657 | 658 | .footer { 659 | width: auto; 660 | } 661 | 662 | .footer { 663 | width: auto; 664 | } 665 | 666 | .github { 667 | display: none; 668 | } 669 | } 670 | 671 | 672 | /* misc. */ 673 | 674 | .revsys-inline { 675 | display: none!important; 676 | } 677 | 678 | /* Make nested-list/multi-paragraph items look better in Releases changelog 679 | * pages. Without this, docutils' magical list fuckery causes inconsistent 680 | * formatting between different release sub-lists. 681 | */ 682 | div#changelog > div.section > ul > li > p:only-child { 683 | margin-bottom: 0; 684 | } 685 | 686 | /* Hide fugly table cell borders in ..bibliography:: directive output */ 687 | table.docutils.citation, table.docutils.citation td, table.docutils.citation th { 688 | border: none; 689 | /* Below needed in some edge cases; if not applied, bottom shadows appear */ 690 | -moz-box-shadow: none; 691 | -webkit-box-shadow: none; 692 | box-shadow: none; 693 | } -------------------------------------------------------------------------------- /cwmi/__init__.py: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Copyright 2018 FireEye Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ######################################################################## 16 | 17 | from .wmi import * 18 | from .winapi import * 19 | 20 | 21 | def create_variant(val, v_type=None): 22 | ''' 23 | Creates a VARIANT instance from a given value 24 | 25 | Args: 26 | val (any): The value to use when creating the VARIANT instance 27 | v_type (int): Variant type 28 | 29 | Returns: 30 | Initialized VARIANT instance 31 | ''' 32 | var = winapi.VARIANT() 33 | winapi.SET_VT(var, winapi.VT_NULL) 34 | if v_type: 35 | if v_type == winapi.VT_I4: 36 | winapi.SET_VT(var, winapi.VT_I4) 37 | winapi.V_VAR(var).lVal = ctypes.c_int32(val) 38 | elif v_type == winapi.VT_R4: 39 | winapi.SET_VT(var, winapi.VT_R4) 40 | winapi.V_VAR(var).fltVal = ctypes.c_float(val) 41 | elif v_type == winapi.VT_LPWSTR: 42 | winapi.SET_VT(var, winapi.VT_LPWSTR) 43 | winapi.V_VAR(var).bstrVal = val 44 | elif v_type == winapi.VT_BSTR: 45 | winapi.SET_VT(var, winapi.VT_BSTR) 46 | bstr = winapi.SysAllocString(val) 47 | winapi.V_VAR(var).bstrVal = bstr 48 | else: 49 | raise NotImplemented() 50 | else: 51 | if isinstance(val, int): 52 | winapi.SET_VT(var, winapi.VT_I4) 53 | winapi.V_VAR(var).lVal = ctypes.c_int32(val) 54 | elif isinstance(val, float): 55 | winapi.SET_VT(var, winapi.VT_R4) 56 | winapi.V_VAR(var).fltVal = ctypes.c_float(val) 57 | elif isinstance(val, str): 58 | winapi.SET_VT(var, winapi.VT_BSTR) 59 | bstr = winapi.SysAllocString(val) 60 | winapi.V_VAR(var).bstrVal = bstr 61 | else: 62 | raise NotImplemented() 63 | return var 64 | 65 | 66 | def destroy_variant(var): 67 | ''' 68 | Destroys an instance of a VARIANT 69 | 70 | Args: 71 | var (VARIANT): Instance to destroy 72 | 73 | Returns: 74 | Nothing 75 | ''' 76 | if winapi.V_VT(var) == winapi.VT_BSTR: 77 | winapi.SysFreeString(winapi.V_VAR3(var).bstrVal) 78 | 79 | 80 | def obj_to_dict(obj, include_var_type=False, flags=0): 81 | ''' 82 | Converts WMI object to python dictionary 83 | 84 | Args: 85 | obj (any): The object to convert 86 | include_var_type (bool): Include variant type 87 | flags (int): Flags to pass into WMI API(s) 88 | 89 | Returns: 90 | Dictionary containing object information 91 | ''' 92 | ret = {} 93 | obj.BeginEnumeration(flags) 94 | while True: 95 | try: 96 | prop_name, var, _, _ = obj.Next(flags) 97 | if include_var_type: 98 | ret[prop_name] = winapi.V_TO_VT_DICT(var) 99 | else: 100 | ret[prop_name] = winapi.V_TO_TYPE(var) 101 | except WindowsError: 102 | break 103 | obj.EndEnumeration() 104 | return ret 105 | 106 | 107 | def safe_array_to_list(safe_array, element_type): 108 | ''' 109 | Converts SAFEARRAY structure to python list 110 | 111 | Args: 112 | safe_array (SAFEARRAY): Array structure to convert 113 | element_type (any): Type of the elements contained in the structure 114 | 115 | Returns: 116 | List containing the converted array elements 117 | ''' 118 | ret = [] 119 | data = winapi.SafeArrayAccessData(safe_array) 120 | str_array = ctypes.cast(data, ctypes.POINTER(element_type)) 121 | try: 122 | for i in range(safe_array.contents.cbElements): 123 | ret.append(str_array[i]) 124 | finally: 125 | winapi.SafeArrayUnaccessData(safe_array) 126 | winapi.SafeArrayDestroy(safe_array) 127 | return ret 128 | 129 | 130 | def get_object_info(namespace, obj_name, values, user=None, password=None, include_var_type=False, flags=0): 131 | ''' 132 | Gets desired values from an object. 133 | 134 | Args: 135 | namespace (str): Namespace to connect to 136 | obj_name (str): Path to object instance/class 137 | values (list): List of values to pull from object 138 | user (str): Username to use when connecting to remote system 139 | password (str): Password to use for remote connection 140 | include_var_type (bool): Include variant type 141 | flags (int): Flags to pass into WMI API(s) 142 | 143 | Returns: 144 | Dictionary containing object data 145 | ''' 146 | ret = {} 147 | with WMI(namespace, user, password) as svc: 148 | with svc.GetObject(obj_name, flags, None) as obj: 149 | for value in values: 150 | var, _, _ = obj.Get(value, flags) 151 | if include_var_type: 152 | ret[value] = winapi.V_TO_VT_DICT(var) 153 | else: 154 | ret[value] = winapi.V_TO_TYPE(var) 155 | return ret 156 | 157 | 158 | def get_all_object_info(namespace, obj_name, user=None, password=None, include_var_type=False, flags=0): 159 | ''' 160 | Gets all data from an object 161 | 162 | Args: 163 | namespace (str): Namespace to connect to 164 | obj_name (str): Path to object instance/class 165 | user (str): Username to use when connecting to remote system 166 | password (str): Password to use for remote connection 167 | include_var_type (bool): Include variant type 168 | flags (int): Flags to pass into WMI API(s) 169 | 170 | Returns: 171 | Dictionary containing object data 172 | ''' 173 | with WMI(namespace, user, password) as svc: 174 | with svc.GetObject(obj_name, flags, None) as obj: 175 | ret = obj_to_dict(obj, include_var_type, flags) 176 | return ret 177 | 178 | 179 | def get_object_names(namespace, obj_name, user=None, password=None, flags=0): 180 | ''' 181 | Gets all names from a given object 182 | 183 | Args: 184 | namespace (str): Namespace to connect to 185 | obj_name (str): Path to object instance/class 186 | user (str): Username to use when connecting to remote system 187 | password (str): Password to use for remote connection 188 | flags (int): Flags to pass into WMI API(s) 189 | 190 | Returns: 191 | List containing object names 192 | ''' 193 | with WMI(namespace, user, password) as svc: 194 | with svc.GetObject(obj_name, flags, None) as obj: 195 | ret = safe_array_to_list(obj.GetNames(None, flags, None), ctypes.c_wchar_p) 196 | return ret 197 | 198 | 199 | def query(namespace, query_str, query_type='WQL', user=None, password=None, include_var_type=False, flags=0): 200 | ''' 201 | Performs a WMI query 202 | 203 | Args: 204 | namespace (str): Namespace to connect to 205 | query_str (str): String to use for the query 206 | query_type (str): Path to object instance/class 207 | user (str): Username to use when connecting to remote system 208 | password (str): Password to use for remote connection 209 | include_var_type (bool): Include variant type 210 | flags (int): Flags to pass into WMI API(s) 211 | 212 | Returns: 213 | Dictionary containing all objects returned by query 214 | ''' 215 | ret = {} 216 | with WMI(namespace, user, password) as svc: 217 | with svc.ExecQuery(query_type, query_str, flags, None) as enum: 218 | # do query, then get all data 219 | while True: 220 | try: 221 | with enum.Next(winapi.WBEM_INFINITE) as obj: 222 | obj.BeginEnumeration(flags) 223 | 224 | inst_data = {} 225 | while True: 226 | try: 227 | prop_name, var, _, _ = obj.Next(flags) 228 | if include_var_type: 229 | inst_data[prop_name] = winapi.V_TO_VT_DICT(var) 230 | else: 231 | inst_data[prop_name] = winapi.V_TO_TYPE(var) 232 | except WindowsError: 233 | break 234 | 235 | obj.EndEnumeration() 236 | var, _, _ = obj.Get('__RELPATH', flags) 237 | inst_relpath = winapi.V_TO_STR(var) 238 | # use instance relative path for key 239 | ret[inst_relpath] = inst_data 240 | except WindowsError: 241 | break 242 | return ret 243 | 244 | 245 | def does_object_exist(namespace, obj_name, user=None, password=None, flags=0): 246 | ''' 247 | Tests if a given object exists 248 | 249 | Args: 250 | namespace (str): Namespace to connect to 251 | obj_name (str): Path to object instance/class 252 | user (str): Username to use when connecting to remote system 253 | password (str): Password to use for remote connection 254 | flags (int): Flags to pass into WMI API(s) 255 | 256 | Returns: 257 | True if object exists, or False if not 258 | ''' 259 | ret = True 260 | with WMI(namespace, user, password) as svc: 261 | try: 262 | with svc.GetObject(obj_name, flags, None): 263 | pass 264 | except WindowsError: 265 | ret = False 266 | return ret 267 | 268 | 269 | def get_method_names(namespace, obj_name, user=None, password=None, flags=0): 270 | ''' 271 | Gets all method names from a given object 272 | 273 | Args: 274 | namespace (str): Namespace to connect to 275 | obj_name (str): Path to object instance/class 276 | user (str): Username to use when connecting to remote system 277 | password (str): Password to use for remote connection 278 | flags (int): Flags to pass into WMI API(s) 279 | 280 | Returns: 281 | List of method names 282 | ''' 283 | ret = [] 284 | with WMI(namespace, user, password) as svc: 285 | with svc.GetObject(obj_name, flags, None) as obj: 286 | obj.BeginMethodEnumeration(flags) 287 | while True: 288 | try: 289 | method_name, in_param, out_param = obj.NextMethod(flags) 290 | ret.append(method_name) 291 | except WindowsError: 292 | break 293 | obj.EndMethodEnumeration() 294 | return ret 295 | 296 | 297 | def get_method_info(namespace, obj_name, user=None, password=None, flags=0): 298 | ''' 299 | Gets method information for a given object/method 300 | 301 | Args: 302 | namespace (str): Namespace to connect to 303 | obj_name (str): Path to object instance/class 304 | user (str): Username to use when connecting to remote system 305 | password (str): Password to use for remote connection 306 | flags (int): Flags to pass into WMI API(s) 307 | 308 | Returns: 309 | Dictionary containing method parameter info 310 | ''' 311 | ret = {} 312 | with WMI(namespace, user, password) as svc: 313 | with svc.GetObject(obj_name, flags, None) as obj: 314 | obj.BeginMethodEnumeration(flags) 315 | 316 | while True: 317 | try: 318 | method_name, in_sig, out_sig = obj.NextMethod(flags) 319 | in_sig_vals = {} 320 | if in_sig: 321 | in_sig_vals = obj_to_dict(in_sig) 322 | in_sig.Release() 323 | 324 | out_sig_vals = {} 325 | if out_sig: 326 | out_sig_vals = obj_to_dict(out_sig) 327 | out_sig.Release() 328 | 329 | ret[method_name] = {'in_signature': in_sig_vals, 330 | 'out_signature': out_sig_vals} 331 | except WindowsError: 332 | break 333 | 334 | obj.EndMethodEnumeration() 335 | return ret 336 | 337 | 338 | def call_method(namespace, obj_path, method_name, input_params=None, user=None, password=None, flags=0): 339 | ''' 340 | Calls object method 341 | 342 | Args: 343 | namespace (str): Namespace to connect to 344 | obj_path (str): Path to object instance/class 345 | method_name (str): Name of the method to call 346 | input_params (dict): Method input parameters 347 | user (str): Username to use when connecting to remote system 348 | password (str): Password to use for remote connection 349 | flags (int): Flags to pass into WMI API(s) 350 | 351 | Returns: 352 | Dictionary containing data returned from the called method 353 | ''' 354 | ret = {} 355 | with WMI(namespace, user, password) as svc: 356 | class_name = obj_path 357 | if '.' in class_name: 358 | class_name = class_name.split('.')[0] 359 | 360 | with svc.GetObject(class_name, flags, None) as obj: 361 | if input_params: 362 | in_obj_param, out_obj_param = obj.GetMethod(method_name, flags) 363 | if in_obj_param: 364 | for prop, var in input_params.items(): 365 | if isinstance(var, dict) or not isinstance(var, VARIANT): 366 | if isinstance(var, dict): 367 | if 'type' in var: 368 | in_var = create_variant(var['value'], var['type']) 369 | else: 370 | raise Exception('Variant type must be specified') 371 | else: 372 | in_var = create_variant(var) 373 | in_obj_param.Put(prop, flags, in_var, 0) 374 | destroy_variant(in_var) 375 | else: 376 | in_obj_param.Put(prop, flags, var, 0) 377 | else: 378 | in_obj_param, out_obj_param = obj.GetMethod(method_name, flags) 379 | 380 | if out_obj_param: 381 | out_obj_param.Release() 382 | 383 | out_obj = svc.ExecMethod(obj_path, method_name, flags, None, in_obj_param) 384 | if in_obj_param: 385 | in_obj_param.Release() 386 | if out_obj: 387 | ret = obj_to_dict(out_obj) 388 | out_obj.Release() 389 | return ret 390 | -------------------------------------------------------------------------------- /utils/i_to_m.py: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Copyright 2018 FireEye Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | ######################################################################## 16 | 17 | import os 18 | import re 19 | import keyword 20 | import argparse 21 | 22 | 23 | # only converts interface classes that are children of IUnknown 24 | def convert_interface(infile, outfile, interface_name, overwrite): 25 | output_data = '' 26 | interface = {} 27 | 28 | with open(infile) as input_file: 29 | search_line = '{:s} : public IUnknown'.format(interface_name) 30 | interface_started = False 31 | method_started = False 32 | method_idx = 3 33 | method = {} 34 | for line in input_file.readlines(): 35 | # look for our interface 36 | line_stripped = line.strip() 37 | if line_stripped and line_stripped.endswith(search_line): 38 | if not interface_started: 39 | if overwrite or not os.path.exists(outfile): 40 | output_data += 'import ctypes\n' 41 | output_data += 'from ctypes import wintypes\n\n' 42 | output_data += 'from .winerr import *\n' 43 | output_data += 'from .wintype import *\n' 44 | output_data += 'from . import winapi\n' 45 | output_data += 'from . import com\n\n\n' 46 | output_data += '_In_ = 1\n' 47 | output_data += '_Out_ = 2\n\n' 48 | else: 49 | output_data += '\n\n' 50 | interface_started = True 51 | elif line_stripped and interface_started: 52 | 53 | if line_stripped.endswith('};'): 54 | # were done parsing interface 55 | break 56 | 57 | # gather interface data 58 | if line_stripped.startswith('virtual') and not method_started: 59 | # get name and return type 60 | method['return_type'] = line_stripped.split(' ')[1] 61 | method['name'] = line_stripped.split(' ')[3].replace('(', '') 62 | method_started = True 63 | 64 | # special case for void methods 65 | if line_stripped.endswith(') = 0;'): 66 | method['params'] = {} 67 | interface[method_idx] = method 68 | method = {} 69 | method_idx += 1 70 | method_started = False 71 | elif method_started: 72 | param = {} 73 | # processing parameters, out takes precedence 74 | if '[out]' in line_stripped: 75 | param['direction'] = '_Out_' 76 | else: 77 | param['direction'] = '_In_' 78 | 79 | name_idx = -1 80 | type_idx = name_idx - 1 81 | 82 | if line_stripped.endswith(','): 83 | char = ',' 84 | else: 85 | name_idx -= 2 86 | type_idx = name_idx - 1 87 | char = ')' 88 | 89 | if '* *' in line_stripped: 90 | type_idx -= 1 91 | 92 | param['name'] = line_stripped.split(' ')[name_idx].replace(char, '') 93 | param['type'] = line_stripped.split(' ')[type_idx].replace(char, '') 94 | 95 | if '* *' in line_stripped: 96 | param['name'] = param['name'].replace('*', '**') 97 | 98 | param['converted_name'] = convert_param(method, param['name']) 99 | param['call_name'] = param['converted_name'] 100 | 101 | pointer_count = len(param['name'].split('*')) - 1 102 | param['pointer_count'] = pointer_count 103 | 104 | if pointer_count: 105 | param['type'] += '{:s}'.format('*' * pointer_count) 106 | param['name'] = param['name'].replace('*', '') 107 | 108 | if 'params' in method: 109 | method['params'].append(param) 110 | else: 111 | method['params'] = [param] 112 | 113 | if line_stripped.endswith(') = 0;'): 114 | # we are now done parsing this method 115 | interface[method_idx] = method 116 | method = {} 117 | method_idx += 1 118 | method_started = False 119 | 120 | # set output data base on gathered interface information. must be sorted 121 | idx_data = '' 122 | iface_data = 'class {:s}(com.IUnknown):\n'.format(interface_name) 123 | method_data = '' 124 | for idx, method in sorted(interface.items()): 125 | idx_str = '{:s}_{:s}_Idx'.format(interface_name, method['name']) 126 | idx_data += '{:s} = {:d}\n'.format(idx_str, idx) 127 | # for each interface, add method parameters 128 | # build method 129 | in_params_str = build_in_params_str(method['params']) 130 | method_data += '\n def {:s}({:s}):\n'.format(method['name'], in_params_str) 131 | method_data += build_prototype(method['params']) 132 | method_data += build_paramflags(method['params']) 133 | pt_str = ' _{:s} = prototype('.format(method['name']) 134 | sp = len(pt_str) 135 | method_data += '{:s}{:s},\n{:s}\'{:s}\',\n{:s}paramflags)\n'.format(pt_str, 136 | idx_str, 137 | ' ' * sp, 138 | method['name'], 139 | ' ' * sp) 140 | method_data += ' _{:s}.errcheck = winapi.RAISE_NON_ZERO_ERR\n'.format(method['name']) 141 | bstr_alloc_str = build_bstr_alloc(method['params']) 142 | method_data += bstr_alloc_str 143 | method_data += build_call(method, True if bstr_alloc_str else False) 144 | method_data += build_bstr_free(method['params'], True if bstr_alloc_str else False) 145 | method_data += build_return(method['params']) 146 | 147 | idx_data += '\n\n' 148 | if not method_data: 149 | method_data += ' pass' 150 | 151 | # stitch results 152 | output_data += idx_data + iface_data + method_data 153 | 154 | if output_data: 155 | mode = 'a' 156 | if overwrite: 157 | mode = 'w' 158 | with open(outfile, mode) as output_file: 159 | output_file.write(output_data) 160 | 161 | 162 | def build_bstr_alloc(params): 163 | bstr_alloc_str = '' 164 | for param in params: 165 | if param['type'] == 'BSTR': 166 | param['call_name'] = '{:s}_bstr'.format(param['converted_name']) 167 | # if network_resource is not None else None 168 | bstr_alloc_str += ' {:s} = winapi.SysAllocString({:s}) if {:s} is not None else None\n'.format( 169 | param['call_name'], 170 | param['converted_name'], 171 | param['converted_name']) 172 | return bstr_alloc_str 173 | 174 | 175 | def build_bstr_free(params, add_finally): 176 | if add_finally: 177 | bstr_free_str = ' finally:\n' 178 | else: 179 | bstr_free_str = '' 180 | for param in params: 181 | if param['type'] == 'BSTR': 182 | bstr_free_str += ' if {:s} is not None:\n winapi.SysFreeString({:s})\n'.format( 183 | param['call_name'], 184 | param['call_name']) 185 | return bstr_free_str 186 | 187 | 188 | def build_call(method, add_try): 189 | call_str = '' 190 | ret_count = 1 191 | ret_ptrs = [] 192 | try_str = '' 193 | if add_try: 194 | try_str = ' try:\n ' 195 | for param in method['params']: 196 | if param['direction'] == '_Out_': 197 | ret_obj_name = 'return_obj' if ret_count < 2 else 'return_obj{:d}'.format(ret_count) 198 | ret_ptrs.append(ret_obj_name) 199 | ret_count += 1 200 | 201 | if ret_ptrs: 202 | call_str += '{:s} {:s} = _{:s}(self.this'.format(try_str, 203 | ', '.join([ret_ptr for ret_ptr in ret_ptrs]), 204 | method['name']) 205 | else: 206 | call_str += '{:s} _{:s}(self.this'.format(try_str, method['name']) 207 | 208 | sp = len(call_str.split('(')[0]) - len(try_str) + (4 if try_str else 0) 209 | for param in method['params']: 210 | if param['direction'] == '_In_': 211 | in_call_str = param['call_name'] 212 | if '*' in param['type']: 213 | if param['type'].startswith('IWbem'): 214 | in_call_str = '{:s}.this if {:s} else None'.format(param['call_name'], 215 | param['call_name']) 216 | else: 217 | in_call_str = 'ctypes.byref({:s}) if {:s} else None'.format(param['call_name'], 218 | param['call_name']) 219 | call_str += ',\n{:s}{:s}'.format(' ' * (sp + 1), in_call_str) 220 | 221 | call_str += '\n{:s})\n'.format(' ' * (sp + 1)) 222 | return call_str 223 | 224 | 225 | def build_return(params): 226 | return_str = '' 227 | try_str = ' try:\n' 228 | except_str = ' except WindowsError:\n ' 229 | ret_count = 1 230 | ret_objs = [] 231 | for param in params: 232 | if param['direction'] == '_Out_': 233 | ret_obj_name = 'return_obj' if ret_count < 2 else 'return_obj{:d}'.format(ret_count) 234 | ret_objs.append(ret_obj_name) 235 | ret_count += 1 236 | if param['pointer_count'] > 1: 237 | if param['type'] == 'SAFEARRAY**': 238 | return_str += ' {:s} = ctypes.cast(wintypes.LPVOID({:s}), ctypes.POINTER(winapi.SAFEARRAY))\n'.format( # NOQA 239 | ret_obj_name, 240 | ret_obj_name) 241 | # return_str += ' {:s} = ctypes.cast(wintypes.LPVOID({:s}.contents.value), ctypes.POINTER(winapi.SAFEARRAY))\n'.format( # NOQA 242 | # ret_obj_name, 243 | # ret_obj_name) 244 | else: 245 | # return_str += '{:s} {:s} = {:s}(wintypes.LPVOID({:s}.contents.value))\n{:s}{:s} = None\n'.format( # NOQA 246 | # try_str, 247 | # ret_obj_name, 248 | # convert_type(param['type'].replace('*', '').strip()), 249 | # ret_obj_name, 250 | # except_str, 251 | # ret_obj_name) 252 | return_str += '{:s} {:s} = {:s}({:s})\n{:s}{:s} = None\n'.format( 253 | try_str, 254 | ret_obj_name, 255 | convert_type(param['type'].replace('*', '').strip()), 256 | ret_obj_name, 257 | except_str, 258 | ret_obj_name) 259 | 260 | elif param['pointer_count'] == 1 and 'BSTR' in param['type']: 261 | return_str += ' {:s} = winapi.convert_bstr_to_str({:s})\n'.format(ret_obj_name, 262 | ret_obj_name) 263 | if ret_objs: 264 | return_str += ' return {:s}\n'.format(', '.join([ret_obj for ret_obj in ret_objs])) 265 | return return_str 266 | 267 | 268 | def convert_type(type_str): 269 | if type_str == 'long': 270 | ret_str = 'ctypes.c_long' 271 | elif type_str == 'LPWSTR': 272 | ret_str = 'wintypes.LPWSTR' 273 | elif type_str == 'LPCWSTR': 274 | ret_str = 'wintypes.LPCWSTR' 275 | elif type_str == 'LONG': 276 | ret_str = 'wintypes.LONG' 277 | elif type_str == 'ULONG': 278 | ret_str = 'wintypes.ULONG' 279 | elif type_str == 'VARIANT': 280 | ret_str = 'winapi.VARIANT' 281 | elif type_str == 'SAFEARRAY': 282 | ret_str = 'winapi.SAFEARRAY' 283 | elif '**' in type_str or '* *' in type_str: 284 | ret_str = 'ctypes.POINTER(wintypes.LPVOID)' 285 | elif '*' in type_str: 286 | ret_str = 'ctypes.POINTER({:s})'.format(convert_type(type_str.replace('*', '').strip())) 287 | else: 288 | ret_str = type_str 289 | return ret_str 290 | 291 | 292 | def build_prototype(params): 293 | proto = ' prototype = ctypes.WINFUNCTYPE(HRESULT' 294 | for param in params: 295 | proto += ',\n{:s}{:s}'.format(' ' * 39, convert_type(param['type'])) 296 | proto += ')\n\n' 297 | return proto 298 | 299 | 300 | def build_paramflags(params): 301 | param_flags = ' paramflags = (' 302 | started = False 303 | for param in params: 304 | if started: 305 | sp = ' ' * 22 306 | else: 307 | sp = '' 308 | 309 | started = True 310 | param_flag = '{:s}({:s}, \'{:s}\'),\n'.format(sp, 311 | param['direction'], 312 | param['name']) 313 | 314 | # if param['direction'] == '_In_': 315 | # started = True 316 | # param_flag = '{:s}({:s}, \'{:s}\'),\n'.format(sp, param['direction'], param['name']) 317 | # else: 318 | # if param['pointer_count'] > 1: 319 | # param_flag = '{:s}({:s}, \'{:s}\', ctypes.pointer(wintypes.LPVOID(None))),\n'.format(sp, 320 | # param['direction'], 321 | # param['name']) 322 | # else: 323 | # param_flag = '{:s}({:s}, \'{:s}\'),\n'.format(sp, 324 | # param['direction'], 325 | # param['name']) 326 | param_flags += param_flag 327 | if len(params): 328 | param_flags += '{:s})\n\n'.format(' ' * 22) 329 | else: 330 | param_flags += ')\n\n' 331 | return param_flags 332 | 333 | 334 | def build_in_params_str(params): 335 | in_params = 'self' 336 | for param in params: 337 | if param['direction'] == '_In_': 338 | in_params += ', ' 339 | in_params += param['converted_name'] 340 | return in_params 341 | 342 | 343 | def convert_param(method, param): 344 | # remove notation, split by upper, convert to lowercase 345 | param_sanitized = param.replace('*', '') 346 | substr = param_sanitized 347 | try: 348 | substr = re.search('([A-Z]\w+)', param_sanitized).group(1) 349 | except: 350 | pass 351 | case_re = re.compile(r'((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))') 352 | converted_param = case_re.sub(r'_\1', substr).lower() 353 | if converted_param in keyword.kwlist or converted_param in dir(__builtins__): 354 | converted_param += '_param' 355 | # check for duplicates. if seen, append number to end 356 | if 'params' in method and len([param for param in method['params'] if param['name'] == converted_param]): 357 | param_names = [param['name'] for param in method['params']] 358 | for x in range(2, 10): 359 | count_name = '{:s}{:d}'.format(converted_param, x) 360 | if count_name not in param_names: 361 | converted_param = count_name 362 | break 363 | return converted_param 364 | 365 | 366 | if __name__ == '__main__': 367 | parser = argparse.ArgumentParser(description='Convert C++ interface into python module for use by cWMI') 368 | parser.add_argument('--infile', help='Input header file that contains the interface', required=True) 369 | parser.add_argument('--outfile', help='Output module file to write to', required=True) 370 | parser.add_argument('--interface', help='Name of the interface (case sensitive)', required=True) 371 | parser.add_argument('--overwrite', action='store_true', help='Overwrite existing file') 372 | args = parser.parse_args() 373 | print('Converting interface {:s}'.format(args.interface)) 374 | convert_interface(args.infile, 375 | args.outfile, 376 | args.interface, 377 | args.overwrite) 378 | print('Done!') 379 | -------------------------------------------------------------------------------- /docs/html/_static/searchtools.js: -------------------------------------------------------------------------------- 1 | /* 2 | * searchtools.js_t 3 | * ~~~~~~~~~~~~~~~~ 4 | * 5 | * Sphinx JavaScript utilities for the full-text search. 6 | * 7 | * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | 13 | /* Non-minified version JS is _stemmer.js if file is provided */ 14 | /** 15 | * Porter Stemmer 16 | */ 17 | var Stemmer = function() { 18 | 19 | var step2list = { 20 | ational: 'ate', 21 | tional: 'tion', 22 | enci: 'ence', 23 | anci: 'ance', 24 | izer: 'ize', 25 | bli: 'ble', 26 | alli: 'al', 27 | entli: 'ent', 28 | eli: 'e', 29 | ousli: 'ous', 30 | ization: 'ize', 31 | ation: 'ate', 32 | ator: 'ate', 33 | alism: 'al', 34 | iveness: 'ive', 35 | fulness: 'ful', 36 | ousness: 'ous', 37 | aliti: 'al', 38 | iviti: 'ive', 39 | biliti: 'ble', 40 | logi: 'log' 41 | }; 42 | 43 | var step3list = { 44 | icate: 'ic', 45 | ative: '', 46 | alize: 'al', 47 | iciti: 'ic', 48 | ical: 'ic', 49 | ful: '', 50 | ness: '' 51 | }; 52 | 53 | var c = "[^aeiou]"; // consonant 54 | var v = "[aeiouy]"; // vowel 55 | var C = c + "[^aeiouy]*"; // consonant sequence 56 | var V = v + "[aeiou]*"; // vowel sequence 57 | 58 | var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 59 | var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 60 | var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 61 | var s_v = "^(" + C + ")?" + v; // vowel in stem 62 | 63 | this.stemWord = function (w) { 64 | var stem; 65 | var suffix; 66 | var firstch; 67 | var origword = w; 68 | 69 | if (w.length < 3) 70 | return w; 71 | 72 | var re; 73 | var re2; 74 | var re3; 75 | var re4; 76 | 77 | firstch = w.substr(0,1); 78 | if (firstch == "y") 79 | w = firstch.toUpperCase() + w.substr(1); 80 | 81 | // Step 1a 82 | re = /^(.+?)(ss|i)es$/; 83 | re2 = /^(.+?)([^s])s$/; 84 | 85 | if (re.test(w)) 86 | w = w.replace(re,"$1$2"); 87 | else if (re2.test(w)) 88 | w = w.replace(re2,"$1$2"); 89 | 90 | // Step 1b 91 | re = /^(.+?)eed$/; 92 | re2 = /^(.+?)(ed|ing)$/; 93 | if (re.test(w)) { 94 | var fp = re.exec(w); 95 | re = new RegExp(mgr0); 96 | if (re.test(fp[1])) { 97 | re = /.$/; 98 | w = w.replace(re,""); 99 | } 100 | } 101 | else if (re2.test(w)) { 102 | var fp = re2.exec(w); 103 | stem = fp[1]; 104 | re2 = new RegExp(s_v); 105 | if (re2.test(stem)) { 106 | w = stem; 107 | re2 = /(at|bl|iz)$/; 108 | re3 = new RegExp("([^aeiouylsz])\\1$"); 109 | re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); 110 | if (re2.test(w)) 111 | w = w + "e"; 112 | else if (re3.test(w)) { 113 | re = /.$/; 114 | w = w.replace(re,""); 115 | } 116 | else if (re4.test(w)) 117 | w = w + "e"; 118 | } 119 | } 120 | 121 | // Step 1c 122 | re = /^(.+?)y$/; 123 | if (re.test(w)) { 124 | var fp = re.exec(w); 125 | stem = fp[1]; 126 | re = new RegExp(s_v); 127 | if (re.test(stem)) 128 | w = stem + "i"; 129 | } 130 | 131 | // Step 2 132 | re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; 133 | if (re.test(w)) { 134 | var fp = re.exec(w); 135 | stem = fp[1]; 136 | suffix = fp[2]; 137 | re = new RegExp(mgr0); 138 | if (re.test(stem)) 139 | w = stem + step2list[suffix]; 140 | } 141 | 142 | // Step 3 143 | re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; 144 | if (re.test(w)) { 145 | var fp = re.exec(w); 146 | stem = fp[1]; 147 | suffix = fp[2]; 148 | re = new RegExp(mgr0); 149 | if (re.test(stem)) 150 | w = stem + step3list[suffix]; 151 | } 152 | 153 | // Step 4 154 | re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; 155 | re2 = /^(.+?)(s|t)(ion)$/; 156 | if (re.test(w)) { 157 | var fp = re.exec(w); 158 | stem = fp[1]; 159 | re = new RegExp(mgr1); 160 | if (re.test(stem)) 161 | w = stem; 162 | } 163 | else if (re2.test(w)) { 164 | var fp = re2.exec(w); 165 | stem = fp[1] + fp[2]; 166 | re2 = new RegExp(mgr1); 167 | if (re2.test(stem)) 168 | w = stem; 169 | } 170 | 171 | // Step 5 172 | re = /^(.+?)e$/; 173 | if (re.test(w)) { 174 | var fp = re.exec(w); 175 | stem = fp[1]; 176 | re = new RegExp(mgr1); 177 | re2 = new RegExp(meq1); 178 | re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); 179 | if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) 180 | w = stem; 181 | } 182 | re = /ll$/; 183 | re2 = new RegExp(mgr1); 184 | if (re.test(w) && re2.test(w)) { 185 | re = /.$/; 186 | w = w.replace(re,""); 187 | } 188 | 189 | // and turn initial Y back to y 190 | if (firstch == "y") 191 | w = firstch.toLowerCase() + w.substr(1); 192 | return w; 193 | } 194 | } 195 | 196 | 197 | 198 | /** 199 | * Simple result scoring code. 200 | */ 201 | var Scorer = { 202 | // Implement the following function to further tweak the score for each result 203 | // The function takes a result array [filename, title, anchor, descr, score] 204 | // and returns the new score. 205 | /* 206 | score: function(result) { 207 | return result[4]; 208 | }, 209 | */ 210 | 211 | // query matches the full name of an object 212 | objNameMatch: 11, 213 | // or matches in the last dotted part of the object name 214 | objPartialMatch: 6, 215 | // Additive scores depending on the priority of the object 216 | objPrio: {0: 15, // used to be importantResults 217 | 1: 5, // used to be objectResults 218 | 2: -5}, // used to be unimportantResults 219 | // Used when the priority is not in the mapping. 220 | objPrioDefault: 0, 221 | 222 | // query found in title 223 | title: 15, 224 | // query found in terms 225 | term: 5 226 | }; 227 | 228 | 229 | 230 | 231 | 232 | var splitChars = (function() { 233 | var result = {}; 234 | var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648, 235 | 1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702, 236 | 2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971, 237 | 2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345, 238 | 3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761, 239 | 3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823, 240 | 4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125, 241 | 8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695, 242 | 11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587, 243 | 43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141]; 244 | var i, j, start, end; 245 | for (i = 0; i < singles.length; i++) { 246 | result[singles[i]] = true; 247 | } 248 | var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709], 249 | [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161], 250 | [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568], 251 | [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807], 252 | [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047], 253 | [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383], 254 | [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450], 255 | [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547], 256 | [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673], 257 | [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820], 258 | [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946], 259 | [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023], 260 | [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173], 261 | [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332], 262 | [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481], 263 | [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718], 264 | [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791], 265 | [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095], 266 | [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205], 267 | [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687], 268 | [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968], 269 | [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869], 270 | [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102], 271 | [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271], 272 | [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592], 273 | [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822], 274 | [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167], 275 | [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959], 276 | [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143], 277 | [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318], 278 | [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483], 279 | [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101], 280 | [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567], 281 | [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292], 282 | [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444], 283 | [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783], 284 | [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311], 285 | [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511], 286 | [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774], 287 | [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071], 288 | [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263], 289 | [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519], 290 | [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647], 291 | [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967], 292 | [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295], 293 | [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274], 294 | [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007], 295 | [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381], 296 | [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]]; 297 | for (i = 0; i < ranges.length; i++) { 298 | start = ranges[i][0]; 299 | end = ranges[i][1]; 300 | for (j = start; j <= end; j++) { 301 | result[j] = true; 302 | } 303 | } 304 | return result; 305 | })(); 306 | 307 | function splitQuery(query) { 308 | var result = []; 309 | var start = -1; 310 | for (var i = 0; i < query.length; i++) { 311 | if (splitChars[query.charCodeAt(i)]) { 312 | if (start !== -1) { 313 | result.push(query.slice(start, i)); 314 | start = -1; 315 | } 316 | } else if (start === -1) { 317 | start = i; 318 | } 319 | } 320 | if (start !== -1) { 321 | result.push(query.slice(start)); 322 | } 323 | return result; 324 | } 325 | 326 | 327 | 328 | 329 | /** 330 | * Search Module 331 | */ 332 | var Search = { 333 | 334 | _index : null, 335 | _queued_query : null, 336 | _pulse_status : -1, 337 | 338 | init : function() { 339 | var params = $.getQueryParameters(); 340 | if (params.q) { 341 | var query = params.q[0]; 342 | $('input[name="q"]')[0].value = query; 343 | this.performSearch(query); 344 | } 345 | }, 346 | 347 | loadIndex : function(url) { 348 | $.ajax({type: "GET", url: url, data: null, 349 | dataType: "script", cache: true, 350 | complete: function(jqxhr, textstatus) { 351 | if (textstatus != "success") { 352 | document.getElementById("searchindexloader").src = url; 353 | } 354 | }}); 355 | }, 356 | 357 | setIndex : function(index) { 358 | var q; 359 | this._index = index; 360 | if ((q = this._queued_query) !== null) { 361 | this._queued_query = null; 362 | Search.query(q); 363 | } 364 | }, 365 | 366 | hasIndex : function() { 367 | return this._index !== null; 368 | }, 369 | 370 | deferQuery : function(query) { 371 | this._queued_query = query; 372 | }, 373 | 374 | stopPulse : function() { 375 | this._pulse_status = 0; 376 | }, 377 | 378 | startPulse : function() { 379 | if (this._pulse_status >= 0) 380 | return; 381 | function pulse() { 382 | var i; 383 | Search._pulse_status = (Search._pulse_status + 1) % 4; 384 | var dotString = ''; 385 | for (i = 0; i < Search._pulse_status; i++) 386 | dotString += '.'; 387 | Search.dots.text(dotString); 388 | if (Search._pulse_status > -1) 389 | window.setTimeout(pulse, 500); 390 | } 391 | pulse(); 392 | }, 393 | 394 | /** 395 | * perform a search for something (or wait until index is loaded) 396 | */ 397 | performSearch : function(query) { 398 | // create the required interface elements 399 | this.out = $('#search-results'); 400 | this.title = $('

' + _('Searching') + '

').appendTo(this.out); 401 | this.dots = $('').appendTo(this.title); 402 | this.status = $('

').appendTo(this.out); 403 | this.output = $('