ReactOS 0.4.16-dev-1946-g52006dd
register.c
Go to the documentation of this file.
1/*
2 * Generation of dll registration scripts
3 *
4 * Copyright 2010 Alexandre Julliard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "config.h"
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <ctype.h>
27
28#include "widl.h"
29#include "utils.h"
30#include "parser.h"
31#include "header.h"
32#include "typegen.h"
33#include "typelib.h"
34
35static int indent;
36
37static const char *format_uuid( const struct uuid *uuid )
38{
39 static char buffer[40];
40 snprintf( buffer, sizeof(buffer),
41 "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
43 uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3],
44 uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7] );
45 return buffer;
46}
47
48static const char *get_coclass_threading( const type_t *class )
49{
50 static const char * const models[] =
51 {
52 NULL,
53 "Apartment", /* THREADING_APARTMENT */
54 "Neutral", /* THREADING_NEUTRAL */
55 "Single", /* THREADING_SINGLE */
56 "Free", /* THREADING_FREE */
57 "Both", /* THREADING_BOTH */
58 };
59 return models[get_attrv( class->attrs, ATTR_THREADING )];
60}
61
62static const type_t *find_ps_factory( const statement_list_t *stmts )
63{
64 const statement_t *stmt;
65
66 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
67 {
68 if (stmt->type == STMT_TYPE)
69 {
70 const type_t *type = stmt->u.type;
71 if (type_get_type(type) == TYPE_COCLASS && !strcmp( type->name, "PSFactoryBuffer" ))
72 return type;
73 }
74 }
75 return NULL;
76}
77
78static void write_interface( const type_t *iface, const type_t *ps_factory )
79{
80 const struct uuid *uuid = get_attrp( iface->attrs, ATTR_UUID );
81 const struct uuid *ps_uuid = get_attrp( ps_factory->attrs, ATTR_UUID );
82
83 if (!uuid) return;
84 if (!is_object( iface )) return;
85 if (!type_iface_get_inherit(iface)) /* special case for IUnknown */
86 {
87 put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), iface->name );
88 return;
89 }
90 if (is_local( iface->attrs )) return;
91 put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), iface->name );
92 put_str( indent, "{\n" );
93 indent++;
94 put_str( indent, "NumMethods = s %u\n", count_methods( iface ));
95 put_str( indent, "ProxyStubClsid32 = s '%s'\n", format_uuid( ps_uuid ));
96 indent--;
97 put_str( indent, "}\n" );
98}
99
100static void write_interfaces( const statement_list_t *stmts, const type_t *ps_factory )
101{
102 const statement_t *stmt;
103
104 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
105 {
106 if (stmt->type == STMT_TYPE && type_get_type( stmt->u.type ) == TYPE_INTERFACE)
107 write_interface( stmt->u.type, ps_factory );
108 }
109}
110
111static void write_typelib_interface( const type_t *iface, const typelib_t *typelib )
112{
113 const struct uuid *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID );
114 const struct uuid *uuid = get_attrp( iface->attrs, ATTR_UUID );
115 unsigned int version = get_attrv( typelib->attrs, ATTR_VERSION );
116
117 if (!uuid) return;
118 if (!is_object( iface )) return;
119 put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), iface->name );
120 put_str( indent, "{\n" );
121 indent++;
122 put_str( indent, "ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'\n" );
123 put_str( indent, "ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'\n" );
124 if (version)
125 put_str( indent, "TypeLib = s '%s' { val Version = s '%u.%u' }\n",
127 else
128 put_str( indent, "TypeLib = s '%s'", format_uuid( typelib_uuid ));
129 indent--;
130 put_str( indent, "}\n" );
131}
132
134{
135 unsigned int i;
136
137 for (i = 0; i < typelib->reg_iface_count; ++i)
138 write_typelib_interface( typelib->reg_ifaces[i], typelib );
139}
140
141static int write_coclass( const type_t *class, const typelib_t *typelib )
142{
143 const struct uuid *uuid = get_attrp( class->attrs, ATTR_UUID );
144 const char *descr = get_attrp( class->attrs, ATTR_HELPSTRING );
145 const char *progid = get_attrp( class->attrs, ATTR_PROGID );
146 const char *vi_progid = get_attrp( class->attrs, ATTR_VIPROGID );
147 const char *threading = get_coclass_threading( class );
148 unsigned int version = get_attrv( class->attrs, ATTR_VERSION );
149
150 if (!uuid) return 0;
151 if (typelib && !threading && !progid) return 0;
152 if (!descr) descr = class->name;
153
154 put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), descr );
155 put_str( indent++, "{\n" );
156 if (threading) put_str( indent, "InprocServer32 = s '%%MODULE%%' { val ThreadingModel = s '%s' }\n",
157 threading );
158 if (progid) put_str( indent, "ProgId = s '%s'\n", progid );
159 if (typelib)
160 {
161 const struct uuid *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID );
162 put_str( indent, "TypeLib = s '%s'\n", format_uuid( typelib_uuid ));
163 if (!version) version = get_attrv( typelib->attrs, ATTR_VERSION );
164 }
165 if (version) put_str( indent, "Version = s '%u.%u'\n", MAJORVERSION(version), MINORVERSION(version) );
166 if (vi_progid) put_str( indent, "VersionIndependentProgId = s '%s'\n", vi_progid );
167 put_str( --indent, "}\n" );
168 return 1;
169}
170
171static void write_coclasses( const statement_list_t *stmts, const typelib_t *typelib )
172{
173 const statement_t *stmt;
174
175 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
176 {
177 if (stmt->type == STMT_TYPE)
178 {
179 const type_t *type = stmt->u.type;
181 }
182 }
183}
184
186{
187 const statement_t *stmt;
188 const type_t *type;
189
190 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
191 {
192 if (stmt->type != STMT_TYPE) continue;
193 if (type_get_type((type = stmt->u.type)) != TYPE_RUNTIMECLASS) continue;
194 if (!get_attrp(type->attrs, ATTR_ACTIVATABLE) && !get_attrp(type->attrs, ATTR_STATIC)) continue;
195 put_str( indent, "ForceRemove %s\n", format_namespace( type->namespace, "", ".", type->name, NULL ) );
196 put_str( indent++, "{\n" );
197 put_str( indent, "val 'DllPath' = s '%%MODULE%%'\n" );
198 put_str( --indent, "}\n" );
199 }
200}
201
202static int write_progid( const type_t *class )
203{
204 const struct uuid *uuid = get_attrp( class->attrs, ATTR_UUID );
205 const char *descr = get_attrp( class->attrs, ATTR_HELPSTRING );
206 const char *progid = get_attrp( class->attrs, ATTR_PROGID );
207 const char *vi_progid = get_attrp( class->attrs, ATTR_VIPROGID );
208
209 if (!uuid) return 0;
210 if (!descr) descr = class->name;
211
212 if (progid)
213 {
214 put_str( indent, "'%s' = s '%s'\n", progid, descr );
215 put_str( indent++, "{\n" );
216 put_str( indent, "CLSID = s '%s'\n", format_uuid( uuid ) );
217 put_str( --indent, "}\n" );
218 }
219 if (vi_progid)
220 {
221 put_str( indent, "'%s' = s '%s'\n", vi_progid, descr );
222 put_str( indent++, "{\n" );
223 put_str( indent, "CLSID = s '%s'\n", format_uuid( uuid ) );
224 if (progid && strcmp( progid, vi_progid )) put_str( indent, "CurVer = s '%s'\n", progid );
225 put_str( --indent, "}\n" );
226 }
227 return 1;
228}
229
230static void write_progids( const statement_list_t *stmts )
231{
232 const statement_t *stmt;
233
234 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
235 {
236 if (stmt->type == STMT_TYPE)
237 {
238 const type_t *type = stmt->u.type;
240 }
241 }
242}
243
245{
246 const type_t *ps_factory;
247
248 if (!do_regscript) return;
249 if (do_everything && !need_proxy_file( stmts )) return;
250
252
253 if (winrt_mode)
254 {
255 put_str( indent, "HKLM\n" );
256 put_str( indent++, "{\n" );
257 put_str( indent, "NoRemove Software\n" );
258 put_str( indent++, "{\n" );
259 put_str( indent, "NoRemove Microsoft\n" );
260 put_str( indent++, "{\n" );
261 put_str( indent, "NoRemove WindowsRuntime\n" );
262 put_str( indent++, "{\n" );
263 put_str( indent, "NoRemove ActivatableClassId\n" );
264 put_str( indent++, "{\n" );
266 put_str( --indent, "}\n" );
267 put_str( --indent, "}\n" );
268 put_str( --indent, "}\n" );
269 put_str( --indent, "}\n" );
270 put_str( --indent, "}\n" );
271 }
272 else
273 {
274 put_str( indent, "HKCR\n" );
275 put_str( indent++, "{\n" );
276
277 ps_factory = find_ps_factory( stmts );
278 if (ps_factory)
279 {
280 put_str( indent, "NoRemove Interface\n" );
281 put_str( indent++, "{\n" );
282 write_interfaces( stmts, ps_factory );
283 put_str( --indent, "}\n" );
284 }
285
286 put_str( indent, "NoRemove CLSID\n" );
287 put_str( indent++, "{\n" );
288 write_coclasses( stmts, NULL );
289 put_str( --indent, "}\n" );
290
291 write_progids( stmts );
292 put_str( --indent, "}\n" );
293 }
294
295 if (strendswith( regscript_name, ".res" )) /* create a binary resource file */
296 {
297 add_output_to_resources( "WINE_REGISTRY", regscript_token );
299 }
300 else
301 {
302 FILE *f = fopen( regscript_name, "w" );
303 if (!f) error( "Could not open %s for output\n", regscript_name );
305 error( "Failed to write to %s\n", regscript_name );
306 if (fclose( f ))
307 error( "Failed to write to %s\n", regscript_name );
308 }
309}
310
312{
313 const statement_t *stmt;
314 unsigned int count = 0;
315
316 if (!do_typelib) return;
317 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
318 {
319 if (stmt->type != STMT_LIBRARY) continue;
320 if (count && !strendswith( typelib_name, ".res" ))
321 error( "Cannot store multiple typelibs into %s\n", typelib_name );
322 else
323 {
324 if (old_typelib)
325 create_sltg_typelib( stmt->u.lib );
326 else
327 create_msft_typelib( stmt->u.lib );
328 }
329 count++;
330 }
332}
333
335{
336 const struct uuid *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID );
337 const char *descr = get_attrp( typelib->attrs, ATTR_HELPSTRING );
338 const expr_t *lcid_expr = get_attrp( typelib->attrs, ATTR_LIBLCID );
339 unsigned int version = get_attrv( typelib->attrs, ATTR_VERSION );
340 unsigned int flags = 0;
341 char id_part[12] = "";
342 char *resname = typelib_name;
343 expr_t *expr;
344
345 if (is_attr( typelib->attrs, ATTR_RESTRICTED )) flags |= 1; /* LIBFLAG_FRESTRICTED */
346 if (is_attr( typelib->attrs, ATTR_CONTROL )) flags |= 2; /* LIBFLAG_FCONTROL */
347 if (is_attr( typelib->attrs, ATTR_HIDDEN )) flags |= 4; /* LIBFLAG_FHIDDEN */
348
349 put_str( indent, "HKCR\n" );
350 put_str( indent++, "{\n" );
351
352 put_str( indent, "NoRemove Typelib\n" );
353 put_str( indent++, "{\n" );
354 put_str( indent, "NoRemove '%s'\n", format_uuid( typelib_uuid ));
355 put_str( indent++, "{\n" );
356 put_str( indent, "'%u.%u' = s '%s'\n",
358 put_str( indent++, "{\n" );
359 expr = get_attrp( typelib->attrs, ATTR_ID );
360 if (expr)
361 {
362 snprintf(id_part, sizeof(id_part), "\\%d", expr->cval);
363 resname = strmake("%s\\%d", typelib_name, expr->cval);
364 }
365 put_str( indent, "'%x' { %s = s '%%MODULE%%%s' }\n",
366 lcid_expr ? lcid_expr->cval : 0, pointer_size == 8 ? "win64" : "win32", id_part );
367 put_str( indent, "FLAGS = s '%u'\n", flags );
368 put_str( --indent, "}\n" );
369 put_str( --indent, "}\n" );
370 put_str( --indent, "}\n" );
371
372 put_str( indent, "NoRemove Interface\n" );
373 put_str( indent++, "{\n" );
375 put_str( --indent, "}\n" );
376
377 put_str( indent, "NoRemove CLSID\n" );
378 put_str( indent++, "{\n" );
380 put_str( --indent, "}\n" );
381
382 write_progids( typelib->stmts );
383 put_str( --indent, "}\n" );
384
385 add_output_to_resources( "WINE_REGISTRY", resname );
386}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
const WCHAR * class
Definition: main.c:68
Definition: list.h:37
#define NULL
Definition: types.h:112
static const WCHAR version[]
Definition: asmname.c:66
#define progid(str)
Definition: exdisp.idl:31
#define vi_progid(str)
Definition: exdisp.idl:32
#define threading(model)
Definition: exdisp.idl:30
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint buffer
Definition: glext.h:5915
GLfloat f
Definition: glext.h:7540
GLbitfield flags
Definition: glext.h:7161
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
Definition: msctf.idl:532
unsigned short Data3
Definition: widltypes.h:34
unsigned int Data1
Definition: widltypes.h:32
unsigned char Data4[8]
Definition: widltypes.h:35
unsigned short Data2
Definition: widltypes.h:33
uint32_t entry
Definition: isohybrid.c:63
#define ATTR_HIDDEN
Definition: mkdosfs.c:367
#define error(str)
Definition: mkdosfs.c:1605
char * strmake(size_t *lenp,...)
Definition: util.c:82
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
const char * descr
Definition: boot.c:45
size_t output_buffer_pos
Definition: utils.c:164
static int strendswith(const char *str, const char *end)
Definition: tools.h:145
static void init_output_buffer(void)
Definition: tools.h:791
void * get_attrp(const attr_list_t *list, enum attr_type attr_type)
Definition: attribute.c:87
unsigned int get_attrv(const attr_list_t *list, enum attr_type attr_type)
Definition: attribute.c:78
int is_attr(const attr_list_t *list, enum attr_type attr_type)
Definition: attribute.c:45
int is_local(const attr_list_t *a)
Definition: header.c:982
int is_object(const type_t *iface)
Definition: header.c:972
int need_proxy_file(const statement_list_t *stmts)
Definition: proxy.c:804
int count_methods(const type_t *iface)
Definition: proxy.c:460
void output_typelib_regscript(const typelib_t *typelib)
Definition: register.c:334
static const type_t * find_ps_factory(const statement_list_t *stmts)
Definition: register.c:62
static int write_progid(const type_t *class)
Definition: register.c:202
static void write_interfaces(const statement_list_t *stmts, const type_t *ps_factory)
Definition: register.c:100
static void write_coclasses(const statement_list_t *stmts, const typelib_t *typelib)
Definition: register.c:171
void write_regscript(const statement_list_t *stmts)
Definition: register.c:244
static const char * format_uuid(const struct uuid *uuid)
Definition: register.c:37
static void write_progids(const statement_list_t *stmts)
Definition: register.c:230
static int write_coclass(const type_t *class, const typelib_t *typelib)
Definition: register.c:141
static int indent
Definition: register.c:35
static void write_typelib_interfaces(const typelib_t *typelib)
Definition: register.c:133
static void write_interface(const type_t *iface, const type_t *ps_factory)
Definition: register.c:78
void write_typelib_regscript(const statement_list_t *stmts)
Definition: register.c:311
static void write_runtimeclasses_registry(const statement_list_t *stmts)
Definition: register.c:185
static void write_typelib_interface(const type_t *iface, const typelib_t *typelib)
Definition: register.c:111
static const char * get_coclass_threading(const type_t *class)
Definition: register.c:48
int create_msft_typelib(typelib_t *typelib)
Definition: write_msft.c:2755
int create_sltg_typelib(typelib_t *typelib)
Definition: write_sltg.c:1777
void add_output_to_resources(const char *type, const char *name)
Definition: utils.c:192
void flush_output_resources(const char *name)
Definition: utils.c:226
void put_str(int indent, const char *format,...)
Definition: utils.c:261
#define MINORVERSION(version)
Definition: utils.h:49
#define MAJORVERSION(version)
Definition: utils.h:48
size_t fwrite(const void *, size_t, size_t, FILE *)
Definition: file.c:3077
int cval
Definition: widltypes.h:371
statement_type_t type
Definition: parser.h:124
typelib_t * lib
Definition: widltypes.h:632
union _statement_t::@5358 u
attr_list_t * attrs
Definition: widltypes.h:503
const char * name
Definition: widltypes.h:500
Definition: query.h:86
char * format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix)
Definition: typetree.c:279
static enum type_type type_get_type(const type_t *type)
Definition: typetree.h:113
static type_t * type_iface_get_inherit(const type_t *type)
Definition: typetree.h:208
int do_regscript
Definition: widl.c:105
char * typelib_name
Definition: widl.c:122
unsigned int pointer_size
Definition: widl.c:147
int do_everything
Definition: widl.c:98
char * regscript_name
Definition: widl.c:130
int do_typelib
Definition: widl.c:101
int winrt_mode
Definition: widl.c:111
int old_typelib
Definition: widl.c:110
char * regscript_token
Definition: widl.c:131
@ TYPE_COCLASS
Definition: widltypes.h:486
@ TYPE_RUNTIMECLASS
Definition: widltypes.h:493
@ TYPE_INTERFACE
Definition: widltypes.h:488
@ ATTR_VIPROGID
Definition: widltypes.h:186
@ ATTR_ACTIVATABLE
Definition: widltypes.h:73
@ ATTR_UUID
Definition: widltypes.h:182
@ ATTR_THREADING
Definition: widltypes.h:177
@ ATTR_VERSION
Definition: widltypes.h:185
@ ATTR_CONTROL
Definition: widltypes.h:92
@ ATTR_LIBLCID
Definition: widltypes.h:134
@ ATTR_STATIC
Definition: widltypes.h:172
@ ATTR_RESTRICTED
Definition: widltypes.h:168
@ ATTR_ID
Definition: widltypes.h:125
@ ATTR_PROGID
Definition: widltypes.h:157
@ ATTR_HELPSTRING
Definition: widltypes.h:121
@ STMT_TYPE
Definition: widltypes.h:267
@ STMT_LIBRARY
Definition: widltypes.h:265
#define snprintf
Definition: wintirpc.h:48