00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "qcomponentfactory_p.h"
00039
00040 #ifndef QT_NO_COMPONENT
00041 #include "qsettings.h"
00042 #include <private/qcomlibrary_p.h>
00043 #include "qdir.h"
00044 #include "qapplication.h"
00045
00103 static QPtrList<QComLibrary> *libraries = 0;
00104
00105 static void cleanup()
00106 {
00107 delete libraries;
00108 libraries = 0;
00109 }
00110
00111 static QPtrList<QComLibrary> *liblist()
00112 {
00113 if ( !libraries ) {
00114 libraries = new QPtrList<QComLibrary>();
00115 libraries->setAutoDelete( TRUE );
00116 qAddPostRoutine( cleanup );
00117 }
00118 return libraries;
00119 }
00120
00146 QRESULT QComponentFactory::createInstance( const QString &cid, const QUuid &iid, QUnknownInterface** iface, QUnknownInterface *outer )
00147 {
00148 QSettings settings;
00149 settings.insertSearchPath( QSettings::Windows, "/Classes" );
00150 bool ok = FALSE;
00151 QString cidStr = cid;
00152 QRESULT res = QE_NOCOMPONENT;
00153
00154 QUuid uuid( cidStr );
00155 if ( uuid.isNull() ) {
00156 uuid = settings.readEntry( "/" + cid + "/CLSID/Default", QString::null, &ok );
00157 cidStr = uuid.toString().upper();
00158 }
00159
00160 if ( cidStr.isEmpty() )
00161 return res;
00162
00163 QString file = settings.readEntry( "/CLSID/" + cidStr + "/InprocServer32/Default", QString::null, &ok );
00164 if ( !ok )
00165 return res;
00166
00167 QComLibrary *library = new QComLibrary( file );
00168 library->setAutoUnload( FALSE );
00169
00170 QComponentFactoryInterface *cfIface =0;
00171 library->queryInterface( IID_QComponentFactory, (QUnknownInterface**)&cfIface );
00172
00173 if ( cfIface ) {
00174 res = cfIface->createInstance( uuid, iid, iface, outer );
00175 cfIface->release();
00176 } else {
00177 res = library->queryInterface( iid, iface );
00178 }
00179 QLibraryInterface *libiface = 0;
00180 if ( library->queryInterface( IID_QLibrary, (QUnknownInterface**)&libiface ) != QS_OK || !qApp ) {
00181 delete library;
00182 } else {
00183 libiface->release();
00184 library->setAutoUnload( TRUE );
00185 liblist()->prepend( library );
00186 }
00187 return res;
00188 }
00189
00199 QRESULT QComponentFactory::registerServer( const QString &filename )
00200 {
00201 QComLibrary lib( filename );
00202 lib.load();
00203 QComponentRegistrationInterface *iface = 0;
00204 QRESULT res = lib.queryInterface( IID_QComponentRegistration, (QUnknownInterface**)&iface );
00205 if ( res != QS_OK )
00206 return res;
00207 QDir dir( filename );
00208 bool ok = iface->registerComponents( dir.absPath() );
00209 iface->release();
00210 return ok ? QS_OK : QS_FALSE;
00211 }
00212
00222 QRESULT QComponentFactory::unregisterServer( const QString &filename )
00223 {
00224 QComLibrary lib( filename );
00225 lib.load();
00226 QComponentRegistrationInterface *iface = 0;
00227 QRESULT res = lib.queryInterface( IID_QComponentRegistration, (QUnknownInterface**)&iface );
00228 if ( res != QS_OK )
00229 return res;
00230 bool ok = iface->unregisterComponents();
00231 iface->release();
00232 return ok ? QS_OK : QS_FALSE;
00233 }
00234
00252 bool QComponentFactory::registerComponent( const QUuid &cid, const QString &filepath, const QString &name, int version, const QString &description )
00253 {
00254 bool ok = FALSE;
00255 QSettings settings;
00256 settings.insertSearchPath( QSettings::Windows, "/Classes" );
00257
00258 QString cidStr = cid.toString().upper();
00259 settings.readEntry( "/CLSID/" + cidStr + "/InprocServer32/Default", QString::null, &ok );
00260 if ( ok )
00261 return FALSE;
00262
00263 ok = settings.writeEntry( "/CLSID/" + cidStr + "/InprocServer32/Default", filepath );
00264 if ( ok && !!description )
00265 settings.writeEntry( "/CLSID/" + cidStr + "/Default", description );
00266
00267
00268 if ( ok && !!name ) {
00269 QString vName = version ? name + "." + QString::number( version ) : name;
00270 settings.writeEntry( "/CLSID/" + cidStr + "/ProgID/Default", vName );
00271 ok = settings.writeEntry( "/" + vName + "/CLSID/Default", cidStr );
00272 if ( ok && !!description )
00273 settings.writeEntry( "/" + vName + "/Default", description );
00274
00275 if ( ok && version ) {
00276 settings.writeEntry( "/CLSID/" + cidStr + "/VersionIndependentProgID/Default", name );
00277 QString curVer = settings.readEntry( "/" + name + "/CurVer/Default" );
00278 if ( !curVer || curVer < vName ) {
00279 settings.writeEntry( "/" + name + "/CurVer/Default", vName );
00280 ok = settings.writeEntry( "/" + name + "/CLSID/Default", cidStr );
00281 if ( ok && !!description )
00282 settings.writeEntry( "/" + name + "/Default", description );
00283 }
00284 }
00285 }
00286
00287 return ok;
00288 }
00289
00299 bool QComponentFactory::unregisterComponent( const QUuid &cid )
00300 {
00301 QSettings settings;
00302 bool ok = FALSE;
00303 settings.insertSearchPath( QSettings::Windows, "/Classes" );
00304
00305 QString cidStr = cid.toString().upper();
00306 if ( cidStr.isEmpty() )
00307 return FALSE;
00308
00309
00310 QString vName = settings.readEntry( "/CLSID/" + cidStr + "/ProgID/Default", QString::null, &ok );
00311 if ( ok ) {
00312 QString name = settings.readEntry( "/CLSID/" + cidStr + "/VersionIndependentProgID/Default", QString::null );
00313 if ( !!name && settings.readEntry( "/" + name + "/CurVer/Default" ) == vName ) {
00314
00315 QString version = vName.right( vName.length() - name.length() - 1 );
00316 QString newVerName;
00317 QString newCidStr;
00318 if ( version.find( '.' ) == -1 ) {
00319 int ver = version.toInt();
00320
00321 while ( ver-- ) {
00322 newVerName = name + "." + QString::number( ver );
00323 newCidStr = settings.readEntry( "/" + newVerName + "/CLSID/Default" );
00324 if ( !!newCidStr )
00325 break;
00326 }
00327 } else {
00328
00329 }
00330 if ( !!newCidStr ) {
00331 settings.writeEntry( "/" + name + "/CurVer/Default", newVerName );
00332 settings.writeEntry( "/" + name + "/CLSID/Default", newCidStr );
00333 } else {
00334 settings.removeEntry( "/" + name + "/CurVer/Default" );
00335 settings.removeEntry( "/" + name + "/CLSID/Default" );
00336 settings.removeEntry( "/" + name + "/Default" );
00337 }
00338 }
00339
00340 settings.removeEntry( "/" + vName + "/CLSID/Default" );
00341 settings.removeEntry( "/" + vName + "/Default" );
00342 }
00343
00344 settings.removeEntry( "/CLSID/" + cidStr + "/VersionIndependentProgID/Default" );
00345 settings.removeEntry( "/CLSID/" + cidStr + "/ProgID/Default" );
00346 settings.removeEntry( "/CLSID/" + cidStr + "/InprocServer32/Default" );
00347 ok = settings.removeEntry( "/CLSID/" + cidStr + "/Default" );
00348
00349 return ok;
00350 }
00351
00352 #endif // QT_NO_COMPONENT