├── 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 |
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 |
45 |
46 |
47 |
48 |
49 | c
50 |
51 |
52 |
53 | cwmi
54 |
55 |
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 |
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 |
58 |
59 |
D
60 |
70 |
71 |
G
72 |
88 |
89 |
O
90 |
96 |
97 |
Q
98 |
104 |
105 |
S
106 |
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 | $('').
192 | attr('href', '#' + this.id).
193 | attr('title', _('Permalink to this headline')).
194 | appendTo(this);
195 | });
196 | $('dt[id]').each(function() {
197 | $('').
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 | $('' + _('Hide Search Matches') + '
')
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 = $('').appendTo(this.out);
404 |
405 | $('#search-progress').text(_('Preparing search...'));
406 | this.startPulse();
407 |
408 | // index already loaded, the browser was quick!
409 | if (this.hasIndex())
410 | this.query(query);
411 | else
412 | this.deferQuery(query);
413 | },
414 |
415 | /**
416 | * execute search (requires search index to be loaded)
417 | */
418 | query : function(query) {
419 | var i;
420 | var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
421 |
422 | // stem the searchterms and add them to the correct list
423 | var stemmer = new Stemmer();
424 | var searchterms = [];
425 | var excluded = [];
426 | var hlterms = [];
427 | var tmp = splitQuery(query);
428 | var objectterms = [];
429 | for (i = 0; i < tmp.length; i++) {
430 | if (tmp[i] !== "") {
431 | objectterms.push(tmp[i].toLowerCase());
432 | }
433 |
434 | if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
435 | tmp[i] === "") {
436 | // skip this "word"
437 | continue;
438 | }
439 | // stem the word
440 | var word = stemmer.stemWord(tmp[i].toLowerCase());
441 | // prevent stemmer from cutting word smaller than two chars
442 | if(word.length < 3 && tmp[i].length >= 3) {
443 | word = tmp[i];
444 | }
445 | var toAppend;
446 | // select the correct list
447 | if (word[0] == '-') {
448 | toAppend = excluded;
449 | word = word.substr(1);
450 | }
451 | else {
452 | toAppend = searchterms;
453 | hlterms.push(tmp[i].toLowerCase());
454 | }
455 | // only add if not already in the list
456 | if (!$u.contains(toAppend, word))
457 | toAppend.push(word);
458 | }
459 | var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
460 |
461 | // console.debug('SEARCH: searching for:');
462 | // console.info('required: ', searchterms);
463 | // console.info('excluded: ', excluded);
464 |
465 | // prepare search
466 | var terms = this._index.terms;
467 | var titleterms = this._index.titleterms;
468 |
469 | // array of [filename, title, anchor, descr, score]
470 | var results = [];
471 | $('#search-progress').empty();
472 |
473 | // lookup as object
474 | for (i = 0; i < objectterms.length; i++) {
475 | var others = [].concat(objectterms.slice(0, i),
476 | objectterms.slice(i+1, objectterms.length));
477 | results = results.concat(this.performObjectSearch(objectterms[i], others));
478 | }
479 |
480 | // lookup as search terms in fulltext
481 | results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
482 |
483 | // let the scorer override scores with a custom scoring function
484 | if (Scorer.score) {
485 | for (i = 0; i < results.length; i++)
486 | results[i][4] = Scorer.score(results[i]);
487 | }
488 |
489 | // now sort the results by score (in opposite order of appearance, since the
490 | // display function below uses pop() to retrieve items) and then
491 | // alphabetically
492 | results.sort(function(a, b) {
493 | var left = a[4];
494 | var right = b[4];
495 | if (left > right) {
496 | return 1;
497 | } else if (left < right) {
498 | return -1;
499 | } else {
500 | // same score: sort alphabetically
501 | left = a[1].toLowerCase();
502 | right = b[1].toLowerCase();
503 | return (left > right) ? -1 : ((left < right) ? 1 : 0);
504 | }
505 | });
506 |
507 | // for debugging
508 | //Search.lastresults = results.slice(); // a copy
509 | //console.info('search results:', Search.lastresults);
510 |
511 | // print the results
512 | var resultCount = results.length;
513 | function displayNextItem() {
514 | // results left, load the summary and display it
515 | if (results.length) {
516 | var item = results.pop();
517 | var listItem = $(' ');
518 | if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
519 | // dirhtml builder
520 | var dirname = item[0] + '/';
521 | if (dirname.match(/\/index\/$/)) {
522 | dirname = dirname.substring(0, dirname.length-6);
523 | } else if (dirname == 'index/') {
524 | dirname = '';
525 | }
526 | listItem.append($(' ').attr('href',
527 | DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
528 | highlightstring + item[2]).html(item[1]));
529 | } else {
530 | // normal html builders
531 | listItem.append($(' ').attr('href',
532 | item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
533 | highlightstring + item[2]).html(item[1]));
534 | }
535 | if (item[3]) {
536 | listItem.append($(' (' + item[3] + ') '));
537 | Search.output.append(listItem);
538 | listItem.slideDown(5, function() {
539 | displayNextItem();
540 | });
541 | } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
542 | var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX;
543 | if (suffix === undefined) {
544 | suffix = '.txt';
545 | }
546 | $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix),
547 | dataType: "text",
548 | complete: function(jqxhr, textstatus) {
549 | var data = jqxhr.responseText;
550 | if (data !== '' && data !== undefined) {
551 | listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
552 | }
553 | Search.output.append(listItem);
554 | listItem.slideDown(5, function() {
555 | displayNextItem();
556 | });
557 | }});
558 | } else {
559 | // no source available, just display title
560 | Search.output.append(listItem);
561 | listItem.slideDown(5, function() {
562 | displayNextItem();
563 | });
564 | }
565 | }
566 | // search finished, update title and status message
567 | else {
568 | Search.stopPulse();
569 | Search.title.text(_('Search Results'));
570 | if (!resultCount)
571 | Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
572 | else
573 | Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
574 | Search.status.fadeIn(500);
575 | }
576 | }
577 | displayNextItem();
578 | },
579 |
580 | /**
581 | * search for object names
582 | */
583 | performObjectSearch : function(object, otherterms) {
584 | var filenames = this._index.filenames;
585 | var docnames = this._index.docnames;
586 | var objects = this._index.objects;
587 | var objnames = this._index.objnames;
588 | var titles = this._index.titles;
589 |
590 | var i;
591 | var results = [];
592 |
593 | for (var prefix in objects) {
594 | for (var name in objects[prefix]) {
595 | var fullname = (prefix ? prefix + '.' : '') + name;
596 | if (fullname.toLowerCase().indexOf(object) > -1) {
597 | var score = 0;
598 | var parts = fullname.split('.');
599 | // check for different match types: exact matches of full name or
600 | // "last name" (i.e. last dotted part)
601 | if (fullname == object || parts[parts.length - 1] == object) {
602 | score += Scorer.objNameMatch;
603 | // matches in last name
604 | } else if (parts[parts.length - 1].indexOf(object) > -1) {
605 | score += Scorer.objPartialMatch;
606 | }
607 | var match = objects[prefix][name];
608 | var objname = objnames[match[1]][2];
609 | var title = titles[match[0]];
610 | // If more than one term searched for, we require other words to be
611 | // found in the name/title/description
612 | if (otherterms.length > 0) {
613 | var haystack = (prefix + ' ' + name + ' ' +
614 | objname + ' ' + title).toLowerCase();
615 | var allfound = true;
616 | for (i = 0; i < otherterms.length; i++) {
617 | if (haystack.indexOf(otherterms[i]) == -1) {
618 | allfound = false;
619 | break;
620 | }
621 | }
622 | if (!allfound) {
623 | continue;
624 | }
625 | }
626 | var descr = objname + _(', in ') + title;
627 |
628 | var anchor = match[3];
629 | if (anchor === '')
630 | anchor = fullname;
631 | else if (anchor == '-')
632 | anchor = objnames[match[1]][1] + '-' + fullname;
633 | // add custom score for some objects according to scorer
634 | if (Scorer.objPrio.hasOwnProperty(match[2])) {
635 | score += Scorer.objPrio[match[2]];
636 | } else {
637 | score += Scorer.objPrioDefault;
638 | }
639 | results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);
640 | }
641 | }
642 | }
643 |
644 | return results;
645 | },
646 |
647 | /**
648 | * search for full-text terms in the index
649 | */
650 | performTermsSearch : function(searchterms, excluded, terms, titleterms) {
651 | var docnames = this._index.docnames;
652 | var filenames = this._index.filenames;
653 | var titles = this._index.titles;
654 |
655 | var i, j, file;
656 | var fileMap = {};
657 | var scoreMap = {};
658 | var results = [];
659 |
660 | // perform the search on the required terms
661 | for (i = 0; i < searchterms.length; i++) {
662 | var word = searchterms[i];
663 | var files = [];
664 | var _o = [
665 | {files: terms[word], score: Scorer.term},
666 | {files: titleterms[word], score: Scorer.title}
667 | ];
668 |
669 | // no match but word was a required one
670 | if ($u.every(_o, function(o){return o.files === undefined;})) {
671 | break;
672 | }
673 | // found search word in contents
674 | $u.each(_o, function(o) {
675 | var _files = o.files;
676 | if (_files === undefined)
677 | return
678 |
679 | if (_files.length === undefined)
680 | _files = [_files];
681 | files = files.concat(_files);
682 |
683 | // set score for the word in each file to Scorer.term
684 | for (j = 0; j < _files.length; j++) {
685 | file = _files[j];
686 | if (!(file in scoreMap))
687 | scoreMap[file] = {}
688 | scoreMap[file][word] = o.score;
689 | }
690 | });
691 |
692 | // create the mapping
693 | for (j = 0; j < files.length; j++) {
694 | file = files[j];
695 | if (file in fileMap)
696 | fileMap[file].push(word);
697 | else
698 | fileMap[file] = [word];
699 | }
700 | }
701 |
702 | // now check if the files don't contain excluded terms
703 | for (file in fileMap) {
704 | var valid = true;
705 |
706 | // check if all requirements are matched
707 | if (fileMap[file].length != searchterms.length)
708 | continue;
709 |
710 | // ensure that none of the excluded terms is in the search result
711 | for (i = 0; i < excluded.length; i++) {
712 | if (terms[excluded[i]] == file ||
713 | titleterms[excluded[i]] == file ||
714 | $u.contains(terms[excluded[i]] || [], file) ||
715 | $u.contains(titleterms[excluded[i]] || [], file)) {
716 | valid = false;
717 | break;
718 | }
719 | }
720 |
721 | // if we have still a valid result we can add it to the result list
722 | if (valid) {
723 | // select one (max) score for the file.
724 | // for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
725 | var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
726 | results.push([docnames[file], titles[file], '', null, score, filenames[file]]);
727 | }
728 | }
729 | return results;
730 | },
731 |
732 | /**
733 | * helper function to return a node containing the
734 | * search summary for a given text. keywords is a list
735 | * of stemmed words, hlwords is the list of normal, unstemmed
736 | * words. the first one is used to find the occurrence, the
737 | * latter for highlighting it.
738 | */
739 | makeSearchSummary : function(text, keywords, hlwords) {
740 | var textLower = text.toLowerCase();
741 | var start = 0;
742 | $.each(keywords, function() {
743 | var i = textLower.indexOf(this.toLowerCase());
744 | if (i > -1)
745 | start = i;
746 | });
747 | start = Math.max(start - 120, 0);
748 | var excerpt = ((start > 0) ? '...' : '') +
749 | $.trim(text.substr(start, 240)) +
750 | ((start + 240 - text.length) ? '...' : '');
751 | var rv = $('
').text(excerpt);
752 | $.each(hlwords, function() {
753 | rv = rv.highlightText(this, 'highlighted');
754 | });
755 | return rv;
756 | }
757 | };
758 |
759 | $(document).ready(function() {
760 | Search.init();
761 | });
--------------------------------------------------------------------------------