ReactOS 0.4.16-dev-527-gdad3a09
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#include "wine/port.h"
23
24#include <stdio.h>
25#include <stdlib.h>
26#ifdef HAVE_UNISTD_H
27# include <unistd.h>
28#endif
29#include <string.h>
30#include <ctype.h>
31
32#include "widl.h"
33#include "utils.h"
34#include "parser.h"
35#include "header.h"
36#include "typegen.h"
37#include "typelib.h"
38
39static int indent;
40
41static const char *format_uuid( const UUID *uuid )
42{
43 static char buffer[40];
44 sprintf( buffer, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
45 uuid->Data1, uuid->Data2, uuid->Data3,
46 uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3],
47 uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7] );
48 return buffer;
49}
50
51static const char *get_coclass_threading( const type_t *class )
52{
53 static const char * const models[] =
54 {
55 NULL,
56 "Apartment", /* THREADING_APARTMENT */
57 "Neutral", /* THREADING_NEUTRAL */
58 "Single", /* THREADING_SINGLE */
59 "Free", /* THREADING_FREE */
60 "Both", /* THREADING_BOTH */
61 };
62 return models[get_attrv( class->attrs, ATTR_THREADING )];
63}
64
65static const type_t *find_ps_factory( const statement_list_t *stmts )
66{
67 const statement_t *stmt;
68
69 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
70 {
71 if (stmt->type == STMT_TYPE)
72 {
73 const type_t *type = stmt->u.type;
74 if (type_get_type(type) == TYPE_COCLASS && !strcmp( type->name, "PSFactoryBuffer" ))
75 return type;
76 }
77 }
78 return NULL;
79}
80
81static void write_interface( const type_t *iface, const type_t *ps_factory )
82{
83 const UUID *uuid = get_attrp( iface->attrs, ATTR_UUID );
84 const UUID *ps_uuid = get_attrp( ps_factory->attrs, ATTR_UUID );
85
86 if (!uuid) return;
87 if (!is_object( iface )) return;
88 if (!type_iface_get_inherit(iface)) /* special case for IUnknown */
89 {
90 put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), iface->name );
91 return;
92 }
93 if (is_local( iface->attrs )) return;
94 put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), iface->name );
95 put_str( indent, "{\n" );
96 indent++;
97 put_str( indent, "NumMethods = s %u\n", count_methods( iface ));
98 put_str( indent, "ProxyStubClsid32 = s '%s'\n", format_uuid( ps_uuid ));
99 indent--;
100 put_str( indent, "}\n" );
101}
102
103static void write_interfaces( const statement_list_t *stmts, const type_t *ps_factory )
104{
105 const statement_t *stmt;
106
107 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
108 {
109 if (stmt->type == STMT_TYPE && type_get_type( stmt->u.type ) == TYPE_INTERFACE)
110 write_interface( stmt->u.type, ps_factory );
111 }
112}
113
114static void write_typelib_interface( const type_t *iface, const typelib_t *typelib )
115{
116 const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID );
117 const UUID *uuid = get_attrp( iface->attrs, ATTR_UUID );
118 unsigned int version = get_attrv( typelib->attrs, ATTR_VERSION );
119
120 if (!uuid) return;
121 if (!is_object( iface )) return;
122 if (!is_attr( iface->attrs, ATTR_OLEAUTOMATION ) && !is_attr( iface->attrs, ATTR_DISPINTERFACE ))
123 return;
124 put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), iface->name );
125 put_str( indent, "{\n" );
126 indent++;
127 put_str( indent, "ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'\n" );
128 put_str( indent, "ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'\n" );
129 if (version)
130 put_str( indent, "TypeLib = s '%s' { val Version = s '%u.%u' }\n",
132 else
133 put_str( indent, "TypeLib = s '%s'", format_uuid( typelib_uuid ));
134 indent--;
135 put_str( indent, "}\n" );
136}
137
139{
140 const statement_t *stmt;
141
142 if (typelib->stmts) LIST_FOR_EACH_ENTRY( stmt, typelib->stmts, const statement_t, entry )
143 {
144 if (stmt->type == STMT_TYPE && type_get_type( stmt->u.type ) == TYPE_INTERFACE)
146 }
147}
148
149static int write_coclass( const type_t *class, const typelib_t *typelib )
150{
151 const UUID *uuid = get_attrp( class->attrs, ATTR_UUID );
152 const char *descr = get_attrp( class->attrs, ATTR_HELPSTRING );
153 const char *progid = get_attrp( class->attrs, ATTR_PROGID );
154 const char *vi_progid = get_attrp( class->attrs, ATTR_VIPROGID );
155 const char *threading = get_coclass_threading( class );
156 unsigned int version = get_attrv( class->attrs, ATTR_VERSION );
157
158 if (!uuid) return 0;
159 if (typelib && !threading && !progid) return 0;
160 if (!descr) descr = class->name;
161
162 put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), descr );
163 put_str( indent++, "{\n" );
164 if (threading) put_str( indent, "InprocServer32 = s '%%MODULE%%' { val ThreadingModel = s '%s' }\n",
165 threading );
166 if (progid) put_str( indent, "ProgId = s '%s'\n", progid );
167 if (typelib)
168 {
169 const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID );
170 put_str( indent, "TypeLib = s '%s'\n", format_uuid( typelib_uuid ));
171 if (!version) version = get_attrv( typelib->attrs, ATTR_VERSION );
172 }
173 if (version) put_str( indent, "Version = s '%u.%u'\n", MAJORVERSION(version), MINORVERSION(version) );
174 if (vi_progid) put_str( indent, "VersionIndependentProgId = s '%s'\n", vi_progid );
175 put_str( --indent, "}\n" );
176 return 1;
177}
178
179static void write_coclasses( const statement_list_t *stmts, const typelib_t *typelib )
180{
181 const statement_t *stmt;
182
183 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
184 {
185 if (stmt->type == STMT_TYPE)
186 {
187 const type_t *type = stmt->u.type;
189 }
190 }
191}
192
193static int write_progid( const type_t *class )
194{
195 const UUID *uuid = get_attrp( class->attrs, ATTR_UUID );
196 const char *descr = get_attrp( class->attrs, ATTR_HELPSTRING );
197 const char *progid = get_attrp( class->attrs, ATTR_PROGID );
198 const char *vi_progid = get_attrp( class->attrs, ATTR_VIPROGID );
199
200 if (!uuid) return 0;
201 if (!descr) descr = class->name;
202
203 if (progid)
204 {
205 put_str( indent, "'%s' = s '%s'\n", progid, descr );
206 put_str( indent++, "{\n" );
207 put_str( indent, "CLSID = s '%s'\n", format_uuid( uuid ) );
208 put_str( --indent, "}\n" );
209 }
210 if (vi_progid)
211 {
212 put_str( indent, "'%s' = s '%s'\n", vi_progid, descr );
213 put_str( indent++, "{\n" );
214 put_str( indent, "CLSID = s '%s'\n", format_uuid( uuid ) );
215 if (progid && strcmp( progid, vi_progid )) put_str( indent, "CurVer = s '%s'\n", progid );
216 put_str( --indent, "}\n" );
217 }
218 return 1;
219}
220
221static void write_progids( const statement_list_t *stmts )
222{
223 const statement_t *stmt;
224
225 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
226 {
227 if (stmt->type == STMT_TYPE)
228 {
229 const type_t *type = stmt->u.type;
231 }
232 }
233}
234
236{
237 const type_t *ps_factory;
238
239 if (!do_regscript) return;
240 if (do_everything && !need_proxy_file( stmts )) return;
241
243
244 put_str( indent, "HKCR\n" );
245 put_str( indent++, "{\n" );
246
247 put_str( indent, "NoRemove Interface\n" );
248 put_str( indent++, "{\n" );
249 ps_factory = find_ps_factory( stmts );
250 if (ps_factory) write_interfaces( stmts, ps_factory );
251 put_str( --indent, "}\n" );
252
253 put_str( indent, "NoRemove CLSID\n" );
254 put_str( indent++, "{\n" );
255 write_coclasses( stmts, NULL );
256 put_str( --indent, "}\n" );
257
258 write_progids( stmts );
259 put_str( --indent, "}\n" );
260
261 if (strendswith( regscript_name, ".res" )) /* create a binary resource file */
262 {
263 add_output_to_resources( "WINE_REGISTRY", regscript_token );
265 }
266 else
267 {
268 FILE *f = fopen( regscript_name, "w" );
269 if (!f) error( "Could not open %s for output\n", regscript_name );
271 error( "Failed to write to %s\n", regscript_name );
272 if (fclose( f ))
273 error( "Failed to write to %s\n", regscript_name );
274 }
275}
276
278{
279 const statement_t *stmt;
280 unsigned int count = 0;
281
282 if (!do_typelib) return;
283 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
284 {
285 if (stmt->type != STMT_LIBRARY) continue;
286 if (count && !strendswith( typelib_name, ".res" ))
287 error( "Cannot store multiple typelibs into %s\n", typelib_name );
288 else
289 create_msft_typelib( stmt->u.lib );
290 count++;
291 }
293}
294
296{
297 const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID );
298 const char *descr = get_attrp( typelib->attrs, ATTR_HELPSTRING );
299 const expr_t *lcid_expr = get_attrp( typelib->attrs, ATTR_LIBLCID );
300 unsigned int version = get_attrv( typelib->attrs, ATTR_VERSION );
301 unsigned int flags = 0;
302 char id_part[12] = "";
303 char *resname = typelib_name;
304 expr_t *expr;
305
306 if (is_attr( typelib->attrs, ATTR_RESTRICTED )) flags |= 1; /* LIBFLAG_FRESTRICTED */
307 if (is_attr( typelib->attrs, ATTR_CONTROL )) flags |= 2; /* LIBFLAG_FCONTROL */
308 if (is_attr( typelib->attrs, ATTR_HIDDEN )) flags |= 4; /* LIBFLAG_FHIDDEN */
309
310 put_str( indent, "HKCR\n" );
311 put_str( indent++, "{\n" );
312
313 put_str( indent, "NoRemove Typelib\n" );
314 put_str( indent++, "{\n" );
315 put_str( indent, "NoRemove '%s'\n", format_uuid( typelib_uuid ));
316 put_str( indent++, "{\n" );
317 put_str( indent, "'%u.%u' = s '%s'\n",
319 put_str( indent++, "{\n" );
320 expr = get_attrp( typelib->attrs, ATTR_ID );
321 if (expr)
322 {
323 sprintf(id_part, "\\%d", expr->cval);
324#ifndef __REACTOS__
325 resname = xmalloc( strlen(typelib_name) + 20 );
326 sprintf(resname, "%s\\%d", typelib_name, expr->cval);
327#endif
328 }
329 put_str( indent, "'%x' { %s = s '%%MODULE%%%s' }\n",
330 lcid_expr ? lcid_expr->cval : 0, pointer_size == 8 ? "win64" : "win32", id_part );
331 put_str( indent, "FLAGS = s '%u'\n", flags );
332 put_str( --indent, "}\n" );
333 put_str( --indent, "}\n" );
334 put_str( --indent, "}\n" );
335
336 put_str( indent, "NoRemove Interface\n" );
337 put_str( indent++, "{\n" );
339 put_str( --indent, "}\n" );
340
341 put_str( indent, "NoRemove CLSID\n" );
342 put_str( indent++, "{\n" );
344 put_str( --indent, "}\n" );
345
346 write_progids( typelib->stmts );
347 put_str( --indent, "}\n" );
348
349 add_output_to_resources( "WINE_REGISTRY", resname );
350}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
const WCHAR * class
Definition: main.c:68
void * xmalloc(int size)
Definition: uimain.c:747
#define ATTR_HIDDEN
Definition: fat.h:160
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
int need_proxy_file(const statement_list_t *stmts)
Definition: proxy.c:809
int count_methods(const type_t *iface)
Definition: proxy.c:465
_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)
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
Definition: msctf.idl:550
uint32_t entry
Definition: isohybrid.c:63
#define error(str)
Definition: mkdosfs.c:1605
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
const char * descr
Definition: boot.c:45
int is_local(const attr_list_t *a)
Definition: header.c:938
int is_attr(const attr_list_t *list, enum attr_type t)
Definition: header.c:99
unsigned int get_attrv(const attr_list_t *list, enum attr_type t)
Definition: header.c:115
void * get_attrp(const attr_list_t *list, enum attr_type t)
Definition: header.c:107
int is_object(const type_t *iface)
Definition: header.c:928
void output_typelib_regscript(const typelib_t *typelib)
Definition: register.c:295
static const type_t * find_ps_factory(const statement_list_t *stmts)
Definition: register.c:65
static int write_progid(const type_t *class)
Definition: register.c:193
static void write_interfaces(const statement_list_t *stmts, const type_t *ps_factory)
Definition: register.c:103
static void write_coclasses(const statement_list_t *stmts, const typelib_t *typelib)
Definition: register.c:179
void write_regscript(const statement_list_t *stmts)
Definition: register.c:235
static void write_progids(const statement_list_t *stmts)
Definition: register.c:221
static int write_coclass(const type_t *class, const typelib_t *typelib)
Definition: register.c:149
static int indent
Definition: register.c:39
static void write_typelib_interfaces(const typelib_t *typelib)
Definition: register.c:138
static const char * format_uuid(const UUID *uuid)
Definition: register.c:41
static void write_interface(const type_t *iface, const type_t *ps_factory)
Definition: register.c:81
void write_typelib_regscript(const statement_list_t *stmts)
Definition: register.c:277
static void write_typelib_interface(const type_t *iface, const typelib_t *typelib)
Definition: register.c:114
static const char * get_coclass_threading(const type_t *class)
Definition: register.c:51
int create_msft_typelib(typelib_t *typelib)
Definition: write_msft.c:2657
size_t output_buffer_pos
Definition: utils.c:253
void add_output_to_resources(const char *type, const char *name)
Definition: utils.c:307
void flush_output_resources(const char *name)
Definition: utils.c:341
int strendswith(const char *str, const char *end)
Definition: utils.c:238
void put_str(int indent, const char *format,...)
Definition: utils.c:423
void init_output_buffer(void)
Definition: utils.c:272
#define MINORVERSION(version)
Definition: utils.h:76
#define MAJORVERSION(version)
Definition: utils.h:75
int cval
Definition: widltypes.h:319
statement_type_t type
Definition: parser.h:124
union _statement_t::@5093 u
typelib_t * lib
Definition: widltypes.h:540
attr_list_t * attrs
Definition: widltypes.h:422
const char * name
Definition: widltypes.h:419
Definition: query.h:86
static enum type_type type_get_type(const type_t *type)
Definition: typetree.h:68
static type_t * type_iface_get_inherit(const type_t *type)
Definition: typetree.h:158
int do_regscript
Definition: widl.c:121
char * typelib_name
Definition: widl.c:138
unsigned int pointer_size
Definition: widl.c:157
int do_everything
Definition: widl.c:113
char * regscript_name
Definition: widl.c:146
int do_typelib
Definition: widl.c:116
char * regscript_token
Definition: widl.c:147
@ TYPE_COCLASS
Definition: widltypes.h:410
@ TYPE_INTERFACE
Definition: widltypes.h:412
@ ATTR_VIPROGID
Definition: widltypes.h:170
@ ATTR_OLEAUTOMATION
Definition: widltypes.h:135
@ ATTR_UUID
Definition: widltypes.h:166
@ ATTR_THREADING
Definition: widltypes.h:161
@ ATTR_VERSION
Definition: widltypes.h:169
@ ATTR_CONTROL
Definition: widltypes.h:86
@ ATTR_LIBLCID
Definition: widltypes.h:122
@ ATTR_RESTRICTED
Definition: widltypes.h:153
@ ATTR_ID
Definition: widltypes.h:112
@ ATTR_DISPINTERFACE
Definition: widltypes.h:94
@ ATTR_PROGID
Definition: widltypes.h:143
@ ATTR_HELPSTRING
Definition: widltypes.h:108
@ STMT_TYPE
Definition: widltypes.h:242
@ STMT_LIBRARY
Definition: widltypes.h:240