File size: 3,694 Bytes
10865e1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import win32com
import win32com.client

if type(__path__) == type(""):
    # For freeze to work!
    import sys

    try:
        import adsi

        sys.modules["win32com.adsi.adsi"] = adsi
    except ImportError:
        pass
else:
    # See if we have a special directory for the binaries (for developers)
    win32com.__PackageSupportBuildPath__(__path__)


# Some helpers
# We want to _look_ like the ADSI module, but provide some additional
# helpers.

# Of specific note - most of the interfaces supported by ADSI
# derive from IDispatch - thus, you get the custome methods from the
# interface, as well as via IDispatch.
import pythoncom

from .adsi import *

LCID = 0

IDispatchType = pythoncom.TypeIIDs[pythoncom.IID_IDispatch]
IADsContainerType = pythoncom.TypeIIDs[adsi.IID_IADsContainer]


def _get_good_ret(
    ob,
    # Named arguments used internally
    resultCLSID=None,
):
    assert resultCLSID is None, "Now have type info for ADSI objects - fix me!"
    # See if the object supports IDispatch
    if hasattr(ob, "Invoke"):
        import win32com.client.dynamic

        name = "Dispatch wrapper around %r" % ob
        return win32com.client.dynamic.Dispatch(ob, name, ADSIDispatch)
    return ob


class ADSIEnumerator:
    def __init__(self, ob):
        # Query the object for the container interface.
        self._cont_ = ob.QueryInterface(IID_IADsContainer)
        self._oleobj_ = ADsBuildEnumerator(self._cont_)  # a PyIADsEnumVARIANT
        self.index = -1

    def __getitem__(self, index):
        return self.__GetIndex(index)

    def __call__(self, index):
        return self.__GetIndex(index)

    def __GetIndex(self, index):
        if type(index) != type(0):
            raise TypeError("Only integer indexes are supported for enumerators")
        if index != self.index + 1:
            # Index requested out of sequence.
            raise ValueError("You must index this object sequentially")
        self.index = index
        result = ADsEnumerateNext(self._oleobj_, 1)
        if len(result):
            return _get_good_ret(result[0])
        # Failed - reset for next time around.
        self.index = -1
        self._oleobj_ = ADsBuildEnumerator(self._cont_)  # a PyIADsEnumVARIANT
        raise IndexError("list index out of range")


class ADSIDispatch(win32com.client.CDispatch):
    def _wrap_dispatch_(
        self, ob, userName=None, returnCLSID=None, UnicodeToString=None
    ):
        assert UnicodeToString is None, "this is deprectated and will be removed"
        if not userName:
            userName = "ADSI-object"
        olerepr = win32com.client.dynamic.MakeOleRepr(ob, None, None)
        return ADSIDispatch(ob, olerepr, userName)

    def _NewEnum(self):
        try:
            return ADSIEnumerator(self)
        except pythoncom.com_error:
            # doesnt support it - let our base try!
            return win32com.client.CDispatch._NewEnum(self)

    def __getattr__(self, attr):
        try:
            return getattr(self._oleobj_, attr)
        except AttributeError:
            return win32com.client.CDispatch.__getattr__(self, attr)

    def QueryInterface(self, iid):
        ret = self._oleobj_.QueryInterface(iid)
        return _get_good_ret(ret)


# We override the global methods to do the right thing.
_ADsGetObject = ADsGetObject  # The one in the .pyd


def ADsGetObject(path, iid=pythoncom.IID_IDispatch):
    ret = _ADsGetObject(path, iid)
    return _get_good_ret(ret)


_ADsOpenObject = ADsOpenObject


def ADsOpenObject(path, username, password, reserved=0, iid=pythoncom.IID_IDispatch):
    ret = _ADsOpenObject(path, username, password, reserved, iid)
    return _get_good_ret(ret)