summaryrefslogtreecommitdiff
path: root/source4/build/pidl/NOTES.txt
blob: 24e55db9ef1f5501fb18510ab6f41635227e1e87 (plain)
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
midl types
----------

pidl uses slightly different types to midl by default. The following
defines in your MS IDL may make things easier to use the same IDL on
both platforms.

#define unistr [string] wchar_t *
#define uint8 char
#define uint16 short
#define uint32 long
#define HYPER_T hyper


Let's look at the mutliple ways you can encode an array.

CONFORMANT ARRAYS
-----------------

A conformant array is one with that ends in [*] or []. The strange
things about conformant arrays are:

 * they can only appear as the last element of a structure

 * the array size appears before the structure itself on the wire. 

So, in this example:

	typedef struct {
		long abc;
		long count;     
		long foo;
		[size_is(count)] long s[*];
	} Struct1;

it appears like this:

[size_is] [abc] [count] [foo] [s...]

the first [size_is] field is the allocation size of the array, and
occurs before the array elements and even before the structure
alignment.

Note that size_is() can refer to a constant, but that doesn't change
the wire representation. It does not make the array a fixed array.

midl.exe would write the above array as the following C header:

       typedef struct {
		long abc;
		long count;     
		long foo;
		long s[1];
	} Struct1;

pidl takes a different approach, and writes it like this:

       typedef struct {
		long abc;
		long count;     
		long foo;
		long *s;
	} Struct1;



VARYING ARRAYS
--------------

A varying array looks like this:

	typedef struct {
		long abc;
		long count;     
		long foo;
		[size_is(count)] long *s;
	} Struct1;

This will look like this on the wire:

[abc] [count] [foo] [PTR_s]    [count] [s...]


FIXED ARRAYS
------------

A fixed array looks like this:

    typedef struct {
	    long s[10];
    } Struct1;

The NDR representation looks just like 10 separate long
declarations. The array size is not encoded on the wire.

pidl also supports "inline" arrays, which are not part of the IDL/NDR
standard. These are declared like this:

    typedef struct {
	    uint32 foo;
	    uint32 count;
	    uint32 bar;
	    long s[count];
    } Struct1;

This appears like this:

[foo] [count] [bar] [s...]

Fixed arrays are an extension added to support some of the strange
embedded structures in security descriptors and spoolss. 

Supported MIDL-compatible properties (attributes is the MIDL term)
------------------------------------
in
out
ref
public
length_is
switch_is
size_is
uuid
case
default
string
unique

PIDL Specific properties 
---------------
noprint
value
relative
subcontext
flag

Unsupported MIDL properties
---------------------------
aggregatable
appobject
async_uuid
bindable
call_as
coclass
control
cpp_quote
defaultbind
defaultcollelem
defaultvalue
defaultvtable
dispinterface
displaybind
dual
entry
first_is
helpcontext
helpfile
helpstringcontext
helpstringdll
helpstring
hidden
idl_module
idl_quote
id
iid_is
immediatebind
importlib
import
include
includelib
last_is
lcid
licensed
local
max_is
module
ms_union
no_injected_text
nonbrowsable
noncreatable
nonextensible
object
odl
oleautomation
optional
pointer_default
pragma
progid
propget
propputref
propput
ptr
range
readonly
requestedit
restricted
retval
source
switch_type
transmit_as
uidefault
usesgetlasterror
v1_enum
vararg
vi_progid
wire_marshal

[public] property
-----------------

The [public] property on a structure or union is a pidl extension that
forces the generated pull/push functions to be non-static. This allows
you to declare types that can be used between modules. If you don't
specify [public] then pull/push functions for other than top-level
functions are declared static.

[relative] property
-------------------

The [relative] property can be supplied on a pointer. When it is used
it declares the pointer as a spoolss style "relative" pointer, which
means it appears on the wire as an offset within the current
encapsulating structure. This is not part of normal IDL/NDR, but it is
a very useful extension as it avoids the manual encoding of many
complex structures.


[noprint] property
------------------

The [noprint] property is a pidl extension that allows you to specify
that pidl should not generate a ndr_print_*() function for that
structure or union. This is used when you wish to define your own
print function that prints a structure in a nicer manner. A good
example is the use of [noprint] on dom_sid, which allows the
pretty-printing of SIDs.

[value] property
----------------

The [value(expression)] property is a pidl extension that allows you
to specify the value of a field when it is put on the wire. This
allows fields that always have a well-known value to be automatically
filled in, thus making the API more programmer friendly. The
expression can be any C expression, although if you refer to variables
in the current structure you will need to dereference them with
r->. See samr_Name as a good example.


[nodiscriminant] property
-------------------------

The [nodiscriminant] property on a union means that the usual uint16
discriminent field at the start of the union on the wire is
omitted. This is not normally allowed in IDL/NDR, but is used for some
spoolss structures.


VALIDATOR
---------

We need to write an IDL validator, so we know that we are writing
valid IDL. Right now the compiler sails on regardless in many cases
even if the IDL is invalid (for example, I don't check that conformant
arrays are always the last element in any structure). There are dozens
of rules that should be checked.