ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

register.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.