Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenregister.c
Go to the documentation of this file.
00001 /* 00002 * Generation of dll registration scripts 00003 * 00004 * Copyright 2010 Alexandre Julliard 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include "config.h" 00022 #include "wine/port.h" 00023 00024 #include <stdio.h> 00025 #include <stdlib.h> 00026 #ifdef HAVE_UNISTD_H 00027 # include <unistd.h> 00028 #endif 00029 #include <string.h> 00030 #include <ctype.h> 00031 00032 #include "widl.h" 00033 #include "utils.h" 00034 #include "parser.h" 00035 #include "header.h" 00036 #include "typegen.h" 00037 00038 static int indent; 00039 00040 static const char *format_uuid( const UUID *uuid ) 00041 { 00042 static char buffer[40]; 00043 sprintf( buffer, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", 00044 uuid->Data1, uuid->Data2, uuid->Data3, 00045 uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3], 00046 uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7] ); 00047 return buffer; 00048 } 00049 00050 static const char *get_coclass_threading( const type_t *class ) 00051 { 00052 static const char * const models[] = 00053 { 00054 NULL, 00055 "Apartment", /* THREADING_APARTMENT */ 00056 "Neutral", /* THREADING_NEUTRAL */ 00057 "Single", /* THREADING_SINGLE */ 00058 "Free", /* THREADING_FREE */ 00059 "Both", /* THREADING_BOTH */ 00060 }; 00061 return models[get_attrv( class->attrs, ATTR_THREADING )]; 00062 } 00063 00064 static const type_t *find_ps_factory( const statement_list_t *stmts ) 00065 { 00066 const statement_t *stmt; 00067 00068 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry ) 00069 { 00070 if (stmt->type == STMT_TYPE) 00071 { 00072 const type_t *type = stmt->u.type; 00073 if (type_get_type(type) == TYPE_COCLASS && !strcmp( type->name, "PSFactoryBuffer" )) 00074 return type; 00075 } 00076 } 00077 return NULL; 00078 } 00079 00080 static void write_interface( const type_t *iface, const type_t *ps_factory ) 00081 { 00082 const UUID *uuid = get_attrp( iface->attrs, ATTR_UUID ); 00083 const UUID *ps_uuid = get_attrp( ps_factory->attrs, ATTR_UUID ); 00084 00085 if (!uuid) return; 00086 if (!is_object( iface )) return; 00087 if (!type_iface_get_inherit(iface)) /* special case for IUnknown */ 00088 { 00089 put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), iface->name ); 00090 return; 00091 } 00092 if (is_local( iface->attrs )) return; 00093 put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), iface->name ); 00094 put_str( indent, "{\n" ); 00095 indent++; 00096 put_str( indent, "NumMethods = s %u\n", count_methods( iface )); 00097 put_str( indent, "ProxyStubClsid32 = s '%s'\n", format_uuid( ps_uuid )); 00098 indent--; 00099 put_str( indent, "}\n" ); 00100 } 00101 00102 static void write_interfaces( const statement_list_t *stmts, const type_t *ps_factory ) 00103 { 00104 const statement_t *stmt; 00105 00106 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry ) 00107 { 00108 if (stmt->type == STMT_TYPE && type_get_type( stmt->u.type ) == TYPE_INTERFACE) 00109 write_interface( stmt->u.type, ps_factory ); 00110 } 00111 } 00112 00113 static void write_typelib_interface( const type_t *iface, const typelib_t *typelib ) 00114 { 00115 const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID ); 00116 const UUID *uuid = get_attrp( iface->attrs, ATTR_UUID ); 00117 unsigned int version = get_attrv( typelib->attrs, ATTR_VERSION ); 00118 00119 if (!uuid) return; 00120 if (!is_object( iface )) return; 00121 if (!is_attr( iface->attrs, ATTR_OLEAUTOMATION ) && !is_attr( iface->attrs, ATTR_DISPINTERFACE )) 00122 return; 00123 put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), iface->name ); 00124 put_str( indent, "{\n" ); 00125 indent++; 00126 put_str( indent, "ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'\n" ); 00127 put_str( indent, "ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'\n" ); 00128 if (version) 00129 put_str( indent, "TypeLib = s '%s' { val Version = s '%u.%u' }\n", 00130 format_uuid( typelib_uuid ), MAJORVERSION(version), MINORVERSION(version) ); 00131 else 00132 put_str( indent, "TypeLib = s '%s'", format_uuid( typelib_uuid )); 00133 indent--; 00134 put_str( indent, "}\n" ); 00135 } 00136 00137 static void write_typelib_interfaces( const typelib_t *typelib ) 00138 { 00139 const statement_t *stmt; 00140 00141 if (typelib->stmts) LIST_FOR_EACH_ENTRY( stmt, typelib->stmts, const statement_t, entry ) 00142 { 00143 if (stmt->type == STMT_TYPE && type_get_type( stmt->u.type ) == TYPE_INTERFACE) 00144 write_typelib_interface( stmt->u.type, typelib ); 00145 } 00146 } 00147 00148 static int write_coclass( const type_t *class, const typelib_t *typelib ) 00149 { 00150 const UUID *uuid = get_attrp( class->attrs, ATTR_UUID ); 00151 const char *descr = get_attrp( class->attrs, ATTR_HELPSTRING ); 00152 const char *progid = get_attrp( class->attrs, ATTR_PROGID ); 00153 const char *vi_progid = get_attrp( class->attrs, ATTR_VIPROGID ); 00154 const char *threading = get_coclass_threading( class ); 00155 unsigned int version = get_attrv( class->attrs, ATTR_VERSION ); 00156 00157 if (!uuid) return 0; 00158 if (typelib && !threading && !progid) return 0; 00159 if (!descr) descr = class->name; 00160 00161 put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), descr ); 00162 put_str( indent++, "{\n" ); 00163 if (threading) put_str( indent, "InprocServer32 = s '%%MODULE%%' { val ThreadingModel = s '%s' }\n", 00164 threading ); 00165 if (progid) put_str( indent, "ProgId = s '%s'\n", progid ); 00166 if (typelib) 00167 { 00168 const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID ); 00169 put_str( indent, "TypeLib = s '%s'\n", format_uuid( typelib_uuid )); 00170 if (!version) version = get_attrv( typelib->attrs, ATTR_VERSION ); 00171 } 00172 if (version) put_str( indent, "Version = s '%u.%u'\n", MAJORVERSION(version), MINORVERSION(version) ); 00173 if (vi_progid) put_str( indent, "VersionIndependentProgId = s '%s'\n", vi_progid ); 00174 put_str( --indent, "}\n" ); 00175 return 1; 00176 } 00177 00178 static void write_coclasses( const statement_list_t *stmts, const typelib_t *typelib ) 00179 { 00180 const statement_t *stmt; 00181 00182 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry ) 00183 { 00184 if (stmt->type == STMT_TYPE) 00185 { 00186 const type_t *type = stmt->u.type; 00187 if (type_get_type(type) == TYPE_COCLASS) write_coclass( type, typelib ); 00188 } 00189 } 00190 } 00191 00192 static int write_progid( const type_t *class ) 00193 { 00194 const UUID *uuid = get_attrp( class->attrs, ATTR_UUID ); 00195 const char *descr = get_attrp( class->attrs, ATTR_HELPSTRING ); 00196 const char *progid = get_attrp( class->attrs, ATTR_PROGID ); 00197 const char *vi_progid = get_attrp( class->attrs, ATTR_VIPROGID ); 00198 00199 if (!uuid) return 0; 00200 if (!descr) descr = class->name; 00201 00202 if (progid) 00203 { 00204 put_str( indent, "'%s' = s '%s'\n", progid, descr ); 00205 put_str( indent++, "{\n" ); 00206 put_str( indent, "CLSID = s '%s'\n", format_uuid( uuid ) ); 00207 put_str( --indent, "}\n" ); 00208 } 00209 if (vi_progid) 00210 { 00211 put_str( indent, "'%s' = s '%s'\n", vi_progid, descr ); 00212 put_str( indent++, "{\n" ); 00213 put_str( indent, "CLSID = s '%s'\n", format_uuid( uuid ) ); 00214 if (progid && strcmp( progid, vi_progid )) put_str( indent, "CurVer = s '%s'\n", progid ); 00215 put_str( --indent, "}\n" ); 00216 } 00217 return 1; 00218 } 00219 00220 static void write_progids( const statement_list_t *stmts ) 00221 { 00222 const statement_t *stmt; 00223 00224 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry ) 00225 { 00226 if (stmt->type == STMT_TYPE) 00227 { 00228 const type_t *type = stmt->u.type; 00229 if (type_get_type(type) == TYPE_COCLASS) write_progid( type ); 00230 } 00231 } 00232 } 00233 00234 void write_regscript( const statement_list_t *stmts ) 00235 { 00236 const type_t *ps_factory; 00237 00238 if (!do_regscript) return; 00239 if (do_everything && !need_proxy_file( stmts )) return; 00240 00241 init_output_buffer(); 00242 00243 put_str( indent, "HKCR\n" ); 00244 put_str( indent++, "{\n" ); 00245 00246 put_str( indent, "NoRemove Interface\n" ); 00247 put_str( indent++, "{\n" ); 00248 ps_factory = find_ps_factory( stmts ); 00249 if (ps_factory) write_interfaces( stmts, ps_factory ); 00250 put_str( --indent, "}\n" ); 00251 00252 put_str( indent, "NoRemove CLSID\n" ); 00253 put_str( indent++, "{\n" ); 00254 write_coclasses( stmts, NULL ); 00255 put_str( --indent, "}\n" ); 00256 00257 write_progids( stmts ); 00258 put_str( --indent, "}\n" ); 00259 00260 if (strendswith( regscript_name, ".res" )) /* create a binary resource file */ 00261 { 00262 add_output_to_resources( "WINE_REGISTRY", regscript_token ); 00263 flush_output_resources( regscript_name ); 00264 } 00265 else 00266 { 00267 FILE *f = fopen( regscript_name, "w" ); 00268 if (!f) error( "Could not open %s for output\n", regscript_name ); 00269 if (fwrite( output_buffer, output_buffer_pos, 1, f ) != output_buffer_pos) 00270 error( "Failed to write to %s\n", regscript_name ); 00271 if (fclose( f )) 00272 error( "Failed to write to %s\n", regscript_name ); 00273 } 00274 } 00275 00276 void output_typelib_regscript( const typelib_t *typelib ) 00277 { 00278 const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID ); 00279 const char *descr = get_attrp( typelib->attrs, ATTR_HELPSTRING ); 00280 const expr_t *lcid_expr = get_attrp( typelib->attrs, ATTR_LIBLCID ); 00281 unsigned int version = get_attrv( typelib->attrs, ATTR_VERSION ); 00282 unsigned int flags = 0; 00283 00284 if (is_attr( typelib->attrs, ATTR_RESTRICTED )) flags |= 1; /* LIBFLAG_FRESTRICTED */ 00285 if (is_attr( typelib->attrs, ATTR_CONTROL )) flags |= 2; /* LIBFLAG_FCONTROL */ 00286 if (is_attr( typelib->attrs, ATTR_HIDDEN )) flags |= 4; /* LIBFLAG_FHIDDEN */ 00287 00288 put_str( indent, "HKCR\n" ); 00289 put_str( indent++, "{\n" ); 00290 00291 put_str( indent, "NoRemove Typelib\n" ); 00292 put_str( indent++, "{\n" ); 00293 put_str( indent, "NoRemove '%s'\n", format_uuid( typelib_uuid )); 00294 put_str( indent++, "{\n" ); 00295 put_str( indent, "'%u.%u' = s '%s'\n", 00296 MAJORVERSION(version), MINORVERSION(version), descr ? descr : typelib->name ); 00297 put_str( indent++, "{\n" ); 00298 put_str( indent, "'%x' { %s = s '%%MODULE%%' }\n", 00299 lcid_expr ? lcid_expr->cval : 0, typelib_kind == SYS_WIN64 ? "win64" : "win32" ); 00300 put_str( indent, "FLAGS = s '%u'\n", flags ); 00301 put_str( --indent, "}\n" ); 00302 put_str( --indent, "}\n" ); 00303 put_str( --indent, "}\n" ); 00304 00305 put_str( indent, "NoRemove Interface\n" ); 00306 put_str( indent++, "{\n" ); 00307 write_typelib_interfaces( typelib ); 00308 put_str( --indent, "}\n" ); 00309 00310 put_str( indent, "NoRemove CLSID\n" ); 00311 put_str( indent++, "{\n" ); 00312 write_coclasses( typelib->stmts, typelib ); 00313 put_str( --indent, "}\n" ); 00314 00315 write_progids( typelib->stmts ); 00316 put_str( --indent, "}\n" ); 00317 00318 add_output_to_resources( "WINE_REGISTRY", typelib_name ); 00319 } Generated on Sat May 26 2012 04:25:31 for ReactOS by
1.7.6.1
|