-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTODO.txt
111 lines (90 loc) · 5.21 KB
/
TODO.txt
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
- Probably not a problem: We don't handle interfaces that are not dual
in genproxy, i.e. dispinterface only. One important such is Range in
the Excel type library. But do we need to? Doesn't "dispinterface"
mean that the interface can be used only in the late-binding way,
and there thus is no need to generate any proxy class for it?
- We should handle references to another type library. For instance
_Application.CommandBars in the Word type library is a property of
type CommandBars which is defined in the MSO type library.
- We should handle an interface that is derived from another (and not
from IDispatch). For instance the above mentioned CommandBars in the
MSO type library is derived from the _IMsoDispObj interface (which
is derived from IDispatch).
- Expand the -t output to be even more useful. Make sure callbacks
(events) are also handled.
- Change terminology in code and comments: "Original application" =
for example Word or Excel. "Replacement application" = for example
Collabora Office. "Proxied application" is too unclear, we use the
"proxy" term too much already.
- Including a coclass should automatically also include its default
interface and default source interface, if any. (For instance, if
Word.Application is mentioned in the -I file, it should not be
necessary to mention Word._Application and Word.ApplicationEvents4.)
- Make sure we have just one CProxiedFoo object for each real COM
object. Currently we can get several if a method that creates one
causes a callback first where the real object is passed as a
parameter.
For instance: during the call to genericInvoke() in
CWord_Documents::Open() a DocumentOpen event is generated and then
in the DocumentOpen case in Word_ApplicationEvents4.cxx we create a
new CWord_Document to proxy it. (That is needed in case the event
handler calls interesting stuff on the object that we want to trace
or wrap.) Back in CWord_Documents::Open(), after genericInvoke has
returned, we again create a new CWord_Document to proxy the return
value from that function.
Commit 4deff7ec7bb883c93dc42ef5960867267bf3360f attempts to handle
this, not sure if it is enough.
- A VT_UNKNOWN VARIANT is an IUnknown pointer. (It is not something
"unknown" and weird.) We probably need to handle such in some
places.
- When doing no redirection, just tracing, as long as the client uses
late binding, we should be able to trace also interfaces we haven't
generated any proxies for, as long as all the necessary type
information is available at run-time. I have more or less ignored
that approach path since I started looking into VB6-created clients
that use early binding where we can trace (or redirect) only
interfaces for which we have generated proxies beforehand.
The condition above is quite a bold one, though. Can we be sure that
random clients (that aren't generic interpreters, like cscript,
which by necessity use late binding) really do use late binding,
that they only use IDispatch::Invoke to call methods, and not
directly call the methods of interfaces they "know"? Probably no. To
handle such, we would need to generate vtables and trampolines at
run-time.
Note: Now we have the possibility to generate trampolines at
run-time. (Vtables are trivial.) So should we start thinking about
this?
(Obviously it would be meaningless to do redirection of initially
unknown interfaces; how would the replacement app know what they do?
The point with tracing is to learn from the output what APIs
real-world clients use and then know what needs to be implemented in
a replacement app.)
But if we start tracing also unknown interfaces (using dynamically
generated vtables and trampolines), if those interfaces don't have
any type information, the resulting output will be a bit hard to
decipher... Still, might well be that it is what needs to be done
for actual customer end cases.
But anyway, how do we know the vtable size of unknown interfaces?
And the parameter lists of the methods? I am probably being too
optimistic above.
- Split up utils.hpp into smaller pieces. Especially, it would be good
to have stuff that the generated proxy classes don't need in
separate header(s), to avoid recompilations of those when those bits
change.
- Is the separate handling of VB6-created executables and others in
injecteddll.cpp:InjectedDllMainFunction() really necessary? Probably
could just use the generic code path for also VB6-generated
executables.
And if we do want to special-case VB6-generated executables, maybe
we need to do that elsewhere, too, so probably should set some
global flag in the parameter block when we have detected that the
wrapped program is a such.
- Add some subtle but obvious hints to the trace-only output to show
whether it is the generated proxy code or generic Invoke() code that
is handling something. (In the verbose output the mention of
genericInvoke() is a giveaway that it was called from generated
proxy code.)
- Turn this file and the other *.txt ones into *.md instead.
- Factor out the mostly copy-pasted identical sequences of hook()
calls in injecteddll.cpp into a separate function. (Checking
carefully whether they actually are identical, of course.)