1 /*
2  * Python bindings module for libolecf (pyolecf)
3  *
4  * Copyright (C) 2008-2021, Joachim Metz <joachim.metz@gmail.com>
5  *
6  * Refer to AUTHORS for acknowledgements.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <common.h>
23 #include <narrow_string.h>
24 #include <types.h>
25 
26 #if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI )
27 #include <stdlib.h>
28 #endif
29 
30 #include "pyolecf.h"
31 #include "pyolecf_error.h"
32 #include "pyolecf_file.h"
33 #include "pyolecf_file_object_io_handle.h"
34 #include "pyolecf_item.h"
35 #include "pyolecf_item_types.h"
36 #include "pyolecf_items.h"
37 #include "pyolecf_libbfio.h"
38 #include "pyolecf_libcerror.h"
39 #include "pyolecf_libolecf.h"
40 #include "pyolecf_property_section.h"
41 #include "pyolecf_property_sections.h"
42 #include "pyolecf_property_set.h"
43 #include "pyolecf_property_set_stream.h"
44 #include "pyolecf_property_value.h"
45 #include "pyolecf_property_values.h"
46 #include "pyolecf_python.h"
47 #include "pyolecf_stream.h"
48 #include "pyolecf_unused.h"
49 #include "pyolecf_value_types.h"
50 
51 #if !defined( LIBOLECF_HAVE_BFIO )
52 
53 LIBOLECF_EXTERN \
54 int libolecf_check_file_signature_file_io_handle(
55      libbfio_handle_t *file_io_handle,
56      libolecf_error_t **error );
57 
58 #endif /* !defined( LIBOLECF_HAVE_BFIO ) */
59 
60 /* The pyolecf module methods
61  */
62 PyMethodDef pyolecf_module_methods[] = {
63 	{ "get_version",
64 	  (PyCFunction) pyolecf_get_version,
65 	  METH_NOARGS,
66 	  "get_version() -> String\n"
67 	  "\n"
68 	  "Retrieves the version." },
69 
70 	{ "check_file_signature",
71 	  (PyCFunction) pyolecf_check_file_signature,
72 	  METH_VARARGS | METH_KEYWORDS,
73 	  "check_file_signature(filename) -> Boolean\n"
74 	  "\n"
75 	  "Checks if a file has an Object Linking and Embedding (OLE) Compound File (CF) signature." },
76 
77 	{ "check_file_signature_file_object",
78 	  (PyCFunction) pyolecf_check_file_signature_file_object,
79 	  METH_VARARGS | METH_KEYWORDS,
80 	  "check_file_signature_file_object(file_object) -> Boolean\n"
81 	  "\n"
82 	  "Checks if a file has an Object Linking and Embedding (OLE) Compound File (CF) signature using a file-like object." },
83 
84 	{ "open",
85 	  (PyCFunction) pyolecf_open_new_file,
86 	  METH_VARARGS | METH_KEYWORDS,
87 	  "open(filename, mode='r') -> Object\n"
88 	  "\n"
89 	  "Opens a file." },
90 
91 	{ "open_file_object",
92 	  (PyCFunction) pyolecf_open_new_file_with_file_object,
93 	  METH_VARARGS | METH_KEYWORDS,
94 	  "open_file_object(file_object, mode='r') -> Object\n"
95 	  "\n"
96 	  "Opens a file using a file-like object." },
97 
98 	/* Sentinel */
99 	{ NULL, NULL, 0, NULL }
100 };
101 
102 /* Retrieves the pyolecf/libolecf version
103  * Returns a Python object if successful or NULL on error
104  */
pyolecf_get_version(PyObject * self PYOLECF_ATTRIBUTE_UNUSED,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)105 PyObject *pyolecf_get_version(
106            PyObject *self PYOLECF_ATTRIBUTE_UNUSED,
107            PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
108 {
109 	const char *errors           = NULL;
110 	const char *version_string   = NULL;
111 	size_t version_string_length = 0;
112 
113 	PYOLECF_UNREFERENCED_PARAMETER( self )
114 	PYOLECF_UNREFERENCED_PARAMETER( arguments )
115 
116 	Py_BEGIN_ALLOW_THREADS
117 
118 	version_string = libolecf_get_version();
119 
120 	Py_END_ALLOW_THREADS
121 
122 	version_string_length = narrow_string_length(
123 	                         version_string );
124 
125 	/* Pass the string length to PyUnicode_DecodeUTF8
126 	 * otherwise it makes the end of string character is part
127 	 * of the string
128 	 */
129 	return( PyUnicode_DecodeUTF8(
130 	         version_string,
131 	         (Py_ssize_t) version_string_length,
132 	         errors ) );
133 }
134 
135 /* Checks if a file has an Object Linking and Embedding (OLE) Compound File (CF) signature
136  * Returns a Python object if successful or NULL on error
137  */
pyolecf_check_file_signature(PyObject * self PYOLECF_ATTRIBUTE_UNUSED,PyObject * arguments,PyObject * keywords)138 PyObject *pyolecf_check_file_signature(
139            PyObject *self PYOLECF_ATTRIBUTE_UNUSED,
140            PyObject *arguments,
141            PyObject *keywords )
142 {
143 	PyObject *string_object     = NULL;
144 	libcerror_error_t *error    = NULL;
145 	const char *filename_narrow = NULL;
146 	static char *function       = "pyolecf_check_file_signature";
147 	static char *keyword_list[] = { "filename", NULL };
148 	int result                  = 0;
149 
150 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
151 	const wchar_t *filename_wide = NULL;
152 #else
153 	PyObject *utf8_string_object = NULL;
154 #endif
155 
156 	PYOLECF_UNREFERENCED_PARAMETER( self )
157 
158 	/* Note that PyArg_ParseTupleAndKeywords with "s" will force Unicode strings to be converted to narrow character string.
159 	 * On Windows the narrow character strings contains an extended ASCII string with a codepage. Hence we get a conversion
160 	 * exception. This will also fail if the default encoding is not set correctly. We cannot use "u" here either since that
161 	 * does not allow us to pass non Unicode string objects and Python (at least 2.7) does not seems to automatically upcast them.
162 	 */
163 	if( PyArg_ParseTupleAndKeywords(
164 	     arguments,
165 	     keywords,
166 	     "O|",
167 	     keyword_list,
168 	     &string_object ) == 0 )
169 	{
170 		return( NULL );
171 	}
172 	PyErr_Clear();
173 
174 	result = PyObject_IsInstance(
175 	          string_object,
176 	          (PyObject *) &PyUnicode_Type );
177 
178 	if( result == -1 )
179 	{
180 		pyolecf_error_fetch_and_raise(
181 		 PyExc_RuntimeError,
182 		 "%s: unable to determine if string object is of type Unicode.",
183 		 function );
184 
185 		return( NULL );
186 	}
187 	else if( result != 0 )
188 	{
189 		PyErr_Clear();
190 
191 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
192 		filename_wide = (wchar_t *) PyUnicode_AsUnicode(
193 		                             string_object );
194 		Py_BEGIN_ALLOW_THREADS
195 
196 		result = libolecf_check_file_signature_wide(
197 		          filename_wide,
198 		          &error );
199 
200 		Py_END_ALLOW_THREADS
201 #else
202 		utf8_string_object = PyUnicode_AsUTF8String(
203 		                      string_object );
204 
205 		if( utf8_string_object == NULL )
206 		{
207 			pyolecf_error_fetch_and_raise(
208 			 PyExc_RuntimeError,
209 			 "%s: unable to convert Unicode string to UTF-8.",
210 			 function );
211 
212 			return( NULL );
213 		}
214 #if PY_MAJOR_VERSION >= 3
215 		filename_narrow = PyBytes_AsString(
216 		                   utf8_string_object );
217 #else
218 		filename_narrow = PyString_AsString(
219 		                   utf8_string_object );
220 #endif
221 		Py_BEGIN_ALLOW_THREADS
222 
223 		result = libolecf_check_file_signature(
224 		          filename_narrow,
225 		          &error );
226 
227 		Py_END_ALLOW_THREADS
228 
229 		Py_DecRef(
230 		 utf8_string_object );
231 
232 #endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
233 
234 		if( result == -1 )
235 		{
236 			pyolecf_error_raise(
237 			 error,
238 			 PyExc_IOError,
239 			 "%s: unable to check file signature.",
240 			 function );
241 
242 			libcerror_error_free(
243 			 &error );
244 
245 			return( NULL );
246 		}
247 		if( result != 0 )
248 		{
249 			Py_IncRef(
250 			 (PyObject *) Py_True );
251 
252 			return( Py_True );
253 		}
254 		Py_IncRef(
255 		 (PyObject *) Py_False );
256 
257 		return( Py_False );
258 	}
259 	PyErr_Clear();
260 
261 #if PY_MAJOR_VERSION >= 3
262 	result = PyObject_IsInstance(
263 	          string_object,
264 	          (PyObject *) &PyBytes_Type );
265 #else
266 	result = PyObject_IsInstance(
267 	          string_object,
268 	          (PyObject *) &PyString_Type );
269 #endif
270 	if( result == -1 )
271 	{
272 		pyolecf_error_fetch_and_raise(
273 		 PyExc_RuntimeError,
274 		 "%s: unable to determine if string object is of type string.",
275 		 function );
276 
277 		return( NULL );
278 	}
279 	else if( result != 0 )
280 	{
281 		PyErr_Clear();
282 
283 #if PY_MAJOR_VERSION >= 3
284 		filename_narrow = PyBytes_AsString(
285 		                   string_object );
286 #else
287 		filename_narrow = PyString_AsString(
288 		                   string_object );
289 #endif
290 		Py_BEGIN_ALLOW_THREADS
291 
292 		result = libolecf_check_file_signature(
293 		          filename_narrow,
294 		          &error );
295 
296 		Py_END_ALLOW_THREADS
297 
298 		if( result == -1 )
299 		{
300 			pyolecf_error_raise(
301 			 error,
302 			 PyExc_IOError,
303 			 "%s: unable to check file signature.",
304 			 function );
305 
306 			libcerror_error_free(
307 			 &error );
308 
309 			return( NULL );
310 		}
311 		if( result != 0 )
312 		{
313 			Py_IncRef(
314 			 (PyObject *) Py_True );
315 
316 			return( Py_True );
317 		}
318 		Py_IncRef(
319 		 (PyObject *) Py_False );
320 
321 		return( Py_False );
322 	}
323 	PyErr_Format(
324 	 PyExc_TypeError,
325 	 "%s: unsupported string object type.",
326 	 function );
327 
328 	return( NULL );
329 }
330 
331 /* Checks if a file has an Object Linking and Embedding (OLE) Compound File (CF) signature using a file-like object
332  * Returns a Python object if successful or NULL on error
333  */
pyolecf_check_file_signature_file_object(PyObject * self PYOLECF_ATTRIBUTE_UNUSED,PyObject * arguments,PyObject * keywords)334 PyObject *pyolecf_check_file_signature_file_object(
335            PyObject *self PYOLECF_ATTRIBUTE_UNUSED,
336            PyObject *arguments,
337            PyObject *keywords )
338 {
339 	PyObject *file_object            = NULL;
340 	libbfio_handle_t *file_io_handle = NULL;
341 	libcerror_error_t *error         = NULL;
342 	static char *function            = "pyolecf_check_file_signature_file_object";
343 	static char *keyword_list[]      = { "file_object", NULL };
344 	int result                       = 0;
345 
346 	PYOLECF_UNREFERENCED_PARAMETER( self )
347 
348 	if( PyArg_ParseTupleAndKeywords(
349 	     arguments,
350 	     keywords,
351 	     "O|",
352 	     keyword_list,
353 	     &file_object ) == 0 )
354 	{
355 		return( NULL );
356 	}
357 	if( pyolecf_file_object_initialize(
358 	     &file_io_handle,
359 	     file_object,
360 	     &error ) != 1 )
361 	{
362 		pyolecf_error_raise(
363 		 error,
364 		 PyExc_MemoryError,
365 		 "%s: unable to initialize file IO handle.",
366 		 function );
367 
368 		libcerror_error_free(
369 		 &error );
370 
371 		goto on_error;
372 	}
373 	Py_BEGIN_ALLOW_THREADS
374 
375 	result = libolecf_check_file_signature_file_io_handle(
376 	          file_io_handle,
377 	          &error );
378 
379 	Py_END_ALLOW_THREADS
380 
381 	if( result == -1 )
382 	{
383 		pyolecf_error_raise(
384 		 error,
385 		 PyExc_IOError,
386 		 "%s: unable to check file signature.",
387 		 function );
388 
389 		libcerror_error_free(
390 		 &error );
391 
392 		goto on_error;
393 	}
394 	if( libbfio_handle_free(
395 	     &file_io_handle,
396 	     &error ) != 1 )
397 	{
398 		pyolecf_error_raise(
399 		 error,
400 		 PyExc_MemoryError,
401 		 "%s: unable to free file IO handle.",
402 		 function );
403 
404 		libcerror_error_free(
405 		 &error );
406 
407 		goto on_error;
408 	}
409 	if( result != 0 )
410 	{
411 		Py_IncRef(
412 		 (PyObject *) Py_True );
413 
414 		return( Py_True );
415 	}
416 	Py_IncRef(
417 	 (PyObject *) Py_False );
418 
419 	return( Py_False );
420 
421 on_error:
422 	if( file_io_handle != NULL )
423 	{
424 		libbfio_handle_free(
425 		 &file_io_handle,
426 		 NULL );
427 	}
428 	return( NULL );
429 }
430 
431 /* Creates a new file object and opens it
432  * Returns a Python object if successful or NULL on error
433  */
pyolecf_open_new_file(PyObject * self PYOLECF_ATTRIBUTE_UNUSED,PyObject * arguments,PyObject * keywords)434 PyObject *pyolecf_open_new_file(
435            PyObject *self PYOLECF_ATTRIBUTE_UNUSED,
436            PyObject *arguments,
437            PyObject *keywords )
438 {
439 	pyolecf_file_t *pyolecf_file = NULL;
440 	static char *function        = "pyolecf_open_new_file";
441 
442 	PYOLECF_UNREFERENCED_PARAMETER( self )
443 
444 	/* PyObject_New does not invoke tp_init
445 	 */
446 	pyolecf_file = PyObject_New(
447 	                struct pyolecf_file,
448 	                &pyolecf_file_type_object );
449 
450 	if( pyolecf_file == NULL )
451 	{
452 		PyErr_Format(
453 		 PyExc_MemoryError,
454 		 "%s: unable to create file.",
455 		 function );
456 
457 		goto on_error;
458 	}
459 	if( pyolecf_file_init(
460 	     pyolecf_file ) != 0 )
461 	{
462 		goto on_error;
463 	}
464 	if( pyolecf_file_open(
465 	     pyolecf_file,
466 	     arguments,
467 	     keywords ) == NULL )
468 	{
469 		goto on_error;
470 	}
471 	return( (PyObject *) pyolecf_file );
472 
473 on_error:
474 	if( pyolecf_file != NULL )
475 	{
476 		Py_DecRef(
477 		 (PyObject *) pyolecf_file );
478 	}
479 	return( NULL );
480 }
481 
482 /* Creates a new file object and opens it using a file-like object
483  * Returns a Python object if successful or NULL on error
484  */
pyolecf_open_new_file_with_file_object(PyObject * self PYOLECF_ATTRIBUTE_UNUSED,PyObject * arguments,PyObject * keywords)485 PyObject *pyolecf_open_new_file_with_file_object(
486            PyObject *self PYOLECF_ATTRIBUTE_UNUSED,
487            PyObject *arguments,
488            PyObject *keywords )
489 {
490 	pyolecf_file_t *pyolecf_file = NULL;
491 	static char *function        = "pyolecf_open_new_file_with_file_object";
492 
493 	PYOLECF_UNREFERENCED_PARAMETER( self )
494 
495 	/* PyObject_New does not invoke tp_init
496 	 */
497 	pyolecf_file = PyObject_New(
498 	                struct pyolecf_file,
499 	                &pyolecf_file_type_object );
500 
501 	if( pyolecf_file == NULL )
502 	{
503 		PyErr_Format(
504 		 PyExc_MemoryError,
505 		 "%s: unable to create file.",
506 		 function );
507 
508 		goto on_error;
509 	}
510 	if( pyolecf_file_init(
511 	     pyolecf_file ) != 0 )
512 	{
513 		goto on_error;
514 	}
515 	if( pyolecf_file_open_file_object(
516 	     pyolecf_file,
517 	     arguments,
518 	     keywords ) == NULL )
519 	{
520 		goto on_error;
521 	}
522 	return( (PyObject *) pyolecf_file );
523 
524 on_error:
525 	if( pyolecf_file != NULL )
526 	{
527 		Py_DecRef(
528 		 (PyObject *) pyolecf_file );
529 	}
530 	return( NULL );
531 }
532 
533 #if PY_MAJOR_VERSION >= 3
534 
535 /* The pyolecf module definition
536  */
537 PyModuleDef pyolecf_module_definition = {
538 	PyModuleDef_HEAD_INIT,
539 
540 	/* m_name */
541 	"pyolecf",
542 	/* m_doc */
543 	"Python libolecf module (pyolecf).",
544 	/* m_size */
545 	-1,
546 	/* m_methods */
547 	pyolecf_module_methods,
548 	/* m_reload */
549 	NULL,
550 	/* m_traverse */
551 	NULL,
552 	/* m_clear */
553 	NULL,
554 	/* m_free */
555 	NULL,
556 };
557 
558 #endif /* PY_MAJOR_VERSION >= 3 */
559 
560 /* Initializes the pyolecf module
561  */
562 #if PY_MAJOR_VERSION >= 3
PyInit_pyolecf(void)563 PyMODINIT_FUNC PyInit_pyolecf(
564                 void )
565 #else
566 PyMODINIT_FUNC initpyolecf(
567                 void )
568 #endif
569 {
570 	PyObject *module           = NULL;
571 	PyGILState_STATE gil_state = 0;
572 
573 #if defined( HAVE_DEBUG_OUTPUT )
574 	libolecf_notify_set_stream(
575 	 stderr,
576 	 NULL );
577 	libolecf_notify_set_verbose(
578 	 1 );
579 #endif
580 
581 	/* Create the module
582 	 * This function must be called before grabbing the GIL
583 	 * otherwise the module will segfault on a version mismatch
584 	 */
585 #if PY_MAJOR_VERSION >= 3
586 	module = PyModule_Create(
587 	          &pyolecf_module_definition );
588 #else
589 	module = Py_InitModule3(
590 	          "pyolecf",
591 	          pyolecf_module_methods,
592 	          "Python libolecf module (pyolecf)." );
593 #endif
594 	if( module == NULL )
595 	{
596 #if PY_MAJOR_VERSION >= 3
597 		return( NULL );
598 #else
599 		return;
600 #endif
601 	}
602 #if PY_VERSION_HEX < 0x03070000
603 	PyEval_InitThreads();
604 #endif
605 	gil_state = PyGILState_Ensure();
606 
607 	/* Setup the file type object
608 	 */
609 	pyolecf_file_type_object.tp_new = PyType_GenericNew;
610 
611 	if( PyType_Ready(
612 	     &pyolecf_file_type_object ) < 0 )
613 	{
614 		goto on_error;
615 	}
616 	Py_IncRef(
617 	 (PyObject *) &pyolecf_file_type_object );
618 
619 	PyModule_AddObject(
620 	 module,
621 	 "file",
622 	 (PyObject *) &pyolecf_file_type_object );
623 
624 	/* Setup the item type object
625 	 */
626 	pyolecf_item_type_object.tp_new = PyType_GenericNew;
627 
628 	if( PyType_Ready(
629 	     &pyolecf_item_type_object ) < 0 )
630 	{
631 		goto on_error;
632 	}
633 	Py_IncRef(
634 	 (PyObject *) &pyolecf_item_type_object );
635 
636 	PyModule_AddObject(
637 	 module,
638 	 "item",
639 	 (PyObject *) &pyolecf_item_type_object );
640 
641 	/* Setup the item_types type object
642 	 */
643 	pyolecf_item_types_type_object.tp_new = PyType_GenericNew;
644 
645 	if( pyolecf_item_types_init_type(
646 	     &pyolecf_item_types_type_object ) != 1 )
647 	{
648 		goto on_error;
649 	}
650 	if( PyType_Ready(
651 	     &pyolecf_item_types_type_object ) < 0 )
652 	{
653 		goto on_error;
654 	}
655 	Py_IncRef(
656 	 (PyObject *) &pyolecf_item_types_type_object );
657 
658 	PyModule_AddObject(
659 	 module,
660 	 "item_types",
661 	 (PyObject *) &pyolecf_item_types_type_object );
662 
663 	/* Setup the items type object
664 	 */
665 	pyolecf_items_type_object.tp_new = PyType_GenericNew;
666 
667 	if( PyType_Ready(
668 	     &pyolecf_items_type_object ) < 0 )
669 	{
670 		goto on_error;
671 	}
672 	Py_IncRef(
673 	 (PyObject *) &pyolecf_items_type_object );
674 
675 	PyModule_AddObject(
676 	 module,
677 	 "items",
678 	 (PyObject *) &pyolecf_items_type_object );
679 
680 	/* Setup the property_section type object
681 	 */
682 	pyolecf_property_section_type_object.tp_new = PyType_GenericNew;
683 
684 	if( PyType_Ready(
685 	     &pyolecf_property_section_type_object ) < 0 )
686 	{
687 		goto on_error;
688 	}
689 	Py_IncRef(
690 	 (PyObject *) &pyolecf_property_section_type_object );
691 
692 	PyModule_AddObject(
693 	 module,
694 	 "property_section",
695 	 (PyObject *) &pyolecf_property_section_type_object );
696 
697 	/* Setup the property_sections type object
698 	 */
699 	pyolecf_property_sections_type_object.tp_new = PyType_GenericNew;
700 
701 	if( PyType_Ready(
702 	     &pyolecf_property_sections_type_object ) < 0 )
703 	{
704 		goto on_error;
705 	}
706 	Py_IncRef(
707 	 (PyObject *) &pyolecf_property_sections_type_object );
708 
709 	PyModule_AddObject(
710 	 module,
711 	 "property_sections",
712 	 (PyObject *) &pyolecf_property_sections_type_object );
713 
714 	/* Setup the property_set type object
715 	 */
716 	pyolecf_property_set_type_object.tp_new = PyType_GenericNew;
717 
718 	if( PyType_Ready(
719 	     &pyolecf_property_set_type_object ) < 0 )
720 	{
721 		goto on_error;
722 	}
723 	Py_IncRef(
724 	 (PyObject *) &pyolecf_property_set_type_object );
725 
726 	PyModule_AddObject(
727 	 module,
728 	 "property_set",
729 	 (PyObject *) &pyolecf_property_set_type_object );
730 
731 	/* Setup the property_set_stream type object
732 	 */
733 	pyolecf_property_set_stream_type_object.tp_new = PyType_GenericNew;
734 
735 	if( PyType_Ready(
736 	     &pyolecf_property_set_stream_type_object ) < 0 )
737 	{
738 		goto on_error;
739 	}
740 	Py_IncRef(
741 	 (PyObject *) &pyolecf_property_set_stream_type_object );
742 
743 	PyModule_AddObject(
744 	 module,
745 	 "property_set_stream",
746 	 (PyObject *) &pyolecf_property_set_stream_type_object );
747 
748 	/* Setup the stream type object
749 	 */
750 	pyolecf_stream_type_object.tp_new = PyType_GenericNew;
751 
752 	if( PyType_Ready(
753 	     &pyolecf_stream_type_object ) < 0 )
754 	{
755 		goto on_error;
756 	}
757 	Py_IncRef(
758 	 (PyObject *) &pyolecf_stream_type_object );
759 
760 	PyModule_AddObject(
761 	 module,
762 	 "stream",
763 	 (PyObject *) &pyolecf_stream_type_object );
764 
765 	/* Setup the property_value type object
766 	 */
767 	pyolecf_property_value_type_object.tp_new = PyType_GenericNew;
768 
769 	if( PyType_Ready(
770 	     &pyolecf_property_value_type_object ) < 0 )
771 	{
772 		goto on_error;
773 	}
774 	Py_IncRef(
775 	 (PyObject *) &pyolecf_property_value_type_object );
776 
777 	PyModule_AddObject(
778 	 module,
779 	 "property_value",
780 	 (PyObject *) &pyolecf_property_value_type_object );
781 
782 	/* Setup the property_values type object
783 	 */
784 	pyolecf_property_values_type_object.tp_new = PyType_GenericNew;
785 
786 	if( PyType_Ready(
787 	     &pyolecf_property_values_type_object ) < 0 )
788 	{
789 		goto on_error;
790 	}
791 	Py_IncRef(
792 	 (PyObject *) &pyolecf_property_values_type_object );
793 
794 	PyModule_AddObject(
795 	 module,
796 	 "property_values",
797 	 (PyObject *) &pyolecf_property_values_type_object );
798 
799 	/* Setup the value_types type object
800 	 */
801 	pyolecf_value_types_type_object.tp_new = PyType_GenericNew;
802 
803 	if( pyolecf_value_types_init_type(
804 	     &pyolecf_value_types_type_object ) != 1 )
805 	{
806 		goto on_error;
807 	}
808 	if( PyType_Ready(
809 	     &pyolecf_value_types_type_object ) < 0 )
810 	{
811 		goto on_error;
812 	}
813 	Py_IncRef(
814 	 (PyObject *) &pyolecf_value_types_type_object );
815 
816 	PyModule_AddObject(
817 	 module,
818 	 "value_types",
819 	 (PyObject *) &pyolecf_value_types_type_object );
820 
821 	PyGILState_Release(
822 	 gil_state );
823 
824 #if PY_MAJOR_VERSION >= 3
825 	return( module );
826 #else
827 	return;
828 #endif
829 
830 on_error:
831 	PyGILState_Release(
832 	 gil_state );
833 
834 #if PY_MAJOR_VERSION >= 3
835 	return( NULL );
836 #else
837 	return;
838 #endif
839 }
840 
841